[SCM] Worms style game branch, master, updated. upstream/0.9.19-2-g9c2c3a0
Gianfranco Costamagna
costamagnagianfranco at yahoo.it
Fri May 31 12:55:37 UTC 2013
The following commit has been merged in the master branch:
commit de08aa440ab0e0cbb7271064d4765e1fdfae361f
Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
Date: Fri May 31 14:09:28 2013 +0200
Imported Upstream version 0.9.19
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8df0976..bb9c0e8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,78 +1,128 @@
project(hedgewars)
-
#initialise cmake environment
-cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
-FOREACH(policy CMP0003 CMP0012)
- IF(POLICY ${policy})
- CMAKE_POLICY(SET ${policy} NEW)
- ENDIF()
-ENDFOREACH()
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules)
-
-
-#detect Mercurial revision (if present)
-set(version_suffix "") #UNSET THIS VARIABLE AT RELEASE TIME
-set(HGCHANGED "")
-IF(version_suffix MATCHES "-dev")
- set(HW_DEV true)
+cmake_minimum_required(VERSION 2.6.0)
+if(CMAKE_VERSION VERSION_LESS "2.8")
+ set(WARNING "WARNING: ")
+ set(allow_parse_args FALSE)
+else()
+ set(WARNING WARNING)
+ set(allow_parse_args TRUE)
+endif()
+foreach(hwpolicy CMP0003 CMP0012 CMP0017)
+ if(POLICY ${hwpolicy})
+ cmake_policy(SET ${hwpolicy} NEW)
+ endif()
+endforeach()
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules")
+
+
+#possible cmake configuration
+option(NOSERVER "Disable gameServer build (off)]" OFF)
+option(NOPNG "Disable screenshoot compression (off)" OFF)
+option(NOVIDEOREC "Disable video recording (off)" OFF)
+
+#set this to ON when 2.1.0 becomes more widespread (and only for linux)
+option(SYSTEM_PHYSFS "Use system physfs (off)" OFF)
+
+option(BUILD_ENGINE_LIBRARY "Enable hwengine library (off)" OFF)
+option(ANDROID "Enable Android build (off)" OFF)
+
+if(UNIX AND NOT APPLE)
+ option(MINIMAL_FLAGS "Respect system flags as much as possible (off)" OFF)
+else()
+ option(NOAUTOUPDATE "Disable OS X Sparkle update checking" OFF)
+endif()
+
+set(FPFLAGS "" CACHE STRING "Additional Freepascal flags")
+set(GHFLAGS "" CACHE STRING "Additional Haskell flags")
+if(UNIX AND NOT APPLE)
+ set(DATA_INSTALL_DIR "share/hedgewars" CACHE STRING "Resource folder path")
+endif()
+
+
+#detect Mercurial revision and init rev/hash information
+find_program(HGCOMMAND hg)
+if(HGCOMMAND AND (EXISTS ${CMAKE_SOURCE_DIR}/.hg))
+ execute_process(COMMAND ${HGCOMMAND} identify -in
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE internal_version
+ ERROR_QUIET
+ )
+ #check local repo status
+ string(REGEX REPLACE "[^+]" "" HGCHANGED ${internal_version})
+ string(REGEX REPLACE "[0-9a-zA-Z]+(.*) ([0-9]+)(.*)" "\\2" HEDGEWARS_REVISION ${internal_version})
+ string(REGEX REPLACE "([0-9a-zA-Z]+)(.*) [0-9]+(.*)" "\\1" HEDGEWARS_HASH ${internal_version})
+
+ if(HGCHANGED)
+ message(${WARNING} "You have uncommitted changes in your repository!")
+ endif()
+ #let's assume that if you have hg you might be interested in debugging
set(default_build_type "DEBUG")
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.hg)
- FIND_PROGRAM(HGCOMMAND hg)
- IF(HGCOMMAND)
- exec_program(${HGCOMMAND}
- ARGS identify -in ${CMAKE_CURRENT_SOURCE_DIR}
- OUTPUT_VARIABLE version_suffix
- )
- STRING(REGEX REPLACE "[^+]" "" HGCHANGED ${version_suffix})
- STRING(REGEX REPLACE "([0-9a-zA-Z]+)(.*) ([0-9]+)(.*)" "\\3-\\1" version_suffix ${version_suffix})
- IF (HGCHANGED)
- MESSAGE(STATUS "Building revision ${version_suffix} (SOURCE CODE MODIFIED)")
- ELSE()
- MESSAGE(STATUS "Building revision ${version_suffix}")
- ENDIF()
- set(version_suffix "-${version_suffix}")
- ENDIF()
- ENDIF()
-ELSE()
- set(HW_DEV false)
+ #write down hash and rev for easy picking should hg be missing
+ file(WRITE "${CMAKE_SOURCE_DIR}/share/version_info.txt" "Hedgewars versioning information, do not modify\nrev ${HEDGEWARS_REVISION}\nhash ${HEDGEWARS_HASH}\n")
+else()
set(default_build_type "RELEASE")
-ENDIF()
+ # when compiling outside rev control, fetch revision and hash information from version_info.txt
+ find_file(version_info version_info.txt PATH ${CMAKE_SOURCE_DIR}/share)
+ if(version_info)
+ file(STRINGS ${version_info} internal_version REGEX "rev")
+ string(REGEX REPLACE "rev ([0-9]*)" "\\1" HEDGEWARS_REVISION ${internal_version})
+ file(STRINGS ${version_info} internal_version REGEX "hash")
+ string(REGEX REPLACE "hash ([a-zA-Z0-9]*)" "\\1" HEDGEWARS_HASH ${internal_version})
+ else()
+ message(${WARNING} "${CMAKE_SOURCE_DIR}/share/version_info.txt not found, revision information "
+ "will be incorrect!!! Contact your source provider to fix this!")
+ set(HEDGEWARS_REVISION "0000")
+ set(HEDGEWARS_HASH "unknown")
+ endif()
+endif()
#versioning
set(CPACK_PACKAGE_VERSION_MAJOR 0)
set(CPACK_PACKAGE_VERSION_MINOR 9)
-set(CPACK_PACKAGE_VERSION_PATCH 18${version_suffix})
-set(HEDGEWARS_PROTO_VER 43)
+set(CPACK_PACKAGE_VERSION_PATCH 19)
+set(HEDGEWARS_PROTO_VER 45)
set(HEDGEWARS_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+message(STATUS "Building ${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION} (${HEDGEWARS_HASH})")
-#set some default values
-option(NOSERVER "Disable gameServer build [default: auto]" OFF)
-option(NOPNG "Disable screenshoot compression [default: auto]" OFF)
-option(NOVIDEOREC "Disable video recording [default: auto]" OFF)
-
-option(BUILD_ENGINE_LIBRARY "Enable hwengine library [default: off]" OFF)
-option(ANDROID "Enable Android build [default: off]" OFF)
-option(NOAUTOUPDATE "Disable OS X Sparkle update checking" OFF)
-option(CROSSAPPLE "Enable OSX when not on OSX [default: off]" OFF)
+#where to build libs and bins
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+#resource paths
+if(UNIX AND NOT APPLE)
+ set(target_binary_install_dir "bin")
+ set(target_library_install_dir "lib")
-#bundle .app setup
-if(APPLE OR CROSSAPPLE)
- #paths for creating the bundle
- set(bundle_name Hedgewars.app)
- set(frameworks_dir ${bundle_name}/Contents/Frameworks/)
- set(CMAKE_INSTALL_PREFIX ${bundle_name}/Contents/MacOS/)
- set(DATA_INSTALL_DIR "../Resources/")
- set(target_dir ".")
- set(minimum_macosx_version "10.6")
+ string(SUBSTRING "${DATA_INSTALL_DIR}" 0 1 sharepath_start)
+ if (NOT (${sharepath_start} MATCHES "/"))
+ set(HEDGEWARS_DATADIR "${CMAKE_INSTALL_PREFIX}/${DATA_INSTALL_DIR}/")
+ else()
+ set(HEDGEWARS_DATADIR "${DATA_INSTALL_DIR}/")
+ endif()
+ set(HEDGEWARS_FULL_DATADIR "${HEDGEWARS_DATADIR}")
else()
- set(target_dir "bin")
+ set(target_binary_install_dir "./")
+
+ if(APPLE)
+ set(target_library_install_dir "../Frameworks/")
+ set(CMAKE_INSTALL_PREFIX "Hedgewars.app/Contents/MacOS/")
+ set(HEDGEWARS_DATADIR "../Resources/")
+ set(HEDGEWARS_FULL_DATADIR "/Applications/${CMAKE_INSTALL_PREFIX}/${HEDGEWARS_DATADIR}")
+ elseif(WIN32)
+ set(target_library_install_dir "./")
+ set(HEDGEWARS_DATADIR "./")
+ set(HEDGEWARS_FULL_DATADIR "${CMAKE_INSTALL_PREFIX}/")
+ link_directories("${EXECUTABLE_OUTPUT_PATH}" "${CMAKE_SOURCE_DIR}/misc/winutils/bin")
+ endif()
endif()
+
if(APPLE)
set(CMAKE_FIND_FRAMEWORK "FIRST")
@@ -82,12 +132,15 @@ if(APPLE)
#detect on which system we are: if sw_vers cannot be found for any reason (re)use minimum_macosx_version
find_program(sw_vers sw_vers)
if(sw_vers)
- exec_program(${sw_vers} ARGS "-productVersion" OUTPUT_VARIABLE current_macosx_version)
+ execute_process(COMMAND ${sw_vers} "-productVersion"
+ OUTPUT_VARIABLE current_macosx_version
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX REPLACE "([0-9]+.[0-9]+).[0-9]+" "\\1" current_macosx_version ${current_macosx_version})
- else()
+ else()
if(NOT minimum_macosx_version)
message(FATAL_ERROR "sw_vers not found! Need explicit MACOSX_DEPLOYMENT_TARGET variable set")
else()
+ message(${WARNING} "sw_vers not found! Fallback to MACOSX_DEPLOYMENT_TARGET variable")
set(current_macosx_version ${minimum_macosx_version})
endif()
endif()
@@ -97,23 +150,23 @@ if(APPLE)
set(minimum_macosx_version ${current_macosx_version})
endif()
- #lower systems don't have enough processing power anyways
- if (minimum_macosx_version LESS "10.4")
+ #lower systems don't have enough processing power anyway
+ if (minimum_macosx_version VERSION_LESS "10.4")
message(FATAL_ERROR "Hedgewars is not supported on Mac OS X pre-10.4")
endif()
#workaround for http://playcontrol.net/ewing/jibberjabber/big_behind-the-scenes_chang.html#SDL_mixer (Update 2)
- if(current_macosx_version MATCHES "10.4")
+ if(current_macosx_version VERSION_EQUAL "10.4")
find_package(SDL_mixer REQUIRED)
set(DYLIB_SMPEG "-dylib_file @loader_path/Frameworks/smpeg.framework/Versions/A/smpeg:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/smpeg.framework/Versions/A/smpeg")
set(DYLIB_MIKMOD "-dylib_file @loader_path/Frameworks/mikmod.framework/Versions/A/mikmod:${SDLMIXER_LIBRARY}/Versions/A/Frameworks/mikmod.framework/Versions/A/mikmod")
- set(pascal_flags "-k${DYLIB_SMPEG}" "-k${DYLIB_MIKMOD}" ${pascal_flags})
- set(CMAKE_C_FLAGS "${DYLIB_SMPEG}" "${DYLIB_MIKMOD}" ${CMAKE_C_FLAGS})
+ set(CMAKE_C_FLAGS "${DYLIB_SMPEG} ${DYLIB_MIKMOD}")
+ list(APPEND pascal_flags "-k${DYLIB_SMPEG}" "-k${DYLIB_MIKMOD}")
endif()
#CMAKE_OSX_ARCHITECTURES and CMAKE_OSX_SYSROOT need to be set for universal binary and correct linking
if(NOT CMAKE_OSX_ARCHITECTURES)
- if(current_macosx_version LESS "10.6")
+ if(current_macosx_version VERSION_LESS "10.6")
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "powerpc*")
set(CMAKE_OSX_ARCHITECTURES "ppc7400")
else()
@@ -126,11 +179,11 @@ if(APPLE)
#CMAKE_OSX_SYSROOT is set at the system version we are supposed to build on
#we need to provide the correct one when host and target differ
- if(NOT ${minimum_macosx_version} MATCHES ${current_macosx_version})
- if(minimum_macosx_version MATCHES "10.4")
+ if(NOT ${minimum_macosx_version} VERSION_EQUAL ${current_macosx_version})
+ if(minimum_macosx_version VERSION_EQUAL "10.4")
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.4u.sdk/")
- set(CMAKE_C_COMPILER "gcc-4.0")
- set(CMAKE_CXX_COMPILER "g++-4.0")
+ set(CMAKE_C_COMPILER "/Developer/usr/bin/gcc-4.0")
+ set(CMAKE_CXX_COMPILER "/Developer/usr/bin/g++-4.0")
else()
string(REGEX REPLACE "([0-9]+.[0-9]+).[0-9]+" "\\1" sdk_version ${minimum_macosx_version})
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX${sdk_version}.sdk/")
@@ -138,12 +191,9 @@ if(APPLE)
endif()
#add user framework directory, other paths can be passed via FPFLAGS
- set(pascal_flags "-Ff~/Library/Frameworks" ${pascal_flags})
+ list(APPEND pascal_flags "-Ff~/Library/Frameworks")
#set deployment target
- set(pascal_flags "-k-macosx_version_min" "-k${minimum_macosx_version}" "-XR${CMAKE_OSX_SYSROOT}" ${pascal_flags})
-
- message(STATUS "Build system: Mac OS X ${current_macosx_version} with GCC:${CMAKE_C_COMPILER}")
- message(STATUS "Target system: Mac OS X ${minimum_macosx_version} for architecture(s):${CMAKE_OSX_ARCHITECTURES}")
+ list(APPEND pascal_flags "-k-macosx_version_min" "-k${minimum_macosx_version}" "-XR${CMAKE_OSX_SYSROOT}")
endif(APPLE)
@@ -151,92 +201,163 @@ endif(APPLE)
if (CMAKE_BUILD_TYPE)
string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
if ( NOT( (CMAKE_BUILD_TYPE MATCHES "RELEASE") OR (CMAKE_BUILD_TYPE MATCHES "DEBUG") ) )
- set (CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Only 'Debug' or 'Release' options are allowed." FORCE)
+ set (CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release)" FORCE)
message (STATUS "Unknown build type, using default (${default_build_type})")
endif ()
else (CMAKE_BUILD_TYPE)
- set (CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Choose the build type, options are: Debug Release." FORCE)
+ set (CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Build type (Debug/Release)" FORCE)
endif (CMAKE_BUILD_TYPE)
-#set default flags values for all projects
-set(CMAKE_C_FLAGS "-pipe ${CMAKE_C_FLAGS}")
-set(CMAKE_C_FLAGS_RELEASE "-w -Os -fomit-frame-pointer ${CMAKE_C_FLAGS_RELEASE}")
-set(CMAKE_C_FLAGS_DEBUG "-Wall -O0 -g -DDEBUG ${CMAKE_C_FLAGS_DEBUG}")
-set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
-set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
-set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
+#set default flags values for all projects (unless MINIMAL_FLAGS is true)
+if(NOT ${MINIMAL_FLAGS})
+ if(WINDOWS)
+ #this flags prevents a few dll hell problems
+ set(CMAKE_C_FLAGS "-static-libgcc ${CMAKE_C_FLAGS}")
+ endif(WINDOWS)
+ set(CMAKE_C_FLAGS "-pipe ${CMAKE_C_FLAGS}")
+ set(CMAKE_C_FLAGS_RELEASE "-w -Os -fomit-frame-pointer ${CMAKE_C_FLAGS_RELEASE}")
+ set(CMAKE_C_FLAGS_DEBUG "-Wall -O0 -g -DDEBUG ${CMAKE_C_FLAGS_DEBUG}")
+ set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
+ set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
+ set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
+else()
+ #CMake adds a lot of additional configuration flags, so let's clear them up
+ set(CMAKE_C_FLAGS_RELEASE "")
+ set(CMAKE_C_FLAGS_DEBUG "-Wall -DDEBUG")
+ set(CMAKE_CXX_FLAGS_RELEASE "")
+ set(CMAKE_CXX_FLAGS_DEBUG "-Wall -DDEBUG")
+endif()
+
+
+#TESTING TIME
+include(CheckCCompilerFlag)
+
+#check for noexecstack on ELF, should be set on Gentoo and similar
+set(CMAKE_REQUIRED_FLAGS "-Wl,-z -Wl,noexecstack")
+check_c_compiler_flag("" HAVE_NOEXECSTACK) #empty because we are testing a linker flag
+if(HAVE_NOEXECSTACK)
+ list(APPEND pascal_flags "-k-z" "-knoexecstack")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_REQUIRED_FLAGS}")
+endif()
+unset(CMAKE_REQUIRED_FLAGS)
+
+#check for ASLR and DEP security features on Windows
+#both supported in binutils >= 2.20, available since Vista and XP SP2 respectively
+set(CMAKE_REQUIRED_FLAGS "-Wl,--nxcompat -Wl,--dynamicbase")
+check_c_compiler_flag("" HAVE_WINASLRDEP) #empty because we are testing a linker flag
+if(HAVE_WINASLRDEP)
+ list(APPEND pascal_flags "-k--nxcompat" "-k--dynamicbase")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_REQUIRED_FLAGS}")
+endif()
+unset(CMAKE_REQUIRED_FLAGS)
#parse additional parameters
if(FPFLAGS OR GHFLAGS)
- math(EXPR cmake_version "${CMAKE_MAJOR_VERSION}*10000 + ${CMAKE_MINOR_VERSION}*100 + ${CMAKE_PATCH_VERSION}")
- if(cmake_version LESS "020800")
- message(STATUS "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
+ if(${allow_parse_args})
+ message(${WARNING} "FPFLAGS and GHFLAGS are available only when using CMake >= 2.8")
else()
separate_arguments(fpflags_parsed UNIX_COMMAND ${FPFLAGS})
separate_arguments(ghflags_parsed UNIX_COMMAND ${GHFLAGS})
endif()
endif()
-set(pascal_flags ${fpflags_parsed} "-vm4079,4080,4081" "-B" "-FE../bin" "-Cs2000000" "-vewnq" "-dDEBUGFILE" ${pascal_flags})
-set(haskell_flags "-O2" ${ghflags_parsed} ${haskell_flags})
+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
+ )
+
#get BUILD_TYPE and enable/disable optimisation
+message(STATUS "Using ${CMAKE_BUILD_TYPE} configuration")
if(CMAKE_BUILD_TYPE MATCHES "DEBUG")
- message(STATUS "Building Debug flavour")
- set(pascal_flags "-O-" "-g" "-gl" "-gv" ${pascal_flags})
- set(haskell_flags "-Wall" "-debug" "-dcore-lint" "-fno-warn-unused-do-bind" ${haskell_flags})
+ 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()
- message(STATUS "Building Release flavour")
-# set(pascal_flags "-O3" "-OpPENTIUM4" "-CfSSE3" "-Xs" "-Si" ${pascal_flags})
- set(pascal_flags "-Os" "-Ooregvar" "-Xs" "-Si" ${pascal_flags})
- set(haskell_flags "-w" "-fno-warn-unused-do-bind" ${haskell_flags})
+ list(APPEND pascal_flags "-Os" # optimise for size
+ "-Xs" # strip binary
+ "-Si" # turn on inlining
+ )
+ list(APPEND haskell_flags "-w" # no warnings
+ )
endif()
+include(${CMAKE_MODULE_PATH}/utils.cmake)
-#finish setting paths
-if(DEFINED DATA_INSTALL_DIR)
- set(SHAREPATH ${DATA_INSTALL_DIR}/hedgewars/)
+#lua discovery
+find_package(Lua)
+if(LUA_FOUND)
+ message(STATUS "Found LUA: ${LUA_DEFAULT}")
else()
- set(SHAREPATH share/hedgewars/)
+ message(STATUS "LUA will be provided by the bundled sources")
+ add_subdirectory(misc/liblua)
+ #linking with liblua.a requires system readline
+ list(APPEND pascal_flags "-k${EXECUTABLE_OUTPUT_PATH}/lib${LUA_LIBRARY}.a" "-k-lreadline")
endif()
-set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
-set(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})
-#server discovery
-if(NOT NOSERVER)
- if(GHC)
- set(ghc_executable ${GHC})
- else()
- find_program(ghc_executable ghc)
+#physfs discovery
+if (${SYSTEM_PHYSFS})
+ if (NOT PHYSFS_LIBRARY OR NOT PHYSFS_INCLUDE_DIR)
+ find_package(PhysFS)
endif()
- if(ghc_executable)
- set(HAVE_NETSERVER true)
- add_subdirectory(gameServer)
- message(STATUS "Found GHC: ${ghc_executable}")
- else()
- message(STATUS "Could NOT find GHC, server will not be built")
- set(HAVE_NETSERVER false)
+ find_file(physfs_h physfs.h ${PHYSFS_INCLUDE_DIR})
+ if(physfs_h)
+ file(STRINGS ${physfs_h} physfs_majorversion REGEX "PHYSFS_VER_MAJOR[\t' ']+[0-9]+")
+ file(STRINGS ${physfs_h} physfs_minorversion REGEX "PHYSFS_VER_MINOR[\t' ']+[0-9]+")
+ file(STRINGS ${physfs_h} physfs_patchversion REGEX "PHYSFS_VER_PATCH[\t' ']+[0-9]+")
+ string(REGEX MATCH "([0-9]+)" physfs_majorversion "${physfs_majorversion}")
+ string(REGEX MATCH "([0-9]+)" physfs_minorversion "${physfs_minorversion}")
+ string(REGEX MATCH "([0-9]+)" physfs_patchversion "${physfs_patchversion}")
+ set(physfs_detected_ver "${physfs_majorversion}.${physfs_minorversion}.${physfs_patchversion}")
+
+ if (physfs_detected_ver VERSION_LESS "2.1.0")
+ message(FATAL_ERROR "PhysFS version is too old (dected ${physfs_detected_ver}, required 2.1.0)")
+ set(physfs_too_old true)
+ endif()
+ endif()
+
+ if (NOT PHYSFS_LIBRARY OR NOT PHYSFS_INCLUDE_DIR)
+ message(FATAL_ERROR "Missing PhysFS! Rerun cmake with -DPHYSFS_SYSTEM=off to build the internal version")
endif()
else()
- message(STATUS "Server will not be built per user request")
- set(HAVE_NETSERVER false)
+ message(STATUS "PhysFS will be provided by the bundled sources")
+ set(physfs_output_name "hw_physfs")
+ 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")
-#lua discovery
-find_package(Lua)
-if(LUA_FOUND)
- message(STATUS "Found LUA: ${LUA_DEFAULT}")
-else()
- message(STATUS "LUA will be provided by the bundled sources")
- add_subdirectory(misc/liblua)
- #linking with liblua.a requires system readline -- this works everywhere, right?
- set(pascal_flags "-k${EXECUTABLE_OUTPUT_PATH}/lib${LUA_LIBRARY}.a" "-k-lreadline" ${pascal_flags})
-endif()
+#physfs helper library
+add_subdirectory(misc/libphyslayer)
+#server
+if(NOT NOSERVER)
+ add_subdirectory(gameServer)
+endif()
#main engine
add_subdirectory(hedgewars)
@@ -248,95 +369,13 @@ if(ANDROID)
endif()
#TODO: when ANDROID, BUILD_ENGINE_LIBRARY should be set
-if(NOT (BUILD_ENGINE_LIBRARY OR ANDROID))
+if(NOT ANDROID)
add_subdirectory(bin)
- add_subdirectory(misc/quazip)
add_subdirectory(QTfrontend)
add_subdirectory(share)
add_subdirectory(tools)
endif()
-# CPack variables
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hedgewars, a free turn-based strategy")
-set(CPACK_PACKAGE_VENDOR "Hedgewars Project")
-set(CPACK_PACKAGE_FILE_NAME "hedgewars-${HEDGEWARS_VERSION}")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "hedgewars-src-${HEDGEWARS_VERSION}")
-set(CPACK_SOURCE_GENERATOR "TBZ2")
-set(CPACK_PACKAGE_EXECUTABLES "hedgewars" "hedgewars")
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
-set(CPACK_PACKAGE_INSTALL_DIRECTORY "Hedgewars ${HEDGEWARS_VERSION}")
-
-if(WIN32 AND NOT UNIX)
- set(CPACK_NSIS_DISPLAY_NAME "Hedgewars")
- set(CPACK_NSIS_HELP_LINK "http://www.hedgewars.org/")
- set(CPACK_NSIS_URL_INFO_ABOUT "http://www.hedgewars.org/")
- set(CPACK_NSIS_CONTACT "unC0Rr at gmail.com")
- set(CPACK_NSIS_MODIFY_PATH OFF)
- set(CPACK_GENERATOR "ZIP;NSIS")
- set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "hedgewars")
-else(WIN32 AND NOT UNIX)
- set(CPACK_STRIP_FILES "bin/hedgewars;bin/hwengine")
-endif(WIN32 AND NOT UNIX)
-
-set(CPACK_SOURCE_IGNORE_FILES
- "~"
- "\\\\.hg"
- "\\\\.svn"
- "\\\\.exe$"
- "\\\\.a$"
- "\\\\.dll$"
- "\\\\.xcf$"
- "\\\\.cxx$"
- "\\\\.db$"
- "\\\\.dof$"
- "\\\\.layout$"
- "\\\\.zip$"
- "\\\\.gz$"
- "\\\\.bz2$"
- "\\\\.tmp$"
- "\\\\.core$"
- "\\\\.sh$"
- "\\\\.sifz$"
- "\\\\.svg$"
- "\\\\.svgz$"
- "\\\\.ppu$"
- "\\\\.psd$"
- "\\\\.o$"
- "Makefile"
- "Doxyfile"
- "CMakeFiles"
- "debug"
- "release$"
- "Debug$"
- "Release$"
- "proto\\\\.inc$"
- "hwconsts\\\\.cpp$"
- "playlist\\\\.inc$"
- "CPack"
- "cmake_install\\\\.cmake$"
- "config\\\\.inc$"
- "hwengine\\\\.desktop$"
- "CMakeCache\\\\.txt$"
-# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libopenalbridge"
-# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libfreetype"
- "^${CMAKE_CURRENT_SOURCE_DIR}/misc/liblua"
-# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libtremor"
- "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/HedgewarsMobile/"
- "^${CMAKE_CURRENT_SOURCE_DIR}/bin/[a-z]"
- "^${CMAKE_CURRENT_SOURCE_DIR}/tools/templates"
- "^${CMAKE_CURRENT_SOURCE_DIR}/doc"
- "^${CMAKE_CURRENT_SOURCE_DIR}/templates"
- "^${CMAKE_CURRENT_SOURCE_DIR}/Graphics"
- "^${CMAKE_CURRENT_SOURCE_DIR}/realtest"
- "^${CMAKE_CURRENT_SOURCE_DIR}/tmp"
- "^${CMAKE_CURRENT_SOURCE_DIR}/utils"
- "^${CMAKE_CURRENT_SOURCE_DIR}/share/hedgewars/Data/Maps/test"
- "^${CMAKE_CURRENT_SOURCE_DIR}/share/hedgewars/Data/Themes/ethereal"
- "^${CMAKE_CURRENT_SOURCE_DIR}/install_manifest.txt"
- "^${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt"
- "^${CMAKE_CURRENT_SOURCE_DIR}/hedgewars\\\\."
-)
-
-include(CPack)
+include(${CMAKE_MODULE_PATH}/CPackConfig.cmake)
diff --git a/CREDITS b/CREDITS
index 9f57606..e4b9eb2 100644
--- a/CREDITS
+++ b/CREDITS
@@ -6,6 +6,13 @@ EXTENDED CREDITS LIST
- see Fonts_LICENSE.txt
==========
+= FORTS
+==========
+- Carlos Vives -> Tank (2010)
+- Dragonfly -> EvilChicken (2010)
+- Randy Broda -> SteelTower (2013)
+
+==========
= HATS
==========
- Robinator -> Terminator (2010)
@@ -66,4 +73,4 @@ EXTENDED CREDITS LIST
http://www.freesound.org/people/Jovica/sounds/38317/
-ALL OTHER CONTENT IS PROPERTY OF Andrey Korotaev <unC0Rr at gmail.com> UNLESS OTHERWISE SPECIFIED
\ No newline at end of file
+ALL OTHER CONTENT IS PROPERTY OF Andrey Korotaev <unC0Rr at gmail.com> UNLESS OTHERWISE SPECIFIED
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 76ae3ed..70920c2 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,10 +1,45 @@
+ features
* bugfixes
+0.9.18 -> 0.9.19:
+ + New Freezer weapon - freezes terrain, water, hedgehogs, mines, cases, explosives
+ + Saucer can aim weapons and fire underwater
+ + Main graphical user interface overhaul
+ + Splashscreen on Windows *_*
+ + Up and down keys navigate in chat history
+ + Several commands from chat available
+ + Support hwplay:// scheme syntax
+ + Supply full revision and hash information in version tag
+ + Better set of options for driving engine
+ + Downloadable content can now be stored in packages for easy uninstall
+ + Lua scripts can load a sidecar overlay package of game resources
+ + Math improvements for better performance/reliability
+ + Smarter AI - now uses drill rocket accurately and is aware of barrels and dud mines. More aggressive in infinite attack, lua can tell to target specific hogs, such as in Mutant
+ + New fort, Steel Tower
+ + New theme, Fruit
+ + New hats - some national ones, Portal, harlequin, more animals...
+ + New maps based on StarBound. SB_Bones, SB_Crystal, SB_Grassy, SB_Grove, SB_Haunty, SB_Oaks, SB_Shrooms, SB_Tentacles
+ + Translation updates - Turkish, French, German, Japanese, Portuguese, Italian, Russian - Campaign french should work correctly now
+ + Theme object masks
+ + Easier weapon selection in shoppa. F1 will select from F5 if there are no weps in F1-F4
+ + Cleaver radius shrunk to improve usability on horizontal throws
+ + Map hog limit is now just a suggestion, not enforced
+ + Static map theme is now just the default, can be changed
+ + Themeable static maps (provide a mask.png without a map.png)
+ + Split seed with '|' to keep the land shape but change the hog placement
+ * You can now move out of the way when throwing a sticky mine or cleaver straight up
+ * Rope sliding should behave more like pre-0.9.18 again
+ * Forbid kicking on 1v1 matches
+ * Desync fixes
+ * Fixed fort mode
+ * Making very large maps now works properly with targetted weapons
+ * ParseCommand should be safe to use in Lua now, at any time
+ * Fixes to many weapons. Mudball, blowtorch, explosives, cluster bomb spread, portal.
+
0.9.17 -> 0.9.18:
+ 'A Classic Fairytale' Campaign
- + Video recorder (requires ffmpeg)
+ + Video recorder (requires ffmpeg/libav)
+ Cleaver weapon
+ AI is now aware of drowning and fall damage
+ AI learned how to use Sniper Rifle and Cake
@@ -28,7 +63,7 @@
* Fix all knowns bugs which caused network game hang when players close engine or quit
* Fix drill strike bug when drill's timer gets ridiculously high value instead of explosion
* Fix some crashes, freezes and memory leaks in frontend and engine
-
+
0.9.16 -> 0.9.17:
+ New theme, Cave
+ New voicepack, Hillbilly
@@ -401,7 +436,7 @@ Frontend/Menu and Netgame:
+ AI updates
+ Teams now work in fort mode, i.e. 2v2
+ Ability to attack whilst jumping/rope swinging
- + Some weapons can only be used after a certain number of turns
+ + Some weapons can only be used after a certain number of turns
+ Lots of new graphics
* Many network/gameplay bug fixes
diff --git a/INSTALL b/INSTALL
index 1ce0fde..898c519 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,18 +1,29 @@
To compile and install you need:
- - Qt >= 4.5
- - FreePascal >= 2.2.4
+ - CMake >= 2.6.0
+ - FreePascal >= 2.2.0
+ - Qt >= 4.5.0
- SDL >= 1.2.5
- SDL_net >= 1.2.5
- SDL_mixer >= 1.2
- SDL_image >= 1.2
- SDL_ttf >= 2.0
- - CMake >= 2.6.0
- Lua >= 5.1.0
+ - Physfs >= 2.1.0
For server:
- Glasgow Haskell Compiler >= 6.10
- bytestring-show package
- dataenc package
- hslogger package
+For videorecording:
+ - FFmpeg or LibAV
+ - GLUT (when SDL < 2)
+For compressed screenshots:
+ - libpng
+
+Lua will be automatically built if not found.
+
+PhysFS will internally built unless -DPHYSFS_SYSTEM=on is passed to cmake
+(also allows to set PHYSFS_LIBRARY and PHYSFS_INCLUDE_DIR if needed).
1. Configure:
$ cmake .
@@ -20,8 +31,12 @@ or
$ cmake -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="install_prefix" \
-DDATA_INSTALL_DIR="data_dir" -DNOSERVER=1 .
-add -DNOSERVER=0 to compile net server; if you have Qt installed but it is
-not found you can set it up with -DQT_QMAKE_EXECUTABLE="path_to_qmake"
+Add -DNOSERVER=0 to compile net server (remember to check out the additional
+dependencies with the hedgewars-server.cabal configuration file. If you have
+Qt installed but it is not found, you can set it up with
+-DQT_QMAKE_EXECUTABLE="path_to_qmake".
+To get a glimpse of the main configuration options, you may use this command
+`cat CMakeLists.txt | grep option`
2. Compile:
$ make
@@ -31,3 +46,4 @@ $ make
That's all! Enjoy!
+
diff --git a/QTfrontend/AutoUpdater.h b/QTfrontend/AutoUpdater.h
deleted file mode 100644
index 914a11e..0000000
--- a/QTfrontend/AutoUpdater.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (C) 2008 Remko Troncon
- */
-
-#ifndef AUTOUPDATER_H
-#define AUTOUPDATER_H
-
-class AutoUpdater
-{
- public:
- virtual ~AutoUpdater();
-
- virtual void checkForUpdates() = 0;
-};
-
-#endif
diff --git a/QTfrontend/CMakeLists.txt b/QTfrontend/CMakeLists.txt
index 5a4216c..65c0c50 100644
--- a/QTfrontend/CMakeLists.txt
+++ b/QTfrontend/CMakeLists.txt
@@ -11,28 +11,40 @@ set(QT_USE_QTOPENGL FALSE)
set(QT_USE_QTMAIN TRUE)
find_package(Qt4 REQUIRED)
-if (NOT CROSSAPPLE)
- include(${QT_USE_FILE})
-endif()
-
-# Check if we need zlib
-check_library_exists("${QT_QTCORE_LIBRARY}" inflateInit2_ ${QT_LIBRARY_DIR} QT_PROVIDES_ZLIB_FUNCTIONS)
-
-if(NOT QT_PROVIDES_ZLIB_FUNCTIONS)
- find_package(ZLIB REQUIRED)
-
- set(HW_LINK_LIBS ${ZLIB_LIBRARIES} ${HW_LINK_LIBS})
-endif()
+include(${QT_USE_FILE})
+find_package(SDL REQUIRED) #video in SDLInteraction
+find_package(SDL_mixer REQUIRED) #audio in SDLInteraction
-# Configure for SDL
-find_package(SDL REQUIRED)
-find_package(SDL_mixer REQUIRED)
-if(NOT NOVIDEOREC)
- find_package(FFMPEG)
+if(${FFMPEG_FOUND})
+ add_definitions(-DVIDEOREC -D__STDC_CONSTANT_MACROS)
+ include_directories(${FFMPEG_INCLUDE_DIR})
+ list(APPEND HW_LINK_LIBS ${FFMPEG_LIBRARIES})
endif()
-include_directories(.)
+# server messages localization
+file(GLOB ServerSources ${CMAKE_SOURCE_DIR}/gameServer/*.hs)
+foreach(hsfile ${ServerSources})
+ file(READ ${hsfile} hs)
+ string(REGEX MATCHALL "loc *\"[^\n\"]+\"" locs ${hs})
+ foreach(str ${locs})
+ string(REGEX REPLACE "loc *\"([^\n\"]+)\"" "QT_TRANSLATE_NOOP(\"server\", \"\\1\")" s ${str})
+ list(APPEND serverlocs ${s})
+ endforeach(str)
+endforeach(hsfile)
+
+list(REMOVE_DUPLICATES serverlocs)
+list(GET serverlocs 0 firstline)
+list(REMOVE_AT serverlocs 0)
+set(locsout "const char * serverMessages[] = {\n")
+foreach(l ${serverlocs})
+ list(APPEND locsout ${l} ",\n")
+endforeach(l)
+list(APPEND locsout ${firstline} "\n}\\;\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/servermessages.h ${locsout})
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/model)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/net)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ui)
@@ -40,33 +52,23 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ui/dialog)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ui/page)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/ui/widget)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/util)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/util/platform)
include_directories(${SDL_INCLUDE_DIR})
include_directories(${SDLMIXER_INCLUDE_DIR})
-include_directories(${FFMPEG_INCLUDE_DIR})
-include_directories(${CMAKE_SOURCE_DIR}/misc/quazip)
+include_directories(${PHYSFS_INCLUDE_DIR})
+include_directories(${PHYSLAYER_INCLUDE_DIR})
+
+
if(UNIX)
# HACK: in freebsd cannot find iconv.h included via SDL.h
include_directories("/usr/local/include")
endif(UNIX)
-
-if(WIN32 AND NOT UNIX)
- set(HEDGEWARS_BINDIR ".")
- set(HEDGEWARS_DATADIR "../share/")
- add_definitions(-DUSE_XFIRE)
-else()
- set(HEDGEWARS_BINDIR ${CMAKE_INSTALL_PREFIX})
- if(DEFINED DATA_INSTALL_DIR)
- set(HEDGEWARS_DATADIR ${DATA_INSTALL_DIR})
- else()
- set(HEDGEWARS_DATADIR ${CMAKE_INSTALL_PREFIX}/share/)
- endif()
- #only the cocoa version of qt supports building 64 bit apps
- if(APPLE AND (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64*") AND (NOT QT_MAC_USE_COCOA))
- message(FATAL_ERROR "Building the 64 bit version of Hedgewars *requires* the Cocoa variant of QT on Mac OS X")
- endif()
+#only the cocoa version of qt supports building 64 bit apps
+if(APPLE AND (CMAKE_OSX_ARCHITECTURES MATCHES "x86_64*") AND (NOT QT_MAC_USE_COCOA))
+ message(FATAL_ERROR "Building the 64 bit version of Hedgewars *requires* the Cocoa variant of QT on Mac OS X")
endif()
-
+#endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/hwconsts.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/hwconsts.cpp)
@@ -75,11 +77,7 @@ file(GLOB ModelCpp model/*.cpp)
file(GLOB_RECURSE UIcpp ui/*.cpp)
file(GLOB UtilCpp util/*.cpp)
-if(${FFMPEG_FOUND})
- add_definitions(-DVIDEOREC -D__STDC_CONSTANT_MACROS)
-endif()
-
-set(hwfr_src
+list(APPEND hwfr_src
${ModelCpp}
${NetCpp}
${UIcpp}
@@ -100,18 +98,18 @@ set(hwfr_src
#xfire integration
if(WIN32)
- set(hwfr_src ${hwfr_src} xfire.cpp ../misc/xfire/xfiregameclient.cpp)
+ list(APPEND hwfr_src util/platform/xfire.cpp util/platform/xfiregameclient.cpp)
endif(WIN32)
if(MINGW)
# resource compilation for mingw
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/hedgewars_rc.o
- COMMAND windres -I ${CMAKE_CURRENT_SOURCE_DIR}
- -i ${CMAKE_CURRENT_SOURCE_DIR}/hedgewars.rc
- -o ${CMAKE_CURRENT_BINARY_DIR}/hedgewars_rc.o)
- set(hwfr_src ${hwfr_src} ${CMAKE_CURRENT_BINARY_DIR}/hedgewars_rc.o)
+ COMMAND windres -I ${CMAKE_CURRENT_SOURCE_DIR}
+ -i ${CMAKE_CURRENT_SOURCE_DIR}/hedgewars.rc
+ -o ${CMAKE_CURRENT_BINARY_DIR}/hedgewars_rc.o)
+ list(APPEND hwfr_src ${CMAKE_CURRENT_BINARY_DIR}/hedgewars_rc.o)
else(MINGW)
- set(hwfr_src ${hwfr_src} hedgewars.rc)
+ list(APPEND hwfr_src hedgewars.rc)
endif(MINGW)
file(GLOB ModelHdr model/*.h)
@@ -140,58 +138,75 @@ set(hwfr_hdrs
achievements.h
binds.h
ui_hwform.h
- KB.h
hwconsts.h
sdlkeys.h
campaign.h
+ ${CMAKE_CURRENT_BINARY_DIR}/servermessages.h
)
set(hwfr_rez hedgewars.qrc)
+if(${BUILD_ENGINE_LIBRARY})
+ add_definitions(-DHWLIBRARY=1)
+ set(hwlibname "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}hwengine${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ list(APPEND HW_LINK_LIBS ${hwlibname})
+endif()
+
qt4_add_resources(hwfr_rez_src ${hwfr_rez})
qt4_wrap_cpp(hwfr_moc_srcs ${hwfr_moc_hdrs})
-if(APPLE OR CROSSAPPLE)
- set(hwfr_src ${hwfr_src} InstallController.cpp CocoaInitializer.mm M3Panel.mm M3InstallController.m NSWorkspace_RBAdditions.m)
- set(HW_LINK_LIBS IOKit ${HW_LINK_LIBS})
-
- if(NOT NOAUTOUPDATE)
- find_package(Sparkle)
- if(SPARKLE_FOUND)
- add_definitions(-DSPARKLE_ENABLED)
- set(hwfr_src ${hwfr_src} AutoUpdater.cpp SparkleAutoUpdater.mm)
- set(HW_LINK_LIBS ${SPARKLE_LIBRARY} ${HW_LINK_LIBS})
- endif()
+if(APPLE)
+ find_library(iokit_framework NAMES IOKit)
+ list(APPEND HW_LINK_LIBS ${iokit_framework})
+ list(APPEND hwfr_src util/platform/CocoaInitializer.mm
+ util/platform/InstallController.cpp
+ util/platform/M3Panel.mm
+ util/platform/M3InstallController.m
+ util/platform/NSWorkspace_RBAdditions.m
+ )
+ include(${CMAKE_MODULE_PATH}/utils.cmake)
+ find_package_or_disable_msg(Sparkle NOAUTOUPDATE "Autoupdater will not be built.")
+ if(SPARKLE_FOUND)
+ add_definitions(-DSPARKLE_ENABLED)
+ list(APPEND hwfr_src util/platform/AutoUpdater.cpp
+ util/platform/SparkleAutoUpdater.mm)
+ list(APPEND HW_LINK_LIBS ${SPARKLE_LIBRARY})
endif()
endif()
+#when debugging, always prompt a console to see fronted messages
+#TODO: check it doesn't interfere on UNIX
+if(CMAKE_BUILD_TYPE MATCHES "RELEASE")
+ set(console_access "WIN32")
+endif(CMAKE_BUILD_TYPE MATCHES "RELEASE")
-add_executable(hedgewars WIN32
+add_executable(hedgewars ${console_access}
${hwfr_src}
${hwfr_moc_srcs}
${hwfr_hdrs}
${hwfr_rez_src}
)
+if((UNIX AND NOT APPLE) AND ${BUILD_ENGINE_LIBRARY})
+ set_target_properties(hedgewars PROPERTIES LINK_FLAGS "-Wl,-rpath,${CMAKE_INSTALL_PREFIX}/${target_library_install_dir}")
+endif()
-set(HW_LINK_LIBS
- quazip
+list(APPEND HW_LINK_LIBS
+ ${PHYSFS_LIBRARY}
+ ${PHYSLAYER_LIBRARY}
${QT_LIBRARIES}
${SDL_LIBRARY}
${SDLMIXER_LIBRARY}
- ${FFMPEG_LIBRARIES}
- ${HW_LINK_LIBS}
)
if(WIN32 AND NOT UNIX)
if(NOT SDL_LIBRARY)
- set(HW_LINK_LIBS ${HW_LINK_LIBS} SDL)
+ list(APPEND HW_LINK_LIBS SDL)
endif()
- set(HW_LINK_LIBS
- ${HW_LINK_LIBS}
+ list(APPEND HW_LINK_LIBS
ole32
oleaut32
winspool
@@ -199,13 +214,8 @@ if(WIN32 AND NOT UNIX)
)
endif()
-
-if (CROSSAPPLE)
- add_dependencies(hedgewars quazip)
-else()
- target_link_libraries(hedgewars ${HW_LINK_LIBS})
-endif()
+target_link_libraries(hedgewars ${HW_LINK_LIBS})
-install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/hedgewars${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_dir})
+install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/hedgewars${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_binary_install_dir})
diff --git a/QTfrontend/CocoaInitializer.h b/QTfrontend/CocoaInitializer.h
deleted file mode 100644
index 81f25f3..0000000
--- a/QTfrontend/CocoaInitializer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
-
-#ifndef COCOAINITIALIZER_H
-#define COCOAINITIALIZER_H
-
-class CocoaInitializer
-{
- public:
- CocoaInitializer();
- ~CocoaInitializer();
-
- private:
- class Private;
- Private* c;
-};
-
-#endif
diff --git a/QTfrontend/CocoaInitializer.mm b/QTfrontend/CocoaInitializer.mm
deleted file mode 100644
index a1f6bcc..0000000
--- a/QTfrontend/CocoaInitializer.mm
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
-
-#include "CocoaInitializer.h"
-
-#include <AppKit/AppKit.h>
-#include <Cocoa/Cocoa.h>
-#include <QtDebug>
-
-class CocoaInitializer::Private
-{
- public:
- NSAutoreleasePool* pool;
-};
-
-CocoaInitializer::CocoaInitializer()
-{
- c = new CocoaInitializer::Private();
- NSApplicationLoad();
- c->pool = [[NSAutoreleasePool alloc] init];
-}
-
-CocoaInitializer::~CocoaInitializer()
-{
- [c->pool release];
- delete c;
-}
diff --git a/QTfrontend/HWApplication.cpp b/QTfrontend/HWApplication.cpp
index c3a7c67..44b1c5e 100644
--- a/QTfrontend/HWApplication.cpp
+++ b/QTfrontend/HWApplication.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2012 Vittorio Giovara <vittorio.giovara at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,30 +18,84 @@
#include "HWApplication.h"
#include <QFileOpenEvent>
+#include <QEvent>
#include "hwform.h"
+#include "MessageDialog.h"
-HWApplication::HWApplication(int &argc, char **argv):
+#if !defined(Q_WS_WIN)
+#include "signal.h"
+#endif
+
+#if !defined(Q_WS_WIN)
+void terminateFrontend(int signal)
+{
+ Q_UNUSED(signal);
+ QCoreApplication::exit(0);
+}
+#endif
+
+HWApplication::HWApplication(int &argc, char **argv) :
QApplication(argc, argv)
{
+#if !defined(Q_WS_WIN)
+ signal(SIGINT, &terminateFrontend);
+#endif
+#if 0
+ qDebug("%s called with", argv[0]);
+ for (int i = 1; i < argc; i++)
+ qDebug("%d: %s", i, argv[i]);
+#endif
+ // on Windows, sending an event right away leads to a segfault
+ // so we use urlString to save the data and send the event just before the app.exec()
+ urlString = NULL;
+ if (argc > 1) {
+ urlString = new QString(argv[1]);
+ if (urlString->contains("//", Qt::CaseInsensitive) == false) {
+ delete urlString;
+ urlString = NULL;
+ }
+ }
+}
+void HWApplication::fakeEvent()
+{
+ QUrl parsedUrl(*urlString);
+ delete urlString;
+ urlString = NULL;
+ QFileOpenEvent *openEvent = new QFileOpenEvent(parsedUrl);
+ QCoreApplication::sendEvent(QCoreApplication::instance(), openEvent);
}
bool HWApplication::event(QEvent *event)
{
QFileOpenEvent *openEvent;
+ QString scheme, path, address;
+
+ if (event->type() == QEvent::FileOpen) {
+ openEvent = (QFileOpenEvent *)event;
+ scheme = openEvent->url().scheme();
+ path = openEvent->url().path();
+ address = openEvent->url().host();
- switch (event->type())
- {
- case QEvent::FileOpen:
- openEvent = (QFileOpenEvent *)event;
- if (form) form->PlayDemoQuick(openEvent->file());
+ QFile file(path);
+ if (scheme == "file" && file.exists()) {
+ form->PlayDemoQuick(path);
return true;
- break;
- default:
- return QApplication::event(event);
- break;
+ } else if (scheme == "hwplay") {
+ int port = openEvent->url().port(NETGAME_DEFAULT_PORT);
+ if (address == "")
+ address = NETGAME_DEFAULT_SERVER;
+ form->NetConnectQuick(address, (quint16) port);
+ return true;
+ } else {
+ const QString errmsg = tr("Scheme '%1' not supported").arg(scheme);
+ MessageDialog::ShowErrorMessage(errmsg, form);
+ return false;
+ }
}
+
+ return QApplication::event(event);
}
diff --git a/QTfrontend/HWApplication.h b/QTfrontend/HWApplication.h
index 5ddc24e..a42ede3 100644
--- a/QTfrontend/HWApplication.h
+++ b/QTfrontend/HWApplication.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2012 Vittorio Giovara <vittorio.giovara at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +20,9 @@
#define HWAPP_H
#include <QApplication>
-#include <QString>
-#include <QEvent>
class HWForm;
+class QEvent;
/**
* @brief Main class of the Qt application.
@@ -41,6 +40,8 @@ class HWApplication : public QApplication
~HWApplication() {};
HWForm *form;
+ QString *urlString;
+ void fakeEvent();
protected:
bool event(QEvent *);
};
diff --git a/QTfrontend/InstallController.cpp b/QTfrontend/InstallController.cpp
deleted file mode 100644
index 25210ee..0000000
--- a/QTfrontend/InstallController.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include "InstallController.h"
-
-InstallController::~InstallController()
-{
-}
diff --git a/QTfrontend/InstallController.h b/QTfrontend/InstallController.h
deleted file mode 100644
index 970874c..0000000
--- a/QTfrontend/InstallController.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef INSTALLCONTROLLER_H
-#define INSTALLCONTROLLER_H
-
-class InstallController
-{
- public:
- virtual ~InstallController();
-
- virtual void showInstallController() = 0;
-};
-
-#endif
diff --git a/QTfrontend/KB.h b/QTfrontend/KB.h
index 0026ca9..a687c5c 100644
--- a/QTfrontend/KB.h
+++ b/QTfrontend/KB.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/M3InstallController.m b/QTfrontend/M3InstallController.m
deleted file mode 100644
index 22dae74..0000000
--- a/QTfrontend/M3InstallController.m
+++ /dev/null
@@ -1,97 +0,0 @@
-/*****************************************************************
- M3InstallController.m
-
- Created by Martin Pilkington on 02/06/2007.
-
- Copyright (c) 2006-2009 M Cubed Software
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- *****************************************************************/
-
-#import "M3InstallController.h"
-#import "NSWorkspace_RBAdditions.h"
-
-#import <Foundation/Foundation.h>
-
- at implementation M3InstallController
-
-- (id) init {
- if ((self = [super init])) {
- NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
- NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ is currently running from a disk image", @"AppName is currently running from a disk image"), appName];
- NSString *body = [NSString stringWithFormat:NSLocalizedString(@"Would you like to install %@ in your applications folder before quitting?", @"Would you like to install App Name in your applications folder before quitting?"), appName];
- alert = [[NSAlert alertWithMessageText:title
- defaultButton:NSLocalizedString(@"Install", @"Install")
- alternateButton:NSLocalizedString(@"Don't Install", @"Don't Install")
- otherButton:nil
- informativeTextWithFormat:body] retain];
- //[alert setShowsSuppressionButton:YES];
- }
- return self;
-}
-
-- (void)displayInstaller {
- NSString *imageFilePath = [[[NSWorkspace sharedWorkspace] propertiesForPath:[[NSBundle mainBundle] bundlePath]] objectForKey:NSWorkspace_RBimagefilepath];
- if (imageFilePath && ![imageFilePath isEqualToString:[NSString stringWithFormat:@"/Users/.%@/%@.sparseimage", NSUserName(), NSUserName()]] && ![[NSUserDefaults standardUserDefaults] boolForKey:@"M3DontAskInstallAgain"]) {
- NSInteger returnValue = [alert runModal];
- if (returnValue == NSAlertDefaultReturn) {
- [self installApp];
- }
- if ([[alert suppressionButton] state] == NSOnState) {
- [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"M3DontAskInstallAgain"];
- }
- }
-}
-
-- (void)installApp {
- NSString *appsPath = [[NSString stringWithString:@"/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]];
- NSString *userAppsPath = [[[NSString stringWithString:@"~/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]] stringByExpandingTildeInPath];
- NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
-
- //Delete the app that is installed
- if ([[NSFileManager defaultManager] fileExistsAtPath:appsPath]) {
- [[NSFileManager defaultManager] removeFileAtPath:appsPath handler:nil];
- }
- //Delete the app that is installed
- if ([[NSFileManager defaultManager] copyPath:[[NSBundle mainBundle] bundlePath] toPath:appsPath
- handler:nil]) {
- NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"%@ installed successfully", @"App Name installed successfully"), appName],
- [NSString stringWithFormat:NSLocalizedString(@"%@ was installed in /Applications", @"App Name was installed in /Applications"), appName],
- NSLocalizedString(@"Quit", @"Quit"), nil, nil);
- } else {
- if ([[NSFileManager defaultManager] fileExistsAtPath:userAppsPath]) {
- [[NSFileManager defaultManager] removeFileAtPath:userAppsPath handler:nil];
- }
- if ([[NSFileManager defaultManager] copyPath:[[NSBundle mainBundle] bundlePath] toPath:userAppsPath
- handler:nil]) {
- NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"%@ installed successfully", @"AppName installed successfully"), appName],
- [NSString stringWithFormat:NSLocalizedString(@"%@ was installed in %@", @"App Name was installed in %@"), appName, [[NSString stringWithString:@"~/Applications"] stringByExpandingTildeInPath]],
- NSLocalizedString(@"Quit", @"Quit"), nil, nil);
- } else {
- NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"Could not install %@", @"Could not install App Name"), appName],
- NSLocalizedString(@"An error occurred when installing", @"An error occurred when installing"), NSLocalizedString(@"Quit", @"Quit"), nil, nil);
- }
- }
-}
-
- at end
diff --git a/QTfrontend/M3Panel.h b/QTfrontend/M3Panel.h
deleted file mode 100644
index 09580ab..0000000
--- a/QTfrontend/M3Panel.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef M3PANEL_H
-#define M3PANEL_H
-
-#include "InstallController.h"
-
-class M3Panel : public InstallController
-{
- public:
- M3Panel(void);
- ~M3Panel();
-
- void showInstallController();
-
- private:
- class Private;
- Private* c;
-};
-
-#endif
diff --git a/QTfrontend/M3Panel.mm b/QTfrontend/M3Panel.mm
deleted file mode 100644
index 672b0e3..0000000
--- a/QTfrontend/M3Panel.mm
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include "M3Panel.h"
-#include "M3InstallController.h"
-
-#include <Cocoa/Cocoa.h>
-
-class M3Panel::Private
-{
- public:
- M3InstallController *install;
-};
-
-M3Panel::M3Panel(void)
-{
- c = new Private;
-
- c->install = [[M3InstallController alloc] init];
- [c->install retain];
-}
-
-M3Panel::~M3Panel()
-{
- [c->install release];
- delete c;
-}
-
-void M3Panel::showInstallController()
-{
- [c->install displayInstaller];
-}
diff --git a/QTfrontend/NSWorkspace_RBAdditions.m b/QTfrontend/NSWorkspace_RBAdditions.m
deleted file mode 100644
index abbfa8c..0000000
--- a/QTfrontend/NSWorkspace_RBAdditions.m
+++ /dev/null
@@ -1,263 +0,0 @@
-//
-// NSWorkspace_RBAdditions.m
-// PathProps
-//
-// Created by Rainer Brockerhoff on 10/04/2007.
-// Copyright 2007 Rainer Brockerhoff. All rights reserved.
-//
-
-#import "NSWorkspace_RBAdditions.h"
-#include <IOKit/IOKitLib.h>
-#include <sys/mount.h>
-#include <mach/mach.h>
-
-NSString* NSWorkspace_RBfstypename = @"NSWorkspace_RBfstypename";
-NSString* NSWorkspace_RBmntonname = @"NSWorkspace_RBmntonname";
-NSString* NSWorkspace_RBmntfromname = @"NSWorkspace_RBmntfromname";
-NSString* NSWorkspace_RBdeviceinfo = @"NSWorkspace_RBdeviceinfo";
-NSString* NSWorkspace_RBimagefilepath = @"NSWorkspace_RBimagefilepath";
-NSString* NSWorkspace_RBconnectiontype = @"NSWorkspace_RBconnectiontype";
-NSString* NSWorkspace_RBpartitionscheme = @"NSWorkspace_RBpartitionscheme";
-NSString* NSWorkspace_RBserverURL = @"NSWorkspace_RBserverURL";
-
-// This static funtion concatenates two strings, but first checks several possibilities...
-// like one or the other nil, or one containing the other already.
-
-static NSString* AddPart(NSString* first,NSString* second) {
- if (!second) {
- return first;
- }
- second = [second stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- if (first) {
- if ([first rangeOfString:second options:NSCaseInsensitiveSearch].location==NSNotFound) {
- if ([second rangeOfString:first options:NSCaseInsensitiveSearch].location==NSNotFound) {
- return [NSString stringWithFormat:@"%@; %@",first,second];
- }
- return second;
- }
- return first;
- }
- return second;
-}
-
-// This static functions recurses "upwards" over the IO registry. Returns strings that are concatenated
-// and ultimately end up under the NSWorkspace_RBdeviceinfo key.
-// This isn't too robust in that it assumes that objects returned by the objectForKey methods are
-// either strings or dictionaries. A "standard" implementations would use either only CoreFoundation and
-// IOKit calls for this, or do more robust type checking on the returned objects.
-//
-// Also notice that this works as determined experimentally in 10.4.9, there's no official docs I could find.
-// YMMV, and it may stop working in any new version of Mac OS X.
-
-static NSString* CheckParents(io_object_t thing,NSString* part,NSMutableDictionary* dict) {
- NSString* result = part;
- io_iterator_t parentsIterator = 0;
- kern_return_t kernResult = IORegistryEntryGetParentIterator(thing,kIOServicePlane,&parentsIterator);
- if ((kernResult==KERN_SUCCESS)&&parentsIterator) {
- io_object_t nextParent = 0;
- while ((nextParent = IOIteratorNext(parentsIterator))) {
- NSDictionary* props = nil;
- NSString* image = nil;
- NSString* partition = nil;
- NSString* connection = nil;
- kernResult = IORegistryEntryCreateCFProperties(nextParent,(CFMutableDictionaryRef*)&props,kCFAllocatorDefault,0);
- if (IOObjectConformsTo(nextParent,"IOApplePartitionScheme")) {
- partition = [props objectForKey:@"Content Mask"];
- } else if (IOObjectConformsTo(nextParent,"IOMedia")) {
- partition = [props objectForKey:@"Content"];
- } else if (IOObjectConformsTo(nextParent,"IODiskImageBlockStorageDeviceOutKernel")) {
- NSData* data = nil;
- if ((data = [[props objectForKey:@"Protocol Characteristics"] objectForKey:@"Virtual Interface Location Path"])) {
- image = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding] autorelease];
- }
- } else if (IOObjectConformsTo(nextParent,"IOHDIXHDDriveInKernel")) {
- image = [props objectForKey:@"KDIURLPath"];
- }
- NSDictionary* subdict;
- if ((subdict = [props objectForKey:@"Protocol Characteristics"])) {
- connection = [subdict objectForKey:@"Physical Interconnect"];
- } else {
- connection = [props objectForKey:@"Physical Interconnect"];
- }
- if (connection) {
- [dict setObject:AddPart([dict objectForKey:NSWorkspace_RBconnectiontype],connection) forKey:NSWorkspace_RBconnectiontype];
- }
- if (partition) {
- [dict setObject:partition forKey:NSWorkspace_RBpartitionscheme];
- }
- if (image) {
- [dict setObject:image forKey:NSWorkspace_RBimagefilepath];
- }
- NSString* value;
- if ((subdict = [props objectForKey:@"Device Characteristics"])) {
- if ((value = [subdict objectForKey:@"Product Name"])) {
- result = AddPart(result,value);
- }
- if ((value = [subdict objectForKey:@"Product Revision Level"])) {
- result = AddPart(result,value);
- }
- if ((value = [subdict objectForKey:@"Vendor Name"])) {
- result = AddPart(result,value);
- }
- }
- if ((value = [props objectForKey:@"USB Serial Number"])) {
- result = AddPart(result,value);
- }
- if ((value = [props objectForKey:@"USB Vendor Name"])) {
- result = AddPart(result,value);
- }
- NSString* cls = [(NSString*)IOObjectCopyClass(nextParent) autorelease];
- if (![cls isEqualToString:@"IOPCIDevice"]) {
-
-// Uncomment the following line to have the device tree dumped to the console.
-// NSLog(@"=================================> %@:%@\n",cls,props);
-
- result = CheckParents(nextParent,result,dict);
- }
- IOObjectRelease(nextParent);
- }
- }
- if (parentsIterator) {
- IOObjectRelease(parentsIterator);
- }
- return result;
-}
-
-// This formats the (partially undocumented) AFPXMountInfo info into a string.
-
-/*
-static NSString* FormatAFPURL(AFPXVolMountInfoPtr mountInfo,NSString** devdesc) {
- UInt8* work = ((UInt8*)mountInfo)+mountInfo->serverNameOffset;
- if (devdesc) {
- *devdesc = [[[NSString alloc] initWithBytes:&work[1] length:work[0] encoding:NSUTF8StringEncoding] autorelease];
- }
- work = ((UInt8*)mountInfo)+mountInfo->volNameOffset;
- NSString* volname = [[[NSString alloc] initWithBytes:&work[1] length:work[0] encoding:NSUTF8StringEncoding] autorelease];
- work = ((UInt8*)mountInfo)+mountInfo->alternateAddressOffset;
- AFPAlternateAddress* afpa = (AFPAlternateAddress*)work;
- AFPTagData* afpta = (AFPTagData*)(&afpa->fAddressList);
- NSString* ip = nil;
- NSString* dns = nil;
- int i = afpa->fAddressCount;
- while ((i-->0)) {
- switch (afpta->fType) {
- case kAFPTagTypeIP:
- if (!ip) {
- ip = [[[NSString alloc] initWithBytes:&afpta->fData[0] length:afpta->fLength-2 encoding:NSUTF8StringEncoding] autorelease];
- }
- break;
- case kAFPTagTypeIPPort:
- ip = [NSString stringWithFormat:@"%u.%u.%u.%u:%u",afpta->fData[0],afpta->fData[1],afpta->fData[2],afpta->fData[3],OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[4])];
- break;
- case kAFPTagTypeDNS:
- dns = [[[NSString alloc] initWithBytes:&afpta->fData[0] length:afpta->fLength-2 encoding:NSUTF8StringEncoding] autorelease];
- break;
- case 0x07:
- ip = [NSString stringWithFormat:@"[%x:%x:%x:%x:%x:%x:%x:%x]",OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[0]),
- OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[2]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[4]),
- OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[6]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[8]),
- OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[10]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[12]),
- OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[14])];
- break;
- }
- afpta = (AFPTagData*)((char*)afpta+afpta->fLength);
- }
- return [NSString stringWithFormat:@"afp://%@/%@",dns?:(ip?:@""),volname];
-}
-*/
-
- at implementation NSWorkspace (NSWorkspace_RBAdditions)
-
-// Returns a NSDictionary with properties for the path. See details in the .h file.
-// This assumes that the length of path is less than PATH_MAX (currently 1024 characters).
-
-- (NSDictionary*)propertiesForPath:(NSString*)path {
- const char* ccpath = (const char*)[path fileSystemRepresentation];
- NSMutableDictionary* result = nil;
- struct statfs fs;
- if (!statfs(ccpath,&fs)) {
- NSString* from = [NSString stringWithUTF8String:fs.f_mntfromname];
- result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- [NSString stringWithUTF8String:fs.f_fstypename],NSWorkspace_RBfstypename,
- [NSString stringWithUTF8String:fs.f_mntonname],NSWorkspace_RBmntonname,
- nil];
- if (strncmp(fs.f_mntfromname,"/dev/",5)==0) {
-// For a local volume,get the IO registry tree and search it for further info.
- mach_port_t masterPort = 0;
- io_iterator_t mediaIterator = 0;
- kern_return_t kernResult = IOMasterPort(bootstrap_port,&masterPort);
- if (kernResult==KERN_SUCCESS) {
- CFMutableDictionaryRef classesToMatch = IOBSDNameMatching(masterPort,0,&fs.f_mntfromname[5]);
- if (classesToMatch) {
- kernResult = IOServiceGetMatchingServices(masterPort,classesToMatch,&mediaIterator);
- if ((kernResult==KERN_SUCCESS)&&mediaIterator) {
- io_object_t firstMedia = 0;
- while ((firstMedia = IOIteratorNext(mediaIterator))) {
- NSString* stuff = CheckParents(firstMedia,nil,result);
- if (stuff) {
- [result setObject:stuff forKey:NSWorkspace_RBdeviceinfo];
- }
- IOObjectRelease(firstMedia);
- }
- }
- }
- }
- if (mediaIterator) {
- IOObjectRelease(mediaIterator);
- }
- if (masterPort) {
- mach_port_deallocate(mach_task_self(),masterPort);
- }
- }
- //Don't need this for disk images, gets around warnings for some deprecated functions
-
- /* else {
-// For a network volume, get the volume reference number and use to get the server URL.
- FSRef ref;
- if (FSPathMakeRef((const UInt8*)ccpath,&ref,NULL)==noErr) {
- FSCatalogInfo info;
- if (FSGetCatalogInfo(&ref,kFSCatInfoVolume,&info,NULL,NULL,NULL)==noErr) {
- ParamBlockRec pb;
- UInt16 vmisize = 0;
- VolumeMountInfoHeaderPtr mountInfo = NULL;
- pb.ioParam.ioCompletion = NULL;
- pb.ioParam.ioNamePtr = NULL;
- pb.ioParam.ioVRefNum = info.volume;
- pb.ioParam.ioBuffer = (Ptr)&vmisize;
- pb.ioParam.ioReqCount = sizeof(vmisize);
- if ((PBGetVolMountInfoSize(&pb)==noErr)&&vmisize) {
- mountInfo = (VolumeMountInfoHeaderPtr)malloc(vmisize);
- if (mountInfo) {
- pb.ioParam.ioBuffer = (Ptr)mountInfo;
- pb.ioParam.ioReqCount = vmisize;
- if (PBGetVolMountInfo(&pb)==noErr) {
- NSString* url = nil;
- switch (mountInfo->media) {
- case AppleShareMediaType:
- url = FormatAFPURL((AFPXVolMountInfoPtr)mountInfo,&from);
- break;
- case 'http':
- url = from;
- break;
- case 'crbm':
- case 'nfs_':
- case 'cifs':
- url = [NSString stringWithUTF8String:(char*)mountInfo+sizeof(VolumeMountInfoHeader)+sizeof(OSType)];
- break;
- }
- if (url) {
- [result setObject:url forKey:NSWorkspace_RBserverURL];
- }
- }
- }
- free(mountInfo);
- }
- }
- }
- }*/
- [result setObject:from forKey:NSWorkspace_RBmntfromname];
- }
- return result;
-}
-
- at end
diff --git a/QTfrontend/SparkleAutoUpdater.mm b/QTfrontend/SparkleAutoUpdater.mm
deleted file mode 100644
index a5d1712..0000000
--- a/QTfrontend/SparkleAutoUpdater.mm
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
-
-#include "SparkleAutoUpdater.h"
-
-#include <Cocoa/Cocoa.h>
-#include <Sparkle/Sparkle.h>
-
-class SparkleAutoUpdater::Private
-{
- public:
- SUUpdater* updater;
-};
-
-SparkleAutoUpdater::SparkleAutoUpdater()
-{
- d = new Private;
-
- d->updater = [SUUpdater sharedUpdater];
- [d->updater retain];
-}
-
-SparkleAutoUpdater::~SparkleAutoUpdater()
-{
- [d->updater release];
- delete d;
-}
-
-void SparkleAutoUpdater::checkForUpdates()
-{
- [d->updater checkForUpdatesInBackground];
-}
-
-void SparkleAutoUpdater::checkForUpdatesNow()
-{
- [d->updater checkForUpdates:NULL];
-}
diff --git a/QTfrontend/achievements.cpp b/QTfrontend/achievements.cpp
index 7f916b2..87ec9e7 100644
--- a/QTfrontend/achievements.cpp
+++ b/QTfrontend/achievements.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/achievements.h b/QTfrontend/achievements.h
index 4f113d2..7630df0 100644
--- a/QTfrontend/achievements.h
+++ b/QTfrontend/achievements.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/binds.cpp b/QTfrontend/binds.cpp
index 76f6678..143bd65 100644
--- a/QTfrontend/binds.cpp
+++ b/QTfrontend/binds.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,17 +20,15 @@
const BindAction cbinds[BINDS_NUMBER] =
{
- {"+up", "up", QT_TRANSLATE_NOOP("binds", "up"), QT_TRANSLATE_NOOP("binds (categories)", "Basic controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Move your hogs and aim:")},
+ {"+up", "up", QT_TRANSLATE_NOOP("binds", "up"), QT_TRANSLATE_NOOP("binds (categories)", "Movement"), QT_TRANSLATE_NOOP("binds (descriptions)", "Hedgehog movement")},
{"+left", "left", QT_TRANSLATE_NOOP("binds", "left"), NULL, NULL},
{"+right", "right", QT_TRANSLATE_NOOP("binds", "right"), NULL, NULL},
{"+down", "down", QT_TRANSLATE_NOOP("binds", "down"), NULL, NULL},
{"+precise", "left_shift", QT_TRANSLATE_NOOP("binds", "precise aim"), NULL, NULL},
{"ljump", "return", QT_TRANSLATE_NOOP("binds", "long jump"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Traverse gaps and obstacles by jumping:")},
{"hjump", "backspace", QT_TRANSLATE_NOOP("binds", "high jump"), NULL, NULL},
- {"+attack", "space", QT_TRANSLATE_NOOP("binds", "attack"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Fire your selected weapon or trigger an utility item:")},
- {"put", "mousel", QT_TRANSLATE_NOOP("binds", "put"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or a target location under the cursor:")},
{"switch", "tab", QT_TRANSLATE_NOOP("binds", "switch"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Switch your currently active hog (if possible):")},
- {"ammomenu", "mouser", QT_TRANSLATE_NOOP("binds", "ammo menu"), QT_TRANSLATE_NOOP("binds (categories)", "Weapon controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or utility item:")},
+ {"ammomenu", "mouser", QT_TRANSLATE_NOOP("binds", "ammo menu"), QT_TRANSLATE_NOOP("binds (categories)", "Weapons"), QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or utility item:")},
{"slot 1", "f1", QT_TRANSLATE_NOOP("binds", "slot 1"), NULL, NULL},
{"slot 2", "f2", QT_TRANSLATE_NOOP("binds", "slot 2"), NULL, NULL},
{"slot 3", "f3", QT_TRANSLATE_NOOP("binds", "slot 3"), NULL, NULL},
@@ -46,7 +44,9 @@ const BindAction cbinds[BINDS_NUMBER] =
{"timer 3", "3", QT_TRANSLATE_NOOP("binds", "timer 3 sec"), NULL, NULL},
{"timer 4", "4", QT_TRANSLATE_NOOP("binds", "timer 4 sec"), NULL, NULL},
{"timer 5", "5", QT_TRANSLATE_NOOP("binds", "timer 5 sec"), NULL, NULL},
- {"findhh", "h", QT_TRANSLATE_NOOP("binds", "find hedgehog"), QT_TRANSLATE_NOOP("binds (categories)", "Camera and cursor controls"), QT_TRANSLATE_NOOP("binds (descriptions)", "Move the camera to the active hog:")},
+ {"+attack", "space", QT_TRANSLATE_NOOP("binds", "attack"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Fire your selected weapon or trigger an utility item:")},
+ {"put", "mousel", QT_TRANSLATE_NOOP("binds", "put"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Pick a weapon or a target location under the cursor:")},
+ {"findhh", "h", QT_TRANSLATE_NOOP("binds", "find hedgehog"), QT_TRANSLATE_NOOP("binds (categories)", "Camera"), QT_TRANSLATE_NOOP("binds (descriptions)", "Move the camera to the active hog:")},
{"+cur_u", "[8]", QT_TRANSLATE_NOOP("binds", "up"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Move the cursor or camera without using the mouse:")},
{"+cur_l", "[4]", QT_TRANSLATE_NOOP("binds", "left"), NULL, NULL},
{"+cur_r", "[6]", QT_TRANSLATE_NOOP("binds", "right"), NULL, NULL},
@@ -55,7 +55,7 @@ const BindAction cbinds[BINDS_NUMBER] =
{"zoomin", "wheelup", QT_TRANSLATE_NOOP("binds", "zoom in"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Modify the camera's zoom level:")},
{"zoomout", "wheeldown", QT_TRANSLATE_NOOP("binds", "zoom out"), NULL, NULL},
{"zoomreset", "mousem", QT_TRANSLATE_NOOP("binds", "reset zoom"), NULL, NULL},
- {"chat", "t", QT_TRANSLATE_NOOP("binds", "chat"), QT_TRANSLATE_NOOP("binds (categories)", "Other"), QT_TRANSLATE_NOOP("binds (descriptions)", "Talk to your team or all participants:")},
+ {"chat", "t", QT_TRANSLATE_NOOP("binds", "chat"), QT_TRANSLATE_NOOP("binds (categories)", "Miscellaneous"), QT_TRANSLATE_NOOP("binds (descriptions)", "Talk to your team or all participants:")},
{"history", "`", QT_TRANSLATE_NOOP("binds", "chat history"), NULL, NULL},
{"pause", "p", QT_TRANSLATE_NOOP("binds", "pause"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Pause, continue or leave your game:")},
{"quit", "escape", QT_TRANSLATE_NOOP("binds", "quit"), NULL, NULL},
@@ -65,6 +65,8 @@ const BindAction cbinds[BINDS_NUMBER] =
{"mute", "8", QT_TRANSLATE_NOOP("binds", "mute audio"), NULL, NULL},
{"fullscr", "f12", QT_TRANSLATE_NOOP("binds", "change mode"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle fullscreen mode:")},
{"capture", "c", QT_TRANSLATE_NOOP("binds", "capture"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Take a screenshot:")},
- {"rotmask", "delete", QT_TRANSLATE_NOOP("binds", "hedgehogs\ninfo"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle labels above hedgehogs:")},
+ {"rotmask", "delete", QT_TRANSLATE_NOOP("binds", "hedgehog info"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Toggle labels above hedgehogs:")},
+#ifdef VIDEOREC
{"record", "r", QT_TRANSLATE_NOOP("binds", "record"), NULL, QT_TRANSLATE_NOOP("binds (descriptions)", "Record video:")}
+#endif
};
diff --git a/QTfrontend/binds.h b/QTfrontend/binds.h
index 162bb8e..774aa47 100644
--- a/QTfrontend/binds.h
+++ b/QTfrontend/binds.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,11 @@
#include <QString>
+#ifdef VIDEOREC
#define BINDS_NUMBER 46
+#else
+#define BINDS_NUMBER 45
+#endif
struct BindAction
{
diff --git a/QTfrontend/campaign.cpp b/QTfrontend/campaign.cpp
index ad1fa68..7e8c69a 100644
--- a/QTfrontend/campaign.cpp
+++ b/QTfrontend/campaign.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,50 +16,19 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-#include <QDir>
-#include <QFile>
-#include <QTextStream>
-#include <QPushButton>
-#include <QListWidget>
-#include <QStackedLayout>
-#include <QLineEdit>
-#include <QLabel>
-#include <QRadioButton>
-#include <QSpinBox>
-#include <QCloseEvent>
-#include <QCheckBox>
-#include <QTextBrowser>
-#include <QAction>
-#include <QTimer>
-#include <QScrollBar>
-#include <QDataWidgetMapper>
-#include <QTableView>
-#include <QCryptographicHash>
-#include <QSignalMapper>
-#include <QShortcut>
-#include <QDesktopServices>
-#include <QInputDialog>
-#include <QPropertyAnimation>
-#include <QSettings>
-
#include "campaign.h"
-#include "gameuiconfig.h"
+
#include "hwconsts.h"
-#include "gamecfgwidget.h"
-#include "bgwidget.h"
-#include "mouseoverfilter.h"
-#include "tcpBase.h"
-#include "DataManager.h"
+#include <QSettings>
-extern QString campaign, campaignTeam;
QStringList getCampMissionList(QString & campaign)
{
- QSettings campfile(DataManager::instance().findFileForRead("Missions/Campaign/" + campaign + "/campaign.ini"), QSettings::IniFormat, 0);
+ QSettings campfile("physfs://Missions/Campaign/" + campaign + "/campaign.ini", QSettings::IniFormat, 0);
campfile.setIniCodec("UTF-8");
unsigned int mNum = campfile.value("MissionNum", 0).toInt();
-
+
QStringList missionList;
for (unsigned int i = 0; i < mNum; i++)
{
@@ -67,7 +36,7 @@ QStringList getCampMissionList(QString & campaign)
}
return missionList;
}
-
+
unsigned int getCampProgress(QString & teamName, QString & campName)
{
QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + teamName + ".hwt", QSettings::IniFormat, 0);
@@ -77,14 +46,7 @@ unsigned int getCampProgress(QString & teamName, QString & campName)
QString getCampaignScript(QString campaign, unsigned int mNum)
{
- QSettings campfile(DataManager::instance().findFileForRead("Missions/Campaign/" + campaign + "/campaign.ini"), QSettings::IniFormat, 0);
+ QSettings campfile("physfs://Missions/Campaign/" + campaign + "/campaign.ini", QSettings::IniFormat, 0);
campfile.setIniCodec("UTF-8");
return campfile.value(QString("Mission %1/Script").arg(mNum)).toString();
}
-
-
-
-
-
-
-
diff --git a/QTfrontend/campaign.h b/QTfrontend/campaign.h
index 181a95c..170ad16 100644
--- a/QTfrontend/campaign.h
+++ b/QTfrontend/campaign.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,21 +19,8 @@
#ifndef CAMPAIGN_H
#define CAMPAIGN_H
-#include <QMainWindow>
-#include <QStack>
-#include <QTime>
-#include <QPointer>
-#include <QPropertyAnimation>
-#include <QUrl>
-#include <QNetworkReply>
-#include <QNetworkRequest>
-#include <QNetworkAccessManager>
-
-#include "netserver.h"
-#include "game.h"
-#include "ui_hwform.h"
-#include "SDLInteraction.h"
-#include "bgwidget.h"
+#include <QString>
+#include <QStringList>
QStringList getCampMissionList(QString & campaign);
unsigned int getCampProgress(QString & teamName, QString & campName);
diff --git a/QTfrontend/drawmapscene.cpp b/QTfrontend/drawmapscene.cpp
index 713a3d0..2b7082c 100644
--- a/QTfrontend/drawmapscene.cpp
+++ b/QTfrontend/drawmapscene.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/drawmapscene.h b/QTfrontend/drawmapscene.h
index dec6e14..6a0516a 100644
--- a/QTfrontend/drawmapscene.h
+++ b/QTfrontend/drawmapscene.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/game.cpp b/QTfrontend/game.cpp
index f8f70e7..b5644bf 100644
--- a/QTfrontend/game.cpp
+++ b/QTfrontend/game.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,29 +22,43 @@
#include <QColor>
#include <QStringListModel>
#include <QTextStream>
+#include <utility>
+#include "hwform.h"
+#include "ui/page/pageoptions.h"
#include "game.h"
#include "hwconsts.h"
#include "gameuiconfig.h"
#include "gamecfgwidget.h"
#include "teamselect.h"
-#include "KB.h"
#include "proto.h"
+#include "binds.h"
#include "campaign.h"
#include <QTextStream>
#include "ThemeModel.h"
+// last game info
+QList<QVariant> lastGameStartArgs = QList<QVariant>();
+GameType lastGameType = gtNone;
+GameCFGWidget * lastGameCfg = NULL;
+QString lastGameAmmo = NULL;
+TeamSelWidget * lastGameTeamSel = NULL;
+
QString training, campaign, campaignScript, campaignTeam; // TODO: Cleaner solution?
HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) :
- TCPBase(true),
+ TCPBase(true, 0),
ammostr(ammo),
m_pTeamSelWidget(pTeamSelWidget)
{
this->config = config;
this->gamecfg = gamecfg;
netSuspend = false;
+
+ lastGameCfg = gamecfg;
+ lastGameAmmo = ammo;
+ lastGameTeamSel = pTeamSelWidget;
}
HWGame::~HWGame()
@@ -57,7 +71,7 @@ void HWGame::onClientDisconnect()
switch (gameType)
{
case gtDemo:
- // for video recording we need demo anyway
+ // for video recording we need demo anyway
emit HaveRecord(rtNeither, demo);
break;
case gtNet:
@@ -74,6 +88,18 @@ void HWGame::onClientDisconnect()
SetGameState(gsStopped);
}
+void HWGame::addKeyBindings(QByteArray * buf)
+{
+ for(int i = 0; i < BINDS_NUMBER; i++)
+ {
+ QString value = config->value(QString("Binds/%1").arg(cbinds[i].action), cbinds[i].strbind).toString();
+ if (value.isEmpty() || value == "default") continue;
+
+ QString bind = QString("edbind " + value + " " + cbinds[i].action);
+ HWProto::addStringToBuffer(*buf, bind);
+ }
+}
+
void HWGame::commonConfig()
{
QByteArray buf;
@@ -91,6 +117,8 @@ void HWGame::commonConfig()
}
HWProto::addStringToBuffer(buf, gt);
+ addKeyBindings(&buf);
+
buf += gamecfg->getFullConfig();
if (m_pTeamSelWidget)
@@ -103,10 +131,11 @@ void HWGame::commonConfig()
HWProto::addStringToBuffer(buf, QString("eammreinf %1").arg(ammostr.mid(3 * cAmmoNumber, cAmmoNumber)));
if(gamecfg->schemeData(15).toBool() || !gamecfg->schemeData(21).toBool()) HWProto::addStringToBuffer(buf, QString("eammstore"));
HWProto::addStringListToBuffer(buf,
- team.teamGameConfig(gamecfg->getInitHealth()));
+ team.teamGameConfig(gamecfg->getInitHealth(), config));
;
}
}
+
RawSendIPC(buf);
}
@@ -120,6 +149,8 @@ void HWGame::SendQuickConfig()
QByteArray teamscfg;
ThemeModel * themeModel = DataManager::instance().themeModel();
+ addKeyBindings(&teamscfg);
+
HWProto::addStringToBuffer(teamscfg, "TL");
HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
.arg((themeModel->rowCount() > 0) ? themeModel->index(rand() % themeModel->rowCount()).data().toString() : "steel"));
@@ -133,7 +164,7 @@ void HWGame::SendQuickConfig()
team1.setNumHedgehogs(4);
HWNamegen::teamRandomNames(team1,true);
HWProto::addStringListToBuffer(teamscfg,
- team1.teamGameConfig(100));
+ team1.teamGameConfig(100, config));
HWTeam team2;
team2.setDifficulty(4);
@@ -143,7 +174,7 @@ void HWGame::SendQuickConfig()
HWNamegen::teamRandomNames(team2,true);
while(!team2.name().compare(team1.name()) || !team2.hedgehog(0).Hat.compare(team1.hedgehog(0).Hat));
HWProto::addStringListToBuffer(teamscfg,
- team2.teamGameConfig(100));
+ team2.teamGameConfig(100, config));
HWProto::addStringToBuffer(teamscfg, QString("eammloadt %1").arg(cDefaultAmmoStore->mid(0, cAmmoNumber)));
HWProto::addStringToBuffer(teamscfg, QString("eammprob %1").arg(cDefaultAmmoStore->mid(cAmmoNumber, cAmmoNumber)));
@@ -151,6 +182,7 @@ void HWGame::SendQuickConfig()
HWProto::addStringToBuffer(teamscfg, QString("eammreinf %1").arg(cDefaultAmmoStore->mid(3 * cAmmoNumber, cAmmoNumber)));
HWProto::addStringToBuffer(teamscfg, QString("eammstore"));
HWProto::addStringToBuffer(teamscfg, QString("eammstore"));
+
RawSendIPC(teamscfg);
}
@@ -161,6 +193,8 @@ void HWGame::SendTrainingConfig()
HWProto::addStringToBuffer(traincfg, "eseed " + QUuid::createUuid().toString());
HWProto::addStringToBuffer(traincfg, "escript " + training);
+ addKeyBindings(&traincfg);
+
RawSendIPC(traincfg);
}
@@ -172,6 +206,8 @@ void HWGame::SendCampaignConfig()
HWProto::addStringToBuffer(campaigncfg, "escript " + campaignScript);
+ addKeyBindings(&campaigncfg);
+
RawSendIPC(campaigncfg);
}
@@ -203,6 +239,7 @@ void HWGame::ParseMessage(const QByteArray & msg)
SendQuickConfig();
break;
}
+ case gtNone:
case gtSave:
case gtDemo:
break;
@@ -230,20 +267,6 @@ void HWGame::ParseMessage(const QByteArray & msg)
emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4));
return;
}
- case 'K':
- {
- ulong kb = msg.mid(2).toULong();
- if (kb==1)
- {
- qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData());
- return;
- }
- if (kb && kb <= KBmsgsCount)
- {
- emit ErrorMessage(KBMessages[kb - 1]);
- }
- return;
- }
case 'i':
{
emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3)));
@@ -269,7 +292,6 @@ void HWGame::ParseMessage(const QByteArray & msg)
int size = msg.size();
QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4));
emit SendChat(msgbody);
- // FIXME: /me command doesn't work here
QByteArray buf;
HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20");
demo.append(buf);
@@ -290,14 +312,22 @@ void HWGame::ParseMessage(const QByteArray & msg)
writeCampaignVar(msg.right(msg.size() - 3));
break;
}
+ case 'W':
+ {
+ // fetch new window resolution via IPC and save it in the settings
+ int size = msg.size();
+ QString newResolution = QString().append(msg.mid(2)).left(size - 4);
+ QStringList wh = newResolution.split('x');
+ config->Form->ui.pageOptions->windowWidthEdit->setValue(wh[0].toInt());
+ config->Form->ui.pageOptions->windowHeightEdit->setValue(wh[1].toInt());
+ break;
+ }
default:
{
if (gameType == gtNet && !netSuspend)
- {
- emit SendNet(msg);
- }
- if (msg.at(1) != 's')
- demo.append(msg);
+ m_netSendBuffer.append(msg);
+
+ demo.append(msg);
}
}
}
@@ -325,29 +355,65 @@ void HWGame::onClientRead()
readbuffer.remove(0, msglen + 1);
ParseMessage(msg);
}
+
+ flushNetBuffer();
+}
+
+void HWGame::flushNetBuffer()
+{
+ if(m_netSendBuffer.size())
+ {
+ emit SendNet(m_netSendBuffer);
+
+ m_netSendBuffer.clear();
+ }
}
QStringList HWGame::getArguments()
{
QStringList arguments;
- QRect resolution = config->vid_Resolution();
- arguments << cfgdir->absolutePath();
- arguments << QString::number(resolution.width());
- arguments << QString::number(resolution.height());
- arguments << QString::number(config->bitDepth()); // bpp
+ std::pair<QRect, QRect> resolutions = config->vid_ResolutionPair();
+ QString nick = config->netNick().toUtf8().toBase64();
+
+ arguments << "--internal"; //Must be passed as first argument
+ arguments << "--port";
arguments << QString("%1").arg(ipc_port);
- arguments << (config->vid_Fullscreen() ? "1" : "0");
- arguments << (config->isSoundEnabled() ? "1" : "0");
- arguments << (config->isMusicEnabled() ? "1" : "0");
- arguments << QString::number(config->volume()); // sound volume
- arguments << QString::number(config->timerInterval());
+ arguments << "--prefix";
arguments << datadir->absolutePath();
- arguments << (config->isShowFPSEnabled() ? "1" : "0");
- arguments << (config->isAltDamageEnabled() ? "1" : "0");
- arguments << config->netNick().toUtf8().toBase64();
+ arguments << "--user-prefix";
+ arguments << cfgdir->absolutePath();
+ arguments << "--locale";
+ arguments << tr("en.txt");
+ arguments << "--frame-interval";
+ arguments << QString::number(config->timerInterval());
+ arguments << "--volume";
+ arguments << QString::number(config->volume());
+ arguments << "--fullscreen-width";
+ arguments << QString::number(resolutions.first.width());
+ arguments << "--fullscreen-height";
+ arguments << QString::number(resolutions.first.height());
+ arguments << "--width";
+ arguments << QString::number(resolutions.second.width());
+ arguments << "--height";
+ arguments << QString::number(resolutions.second.height());
+ arguments << "--raw-quality";
arguments << QString::number(config->translateQuality());
+ arguments << "--stereo";
arguments << QString::number(config->stereoMode());
- arguments << tr("en.txt");
+ if (config->vid_Fullscreen())
+ arguments << "--fullscreen";
+ if (config->isShowFPSEnabled())
+ arguments << "--showfps";
+ if (config->isAltDamageEnabled())
+ arguments << "--altdmg";
+ if (!config->isSoundEnabled())
+ arguments << "--nosound";
+ if (!config->isMusicEnabled())
+ arguments << "--nomusic";
+ if (!nick.isEmpty()) {
+ arguments << "--nick";
+ arguments << nick;
+ }
return arguments;
}
@@ -367,7 +433,7 @@ void HWGame::PlayDemo(const QString & demofilename, bool isSave)
// run engine
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
@@ -375,43 +441,59 @@ void HWGame::StartNet()
{
gameType = gtNet;
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
void HWGame::StartLocal()
{
+ lastGameStartArgs.clear();
+ lastGameType = gtLocal;
+
gameType = gtLocal;
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
void HWGame::StartQuick()
{
+ lastGameStartArgs.clear();
+ lastGameType = gtQLocal;
+
gameType = gtQLocal;
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
void HWGame::StartTraining(const QString & file)
{
+ lastGameStartArgs.clear();
+ lastGameStartArgs.append(file);
+ lastGameType = gtTraining;
+
gameType = gtTraining;
training = "Missions/Training/" + file + ".lua";
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
void HWGame::StartCampaign(const QString & camp, const QString & campScript, const QString & campTeam)
{
+ lastGameStartArgs.clear();
+ lastGameStartArgs.append(camp);
+ lastGameStartArgs.append(campScript);
+ lastGameStartArgs.append(campTeam);
+ lastGameType = gtCampaign;
+
gameType = gtCampaign;
campaign = camp;
campaignScript = "Missions/Campaign/" + camp + "/" + campScript;
campaignTeam = campTeam;
demo.clear();
- Start();
+ Start(false);
SetGameState(gsStarted);
}
@@ -435,7 +517,7 @@ void HWGame::abort()
void HWGame::sendCampaignVar(const QByteArray &varToSend)
{
QString varToFind(varToSend);
- QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + campaignTeam + ".hwt", QSettings::IniFormat, 0);
+ QSettings teamfile(QString("physfs://Teams/%1.hwt").arg(campaignTeam), QSettings::IniFormat, 0);
teamfile.setIniCodec("UTF-8");
QString varValue = teamfile.value("Campaign " + campaign + "/" + varToFind, "").toString();
QByteArray command;
@@ -452,7 +534,7 @@ void HWGame::writeCampaignVar(const QByteArray & varVal)
QString varToWrite = QString::fromUtf8(varVal.left(i));
QString varValue = QString::fromUtf8(varVal.mid(i + 1));
- QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + campaignTeam + ".hwt", QSettings::IniFormat, 0);
+ QSettings teamfile(QString("physfs://Teams/%1.hwt").arg(campaignTeam), QSettings::IniFormat, 0);
teamfile.setIniCodec("UTF-8");
teamfile.setValue("Campaign " + campaign + "/" + varToWrite, varValue);
}
diff --git a/QTfrontend/game.h b/QTfrontend/game.h
index 24b272b..9740acb 100644
--- a/QTfrontend/game.h
+++ b/QTfrontend/game.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +29,18 @@ class GameUIConfig;
class GameCFGWidget;
class TeamSelWidget;
+enum GameType
+{
+ gtNone = 0,
+ gtLocal = 1,
+ gtQLocal = 2,
+ gtDemo = 3,
+ gtNet = 4,
+ gtTraining = 5,
+ gtCampaign = 6,
+ gtSave = 7,
+};
+
enum GameState
{
gsNotStarted = 0,
@@ -49,6 +61,13 @@ enum RecordType
bool checkForDir(const QString & dir);
+// last game info
+extern QList<QVariant> lastGameStartArgs;
+extern GameType lastGameType;
+extern GameCFGWidget * lastGameCfg;
+extern QString lastGameAmmo;
+extern TeamSelWidget * lastGameTeamSel;
+
class HWGame : public TCPBase
{
Q_OBJECT
@@ -86,23 +105,15 @@ class HWGame : public TCPBase
void FromNetChat(const QString & msg);
private:
- enum GameType
- {
- gtLocal = 1,
- gtQLocal = 2,
- gtDemo = 3,
- gtNet = 4,
- gtTraining = 5,
- gtCampaign = 6,
- gtSave = 7,
- };
char msgbuf[MAXMSGCHARS];
QString ammostr;
GameUIConfig * config;
GameCFGWidget * gamecfg;
TeamSelWidget* m_pTeamSelWidget;
GameType gameType;
+ QByteArray m_netSendBuffer;
+ void addKeyBindings(QByteArray * buf);
void commonConfig();
void SendConfig();
void SendQuickConfig();
@@ -113,6 +124,7 @@ class HWGame : public TCPBase
void SetGameState(GameState state);
void sendCampaignVar(const QByteArray & varToSend);
void writeCampaignVar(const QByteArray &varVal);
+ void flushNetBuffer();
};
#endif
diff --git a/QTfrontend/gameuiconfig.cpp b/QTfrontend/gameuiconfig.cpp
index d4953d0..73f5236 100644
--- a/QTfrontend/gameuiconfig.cpp
+++ b/QTfrontend/gameuiconfig.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +24,8 @@
#include <QStandardItemModel>
#include <QNetworkProxy>
#include <QNetworkProxyFactory>
+#include <utility>
+#include <QVariant>
#include "gameuiconfig.h"
#include "hwform.h"
@@ -34,6 +36,7 @@
#include "fpsedit.h"
#include "HWApplication.h"
#include "DataManager.h"
+#include "SDL.h"
const QNetworkProxy::ProxyType proxyTypesMap[] = {
@@ -44,24 +47,35 @@ const QNetworkProxy::ProxyType proxyTypesMap[] = {
GameUIConfig::GameUIConfig(HWForm * FormWidgets, const QString & fileName)
- : QSettings(fileName, QSettings::IniFormat)
+ : QSettings(fileName, QSettings::IniFormat, FormWidgets)
{
Form = FormWidgets;
- connect(Form->ui.pageOptions->CBEnableFrontendMusic, SIGNAL(toggled(bool)), Form, SLOT(Music(bool)));
+ setIniCodec("UTF-8");
+
+ connect(Form->ui.pageOptions->CBFrontendMusic, SIGNAL(toggled(bool)), Form, SLOT(Music(bool)));
+
+ for(int i = 0; i < BINDS_NUMBER; i++)
+ {
+ m_binds.append(BindAction());
+ m_binds[i].action = cbinds[i].action;
+ m_binds[i].strbind = cbinds[i].strbind;
+ }
//Form->resize(value("frontend/width", 640).toUInt(), value("frontend/height", 450).toUInt());
resizeToConfigValues();
reloadValues();
+#ifdef VIDEOREC
reloadVideosValues();
+#endif
}
void GameUIConfig::reloadValues(void)
{
Form->ui.pageOptions->WeaponTooltip->setChecked(value("misc/weaponTooltips", true).toBool());
- int t = Form->ui.pageOptions->CBResolution->findText(value("video/resolution").toString());
+ int t = Form->ui.pageOptions->CBResolution->findText(value("video/fullscreenResolution").toString());
if (t < 0)
{
if (Form->ui.pageOptions->CBResolution->count() > 1)
@@ -70,6 +84,20 @@ void GameUIConfig::reloadValues(void)
Form->ui.pageOptions->CBResolution->setCurrentIndex(0);
}
else Form->ui.pageOptions->CBResolution->setCurrentIndex(t);
+
+ // Default the windowed resolution to 5/6 of the screen size
+ int screenWidth = SDL_GetVideoInfo()->current_w * 5 / 6;
+ int screenHeight = SDL_GetVideoInfo()->current_h * 5 / 6;
+ QString widthStr; widthStr.setNum(screenWidth);
+ QString heightStr; heightStr.setNum(screenHeight);
+ QString wWidth = value("video/windowedWidth", widthStr).toString();
+ QString wHeight = value("video/windowedHeight", heightStr).toString();
+ // If left blank reset the resolution to the default
+ wWidth = (wWidth == "" ? widthStr : wWidth);
+ wHeight = (wHeight == "" ? heightStr : wHeight);
+ Form->ui.pageOptions->windowWidthEdit->setValue(wWidth.toInt());
+ Form->ui.pageOptions->windowHeightEdit->setValue(wHeight.toInt());
+
Form->ui.pageOptions->CBResolution->setCurrentIndex((t < 0) ? 1 : t);
Form->ui.pageOptions->CBFullscreen->setChecked(value("video/fullscreen", false).toBool());
bool ffscr=value("frontend/fullscreen", false).toBool();
@@ -77,14 +105,14 @@ void GameUIConfig::reloadValues(void)
Form->ui.pageOptions->SLQuality->setValue(value("video/quality", 5).toUInt());
Form->ui.pageOptions->CBStereoMode->setCurrentIndex(value("video/stereo", 0).toUInt());
- Form->ui.pageOptions->CBEnableFrontendSound->setChecked(value("frontend/effects", true).toBool());
- Form->ui.pageOptions->CBEnableSound->setChecked(value("audio/sound", true).toBool());
- Form->ui.pageOptions->CBEnableFrontendSound->setChecked(value("frontend/sound", true).toBool());
- Form->ui.pageOptions->CBEnableMusic->setChecked(value("audio/music", true).toBool());
- Form->ui.pageOptions->CBEnableFrontendMusic->setChecked(value("frontend/music", true).toBool());
- Form->ui.pageOptions->volumeBox->setValue(value("audio/volume", 100).toUInt());
-
- QString netNick = value("net/nick", "").toString();
+ Form->ui.pageOptions->CBFrontendEffects->setChecked(value("frontend/effects", true).toBool());
+ Form->ui.pageOptions->CBSound->setChecked(value("audio/sound", true).toBool());
+ Form->ui.pageOptions->CBFrontendSound->setChecked(value("frontend/sound", true).toBool());
+ Form->ui.pageOptions->CBMusic->setChecked(value("audio/music", true).toBool());
+ Form->ui.pageOptions->CBFrontendMusic->setChecked(value("frontend/music", true).toBool());
+ Form->ui.pageOptions->SLVolume->setValue(value("audio/volume", 100).toUInt());
+
+ QString netNick = value("net/nick", tr("Guest")+QString("%1").arg(rand())).toString();
Form->ui.pageOptions->editNetNick->setText(netNick);
bool savePwd = value("net/savepassword",true).toBool();
Form->ui.pageOptions->CBSavePassword->setChecked(savePwd);
@@ -92,19 +120,21 @@ void GameUIConfig::reloadValues(void)
Form->ui.pageOptions->editNetPassword->installEventFilter(this);
int passLength = value("net/passwordlength", 0).toInt();
- setNetPasswordLength(passLength);
- if (savePwd == false) {
- Form->ui.pageOptions->editNetPassword->setEnabled(savePwd);
+ if (!savePwd) {
+ Form->ui.pageOptions->editNetPassword->setEnabled(false);
Form->ui.pageOptions->editNetPassword->setText("");
- setNetPasswordLength(0);
+ setNetPasswordLength(0);
+ } else
+ {
+ setNetPasswordLength(passLength);
}
delete netHost;
netHost = new QString(value("net/ip", "").toString());
- netPort = value("net/port", 46631).toUInt();
+ netPort = value("net/port", NETGAME_DEFAULT_PORT).toUInt();
Form->ui.pageNetServer->leServerDescr->setText(value("net/servername", "hedgewars server").toString());
- Form->ui.pageNetServer->sbPort->setValue(value("net/serverport", 46631).toUInt());
+ Form->ui.pageNetServer->sbPort->setValue(value("net/serverport", NETGAME_DEFAULT_PORT).toUInt());
Form->ui.pageOptions->CBShowFPS->setChecked(value("fps/show", false).toBool());
Form->ui.pageOptions->fpsedit->setValue(value("fps/limit", 27).toUInt());
@@ -124,39 +154,51 @@ void GameUIConfig::reloadValues(void)
Form->ui.pageOptions->leProxyLogin->setText(value("proxy/login", "").toString());
Form->ui.pageOptions->leProxyPassword->setText(value("proxy/password", "").toString());
- depth = HWApplication::desktop()->depth();
- if (depth < 16) depth = 16;
- else if (depth > 16) depth = 32;
-
{ // load colors
QStandardItemModel * model = DataManager::instance().colorsModel();
for(int i = model->rowCount() - 1; i >= 0; --i)
- model->item(i)->setData(QColor(value(QString("colors/color%1").arg(i), model->item(i)->data().value<QColor>()).value<QColor>()));
+ model->item(i)->setData(QColor(value(QString("colors/color%1").arg(i), model->item(i)->data()).toString()));
+ }
+
+ { // load binds
+ for(int i = 0; i < BINDS_NUMBER; i++)
+ {
+ m_binds[i].strbind = value(QString("Binds/%1").arg(m_binds[i].action), cbinds[i].strbind).toString();
+ if (m_binds[i].strbind.isEmpty() || m_binds[i].strbind == "default") m_binds[i].strbind = cbinds[i].strbind;
+ }
}
}
void GameUIConfig::reloadVideosValues(void)
{
- Form->ui.pageVideos->framerateBox->setValue(value("videorec/fps",25).toUInt());
- Form->ui.pageVideos->bitrateBox->setValue(value("videorec/bitrate",400).toUInt());
- bool useGameRes = value("videorec/usegameres",true).toBool();
+ // one pass with default values
+ Form->ui.pageOptions->setDefaultOptions();
+
+ // then load user configuration
+ Form->ui.pageOptions->framerateBox->setCurrentIndex(
+ Form->ui.pageOptions->framerateBox->findData(
+ value("videorec/framerate", rec_Framerate()).toString() + " fps",
+ Qt::MatchExactly) );
+ Form->ui.pageOptions->bitrateBox->setValue(value("videorec/bitrate", rec_Bitrate()).toUInt());
+ bool useGameRes = value("videorec/usegameres",Form->ui.pageOptions->checkUseGameRes->isChecked()).toBool();
if (useGameRes)
{
QRect res = vid_Resolution();
- Form->ui.pageVideos->widthEdit->setText(QString::number(res.width()));
- Form->ui.pageVideos->heightEdit->setText(QString::number(res.height()));
+ Form->ui.pageOptions->widthEdit->setText(QString::number(res.width()));
+ Form->ui.pageOptions->heightEdit->setText(QString::number(res.height()));
}
else
{
- Form->ui.pageVideos->widthEdit->setText(value("videorec/width","800").toString());
- Form->ui.pageVideos->heightEdit->setText(value("videorec/height","600").toString());
+ Form->ui.pageOptions->widthEdit->setText(value("videorec/width","800").toString());
+ Form->ui.pageOptions->heightEdit->setText(value("videorec/height","600").toString());
}
- Form->ui.pageVideos->checkUseGameRes->setChecked(useGameRes);
- Form->ui.pageVideos->checkRecordAudio->setChecked(value("videorec/audio",true).toBool());
- if (!Form->ui.pageVideos->tryCodecs(value("videorec/format","no").toString(),
+ Form->ui.pageOptions->checkUseGameRes->setChecked(useGameRes);
+ Form->ui.pageOptions->checkRecordAudio->setChecked(
+ value("videorec/audio",Form->ui.pageOptions->checkRecordAudio->isChecked()).toBool() );
+ if (!Form->ui.pageOptions->tryCodecs(value("videorec/format","no").toString(),
value("videorec/videocodec","no").toString(),
value("videorec/audiocodec","no").toString()))
- Form->ui.pageVideos->setDefaultCodecs();
+ Form->ui.pageOptions->setDefaultCodecs();
}
QStringList GameUIConfig::GetTeamsList()
@@ -175,12 +217,23 @@ QStringList GameUIConfig::GetTeamsList()
void GameUIConfig::resizeToConfigValues()
{
- Form->resize(value("frontend/width", 800).toUInt(), value("frontend/height", 600).toUInt());
+ // fill 2/3 of the screen desktop
+ const QRect deskSize = HWApplication::desktop()->screenGeometry(-1);
+ Form->resize(value("frontend/width", qMin(qMax(deskSize.width()*2/3,800),deskSize.width())).toUInt(),
+ value("frontend/height", qMin(qMax(deskSize.height()*2/3,600),deskSize.height())).toUInt());
+
+ // move the window to the center of the screen
+ QPoint center = HWApplication::desktop()->availableGeometry(-1).center();
+ center.setX(center.x() - (Form->width()/2));
+ center.setY(center.y() - (Form->height()/2));
+ Form->move(center);
}
void GameUIConfig::SaveOptions()
{
- setValue("video/resolution", Form->ui.pageOptions->CBResolution->currentText());
+ setValue("video/fullscreenResolution", Form->ui.pageOptions->CBResolution->currentText());
+ setValue("video/windowedWidth", Form->ui.pageOptions->windowWidthEdit->text());
+ setValue("video/windowedHeight", Form->ui.pageOptions->windowHeightEdit->text());
setValue("video/fullscreen", vid_Fullscreen());
setValue("video/quality", Form->ui.pageOptions->SLQuality->value());
@@ -207,14 +260,16 @@ void GameUIConfig::SaveOptions()
setValue("frontend/sound", isFrontendSoundEnabled());
setValue("audio/music", isMusicEnabled());
setValue("frontend/music", isFrontendMusicEnabled());
- setValue("audio/volume", Form->ui.pageOptions->volumeBox->value());
+ setValue("audio/volume", Form->ui.pageOptions->SLVolume->value());
setValue("net/nick", netNick());
- if (netPasswordIsValid() && Form->ui.pageOptions->CBSavePassword->isChecked())
- {
- setValue("net/passwordhash", netPasswordHash());
- setValue("net/passwordlength", netPasswordLength());
+ if (netPasswordIsValid() && Form->ui.pageOptions->CBSavePassword->isChecked()) {
+ setPasswordHash(netPasswordHash());
}
+ else if(!Form->ui.pageOptions->CBSavePassword->isChecked()) {
+ clearPasswordHash();
+ }
+
setValue("net/savepassword", Form->ui.pageOptions->CBSavePassword->isChecked());
setValue("net/ip", *netHost);
setValue("net/port", netPort);
@@ -265,10 +320,10 @@ void GameUIConfig::SaveOptions()
{ // save colors
QStandardItemModel * model = DataManager::instance().colorsModel();
for(int i = model->rowCount() - 1; i >= 0; --i)
- setValue(QString("colors/color%1").arg(i), model->item(i)->data());
+ setValue(QString("colors/color%1").arg(i), model->item(i)->data().value<QColor>().name());
}
- Form->gameSettings->sync();
+ sync();
}
void GameUIConfig::SaveVideosOptions()
@@ -277,14 +332,20 @@ void GameUIConfig::SaveVideosOptions()
setValue("videorec/format", AVFormat());
setValue("videorec/videocodec", videoCodec());
setValue("videorec/audiocodec", audioCodec());
- setValue("videorec/fps", rec_Framerate());
+ setValue("videorec/framerate", rec_Framerate());
setValue("videorec/bitrate", rec_Bitrate());
setValue("videorec/width", res.width());
setValue("videorec/height", res.height());
- setValue("videorec/usegameres", Form->ui.pageVideos->checkUseGameRes->isChecked());
+ setValue("videorec/usegameres", Form->ui.pageOptions->checkUseGameRes->isChecked());
setValue("videorec/audio", recordAudio());
- Form->gameSettings->sync();
+ sync();
+}
+
+void GameUIConfig::setValue(const QString &key, const QVariant &value)
+{
+ //qDebug() << "[settings]" << key << value;
+ QSettings::setValue(key, value);
}
QString GameUIConfig::language()
@@ -292,16 +353,28 @@ QString GameUIConfig::language()
return Form->ui.pageOptions->CBLanguage->itemData(Form->ui.pageOptions->CBLanguage->currentIndex()).toString();
}
-QRect GameUIConfig::vid_Resolution()
-{
- QRect result(0, 0, 640, 480);
+std::pair<QRect, QRect> GameUIConfig::vid_ResolutionPair() {
+ // returns a pair of both the fullscreen and the windowed resolution
+ QRect full(0, 0, 640, 480);
+ QRect windowed(0, 0, 640, 480);
QStringList wh = Form->ui.pageOptions->CBResolution->currentText().split('x');
if (wh.size() == 2)
{
- result.setWidth(wh[0].toInt());
- result.setHeight(wh[1].toInt());
+ full.setWidth(wh[0].toInt());
+ full.setHeight(wh[1].toInt());
}
- return result;
+ windowed.setWidth(Form->ui.pageOptions->windowWidthEdit->text().toInt());
+ windowed.setHeight(Form->ui.pageOptions->windowHeightEdit->text().toInt());
+ return std::make_pair(full, windowed);
+}
+
+QRect GameUIConfig::vid_Resolution()
+{
+ std::pair<QRect, QRect> result = vid_ResolutionPair();
+ if(Form->ui.pageOptions->CBFullscreen->isChecked())
+ return result.first;
+ else
+ return result.second;
}
bool GameUIConfig::vid_Fullscreen()
@@ -370,20 +443,20 @@ bool GameUIConfig::isFrontendFullscreen() const
bool GameUIConfig::isSoundEnabled()
{
- return Form->ui.pageOptions->CBEnableSound->isChecked();
+ return Form->ui.pageOptions->CBSound->isChecked();
}
bool GameUIConfig::isFrontendSoundEnabled()
{
- return Form->ui.pageOptions->CBEnableFrontendSound->isChecked();
+ return Form->ui.pageOptions->CBFrontendSound->isChecked();
}
bool GameUIConfig::isMusicEnabled()
{
- return Form->ui.pageOptions->CBEnableMusic->isChecked();
+ return Form->ui.pageOptions->CBMusic->isChecked();
}
bool GameUIConfig::isFrontendMusicEnabled()
{
- return Form->ui.pageOptions->CBEnableFrontendMusic->isChecked();
+ return Form->ui.pageOptions->CBFrontendMusic->isChecked();
}
bool GameUIConfig::isShowFPSEnabled()
@@ -418,11 +491,6 @@ quint8 GameUIConfig::timerInterval()
return 35 - Form->ui.pageOptions->fpsedit->value();
}
-quint8 GameUIConfig::bitDepth()
-{
- return depth;
-}
-
QString GameUIConfig::netNick()
{
return Form->ui.pageOptions->editNetNick->text();
@@ -445,7 +513,55 @@ int GameUIConfig::netPasswordLength()
bool GameUIConfig::netPasswordIsValid()
{
- return (netPasswordLength() == 0 || Form->ui.pageOptions->editNetPassword->text() != QString(netPasswordLength(), '\0'));
+ return (netPasswordLength() == 0 || Form->ui.pageOptions->editNetPassword->text() != QString(netPasswordLength(), '*'));
+}
+
+void GameUIConfig::clearPasswordHash()
+{
+ setValue("net/passwordhash", QString());
+ setValue("net/passwordlength", 0);
+ setValue("net/savepassword", false); //changes the savepassword value to false in order to not let the user save an empty password in PAGE_SETUP
+ Form->ui.pageOptions->editNetPassword->setEnabled(false);
+ Form->ui.pageOptions->editNetPassword->setText("");
+}
+
+void GameUIConfig::setPasswordHash(const QString & passwordhash)
+{
+ setValue("net/passwordhash", passwordhash);
+ if (passwordhash!=NULL && passwordhash.size() > 0)
+ {
+ // WTF - the whole point of "password length" was to have the dots match what they typed. This is totally pointless, and all hashes are the same length for a given hash so might as well hardcode it.
+ // setValue("net/passwordlength", passwordhash.size()/4);
+ setValue("net/passwordlength", 8);
+
+ // More WTF
+ //setNetPasswordLength(passwordhash.size()/4); //the hash.size() is divided by 4 let PAGE_SETUP use a reasonable number of stars to display the PW
+ setNetPasswordLength(8);
+ }
+ else
+ {
+ setValue("net/passwordlength", 0);
+ setNetPasswordLength(0);
+ }
+}
+
+QString GameUIConfig::passwordHash()
+{
+ return value("net/passwordhash").toString();
+}
+
+void GameUIConfig::clearTempHash()
+{
+ setTempHash(QString());
+}
+
+void GameUIConfig::setTempHash(const QString & temphash)
+{
+ this->temphash = temphash;
+}
+
+QString GameUIConfig::tempHash() {
+ return this->temphash;
}
// When hedgewars launches, the password field is set with null characters. If the user tries to edit the field and there are such characters, then clear the field
@@ -470,7 +586,7 @@ void GameUIConfig::setNetPasswordLength(int passwordLength)
{
if (passwordLength > 0)
{
- Form->ui.pageOptions->editNetPassword->setText(QString(passwordLength, '\0'));
+ Form->ui.pageOptions->editNetPassword->setText(QString(passwordLength, '*'));
}
else
{
@@ -480,45 +596,61 @@ void GameUIConfig::setNetPasswordLength(int passwordLength)
quint8 GameUIConfig::volume()
{
- return Form->ui.pageOptions->volumeBox->value() * 128 / 100;
+ return Form->ui.pageOptions->SLVolume->value() * 128 / 100;
}
QString GameUIConfig::AVFormat()
{
- return Form->ui.pageVideos->format();
+ return Form->ui.pageOptions->format();
}
QString GameUIConfig::videoCodec()
{
- return Form->ui.pageVideos->videoCodec();
+ return Form->ui.pageOptions->videoCodec();
}
QString GameUIConfig::audioCodec()
{
- return Form->ui.pageVideos->audioCodec();
+ return Form->ui.pageOptions->audioCodec();
}
QRect GameUIConfig::rec_Resolution()
{
- if (Form->ui.pageVideos->checkUseGameRes->isChecked())
+ if (Form->ui.pageOptions->checkUseGameRes->isChecked())
return vid_Resolution();
QRect res(0,0,0,0);
- res.setWidth(Form->ui.pageVideos->widthEdit->text().toUInt());
- res.setHeight(Form->ui.pageVideos->heightEdit->text().toUInt());
+ res.setWidth(Form->ui.pageOptions->widthEdit->text().toUInt());
+ res.setHeight(Form->ui.pageOptions->heightEdit->text().toUInt());
return res;
}
int GameUIConfig::rec_Framerate()
{
- return Form->ui.pageVideos->framerateBox->value();
+ // remove the "fps" label
+ QString fpsText = Form->ui.pageOptions->framerateBox->currentText();
+ QStringList fpsList = fpsText.split(" ");
+ return fpsList.first().toInt();
}
int GameUIConfig::rec_Bitrate()
{
- return Form->ui.pageVideos->bitrateBox->value();
+ return Form->ui.pageOptions->bitrateBox->value();
}
bool GameUIConfig::recordAudio()
{
- return Form->ui.pageVideos->checkRecordAudio->isChecked();
+ return Form->ui.pageOptions->checkRecordAudio->isChecked();
+}
+
+// Gets a bind for a bindID
+QString GameUIConfig::bind(int bindID)
+{
+ return m_binds[bindID].strbind;
+}
+
+// Sets a bind for a bindID and saves it
+void GameUIConfig::setBind(int bindID, QString & strbind)
+{
+ m_binds[bindID].strbind = strbind;
+ setValue(QString("Binds/%1").arg(m_binds[bindID].action), strbind);
}
diff --git a/QTfrontend/gameuiconfig.h b/QTfrontend/gameuiconfig.h
index ac89d35..c3c0159 100644
--- a/QTfrontend/gameuiconfig.h
+++ b/QTfrontend/gameuiconfig.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,9 @@
#include <QStringList>
#include <QRect>
#include <QEvent>
+#include <QList>
+#include <utility>
+#include "binds.h"
class HWForm;
class QSettings;
@@ -36,6 +39,7 @@ class GameUIConfig : public QSettings
GameUIConfig(HWForm * FormWidgets, const QString & fileName);
QStringList GetTeamsList();
QRect vid_Resolution();
+ std::pair<QRect, QRect> vid_ResolutionPair();
bool vid_Fullscreen();
quint32 translateQuality();
bool isSoundEnabled();
@@ -48,16 +52,24 @@ class GameUIConfig : public QSettings
bool appendDateTimeToRecordName();
quint8 volume();
quint8 timerInterval();
- quint8 bitDepth();
QString netNick();
QByteArray netPasswordHash();
int netPasswordLength();
+ void clearPasswordHash();
+ void setPasswordHash(const QString & passwordhash);
+ QString passwordHash();
+ void clearTempHash();
+ void setTempHash(const QString & temphash);
+ QString tempHash();
void setNetPasswordLength(int passwordLength);
bool isReducedQuality() const;
bool isFrontendEffects() const;
bool isFrontendFullscreen() const;
void resizeToConfigValues();
quint32 stereoMode() const;
+ void setValue(const QString & key, const QVariant & value);
+ QString bind(int bindID);
+ void setBind(int bindID, QString & strbind);
QString AVFormat();
QString videoCodec();
@@ -85,7 +97,8 @@ class GameUIConfig : public QSettings
private:
bool netPasswordIsValid();
bool eventFilter(QObject *object, QEvent *event);
- quint8 depth;
+ QString temphash;
+ QList<BindAction> m_binds;
};
#endif
diff --git a/QTfrontend/hedgewars.qrc b/QTfrontend/hedgewars.qrc
index 999976d..0e7ffc4 100644
--- a/QTfrontend/hedgewars.qrc
+++ b/QTfrontend/hedgewars.qrc
@@ -44,6 +44,9 @@
<file>res/HedgewarsTitle.png</file>
<file>res/LocalPlay.png</file>
<file>res/NetworkPlay.png</file>
+ <file>res/NetworkPlayDisabled.png</file>
+ <file>res/audio.png</file>
+ <file>res/camera.png</file>
<file>res/Settings.png</file>
<file>res/dropdown.png</file>
<file>res/new.png</file>
@@ -102,6 +105,7 @@
<file>res/iconRope.png</file>
<file>res/dice.png</file>
<file>res/Star.png</file>
+ <file>res/inverse-corner-bl.png</file>
<file>res/Flake.png</file>
<file>res/Egg.png</file>
<file>res/Confetti.png</file>
@@ -129,6 +133,7 @@
<file>res/StatsMostSelfDamage.png</file>
<file>res/StatsSelfKilled.png</file>
<file>res/StatsSkipped.png</file>
+ <file>res/Start.png</file>
<file>res/mapRandom.png</file>
<file>res/mapMaze.png</file>
<file>res/mapMissing.png</file>
@@ -145,5 +150,8 @@
<file>res/chat/serveradmin_gray.png</file>
<file>res/chat/lamp_off.png</file>
<file>res/chat/ingame.png</file>
+ <file>res/splash.png</file>
+ <file>res/html/about.html</file>
+ <file>res/xml/tips.xml</file>
</qresource>
</RCC>
diff --git a/QTfrontend/hedgewars.qrc.depends b/QTfrontend/hedgewars.qrc.depends
index 999976d..0e7ffc4 100644
--- a/QTfrontend/hedgewars.qrc.depends
+++ b/QTfrontend/hedgewars.qrc.depends
@@ -44,6 +44,9 @@
<file>res/HedgewarsTitle.png</file>
<file>res/LocalPlay.png</file>
<file>res/NetworkPlay.png</file>
+ <file>res/NetworkPlayDisabled.png</file>
+ <file>res/audio.png</file>
+ <file>res/camera.png</file>
<file>res/Settings.png</file>
<file>res/dropdown.png</file>
<file>res/new.png</file>
@@ -102,6 +105,7 @@
<file>res/iconRope.png</file>
<file>res/dice.png</file>
<file>res/Star.png</file>
+ <file>res/inverse-corner-bl.png</file>
<file>res/Flake.png</file>
<file>res/Egg.png</file>
<file>res/Confetti.png</file>
@@ -129,6 +133,7 @@
<file>res/StatsMostSelfDamage.png</file>
<file>res/StatsSelfKilled.png</file>
<file>res/StatsSkipped.png</file>
+ <file>res/Start.png</file>
<file>res/mapRandom.png</file>
<file>res/mapMaze.png</file>
<file>res/mapMissing.png</file>
@@ -145,5 +150,8 @@
<file>res/chat/serveradmin_gray.png</file>
<file>res/chat/lamp_off.png</file>
<file>res/chat/ingame.png</file>
+ <file>res/splash.png</file>
+ <file>res/html/about.html</file>
+ <file>res/xml/tips.xml</file>
</qresource>
</RCC>
diff --git a/QTfrontend/hwconsts.cpp.in b/QTfrontend/hwconsts.cpp.in
index 2f20d56..b040415 100644
--- a/QTfrontend/hwconsts.cpp.in
+++ b/QTfrontend/hwconsts.cpp.in
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,13 +19,17 @@
#include <QStandardItemModel>
#include "hwconsts.h"
+#include "weapons.h"
-QString * cProtoVer = new QString("${HEDGEWARS_PROTO_VER}");
+// cDataDir gets 'Data' appended later (in main.cpp)
QString * cDataDir = new QString("${HEDGEWARS_DATADIR}");
-QString * cConfigDir = new QString("");
-QString * cVersionString = new QString("${HEDGEWARS_VERSION}${HGCHANGED}");
+QString * cProtoVer = new QString("${HEDGEWARS_PROTO_VER}");
+QString * cVersionString = new QString("${HEDGEWARS_VERSION}");
+QString * cRevisionString = new QString("${HEDGEWARS_REVISION}");
+QString * cHashString = new QString("${HEDGEWARS_HASH}");
-QDir * bindir = new QDir("${HEDGEWARS_BINDIR}");
+
+QDir * bindir = new QDir();
QDir * cfgdir = new QDir();
QDir * datadir = new QDir();
@@ -60,6 +64,9 @@ QList< QPair<QString, QString> > cDefaultAmmos =
<< qMakePair(QString("Thinking with Portals"), QString(
AMMOLINE_PORTALS_QT AMMOLINE_PORTALS_PROB
AMMOLINE_PORTALS_DELAY AMMOLINE_PORTALS_CRATE ))
+ << qMakePair(QString("One of Everything"), QString(
+ AMMOLINE_ONEEVERY_QT AMMOLINE_ONEEVERY_PROB
+ AMMOLINE_ONEEVERY_DELAY AMMOLINE_ONEEVERY_CRATE ))
;
unsigned int colors[] = HW_TEAMCOLOR_ARRAY;
@@ -67,8 +74,5 @@ unsigned int colors[] = HW_TEAMCOLOR_ARRAY;
QString * netHost = new QString();
quint16 netPort = NETGAME_DEFAULT_PORT;
-bool haveServer = ${HAVE_NETSERVER};
-bool isDevBuild = ${HW_DEV};
-
int season = SEASON_NONE;
int years_since_foundation = 0;
diff --git a/QTfrontend/hwconsts.h b/QTfrontend/hwconsts.h
index 33652f0..1ca4684 100644
--- a/QTfrontend/hwconsts.h
+++ b/QTfrontend/hwconsts.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,8 +25,9 @@
extern QString * cProtoVer;
extern QString * cVersionString;
+extern QString * cRevisionString;
+extern QString * cHashString;
extern QString * cDataDir;
-extern QString * cConfigDir;
extern QDir * bindir;
extern QDir * cfgdir;
@@ -49,8 +50,6 @@ extern unsigned int colors[];
extern QString * netHost;
extern quint16 netPort;
-extern bool haveServer;
-extern bool isDevBuild;
//Current season, SEASON_NONE by default
extern int season;
@@ -61,42 +60,6 @@ extern int years_since_foundation;
#endif
-#define HEDGEHOGS_PER_TEAM 8
-
-#define AMMOLINE_DEFAULT_QT "93919294221991210322351110012010000002111101010111110101"
-#define AMMOLINE_DEFAULT_PROB "04050405416006555465544647765766666661555101011154110101"
-#define AMMOLINE_DEFAULT_DELAY "00000000000002055000000400070040000000002200000006000000"
-#define AMMOLINE_DEFAULT_CRATE "13111103121111111231141111111111111112111111011111110101"
-
-#define AMMOLINE_CRAZY_QT "99999999999999999929999999999999992999999999099999920909"
-#define AMMOLINE_CRAZY_PROB "11111101111111111111111111111111111111111111011111110101"
-#define AMMOLINE_CRAZY_DELAY "00000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_CRAZY_CRATE "13111103121111111231141111111111111112111101011111110101"
-
-#define AMMOLINE_PROMODE_QT "90900090000000000000090000000000000000000000000000000000"
-#define AMMOLINE_PROMODE_PROB "00000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_PROMODE_DELAY "00000000000002055000000400070040000000002000000000000002"
-#define AMMOLINE_PROMODE_CRATE "11111111111111111111111111111111111111111001011111110101"
-
-#define AMMOLINE_SHOPPA_QT "00000099000000000000000000000000000000000000000000000000"
-#define AMMOLINE_SHOPPA_PROB "44444100442444022101121212224220000000020004000100110001"
-#define AMMOLINE_SHOPPA_DELAY "00000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_SHOPPA_CRATE "11111111111111111111111111111111111111111011011111110001"
-
-#define AMMOLINE_CLEAN_QT "10100090000100000110000000000000000000000000000010000000"
-#define AMMOLINE_CLEAN_PROB "04050405416006555465544647765766666661555101011154110101"
-#define AMMOLINE_CLEAN_DELAY "00000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_CLEAN_CRATE "13111103121111111231141111111111111112111111011111110101"
-
-#define AMMOLINE_MINES_QT "00000099000900000003000000000000000000000000000000000000"
-#define AMMOLINE_MINES_PROB "00000000000000000000000000000000000000000000000000000000"
-#define AMMOLINE_MINES_DELAY "00000000000002055000000400070040000000002000000006000000"
-#define AMMOLINE_MINES_CRATE "11111111111111111111111111111111111111111111011111110101"
-
-#define AMMOLINE_PORTALS_QT "90000090020000000021000000000000001100000900000000000000"
-#define AMMOLINE_PORTALS_PROB "04050405416006555465544647765766666661555101011154110101"
-#define AMMOLINE_PORTALS_DELAY "00000000000002055000000400070040000000002000000006000000"
-#define AMMOLINE_PORTALS_CRATE "13111103121111111231141111111111111112111111011111110101"
//Different seasons; assigned to season (int)
#define SEASON_NONE 0
@@ -104,7 +67,9 @@ extern int years_since_foundation;
#define SEASON_HWBDAY 4
#define SEASON_EASTER 8
+#define NETGAME_DEFAULT_SERVER "netserver.hedgewars.org"
#define NETGAME_DEFAULT_PORT 46631
+#define HEDGEHOGS_PER_TEAM 8
// see http://en.wikipedia.org/wiki/List_of_colors
diff --git a/QTfrontend/hwform.cpp b/QTfrontend/hwform.cpp
index c462b50..dddaff5 100644
--- a/QTfrontend/hwform.cpp
+++ b/QTfrontend/hwform.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
#include <QTextStream>
#include <QMessageBox>
#include <QPushButton>
+#include <QSpinBox>
#include <QListWidget>
#include <QStackedLayout>
#include <QLineEdit>
@@ -39,9 +40,12 @@
#include <QSignalMapper>
#include <QShortcut>
#include <QDesktopServices>
+#include <QDesktopWidget>
+#include <QApplication>
#include <QInputDialog>
#include <QPropertyAnimation>
#include <QSettings>
+#include <QSortFilterProxyModel>
#if (QT_VERSION >= 0x040600)
#include <QGraphicsEffect>
@@ -70,10 +74,8 @@
#include "pagemultiplayer.h"
#include "pagenet.h"
#include "pagemain.h"
-#include "pagefeedback.h"
#include "pagenetserver.h"
#include "pagedrawmap.h"
-#include "pagenettype.h"
#include "pagegamestats.h"
#include "pageplayrecord.h"
#include "pagedata.h"
@@ -94,8 +96,23 @@
#include "roomslistmodel.h"
#include "recorder.h"
#include "playerslistmodel.h"
+#include "feedbackdialog.h"
+#include "MessageDialog.h"
#include "DataManager.h"
+#include "AutoUpdater.h"
+
+#ifdef Q_WS_WIN
+#define WINVER 0x0500
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+#ifdef Q_WS_MAC
+#include <sys/sysctl.h>
+#endif
#ifdef __APPLE__
#include "M3Panel.h"
@@ -111,7 +128,6 @@ bool frontendEffects = true;
QString playerHash;
GameUIConfig* HWForm::config = NULL;
-QSettings* HWForm::gameSettings = NULL;
HWForm::HWForm(QWidget *parent, QString styleSheet)
: QMainWindow(parent)
@@ -122,17 +138,11 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
, hwnet(0)
{
// set music track
- SDLInteraction::instance().setMusicTrack(
- DataManager::instance().findFileForRead("Music/main_theme.ogg")
- );
+ SDLInteraction::instance().setMusicTrack("/Music/main_theme.ogg");
#ifdef USE_XFIRE
xfire_init();
#endif
- gameSettings = new QSettings(cfgdir->absolutePath() + "/hedgewars.ini", QSettings::IniFormat);
- frontendEffects = gameSettings->value("frontend/effects", true).toBool();
- playerHash = QString(QCryptographicHash::hash(gameSettings->value("net/nick","").toString().toUtf8(), QCryptographicHash::Md5).toHex());
-
this->setStyleSheet(styleSheet);
ui.setupUi(this);
setMinimumSize(760, 580);
@@ -141,21 +151,39 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
ui.pageOptions->CBResolution->addItems(SDLInteraction::instance().getResolutions());
- config = new GameUIConfig(this, cfgdir->absolutePath() + "/hedgewars.ini");
+ config = new GameUIConfig(this, DataManager::instance().settingsFileName());
+ frontendEffects = config->value("frontend/effects", true).toBool();
+ playerHash = QString(QCryptographicHash::hash(config->value("net/nick",tr("Guest")+QString("%1").arg(rand())).toString().toUtf8(), QCryptographicHash::Md5).toHex());
+ ui.pageRoomsList->setSettings(config);
+ ui.pageNetGame->setSettings(config);
+ ui.pageNetGame->chatWidget->setSettings(config);
+ ui.pageRoomsList->chatWidget->setSettings(config);
+ ui.pageOptions->setConfig(config);
+#ifdef VIDEOREC
ui.pageVideos->init(config);
+#endif
#ifdef __APPLE__
- panel = new M3Panel;
-
+ AutoUpdater* updater = NULL;
+ if (config->isAutoUpdateEnabled())
+ {
+#ifdef __APPLE__
#ifdef SPARKLE_ENABLED
- AutoUpdater* updater;
-
- updater = new SparkleAutoUpdater();
- if (updater && config->isAutoUpdateEnabled())
- updater->checkForUpdates();
+ updater = new SparkleAutoUpdater();
+#endif
+#endif
+ if (updater)
+ {
+ updater->checkForUpdates();
+ delete updater;
+ }
+ }
#endif
+#ifdef __APPLE__
+ panel = new M3Panel;
+
QShortcut *hideFrontend = new QShortcut(QKeySequence("Ctrl+M"), this);
connect (hideFrontend, SIGNAL(activated()), this, SLOT(showMinimized()));
#else
@@ -189,13 +217,7 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
connect(ui.pageMain->BtnSetup, SIGNAL(clicked()), pageSwitchMapper, SLOT(map()));
pageSwitchMapper->setMapping(ui.pageMain->BtnSetup, ID_PAGE_SETUP);
-#if 0
- connect(ui.pageMain->BtnFeedback, SIGNAL(clicked()), pageSwitchMapper, SLOT(map()));
- pageSwitchMapper->setMapping(ui.pageMain->BtnFeedback, ID_PAGE_FEEDBACK);
-#endif
-
- connect(ui.pageMain->BtnNet, SIGNAL(clicked()), pageSwitchMapper, SLOT(map()));
- pageSwitchMapper->setMapping(ui.pageMain->BtnNet, ID_PAGE_NETTYPE);
+ connect(ui.pageMain->BtnFeedback, SIGNAL(clicked()), this, SLOT(showFeedbackDialog()));
connect(ui.pageMain->BtnInfo, SIGNAL(clicked()), pageSwitchMapper, SLOT(map()));
pageSwitchMapper->setMapping(ui.pageMain->BtnInfo, ID_PAGE_INFO);
@@ -212,8 +234,6 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
//connect(ui.pageMain->BtnExit, SIGNAL(pressed()), this, SLOT(btnExitPressed()));
//connect(ui.pageMain->BtnExit, SIGNAL(clicked()), this, SLOT(btnExitClicked()));
- connect(ui.pageFeedback->BtnSend, SIGNAL(clicked()), this, SLOT(SendFeedback()));
-
connect(ui.pageEditTeam, SIGNAL(goBack()), this, SLOT(AfterTeamEdit()));
connect(ui.pageMultiplayer->BtnStartMPGame, SIGNAL(clicked()), this, SLOT(StartMPGame()));
@@ -266,6 +286,7 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
connect(ui.pageInfo->BtnSnapshots, SIGNAL(clicked()), this, SLOT(OpenSnapshotFolder()));
connect(ui.pageGameStats, SIGNAL(saveDemoRequested()), this, SLOT(saveDemoWithCustomName()));
+ connect(ui.pageGameStats, SIGNAL(restartGameRequested()), this, SLOT(restartGame()));
connect(ui.pageSinglePlayer->BtnSimpleGamePage, SIGNAL(clicked()), this, SLOT(SimpleGame()));
connect(ui.pageSinglePlayer->BtnTrainPage, SIGNAL(clicked()), pageSwitchMapper, SLOT(map()));
@@ -295,10 +316,8 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
// this, SLOT(GoBack())); // executed third
- connect(ui.pageNetType->BtnLAN, SIGNAL(clicked()), this, SLOT(GoToNet()));
- connect(ui.pageNetType->BtnOfficialServer, SIGNAL(clicked()), this, SLOT(NetConnectOfficialServer()));
-
- connect(ui.pageConnecting, SIGNAL(cancelConnection()), this, SLOT(GoBack()));
+ connect(ui.pageMain->BtnNetLocal, SIGNAL(clicked()), this, SLOT(GoToNet()));
+ connect(ui.pageMain->BtnNetOfficial, SIGNAL(clicked()), this, SLOT(NetConnectOfficialServer()));
connect(ui.pageVideos, SIGNAL(goBack()), config, SLOT(SaveVideosOptions()));
@@ -331,7 +350,9 @@ HWForm::HWForm(QWidget *parent, QString styleSheet)
}
}
+ ui.Pages->setCurrentIndex(ID_PAGE_INFO);
PagesStack.push(ID_PAGE_MAIN);
+ ((AbstractPage*)ui.Pages->widget(ID_PAGE_MAIN))->triggerPageEnter();
GoBack();
}
@@ -340,7 +361,7 @@ void HWForm::updateXfire(void)
{
if(hwnet && (hwnet->clientState() != HWNewNet::Disconnected))
{
- xfire_setvalue(XFIRE_SERVER, !hwnet->getHost().compare("netserver.hedgewars.org:46631") ? "Official server" : hwnet->getHost().toAscii());
+ xfire_setvalue(XFIRE_SERVER, !hwnet->getHost().compare(QString("%1:%2").arg(NETGAME_DEFAULT_SERVER).arg(NETGAME_DEFAULT_PORT)) ? "Official server" : hwnet->getHost().toAscii());
switch(hwnet->clientState())
{
case HWNewNet::Connecting: // Connecting
@@ -443,23 +464,27 @@ void HWForm::UpdateWeapons()
}
}
-void HWForm::UpdateTeamsLists(const QStringList* editable_teams)
+void HWForm::UpdateTeamsLists()
{
- QStringList teamslist;
- if(editable_teams)
- {
- teamslist =* editable_teams;
- }
- else
- {
- teamslist = config->GetTeamsList();
- }
+ QStringList teamslist = config->GetTeamsList();
if(teamslist.empty())
{
- HWTeam defaultTeam(tr("DefaultTeam"));
+ QString currentNickName = config->value("net/nick",tr("Guest")+QString("%1").arg(rand())).toString().toUtf8();
+ QString teamName;
+
+ if (currentNickName.isEmpty())
+ {
+ teamName = tr("DefaultTeam");
+ }
+ else
+ {
+ teamName = tr("%1's Team").arg(currentNickName);
+ }
+
+ HWTeam defaultTeam(teamName);
defaultTeam.saveToFile();
- teamslist.push_back(tr("DefaultTeam"));
+ teamslist.push_back(teamName);
}
ui.pageOptions->CBTeamName->clear();
@@ -530,11 +555,56 @@ void HWForm::GoToVideos()
GoToPage(ID_PAGE_VIDEOS);
}
+//TODO: maybe find a better place for this?
+QString HWForm::stringifyPageId(quint32 id)
+{
+ QString pageName;
+ switch (id)
+ {
+ case ID_PAGE_SETUP_TEAM : pageName = "PAGE_SETUP_TEAM"; break;
+ case ID_PAGE_SETUP : pageName = "PAGE_SETUP"; break;
+ case ID_PAGE_MULTIPLAYER : pageName = "PAGE_MULTIPLAYER"; break;
+ case ID_PAGE_DEMOS : pageName = "PAGE_DEMOS"; break;
+ case ID_PAGE_NET : pageName = "PAGE_NET"; break;
+ case ID_PAGE_NETGAME : pageName = "PAGE_NETGAME"; break;
+ case ID_PAGE_INFO : pageName = "PAGE_INFO"; break;
+ case ID_PAGE_MAIN : pageName = "PAGE_MAIN"; break;
+ case ID_PAGE_GAMESTATS : pageName = "PAGE_GAMESTATS"; break;
+ case ID_PAGE_SINGLEPLAYER : pageName = "PAGE_SINGLEPLAYER"; break;
+ case ID_PAGE_TRAINING : pageName = "PAGE_TRAINING"; break;
+ case ID_PAGE_SELECTWEAPON : pageName = "PAGE_SELECTWEAPON"; break;
+ case ID_PAGE_NETSERVER : pageName = "PAGE_NETSERVER"; break;
+ case ID_PAGE_INGAME : pageName = "PAGE_INGAME"; break;
+ case ID_PAGE_ROOMSLIST : pageName = "PAGE_ROOMSLIST"; break;
+ case ID_PAGE_CONNECTING : pageName = "PAGE_CONNECTING"; break;
+ case ID_PAGE_SCHEME : pageName = "PAGE_SCHEME"; break;
+ case ID_PAGE_ADMIN : pageName = "PAGE_ADMIN"; break;
+ case ID_PAGE_CAMPAIGN : pageName = "PAGE_CAMPAIGN"; break;
+ case ID_PAGE_DRAWMAP : pageName = "PAGE_DRAWMAP"; break;
+ case ID_PAGE_DATADOWNLOAD : pageName = "PAGE_DATADOWNLOAD"; break;
+ case ID_PAGE_VIDEOS : pageName = "PAGE_VIDEOS"; break;
+ case MAX_PAGE : pageName = "MAX_PAGE"; break;
+ default : pageName = "UNKNOWN_PAGE"; break;
+ }
+ return pageName;
+}
+
void HWForm::OnPageShown(quint8 id, quint8 lastid)
{
#ifdef USE_XFIRE
updateXfire();
#endif
+
+ qDebug("Leaving %s, entering %s", qPrintable(stringifyPageId(lastid)), qPrintable(stringifyPageId(id)));
+ if (lastid == ID_PAGE_MAIN)
+ {
+ ui.pageMain->resetNetworkChoice();
+ }
+
+ // pageEnter and pageLeave events
+ ((AbstractPage*)ui.Pages->widget(lastid))->triggerPageLeave();
+ ((AbstractPage*)ui.Pages->widget(id))->triggerPageEnter();
+
if (id == ID_PAGE_DATADOWNLOAD)
{
ui.pageDataDownload->fetchList();
@@ -606,25 +676,26 @@ void HWForm::OnPageShown(quint8 id, quint8 lastid)
curTeamSelWidget->resetPlayingTeams(teamsList);
}
}
- else if (id == ID_PAGE_GAMESTATS)
+
+ if (id == ID_PAGE_GAMESTATS)
{
- ui.pageGameStats->renderStats();
+ switch(lastGameType) {
+ case gtLocal:
+ case gtQLocal:
+ case gtTraining:
+ case gtCampaign:
+ ui.pageGameStats->restartBtnVisible(true);
+ break;
+ default:
+ ui.pageGameStats->restartBtnVisible(false);
+ break;
+ }
}
if (id == ID_PAGE_MAIN)
{
ui.pageOptions->setTeamOptionsEnabled(true);
}
-
- if (id == ID_PAGE_SETUP)
- {
- config->reloadValues();
- }
-
- if (id == ID_PAGE_VIDEOS )
- {
- config->reloadVideosValues();
- }
}
void HWForm::GoToPage(int id)
@@ -640,10 +711,11 @@ void HWForm::GoToPage(int id)
/* if (id == ID_PAGE_DRAWMAP || id == ID_PAGE_GAMESTATS)
stopAnim = true;
- This were disabled due to broken flake animations. I believe the more general problems w/ opacity that forced its disable makes blocking these
- unnecessary.
+ This were disabled due to broken flake animations. I believe the more general problems w/ opacity that forced its disable makes blocking these
+ unnecessary.
*/
+
#if (QT_VERSION >= 0x040600)
if (!stopAnim)
{
@@ -699,8 +771,8 @@ void HWForm::GoToPage(int id)
animationOldSlide->start(QAbstractAnimation::DeleteWhenStopped);
animationNewSlide->start(QAbstractAnimation::DeleteWhenStopped);
- /* this is for the situation when the animation below is interrupted by a new animation. For some reason, finished is not being fired */
- for(int i=0;i<MAX_PAGE;i++) if (i!=id && i!=lastid) ui.Pages->widget(i)->hide();
+ /* this is for the situation when the animation below is interrupted by a new animation. For some reason, finished is not being fired */
+ for(int i=0;i<MAX_PAGE;i++) if (i!=id && i!=lastid) ui.Pages->widget(i)->hide();
}
#endif
}
@@ -711,6 +783,7 @@ void HWForm::GoBack()
int curid = ui.Pages->currentIndex();
if (curid == ID_PAGE_MAIN)
{
+ ((AbstractPage*)ui.Pages->widget(ID_PAGE_MAIN))->triggerPageLeave();
if (!ui.pageVideos->tryQuit(this))
return;
stopAnim = true;
@@ -896,18 +969,8 @@ void HWForm::AfterTeamEdit()
void HWForm::DeleteTeam(const QString & teamName)
{
- QMessageBox reallyDeleteMsg(this);
- reallyDeleteMsg.setIcon(QMessageBox::Question);
- reallyDeleteMsg.setWindowTitle(QMessageBox::tr("Teams - Are you sure?"));
- reallyDeleteMsg.setText(QMessageBox::tr("Do you really want to delete the team '%1'?").arg(teamName));
- reallyDeleteMsg.setWindowModality(Qt::WindowModal);
- reallyDeleteMsg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
-
- if (reallyDeleteMsg.exec() == QMessageBox::Ok)
- {
- ui.pageEditTeam->deleteTeam(teamName);
- UpdateTeamsLists();
- }
+ ui.pageEditTeam->deleteTeam(teamName);
+ UpdateTeamsLists();
}
void HWForm::DeleteScheme()
@@ -915,7 +978,7 @@ void HWForm::DeleteScheme()
ui.pageScheme->selectScheme->setCurrentIndex(ui.pageOptions->SchemesName->currentIndex());
if (ui.pageOptions->SchemesName->currentIndex() < ammoSchemeModel->numberOfDefaultSchemes)
{
- ShowErrorMessage(QMessageBox::tr("Cannot delete default scheme '%1'!").arg(ui.pageOptions->SchemesName->currentText()));
+ MessageDialog::ShowErrorMessage(QMessageBox::tr("Cannot delete default scheme '%1'!").arg(ui.pageOptions->SchemesName->currentText()), this);
}
else
{
@@ -941,7 +1004,7 @@ void HWForm::PlayDemo()
QListWidgetItem * curritem = ui.pagePlayDemo->DemosList->currentItem();
if (!curritem)
{
- ShowErrorMessage(QMessageBox::tr("Please select a record from the list"));
+ MessageDialog::ShowErrorMessage(QMessageBox::tr("Please select a record from the list"), this);
return;
}
CreateGame(0, 0, 0);
@@ -950,56 +1013,106 @@ void HWForm::PlayDemo()
void HWForm::PlayDemoQuick(const QString & demofilename)
{
- if (game && game->gameState == gsStarted) return;
- GoBack(); //needed to cleanly disconnect from netgame
GoToPage(ID_PAGE_MAIN);
+ //GoBack() <- don't or you'll close the socket
CreateGame(0, 0, 0);
game->PlayDemo(demofilename, false);
}
+void HWForm::NetConnectQuick(const QString & host, quint16 port)
+{
+ GoToPage(ID_PAGE_MAIN);
+ NetConnectServer(host, port);
+}
+
void HWForm::NetConnectServer(const QString & host, quint16 port)
{
+ qDebug("connecting to %s:%d", qPrintable(host), port);
_NetConnect(host, port, ui.pageOptions->editNetNick->text().trimmed());
}
void HWForm::NetConnectOfficialServer()
{
- NetConnectServer("netserver.hedgewars.org", 46631);
+ NetConnectServer(NETGAME_DEFAULT_SERVER, NETGAME_DEFAULT_PORT);
}
void HWForm::NetPassword(const QString & nick)
{
- int passLength = config->value("net/passwordlength", 0).toInt();
- QString hash = config->value("net/passwordhash", "").toString();
+ Q_UNUSED(nick);
+ //Get hashes
+ QString hash = config->passwordHash();
+ QString temphash = config->tempHash();
- // If the password is blank, ask the user to enter one in
- if (passLength == 0)
- {
- HWPasswordDialog * hpd = new HWPasswordDialog(this, tr("Your nickname %1 is\nregistered on Hedgewars.org\nPlease provide your password below\nor pick another nickname in game config:").arg(nick));
- hpd->cbSave->setChecked(config->value("net/savepassword", true).toBool());
- if (hpd->exec() != QDialog::Accepted)
- {
- ForcedDisconnect(tr("No password supplied."));
- delete hpd;
- return;
- }
+ //Check them
- QString password = hpd->lePassword->text();
- hash = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex();
+ if (temphash.isEmpty() && hash.isEmpty()) { //If the user enters a registered nick with no password, sends a bogus hash
+ hwnet->SendPasswordHash("THISISNOHASH");
+ }
+ else if (temphash.isEmpty()) { //Send saved hash as default
+ hwnet->SendPasswordHash(hash);
+ }
+ else { //Send the hash
+ hwnet->SendPasswordHash(temphash);
+ }
- bool save = hpd->cbSave->isChecked();
- config->setValue("net/savepassword", save);
- if (save) // user wants to save password
- {
- config->setValue("net/passwordhash", hash);
- config->setValue("net/passwordlength", password.size());
- config->setNetPasswordLength(password.size());
- }
+ //Remove temporary hash from config
+ config->clearTempHash();
+}
+
+void HWForm::NetNickRegistered(const QString & nick)
+{
+ //Get hashes
+ QString hash = config->passwordHash();
+ QString temphash = config->tempHash();
+
+ if (hash.isEmpty()) {
+ if (temphash.isEmpty()) { //If the user enters a registered nick with no password
+ QString suppliedpass;
+ while (suppliedpass.isEmpty()) {
+ QInputDialog nickRegedDialog(this);
+ nickRegedDialog.setWindowModality(Qt::WindowModal);
+ nickRegedDialog.setInputMode(QInputDialog::TextInput);
+ nickRegedDialog.setWindowTitle(tr("Hedgewars - Nick registered"));
+ nickRegedDialog.setLabelText(tr("This nick is registered, and you haven't specified a password.\n\nIf this nick isn't yours, please register your own nick at www.hedgewars.org\n\nPassword:"));
+ nickRegedDialog.setTextEchoMode(QLineEdit::Password);
+ nickRegedDialog.exec();
- delete hpd;
+ suppliedpass = nickRegedDialog.textValue();
+
+ if (nickRegedDialog.result() == QDialog::Rejected) {
+ config->clearPasswordHash();
+ config->clearTempHash();
+ GoBack();
+ return;
+ }
+ temphash = QCryptographicHash::hash(suppliedpass.toUtf8(), QCryptographicHash::Md5).toHex();
+ config->setTempHash(temphash);
+ }
+ }
}
+ NetPassword(nick);
+}
+
+void HWForm::NetNickNotRegistered(const QString & nick)
+{
+ Q_UNUSED(nick);
+
+ QMessageBox noRegMsg(this);
+ noRegMsg.setIcon(QMessageBox::Information);
+ noRegMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Nick not registered"));
+ noRegMsg.setWindowModality(Qt::WindowModal);
+ noRegMsg.setText(tr("Your nickname is not registered.\nTo prevent someone else from using it,\nplease register it at www.hedgewars.org"));
- hwnet->SendPasswordHash(hash);
+ if (!config->passwordHash().isEmpty())
+ {
+ config->clearPasswordHash();
+ noRegMsg.setText(noRegMsg.text()+tr("\n\nYour password wasn't saved either."));
+ }
+ if (!config->tempHash().isEmpty())
+ {
+ config->clearTempHash();
+ }
+ noRegMsg.exec();
}
void HWForm::NetNickTaken(const QString & nick)
@@ -1009,7 +1122,16 @@ void HWForm::NetNickTaken(const QString & nick)
if (!ok || newNick.isEmpty())
{
- ForcedDisconnect(tr("No nickname supplied."));
+ //ForcedDisconnect(tr("No nickname supplied."));
+ bool retry = RetryDialog(tr("Hedgewars - Empty nickname"), tr("No nickname supplied."));
+ GoBack();
+ if (retry) {
+ if (hwnet->m_private_game) {
+ QStringList list = hwnet->getHost().split(":");
+ NetConnectServer(list.at(0), list.at(1).toShort());
+ } else
+ NetConnectOfficialServer();
+ }
return;
}
@@ -1024,8 +1146,39 @@ void HWForm::NetNickTaken(const QString & nick)
void HWForm::NetAuthFailed()
{
// Set the password blank if case the user tries to join and enter his password again
- config->setValue("net/passwordlength", 0);
- config->setNetPasswordLength(0);
+ config->clearTempHash();
+
+ //Try to login again
+ bool retry = RetryDialog(tr("Hedgewars - Wrong password"), tr("You entered a wrong password."));
+ GoBack();
+
+ config->clearPasswordHash();
+ config->clearTempHash();
+ if (retry) {
+ NetConnectOfficialServer();
+ }
+}
+
+bool HWForm::RetryDialog(const QString & title, const QString & label)
+{
+ QMessageBox retryMsg(this);
+ retryMsg.setIcon(QMessageBox::Warning);
+ retryMsg.setWindowTitle(title);
+ retryMsg.setText(label);
+ retryMsg.setWindowModality(Qt::WindowModal);
+
+ retryMsg.addButton(QMessageBox::Cancel);
+
+ QPushButton *retryButton = retryMsg.addButton(QMessageBox::Ok);
+ retryButton->setText(tr("Try Again"));
+ retryButton->setFocus();
+
+ retryMsg.exec();
+
+ if (retryMsg.clickedButton() == retryButton) {
+ return true;
+ }
+ return false;
}
void HWForm::NetTeamAccepted(const QString & team)
@@ -1038,7 +1191,7 @@ void HWForm::NetError(const QString & errmsg)
switch (ui.Pages->currentIndex())
{
case ID_PAGE_INGAME:
- ShowErrorMessage(errmsg);
+ MessageDialog::ShowErrorMessage(errmsg, this);
// no break
case ID_PAGE_NETGAME:
ui.pageNetGame->displayError(errmsg);
@@ -1058,18 +1211,20 @@ void HWForm::NetWarning(const QString & wrnmsg)
void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
{
- if(hwnet)
- {
+ Q_UNUSED(nick);
+
+ if (hwnet) {
+ // destroy old connection
hwnet->Disconnect();
delete hwnet;
- hwnet=0;
+ hwnet = NULL;
}
hwnet = new HWNewNet();
GoToPage(ID_PAGE_CONNECTING);
- connect(hwnet, SIGNAL(AskForRunGame()), this, SLOT(CreateNetGame()));
+ connect(hwnet, SIGNAL(AskForRunGame()), this, SLOT(CreateNetGame()), Qt::QueuedConnection);
connect(hwnet, SIGNAL(connected()), this, SLOT(NetConnected()), Qt::QueuedConnection);
connect(hwnet, SIGNAL(Error(const QString&)), this, SLOT(NetError(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(Warning(const QString&)), this, SLOT(NetWarning(const QString&)), Qt::QueuedConnection);
@@ -1078,13 +1233,14 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
connect(hwnet, SIGNAL(AddNetTeam(const HWTeam&)), this, SLOT(AddNetTeam(const HWTeam&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(RemoveNetTeam(const HWTeam&)), this, SLOT(RemoveNetTeam(const HWTeam&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(TeamAccepted(const QString&)), this, SLOT(NetTeamAccepted(const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(AskForPassword(const QString&)), this, SLOT(NetPassword(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(NickRegistered(const QString&)), this, SLOT(NetNickRegistered(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(NickNotRegistered(const QString&)), this, SLOT(NetNickNotRegistered(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(NickTaken(const QString&)), this, SLOT(NetNickTaken(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(AuthFailed()), this, SLOT(NetAuthFailed()), Qt::QueuedConnection);
//connect(ui.pageNetGame->BtnBack, SIGNAL(clicked()), hwnet, SLOT(partRoom()));
ui.pageRoomsList->chatWidget->setUsersModel(hwnet->lobbyPlayersModel());
- ui.pageNetGame->pChatWidget->setUsersModel(hwnet->roomPlayersModel());
+ ui.pageNetGame->chatWidget->setUsersModel(hwnet->roomPlayersModel());
// rooms list page stuff
ui.pageRoomsList->setModel(hwnet->roomsListModel());
@@ -1109,31 +1265,35 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
// room status stuff
connect(hwnet, SIGNAL(roomMaster(bool)),
- this, SLOT(NetGameChangeStatus(bool)), Qt::QueuedConnection);
+ this, SLOT(NetGameChangeStatus(bool)));
// net page stuff
- connect(hwnet, SIGNAL(chatStringFromNet(const QString&)),
- ui.pageNetGame->pChatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(roomNameUpdated(const QString &)),
+ ui.pageNetGame, SLOT(setRoomName(const QString &)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(roomChatAction(const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onChatAction(const QString&, const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(roomChatMessage(const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onChatMessage(const QString&, const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringFromMe(const QString&)),
- ui.pageNetGame->pChatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
connect(hwnet, SIGNAL(roomMaster(bool)),
- ui.pageNetGame->pChatWidget, SLOT(adminAccess(bool)), Qt::QueuedConnection);
- connect(ui.pageNetGame->pChatWidget, SIGNAL(chatLine(const QString&)),
- hwnet, SLOT(chatLineToNet(const QString&)));
+ ui.pageNetGame->chatWidget, SLOT(adminAccess(bool)), Qt::QueuedConnection);
+ connect(ui.pageNetGame->chatWidget, SIGNAL(chatLine(const QString&)),
+ hwnet, SLOT(chatLineToNetWithEcho(const QString&)));
connect(ui.pageNetGame->BtnGo, SIGNAL(clicked()), hwnet, SLOT(ToggleReady()));
connect(hwnet, SIGNAL(setMyReadyStatus(bool)),
ui.pageNetGame, SLOT(setReadyStatus(bool)), Qt::QueuedConnection);
// chat widget actions
- connect(ui.pageNetGame->pChatWidget, SIGNAL(kick(const QString&)),
+ connect(ui.pageNetGame->chatWidget, SIGNAL(kick(const QString&)),
hwnet, SLOT(kickPlayer(const QString&)));
- connect(ui.pageNetGame->pChatWidget, SIGNAL(ban(const QString&)),
+ connect(ui.pageNetGame->chatWidget, SIGNAL(ban(const QString&)),
hwnet, SLOT(banPlayer(const QString&)));
- connect(ui.pageNetGame->pChatWidget, SIGNAL(info(const QString&)),
+ connect(ui.pageNetGame->chatWidget, SIGNAL(info(const QString&)),
hwnet, SLOT(infoPlayer(const QString&)));
- connect(ui.pageNetGame->pChatWidget, SIGNAL(follow(const QString&)),
+ connect(ui.pageNetGame->chatWidget, SIGNAL(follow(const QString&)),
hwnet, SLOT(followPlayer(const QString&)));
+ connect(ui.pageNetGame->chatWidget, SIGNAL(consoleCommand(const QString&)),
+ hwnet, SLOT(consoleCommand(const QString&)));
connect(ui.pageRoomsList->chatWidget, SIGNAL(kick(const QString&)),
hwnet, SLOT(kickPlayer(const QString&)));
connect(ui.pageRoomsList->chatWidget, SIGNAL(ban(const QString&)),
@@ -1142,26 +1302,41 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
hwnet, SLOT(infoPlayer(const QString&)));
connect(ui.pageRoomsList->chatWidget, SIGNAL(follow(const QString&)),
hwnet, SLOT(followPlayer(const QString&)));
+ connect(ui.pageRoomsList->chatWidget, SIGNAL(consoleCommand(const QString&)),
+ hwnet, SLOT(consoleCommand(const QString&)));
+
+// player info
+ connect(hwnet, SIGNAL(playerInfo(const QString&, const QString&, const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onPlayerInfo(const QString&, const QString&, const QString&, const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(playerInfo(const QString&, const QString&, const QString&, const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(onPlayerInfo(const QString&, const QString&, const QString&, const QString&)), Qt::QueuedConnection);
// chatting
connect(ui.pageRoomsList->chatWidget, SIGNAL(chatLine(const QString&)),
hwnet, SLOT(chatLineToLobby(const QString&)));
- connect(hwnet, SIGNAL(chatStringLobby(const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(chatStringLobby(const QString&, const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&, const QString&)));
- connect(hwnet, SIGNAL(chatStringFromMeLobby(const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(lobbyChatAction(const QString&,const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onChatAction(const QString&,const QString&)), Qt::QueuedConnection);
+ connect(hwnet, SIGNAL(lobbyChatMessage(const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(onChatMessage(const QString&, const QString&)), Qt::QueuedConnection);
// nick list stuff
- connect(hwnet, SIGNAL(nickAdded(const QString&, bool)),
- ui.pageNetGame->pChatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(nickRemoved(const QString&)),
- ui.pageNetGame->pChatWidget, SLOT(nickRemoved(const QString&)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(nickAddedLobby(const QString&, bool)),
- ui.pageRoomsList->chatWidget, SLOT(nickAdded(const QString&, bool)), Qt::QueuedConnection);
- connect(hwnet, SIGNAL(nickRemovedLobby(const QString&)),
- ui.pageRoomsList->chatWidget, SLOT(nickRemoved(const QString&)), Qt::QueuedConnection);
+ {
+ QSortFilterProxyModel * playersSortFilterModel = qobject_cast<QSortFilterProxyModel *>(hwnet->lobbyPlayersModel());
+ if(playersSortFilterModel)
+ {
+ PlayersListModel * players = qobject_cast<PlayersListModel *>(playersSortFilterModel->sourceModel());
+ connect(players, SIGNAL(nickAdded(const QString&, bool)),
+ ui.pageNetGame->chatWidget, SLOT(nickAdded(const QString&, bool)));
+ connect(players, SIGNAL(nickRemoved(const QString&)),
+ ui.pageNetGame->chatWidget, SLOT(nickRemoved(const QString&)));
+ connect(players, SIGNAL(nickAddedLobby(const QString&, bool)),
+ ui.pageRoomsList->chatWidget, SLOT(nickAdded(const QString&, bool)));
+ connect(players, SIGNAL(nickRemovedLobby(const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(nickRemoved(const QString&)));
+ connect(players, SIGNAL(nickRemovedLobby(const QString&, const QString&)),
+ ui.pageRoomsList->chatWidget, SLOT(nickRemoved(const QString&, const QString&)));
+ }
+ }
// teams selecting stuff
connect(ui.pageNetGame->pNetTeamsWidget, SIGNAL(hhogsNumChanged(const HWTeam&)),
@@ -1180,11 +1355,16 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
connect(hwnet, SIGNAL(serverMessageNew(const QString&)), ui.pageAdmin, SLOT(serverMessageNew(const QString &)));
connect(hwnet, SIGNAL(serverMessageOld(const QString&)), ui.pageAdmin, SLOT(serverMessageOld(const QString &)));
connect(hwnet, SIGNAL(latestProtocolVar(int)), ui.pageAdmin, SLOT(protocol(int)));
+ connect(hwnet, SIGNAL(bansList(const QStringList &)), ui.pageAdmin, SLOT(setBansList(const QStringList &)));
connect(ui.pageAdmin, SIGNAL(setServerMessageNew(const QString&)), hwnet, SLOT(setServerMessageNew(const QString &)));
connect(ui.pageAdmin, SIGNAL(setServerMessageOld(const QString&)), hwnet, SLOT(setServerMessageOld(const QString &)));
connect(ui.pageAdmin, SIGNAL(setProtocol(int)), hwnet, SLOT(setLatestProtocolVar(int)));
connect(ui.pageAdmin, SIGNAL(askServerVars()), hwnet, SLOT(askServerVars()));
connect(ui.pageAdmin, SIGNAL(clearAccountsCache()), hwnet, SLOT(clearAccountsCache()));
+ connect(ui.pageAdmin, SIGNAL(bansListRequest()), hwnet, SLOT(getBanList()));
+ connect(ui.pageAdmin, SIGNAL(removeBan(QString)), hwnet, SLOT(removeBan(QString)));
+ connect(ui.pageAdmin, SIGNAL(banIP(QString,QString,int)), hwnet, SLOT(banIP(QString,QString,int)));
+ connect(ui.pageAdmin, SIGNAL(banNick(QString,QString,int)), hwnet, SLOT(banNick(QString,QString,int)));
// disconnect
connect(hwnet, SIGNAL(disconnected(const QString&)), this, SLOT(ForcedDisconnect(const QString&)), Qt::QueuedConnection);
@@ -1194,21 +1374,101 @@ void HWForm::_NetConnect(const QString & hostName, quint16 port, QString nick)
connect(ui.pageNetGame->pGameCFG, SIGNAL(paramChanged(const QString &, const QStringList &)), hwnet, SLOT(onParamChanged(const QString &, const QStringList &)));
connect(hwnet, SIGNAL(configAsked()), ui.pageNetGame->pGameCFG, SLOT(fullNetConfig()));
- while (nick.isEmpty())
- {
- nick = QInputDialog::getText(this,
- QObject::tr("Nickname"),
- QObject::tr("Please enter your nickname"),
- QLineEdit::Normal,
- QDir::home().dirName());
- config->setValue("net/nick",nick);
- config->updNetNick();
- }
+ //nick and pass stuff
+ hwnet->m_private_game = !(hostName == NETGAME_DEFAULT_SERVER && port == NETGAME_DEFAULT_PORT);
+ if (hwnet->m_private_game == false && AskForNickAndPwd() != 0)
+ return;
- ui.pageRoomsList->setUser(nick);
- ui.pageNetGame->setUser(nick);
+ QString nickname = config->value("net/nick",tr("Guest")+QString("%1").arg(rand())).toString();
+ ui.pageRoomsList->setUser(nickname);
+ ui.pageNetGame->setUser(nickname);
- hwnet->Connect(hostName, port, nick);
+ hwnet->Connect(hostName, port, nickname);
+}
+
+int HWForm::AskForNickAndPwd(void)
+{
+ //remove temppasswordhash just in case
+ config->clearTempHash();
+
+ //initialize
+ QString hash;
+ QString temphash;
+ QString nickname;
+ QString password;
+
+ do {
+ nickname = config->value("net/nick",tr("Guest")+QString("%1").arg(rand())).toString();
+ hash = config->passwordHash();
+ temphash = config->tempHash();
+
+ //if something from login is missing, start dialog loop
+ if (nickname.isEmpty() || hash.isEmpty()) {
+ //open dialog
+ HWPasswordDialog * pwDialog = new HWPasswordDialog(this);
+ // make the "new account" button dialog open a browser with the registration page
+ connect(pwDialog->pbNewAccount, SIGNAL(clicked()), this, SLOT(openRegistrationPage()));
+ pwDialog->cbSave->setChecked(config->value("net/savepassword", true).toBool());
+
+ //if nickname is present, put it into the field
+ if (!nickname.isEmpty()) {
+ pwDialog->leNickname->setText(nickname);
+ pwDialog->lePassword->setFocus();
+ }
+
+ //if dialog close, create an error message
+ if (pwDialog->exec() != QDialog::Accepted) {
+ delete pwDialog;
+ GoBack();
+ break;
+ }
+
+ //set nick and pass from the dialog
+ nickname = pwDialog->leNickname->text();
+ password = pwDialog->lePassword->text();
+ bool save = pwDialog->cbSave->isChecked();
+ //clean up
+ delete pwDialog;
+
+ //check the nickname variable
+ if (nickname.isEmpty()) {
+ int retry = RetryDialog(tr("Hedgewars - Empty nickname"), tr("No nickname supplied."));
+ GoBack();
+ if (retry) {
+ if (hwnet->m_private_game) {
+ QStringList list = hwnet->getHost().split(":");
+ NetConnectServer(list.at(0), list.at(1).toShort());
+ } else
+ NetConnectOfficialServer();
+ }
+ break; //loop restart
+ } else {
+ //update nickname if it's fine
+ config->setValue("net/nick", nickname);
+ config->updNetNick();
+ }
+
+ //check the password variable
+ if (password.isEmpty()) {
+ config->clearPasswordHash();
+ break;
+ } else {
+ //calculate temphash and set it into config
+ temphash = QCryptographicHash::hash(password.toUtf8(), QCryptographicHash::Md5).toHex();
+ config->setTempHash(temphash);
+
+ //if user wants to save password
+ config->setValue("net/savepassword", save);
+ if (save) {
+ // user wants to save password
+ ui.pageOptions->CBSavePassword->setChecked(true);
+ config->setPasswordHash(temphash);
+ }
+ }
+ }
+ } while (nickname.isEmpty() || (hash.isEmpty() && temphash.isEmpty())); //while a nickname, or both hashes are missing
+
+ return 0;
}
void HWForm::NetConnect()
@@ -1235,7 +1495,7 @@ void HWForm::NetStartServer()
pnetserver = new HWNetServer;
if (!pnetserver->StartServer(ui.pageNetServer->sbPort->value()))
{
- ShowErrorMessage(QMessageBox::tr("Unable to start server"));
+ MessageDialog::ShowErrorMessage(QMessageBox::tr("Unable to start server"), this);
delete pnetserver;
pnetserver = 0;
@@ -1275,16 +1535,32 @@ void HWForm::NetDisconnect()
void HWForm::ForcedDisconnect(const QString & reason)
{
+ if (reason == "Reconnected too fast") { //TODO: this is a hack, which should be remade
+ bool retry = RetryDialog(tr("Hedgewars - Connection error"), tr("You reconnected too fast.\nPlease wait a few seconds and try again."));
+ if (retry) {
+ if (hwnet->m_private_game) {
+ QStringList list = hwnet->getHost().split(":");
+ NetConnectServer(list.at(0), list.at(1).toUInt());
+ } else
+ NetConnectOfficialServer();
+ }
+ else {
+ while (ui.Pages->currentIndex() != ID_PAGE_NET
+ && ui.Pages->currentIndex() != ID_PAGE_MAIN)
+ {
+ GoBack();
+ }
+ }
+ return;
+ }
if (pnetserver)
return; // we have server - let it care of all things
- if (hwnet)
- {
+ if (hwnet) {
QString errorStr = QMessageBox::tr("Connection to server is lost") + (reason.isEmpty()?"":("\n\n" + HWNewNet::tr("Quit reason: ") + '"' + reason +'"'));
- ShowErrorMessage(errorStr);
+ MessageDialog::ShowErrorMessage(errorStr, this);
}
while (ui.Pages->currentIndex() != ID_PAGE_NET
- && ui.Pages->currentIndex() != ID_PAGE_NETTYPE
&& ui.Pages->currentIndex() != ID_PAGE_MAIN)
{
GoBack();
@@ -1298,7 +1574,7 @@ void HWForm::NetConnected()
void HWForm::NetGameEnter()
{
- ui.pageNetGame->pChatWidget->clear();
+ ui.pageNetGame->chatWidget->clear();
GoToPage(ID_PAGE_NETGAME);
}
@@ -1349,7 +1625,7 @@ void HWForm::GameStateChanged(GameState gameState)
//setVisible(true);
setFocusPolicy(Qt::StrongFocus);
if (id == ID_PAGE_INGAME) GoBack();
- Music(ui.pageOptions->CBEnableFrontendMusic->isChecked());
+ Music(ui.pageOptions->CBFrontendMusic->isChecked());
if (wBackground) wBackground->startAnimation();
GoToPage(ID_PAGE_GAMESTATS);
if (hwnet && (!game || !game->netSuspend)) hwnet->gameFinished(true);
@@ -1367,7 +1643,7 @@ void HWForm::GameStateChanged(GameState gameState)
(gameState == gsInterrupted || gameState == gsStopped || gameState == gsDestroyed || gameState == gsHalted)))
{
if (id == ID_PAGE_INGAME) GoBack();
- Music(ui.pageOptions->CBEnableFrontendMusic->isChecked());
+ Music(ui.pageOptions->CBFrontendMusic->isChecked());
if (wBackground) wBackground->startAnimation();
if (hwnet) hwnet->gameFinished(false);
}
@@ -1387,16 +1663,6 @@ void HWForm::CreateGame(GameCFGWidget * gamecfg, TeamSelWidget* pTeamSelWidget,
m_lastDemo = QByteArray();
}
-void HWForm::ShowErrorMessage(const QString & msg)
-{
- QMessageBox msgMsg(this);
- msgMsg.setIcon(QMessageBox::Warning);
- msgMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Error"));
- msgMsg.setText(msg);
- msgMsg.setWindowModality(Qt::WindowModal);
- msgMsg.exec();
-}
-
void HWForm::GetRecord(RecordType type, const QByteArray & record)
{
if (type != rtNeither)
@@ -1408,9 +1674,7 @@ void HWForm::GetRecord(RecordType type, const QByteArray & record)
QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm") :
"LastRound";
- QStringList versionParts = cVersionString->split('-');
- if ( (versionParts.size() == 2) && (!versionParts[1].isEmpty()) && (versionParts[1].contains(':')) )
- recordFileName = recordFileName + "_" + versionParts[1].replace(':','-');
+ recordFileName += "_" + *cRevisionString + "-" + *cHashString;
if (type == rtDemo)
{
@@ -1429,7 +1693,7 @@ void HWForm::GetRecord(RecordType type, const QByteArray & record)
QFile demofile(filename);
if (!demofile.open(QIODevice::WriteOnly))
- ShowErrorMessage(tr("Cannot save record to file %1").arg(filename));
+ MessageDialog::ShowErrorMessage(tr("Cannot save record to file %1").arg(filename), this);
else
{
demofile.write(demo);
@@ -1484,7 +1748,9 @@ void HWForm::closeEvent(QCloseEvent *event)
xfire_free();
#endif
config->SaveOptions();
+#if VIDEOREC
config->SaveVideosOptions();
+#endif
event->accept();
}
@@ -1498,9 +1764,6 @@ void HWForm::Music(bool checked)
void HWForm::NetGameChangeStatus(bool isMaster)
{
- ui.pageNetGame->pGameCFG->setEnabled(isMaster);
- ui.pageNetGame->pNetTeamsWidget->setInteractivity(isMaster);
-
if (isMaster)
NetGameMaster();
else
@@ -1512,25 +1775,29 @@ void HWForm::NetGameMaster()
ui.pageNetGame->setMasterMode(true);
ui.pageNetGame->restrictJoins->setChecked(false);
ui.pageNetGame->restrictTeamAdds->setChecked(false);
+ ui.pageNetGame->restrictUnregistered->setChecked(false);
ui.pageNetGame->pGameCFG->GameSchemes->setModel(ammoSchemeModel);
- ui.pageNetGame->pGameCFG->setEnabled(true);
+ ui.pageNetGame->pGameCFG->setMaster(true);
ui.pageNetGame->pNetTeamsWidget->setInteractivity(true);
if (hwnet)
{
// disconnect connections first to ensure their inexistance and not to connect twice
- ui.pageNetGame->BtnStart->disconnect(hwnet);
+ ui.pageNetGame->BtnStart->disconnect(this);
ui.pageNetGame->BtnUpdate->disconnect(hwnet);
+ ui.pageNetGame->leRoomName->disconnect(hwnet);
ui.pageNetGame->restrictJoins->disconnect(hwnet);
ui.pageNetGame->restrictTeamAdds->disconnect(hwnet);
+ ui.pageNetGame->restrictUnregistered->disconnect(hwnet);
ui.pageNetGame->disconnect(hwnet, SLOT(updateRoomName(const QString&)));
ui.pageNetGame->setRoomName(hwnet->getRoom());
- connect(ui.pageNetGame->BtnStart, SIGNAL(clicked()), hwnet, SLOT(startGame()));
+ connect(ui.pageNetGame->BtnStart, SIGNAL(clicked()), this, SLOT(startGame()));
connect(ui.pageNetGame, SIGNAL(askForUpdateRoomName(const QString &)), hwnet, SLOT(updateRoomName(const QString &)));
connect(ui.pageNetGame->restrictJoins, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictJoins()));
connect(ui.pageNetGame->restrictTeamAdds, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictTeamAdds()));
+ connect(ui.pageNetGame->restrictUnregistered, SIGNAL(triggered()), hwnet, SLOT(toggleRegisteredOnly()));
connect(ui.pageNetGame->pGameCFG->GameSchemes->model(),
SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
ui.pageNetGame->pGameCFG,
@@ -1541,15 +1808,18 @@ void HWForm::NetGameMaster()
void HWForm::NetGameSlave()
{
- ui.pageNetGame->pGameCFG->setEnabled(false);
+ ui.pageNetGame->pGameCFG->setMaster(false);
ui.pageNetGame->pNetTeamsWidget->setInteractivity(false);
if (hwnet)
{
NetAmmoSchemeModel * netAmmo = new NetAmmoSchemeModel(hwnet);
connect(hwnet, SIGNAL(netSchemeConfig(QStringList &)), netAmmo, SLOT(setNetSchemeConfig(QStringList &)));
+
ui.pageNetGame->pGameCFG->GameSchemes->setModel(netAmmo);
+ ui.pageNetGame->setRoomName(hwnet->getRoom());
+
ui.pageNetGame->pGameCFG->GameSchemes->view()->disconnect(hwnet);
connect(hwnet, SIGNAL(netSchemeConfig(QStringList &)),
this, SLOT(selectFirstNetScheme()));
@@ -1636,19 +1906,30 @@ void HWForm::UpdateCampaignPageProgress(int index)
// used for --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]
QString HWForm::getDemoArguments()
{
- QRect resolution = config->vid_Resolution();
- return QString(QString::number(resolution.width()) + " "
- + QString::number(resolution.height()) + " "
- + QString::number(config->bitDepth()) + " " // bpp
- + QString::number(config->volume()) + " " // sound volume
- + (config->isMusicEnabled() ? "1" : "0") + " "
- + (config->isSoundEnabled() ? "1" : "0") + " "
- + config->language() + ".txt "
- + (config->vid_Fullscreen() ? "1" : "0") + " "
- + (config->isShowFPSEnabled() ? "1" : "0") + " "
- + (config->isAltDamageEnabled() ? "1" : "0") + " "
- + QString::number(config->timerInterval()) + " "
- + QString::number(config->translateQuality()));
+
+ QString prefix = "\"" + datadir->absolutePath() + "\"";
+ QString userPrefix = "\"" + cfgdir->absolutePath() + "\"";
+#ifdef Q_WS_WIN
+ prefix = prefix.replace("/","\\");
+ userPrefix = userPrefix.replace("/","\\");
+#endif
+
+ std::pair<QRect, QRect> resolutions = config->vid_ResolutionPair();
+ return QString("--prefix " + prefix
+ + " --user-prefix " + userPrefix
+ + " --fullscreen-width " + QString::number(resolutions.first.width())
+ + " --fullscreen-height " + QString::number(resolutions.first.height())
+ + " --width " + QString::number(resolutions.second.width())
+ + " --height " + QString::number(resolutions.second.height())
+ + " --volume " + QString::number(config->volume())
+ + (config->isMusicEnabled() ? "" : " --nomusic")
+ + (config->isSoundEnabled() ? "" : " --nosound")
+ + " --locale " + config->language() + ".txt"
+ + (config->vid_Fullscreen() ? " --fullscreen" : "")
+ + (config->isShowFPSEnabled() ? " --showfps" : "")
+ + (config->isAltDamageEnabled() ? " --altdmg" : "")
+ + " --frame-interval " + QString::number(config->timerInterval())
+ + " --raw-quality " + QString::number(config->translateQuality()));
}
void HWForm::AssociateFiles()
@@ -1657,14 +1938,22 @@ void HWForm::AssociateFiles()
QString arguments = getDemoArguments();
#ifdef _WIN32
QSettings registry_hkcr("HKEY_CLASSES_ROOT", QSettings::NativeFormat);
+
+ // file extension(s)
registry_hkcr.setValue(".hwd/Default", "Hedgewars.Demo");
registry_hkcr.setValue(".hws/Default", "Hedgewars.Save");
registry_hkcr.setValue("Hedgewars.Demo/Default", tr("Hedgewars Demo File", "File Types"));
registry_hkcr.setValue("Hedgewars.Save/Default", tr("Hedgewars Save File", "File Types"));
registry_hkcr.setValue("Hedgewars.Demo/DefaultIcon/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwdfile.ico\",0");
registry_hkcr.setValue("Hedgewars.Save/DefaultIcon/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwsfile.ico\",0");
- registry_hkcr.setValue("Hedgewars.Demo/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" \"" + cfgdir->absolutePath().replace("/","\\") + "\" \"" + datadir->absolutePath().replace("/", "\\") + "\" \"%1\" --set-everything "+arguments);
- registry_hkcr.setValue("Hedgewars.Save/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" \"" + cfgdir->absolutePath().replace("/","\\") + "\" \"" + datadir->absolutePath().replace("/", "\\") + "\" \"%1\" --set-everything "+arguments);
+ registry_hkcr.setValue("Hedgewars.Demo/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" " + arguments + " %1");
+ registry_hkcr.setValue("Hedgewars.Save/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hwengine.exe\" " + arguments + " %1");
+
+ // custom url scheme(s)
+ registry_hkcr.setValue("hwplay/Default", "\"URL:Hedgewars ServerAccess Scheme\"");
+ registry_hkcr.setValue("hwplay/URL Protocol", "");
+ registry_hkcr.setValue("hwplay/DefaultIcon/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hedgewars.exe\",0");
+ registry_hkcr.setValue("hwplay/Shell/Open/Command/Default", "\"" + bindir->absolutePath().replace("/", "\\") + "\\hedgewars.exe\" %1");
#elif defined __APPLE__
// only useful when other apps have taken precedence over our file extensions and you want to reset it
system("defaults write com.apple.LaunchServices LSHandlers -array-add '<dict><key>LSHandlerContentTag</key><string>hwd</string><key>LSHandlerContentTagClass</key><string>public.filename-extension</string><key>LSHandlerRoleAll</key><string>org.hedgewars.desktop</string></dict>'");
@@ -1680,12 +1969,14 @@ void HWForm::AssociateFiles()
if (success) success = checkForDir(QDir::home().absolutePath() + "/.local/share");
if (success) success = checkForDir(QDir::home().absolutePath() + "/.local/share/applications");
if (success) success = system(("cp "+datadir->absolutePath()+"/misc/hedgewars-mimeinfo.xml "+QDir::home().absolutePath()+"/.local/share/mime/packages").toLocal8Bit().constData())==0;
+ if (success) success = system(("cp "+datadir->absolutePath()+"/misc/hedgewars.desktop "+QDir::home().absolutePath()+"/.local/share/applications").toLocal8Bit().constData())==0;
if (success) success = system(("cp "+datadir->absolutePath()+"/misc/hwengine.desktop "+QDir::home().absolutePath()+"/.local/share/applications").toLocal8Bit().constData())==0;
if (success) success = system(("update-mime-database "+QDir::home().absolutePath()+"/.local/share/mime").toLocal8Bit().constData())==0;
+ if (success) success = system("xdg-mime default hedgewars.desktop x-scheme-handler/hwplay")==0;
if (success) success = system("xdg-mime default hwengine.desktop application/x-hedgewars-demo")==0;
if (success) success = system("xdg-mime default hwengine.desktop application/x-hedgewars-save")==0;
// hack to add user's settings to hwengine. might be better at this point to read in the file, append it, and write it out to its new home. This assumes no spaces in the data dir path
- if (success) success = system(("sed -i 's/^\\(Exec=.*\\) \\([^ ]* %f\\)/\\1 "+cfgdir->absolutePath().replace(" ","\\\\ ").replace("/","\\/")+" \\2 --set-everything "+arguments+"/' "+QDir::home().absolutePath()+"/.local/share/applications/hwengine.desktop").toLocal8Bit().constData())==0;
+ if (success) success = system(("sed -i 's|^\\(Exec=.*\\) \\(%f\\)|\\1 \\2 "+arguments+"|' "+QDir::home().absolutePath()+"/.local/share/applications/hwengine.desktop").toLocal8Bit().constData())==0;
#endif
if (success)
{
@@ -1697,7 +1988,12 @@ void HWForm::AssociateFiles()
infoMsg.exec();
}
else
- ShowErrorMessage(QMessageBox::tr("File association failed."));
+ MessageDialog::ShowErrorMessage(QMessageBox::tr("File association failed."), this);
+}
+
+void HWForm::openRegistrationPage()
+{
+ QDesktopServices::openUrl(QUrl("http://www.hedgewars.org/user/register"));
}
void HWForm::saveDemoWithCustomName()
@@ -1716,7 +2012,7 @@ void HWForm::saveDemoWithCustomName()
QFile demofile(filePath);
ok = demofile.open(QIODevice::WriteOnly);
if (!ok)
- ShowErrorMessage(tr("Cannot save record to file %1").arg(filePath));
+ MessageDialog::ShowErrorMessage(tr("Cannot save record to file %1").arg(filePath), this);
else
{
ok = -1 != demofile.write(m_lastDemo);
@@ -1728,107 +2024,67 @@ void HWForm::saveDemoWithCustomName()
}
}
-void HWForm::SendFeedback()
+void HWForm::restartGame()
{
- //Create Xml representation of google code issue first
- if (!CreateIssueXml())
- {
- ShowErrorMessage(QMessageBox::tr("Please fill out all fields"));
- return;
- }
-
- //Google login using fake account (feedback.hedgewars at gmail.com)
- nam = new QNetworkAccessManager(this);
- connect(nam, SIGNAL(finished(QNetworkReply*)),
- this, SLOT(finishedSlot(QNetworkReply*)));
-
- QUrl url(QString("https://www.google.com/accounts/ClientLogin?"
- "accountType=GOOGLE&Email=feedback.hedgewars at gmail.com&Passwd=hwfeedback&service=code&source=HedgewarsFoundation-Hedgewars-")
- + (cVersionString?(*cVersionString):QString("")));
- nam->get(QNetworkRequest(url));
+ // get rid off old game stats page
+ if(ui.Pages->currentIndex() == ID_PAGE_GAMESTATS)
+ GoBack();
+ CreateGame(lastGameCfg, lastGameTeamSel, lastGameAmmo);
+
+ switch(lastGameType) {
+ case gtTraining:
+ game->StartTraining(lastGameStartArgs.at(0).toString());
+ break;
+ case gtQLocal:
+ game->StartQuick();
+ break;
+ case gtCampaign:
+ game->StartCampaign(lastGameStartArgs.at(0).toString(), lastGameStartArgs.at(1).toString(), lastGameStartArgs.at(2).toString());
+ break;
+ case gtLocal:
+ game->StartLocal();
+ break;
+ default:
+ break;
+ }
}
-bool HWForm::CreateIssueXml()
+void HWForm::ShowErrorMessage(const QString & msg)
{
- QString summary = ui.pageFeedback->summary->text();
- QString description = ui.pageFeedback->description->toPlainText();
-
- //Check if all necessary information is entered
- if (summary.isEmpty() || description.isEmpty())
- return false;
-
- issueXml =
- "<?xml version='1.0' encoding='UTF-8'?>"
- "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:issues='http://code.google.com/p/hedgewars/issues/list'>"
- "<title>";
- issueXml.append(summary);
- issueXml.append("</title><content type='html'>");
- issueXml.append(description);
- issueXml.append("</content><author><name>feedback.hedgewars</name></author></entry>");
-
- return true;
+ MessageDialog::ShowErrorMessage(msg, this);
}
-void HWForm::finishedSlot(QNetworkReply* reply)
+void HWForm::showFeedbackDialog()
{
- if (reply && reply->error() == QNetworkReply::NoError)
- {
- QByteArray array = reply->readAll();
- QString str(array);
-
- if (authToken.length() != 0)
- {
-
- QMessageBox infoMsg(this);
- infoMsg.setIcon(QMessageBox::Information);
- infoMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Success"));
- infoMsg.setText(QMessageBox::tr("Successfully posted the issue on hedgewars.googlecode.com"));
- infoMsg.setWindowModality(Qt::WindowModal);
- infoMsg.exec();
-
- ui.pageFeedback->summary->clear();
- ui.pageFeedback->description->clear();
- authToken = "";
- return;
- }
-
- if (!getAuthToken(str))
- {
- ShowErrorMessage(QMessageBox::tr("Error during authentication at google.com"));
- return;
- }
-
- QByteArray body(issueXml.toUtf8());
- QNetworkRequest header(QUrl("https://code.google.com/feeds/issues/p/hedgewars/issues/full"));
- header.setRawHeader("Content-Length", QString::number(issueXml.length()).toAscii());
- header.setRawHeader("Content-Type", "application/atom+xml");
- header.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(authToken).toUtf8());
- nam->post(header, body);
-
- }
- else if (authToken.length() == 0)
- ShowErrorMessage(QMessageBox::tr("Error during authentication at google.com"));
- else
- {
- ShowErrorMessage(QMessageBox::tr("Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)"));
- authToken = "";
- }
+ QNetworkRequest newRequest(QUrl("http://www.hedgewars.org"));
+ QNetworkAccessManager *manager = new QNetworkAccessManager(this);
+ QNetworkReply *reply = manager->get(newRequest);
+ connect(reply, SIGNAL(finished()), this, SLOT(showFeedbackDialogNetChecked()));
}
-bool HWForm::getAuthToken(QString str)
+void HWForm::showFeedbackDialogNetChecked()
{
- QRegExp ex("Auth=(.+)");
-
- if (-1 == ex.indexIn(str))
- return false;
-
- authToken = ex.cap(1);
- authToken.remove(QChar('\n'));
+ QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
- return true;
+ if (reply && (reply->error() == QNetworkReply::NoError)) {
+ FeedbackDialog dialog(this);
+ dialog.exec();
+ } else
+ MessageDialog::ShowErrorMessage(tr("This page requires an internet connection."), this);
}
+void HWForm::startGame()
+{
+ QMessageBox questionMsg(this);
+ questionMsg.setIcon(QMessageBox::Question);
+ questionMsg.setWindowTitle(QMessageBox::tr("Not all players are ready"));
+ questionMsg.setText(QMessageBox::tr("Are you sure you want to start this game?\nNot all players are ready."));
+ questionMsg.setWindowModality(Qt::WindowModal);
+ questionMsg.addButton(QMessageBox::Yes);
+ questionMsg.addButton(QMessageBox::Cancel);
-
+ if (hwnet->allPlayersReady() || questionMsg.exec() == QMessageBox::Yes)
+ hwnet->startGame();
+}
diff --git a/QTfrontend/hwform.h b/QTfrontend/hwform.h
index dcc3f92..35fc424 100644
--- a/QTfrontend/hwform.h
+++ b/QTfrontend/hwform.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -61,14 +61,15 @@ class HWForm : public QMainWindow
HWForm(QWidget *parent = 0, QString styleSheet = "");
Ui_HWForm ui;
static GameUIConfig * config;
- static QSettings * gameSettings; // Same file GameUIConfig points to but without the baggage. Needs sync() calls if you want to get GameUIConfig changes though
void updateXfire();
- void PlayDemoQuick(const QString & demofilename);
void exit();
void setButtonDescription(QString desc);
void backDescription();
void GoToVideos();
+ void NetConnectQuick(const QString & host, quint16 port);
+ void PlayDemoQuick(const QString & demofilename);
+
private slots:
void GoToSaves();
void GoToDemos();
@@ -106,8 +107,11 @@ class HWForm : public QMainWindow
void NetWarning(const QString & wrnmsg);
void NetGameEnter();
void NetPassword(const QString & nick);
+ void NetNickRegistered(const QString & nick);
+ void NetNickNotRegistered(const QString & nick);
void NetNickTaken(const QString & nick);
void NetAuthFailed();
+ bool RetryDialog(const QString & title, const QString & label);
void NetTeamAccepted(const QString& team);
void AddNetTeam(const HWTeam& team);
void RemoveNetTeam(const HWTeam& team);
@@ -124,15 +128,8 @@ class HWForm : public QMainWindow
void UpdateCampaignPage(int index);
void UpdateCampaignPageProgress(int index);
void InitCampaignPage();
- //Starts the transmission process for the feedback
- void SendFeedback();
- //Make a xml representation of the issue to be created
- bool CreateIssueXml();
- //Called the first time when receiving authorization token from google,
- //second time when receiving the response after posting the issue
- void finishedSlot(QNetworkReply* reply);
- //Filter the auth token from the reply from google
- bool getAuthToken(QString str);
+ void showFeedbackDialog();
+ void showFeedbackDialogNetChecked();
void NetGameChangeStatus(bool isMaster);
void NetGameMaster();
@@ -143,14 +140,20 @@ class HWForm : public QMainWindow
void selectFirstNetScheme();
void saveDemoWithCustomName();
+ void openRegistrationPage();
+
+ void startGame();
+ void restartGame();
private:
void _NetConnect(const QString & hostName, quint16 port, QString nick);
- void UpdateTeamsLists(const QStringList* editable_teams=0);
+ int AskForNickAndPwd(void);
+ void UpdateTeamsLists();
void CreateGame(GameCFGWidget * gamecfg, TeamSelWidget* pTeamSelWidget, QString ammo);
void closeEvent(QCloseEvent *event);
void CustomizePalettes();
void resizeEvent(QResizeEvent * event);
+ QString stringifyPageId(quint32 id);
//void keyReleaseEvent(QKeyEvent *event);
enum PageIDs
@@ -173,13 +176,11 @@ class HWForm : public QMainWindow
ID_PAGE_CONNECTING ,
ID_PAGE_SCHEME ,
ID_PAGE_ADMIN ,
- ID_PAGE_NETTYPE ,
ID_PAGE_CAMPAIGN ,
ID_PAGE_DRAWMAP ,
ID_PAGE_DATADOWNLOAD ,
- ID_PAGE_FEEDBACK ,
- ID_PAGE_VIDEOS,
- MAX_PAGE
+ ID_PAGE_VIDEOS ,
+ MAX_PAGE
};
QPointer<HWGame> game;
QPointer<HWNetServer> pnetserver;
@@ -193,9 +194,6 @@ class HWForm : public QMainWindow
BGWidget * wBackground;
QSignalMapper * pageSwitchMapper;
QByteArray m_lastDemo;
- QNetworkAccessManager * nam;
- QString issueXml;
- QString authToken;
QPropertyAnimation *animationNewSlide;
QPropertyAnimation *animationOldSlide;
diff --git a/QTfrontend/main.cpp b/QTfrontend/main.cpp
index 7a2114a..06c2e50 100644
--- a/QTfrontend/main.cpp
+++ b/QTfrontend/main.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,27 +20,34 @@
#include <QTranslator>
#include <QLocale>
-#include <QMessageBox>
#include <QPlastiqueStyle>
#include <QRegExp>
#include <QMap>
#include <QSettings>
#include <QStringListModel>
#include <QDate>
+#include <QDesktopWidget>
+#include <QLabel>
#include "hwform.h"
#include "hwconsts.h"
#include "newnetclient.h"
#include "DataManager.h"
+#include "FileEngine.h"
+#include "MessageDialog.h"
#ifdef _WIN32
#include <Shlobj.h>
-#endif
-#ifdef __APPLE__
+#elif defined __APPLE__
#include "CocoaInitializer.h"
#endif
+// Program resources
+#ifdef __APPLE__
+static CocoaInitializer * cocoaInit = NULL;
+#endif
+static FileEngineHandler * engine = NULL;
//Determines the day of easter in year
//from http://aa.usno.navy.mil/faq/docs/easter.php,adapted to C/C++
@@ -85,27 +92,63 @@ void checkSeason()
season = SEASON_NONE;
}
+
bool checkForDir(const QString & dir)
{
- QDir tmpdir;
- if (!tmpdir.exists(dir))
- if (!tmpdir.mkdir(dir))
+ QDir tmpdir(dir);
+ if (!tmpdir.exists())
+ if (!tmpdir.mkpath(dir))
{
- QMessageBox directoryMsg(QApplication::activeWindow());
- directoryMsg.setIcon(QMessageBox::Warning);
- directoryMsg.setWindowTitle(QMessageBox::tr("Main - Error"));
- directoryMsg.setText(QMessageBox::tr("Cannot create directory %1").arg(dir));
- directoryMsg.setWindowModality(Qt::WindowModal);
- directoryMsg.exec();
+ MessageDialog::ShowErrorMessage(HWApplication::tr("Cannot create directory %1").arg(dir));
return false;
}
return true;
}
+// Guaranteed to be the last thing ran in the application's life time.
+// Closes resources that need to exist as long as possible.
+void closeResources(void)
+{
+#ifdef __APPLE__
+ if (cocoaInit != NULL)
+ {
+ delete cocoaInit;
+ cocoaInit = NULL;
+ }
+#endif
+ if (engine != NULL)
+ {
+ delete engine;
+ engine = NULL;
+ }
+}
+
int main(int argc, char *argv[])
{
+ // Since we're calling this first, closeResources() will be the last thing called after main() returns.
+ atexit(closeResources);
+
+#ifdef __APPLE__
+ cocoaInit = new CocoaInitializer(); // Creates the autoreleasepool preventing cocoa object leaks on OS X.
+#endif
+
HWApplication app(argc, argv);
+ QLabel *splash = NULL;
+#if defined Q_WS_WIN
+ QPixmap pixmap(":res/splash.png");
+ splash = new QLabel(0, Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
+ splash->setAttribute(Qt::WA_TranslucentBackground);
+ const QRect deskSize = HWApplication::desktop()->screenGeometry(-1);
+ QPoint splashCenter = QPoint( (deskSize.width() - pixmap.width())/2,
+ (deskSize.height() - pixmap.height())/2 );
+ splash->move(splashCenter);
+ splash->setPixmap(pixmap);
+ splash->show();
+#endif
+
+ engine = new FileEngineHandler(argv[0]);
+
app.setAttribute(Qt::AA_DontShowIconsInMenus,false);
QStringList arguments = app.arguments();
@@ -143,11 +186,16 @@ int main(int argc, char *argv[])
if(parsedArgs.contains("config-dir"))
{
QFileInfo f(parsedArgs["config-dir"]);
- *cConfigDir = f.absoluteFilePath();
+ cfgdir->setPath(f.absoluteFilePath());
custom_config = true;
}
+ else
+ {
+ cfgdir->setPath(QDir::homePath());
+ custom_config = false;
+ }
- app.setStyle(new QPlastiqueStyle);
+ app.setStyle(new QPlastiqueStyle());
QDateTime now = QDateTime::currentDateTime();
srand(now.toTime_t());
@@ -157,14 +205,9 @@ int main(int argc, char *argv[])
qRegisterMetaType<HWTeam>("HWTeam");
- bindir->cd("bin"); // workaround over NSIS installer
-
- if(cConfigDir->length() == 0)
- cfgdir->setPath(cfgdir->homePath());
- else
- cfgdir->setPath(*cConfigDir);
+ bindir->cd(QCoreApplication::applicationDirPath());
- if(cConfigDir->length() == 0)
+ if(custom_config == false)
{
#ifdef __APPLE__
checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars");
@@ -205,34 +248,37 @@ int main(int argc, char *argv[])
datadir->cd(bindir->absolutePath());
datadir->cd(*cDataDir);
- if(!datadir->cd("hedgewars/Data"))
+ if (!datadir->cd("Data"))
{
- QMessageBox missingMsg(QApplication::activeWindow());
- missingMsg.setIcon(QMessageBox::Critical);
- missingMsg.setWindowTitle(QMessageBox::tr("Main - Error"));
- missingMsg.setText(QMessageBox::tr("Failed to open data directory:\n%1\n\n"
- "Please check your installation!").
- arg(datadir->absolutePath()+"/hedgewars/Data"));
- missingMsg.setWindowModality(Qt::WindowModal);
- missingMsg.exec();
+ MessageDialog::ShowFatalMessage(HWApplication::tr("Failed to open data directory:\n%1\n\nPlease check your installation!").arg(datadir->absolutePath()+"/Data"));
return 1;
}
- DataManager & dataMgr = DataManager::instance();
+ // setup PhysFS
+ engine->mount(datadir->absolutePath());
+ engine->mount(cfgdir->absolutePath() + "/Data");
+ engine->mount(cfgdir->absolutePath());
+ engine->setWriteDir(cfgdir->absolutePath());
+ engine->mountPacks();
QTranslator Translator;
{
- QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini", QSettings::IniFormat);
+ QSettings settings(DataManager::instance().settingsFileName(), QSettings::IniFormat);
+ settings.setIniCodec("UTF-8");
+
QString cc = settings.value("misc/locale", QString()).toString();
- if(cc.isEmpty())
+ if (cc.isEmpty())
+ {
cc = QLocale::system().name();
+ // Fallback to current input locale if "C" locale is returned
+ if(cc == "C")
+ cc = HWApplication::keyboardInputLocale().name();
+ }
+
// load locale file into translator
- Translator.load(
- dataMgr.findFileForRead(
- QString("Locale/hedgewars_" + cc)
- )
- );
+ if (!Translator.load(QString("physfs://Locale/hedgewars_%1").arg(cc)))
+ qWarning("Failed to install translation (%s)", qPrintable(cc));
app.installTranslator(&Translator);
}
@@ -245,10 +291,6 @@ int main(int argc, char *argv[])
registry_hklm.setValue("Software/Hedgewars/Path", bindir->absolutePath().replace("/", "\\"));
}
#endif
-#ifdef __APPLE__
- // this creates the autoreleasepool that prevents leaking
- CocoaInitializer initializer;
-#endif
QString style = "";
QString fname;
@@ -271,10 +313,11 @@ int main(int argc, char *argv[])
break;
default :
fname = "qt.css";
+ break;
}
// load external stylesheet if there is any
- QFile extFile(dataMgr.findFileForRead("css/" + fname));
+ QFile extFile("physfs://css/" + fname);
QFile resFile(":/res/css/" + fname);
@@ -283,7 +326,13 @@ int main(int argc, char *argv[])
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
style.append(file.readAll());
+ qWarning("Starting Hedgewars %s-r%d (%s)", qPrintable(*cVersionString), cRevisionString->toInt(), qPrintable(*cHashString));
+
app.form = new HWForm(NULL, style);
app.form->show();
+ if(splash)
+ splash->close();
+ if (app.urlString)
+ app.fakeEvent();
return app.exec();
}
diff --git a/QTfrontend/main.cpp.orig b/QTfrontend/main.cpp.orig
deleted file mode 100644
index 67437cf..0000000
--- a/QTfrontend/main.cpp.orig
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include "HWApplication.h"
-
-#include <QTranslator>
-#include <QLocale>
-#include <QMessageBox>
-#include <QPlastiqueStyle>
-#include <QRegExp>
-#include <QMap>
-#include <QSettings>
-#include <QStringListModel>
-#include <QDate>
-
-#include "hwform.h"
-#include "hwconsts.h"
-#include "newnetclient.h"
-
-#include "DataManager.h"
-
-#ifdef _WIN32
-#include <Shlobj.h>
-#endif
-#ifdef __APPLE__
-#include "CocoaInitializer.h"
-#endif
-
-
-//Determines the day of easter in year
-//from http://aa.usno.navy.mil/faq/docs/easter.php,adapted to C/C++
-QDate calculateEaster(long year)
-{
- int c, n, k, i, j, l, m, d;
-
- c = year/100;
- n = year - 19*(year/19);
- k = (c - 17)/25;
- i = c - c/4 - (c - k)/3 + 19*n + 15;
- i = i - 30*(i/30);
- i = i - (i/28)*(1 - (i/28)*(29/(i + 1))*((21 - n)/11));
- j = year + year/4 + i + 2 - c + c/4;
- j = j - 7*(j/7);
- l = i - j;
- m = 3 + (l + 40)/44;
- d = l + 28 - 31*(m / 4);
-
- return QDate(year, m, d);
-}
-
-//Checks season and assigns it to the variable season in "hwconsts.h"
-void checkSeason()
-{
- QDate date = QDate::currentDate();
-
- //Christmas?
- if (date.month() == 12 && date.day() >= 24
- && date.day() <= 26)
- season = SEASON_CHRISTMAS;
- //Hedgewars birthday?
- else if (date.month() == 10 && date.day() == 31)
- {
- season = SEASON_HWBDAY;
- years_since_foundation = date.year() - 2004;
- }
- //Easter?
- else if (calculateEaster(date.year()) == date)
- season = SEASON_EASTER;
- else
- season = SEASON_NONE;
-}
-
-bool checkForDir(const QString & dir)
-{
- QDir tmpdir;
- if (!tmpdir.exists(dir))
- if (!tmpdir.mkdir(dir))
- {
- QMessageBox directoryMsg(QApplication::activeWindow());
- directoryMsg.setIcon(QMessageBox::Warning);
- directoryMsg.setWindowTitle(QMessageBox::tr("Main - Error"));
- directoryMsg.setText(QMessageBox::tr("Cannot create directory %1").arg(dir));
- directoryMsg.setWindowModality(Qt::WindowModal);
- directoryMsg.exec();
- return false;
- }
- return true;
-}
-
-int main(int argc, char *argv[])
-{
- HWApplication app(argc, argv);
-
- app.setAttribute(Qt::AA_DontShowIconsInMenus,false);
-
- QStringList arguments = app.arguments();
- QMap<QString, QString> parsedArgs;
- {
- QList<QString>::iterator i = arguments.begin();
- while(i != arguments.end())
- {
- QString arg = *i;
-
- QRegExp opt("--(\\S+)=(.+)");
- if(opt.exactMatch(arg))
- {
- parsedArgs[opt.cap(1)] = opt.cap(2);
- i = arguments.erase(i);
- }
- else
- {
- ++i;
- }
- }
- }
-
- if(parsedArgs.contains("data-dir"))
- {
- QFileInfo f(parsedArgs["data-dir"]);
- if(!f.exists())
- {
- qWarning() << "WARNING: Cannot open DATA_PATH=" << f.absoluteFilePath();
- }
- *cDataDir = f.absoluteFilePath();
- custom_data = true;
- }
-
- if(parsedArgs.contains("config-dir"))
- {
- QFileInfo f(parsedArgs["config-dir"]);
- *cConfigDir = f.absoluteFilePath();
- custom_config = true;
- }
-
- app.setStyle(new QPlastiqueStyle);
-
- QDateTime now = QDateTime::currentDateTime();
- srand(now.toTime_t());
- rand();
-
- Q_INIT_RESOURCE(hedgewars);
-
- qRegisterMetaType<HWTeam>("HWTeam");
-
- bindir->cd("bin"); // workaround over NSIS installer
-
- if(cConfigDir->length() == 0)
- cfgdir->setPath(cfgdir->homePath());
- else
- cfgdir->setPath(*cConfigDir);
-
- if(cConfigDir->length() == 0)
- {
-#ifdef __APPLE__
- checkForDir(cfgdir->absolutePath() + "/Library/Application Support/Hedgewars");
- cfgdir->cd("Library/Application Support/Hedgewars");
-#elif defined _WIN32
- char path[1024];
- if(!SHGetFolderPathA(0, CSIDL_PERSONAL, NULL, 0, path))
- {
- cfgdir->cd(path);
- checkForDir(cfgdir->absolutePath() + "/Hedgewars");
- cfgdir->cd("Hedgewars");
- }
- else // couldn't retrieve documents folder? almost impossible, but in case fall back to classic path
- {
- checkForDir(cfgdir->absolutePath() + "/.hedgewars_0.9.18");
- cfgdir->cd(".hedgewars");
- }
-#else
- checkForDir(cfgdir->absolutePath() + "/.hedgewars_0.9.18");
- cfgdir->cd(".hedgewars_0.9.18");
-#endif
- }
-
- if (checkForDir(cfgdir->absolutePath()))
- {
- // alternative loading/lookup paths
- checkForDir(cfgdir->absolutePath() + "/Data");
-
- // config/save paths
- checkForDir(cfgdir->absolutePath() + "/Demos");
- checkForDir(cfgdir->absolutePath() + "/Saves");
- checkForDir(cfgdir->absolutePath() + "/Screenshots");
- checkForDir(cfgdir->absolutePath() + "/Teams");
- checkForDir(cfgdir->absolutePath() + "/Logs");
- checkForDir(cfgdir->absolutePath() + "/Videos");
- checkForDir(cfgdir->absolutePath() + "/VideoTemp");
- }
-
- datadir->cd(bindir->absolutePath());
- datadir->cd(*cDataDir);
- if(!datadir->cd("hedgewars/Data"))
- {
- QMessageBox missingMsg(QApplication::activeWindow());
- missingMsg.setIcon(QMessageBox::Critical);
- missingMsg.setWindowTitle(QMessageBox::tr("Main - Error"));
- missingMsg.setText(QMessageBox::tr("Failed to open data directory:\n%1\n\n"
- "Please check your installation!").
- arg(datadir->absolutePath()+"/hedgewars/Data"));
- missingMsg.setWindowModality(Qt::WindowModal);
- missingMsg.exec();
- return 1;
- }
-
- DataManager & dataMgr = DataManager::instance();
-
- QTranslator Translator;
- {
- QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini", QSettings::IniFormat);
- QString cc = settings.value("misc/locale", QString()).toString();
- if(cc.isEmpty())
- cc = QLocale::system().name();
-
- // load locale file into translator
- Translator.load(
- dataMgr.findFileForRead(
- QString("Locale/hedgewars_" + cc)
- )
- );
- app.installTranslator(&Translator);
- }
-
-#ifdef _WIN32
- // Win32 registry setup (used for xfire detection etc. - don't set it if we're running in "portable" mode with a custom config dir)
- if(!custom_config)
- {
- QSettings registry_hklm("HKEY_LOCAL_MACHINE", QSettings::NativeFormat);
- registry_hklm.setValue("Software/Hedgewars/Frontend", bindir->absolutePath().replace("/", "\\") + "\\hedgewars.exe");
- registry_hklm.setValue("Software/Hedgewars/Path", bindir->absolutePath().replace("/", "\\"));
- }
-#endif
-#ifdef __APPLE__
- // this creates the autoreleasepool that prevents leaking
- CocoaInitializer initializer;
-#endif
-
- QString style = "";
- QString fname;
-
- checkSeason();
- //For each season, there is an extra stylesheet
- //Todo: change background for easter and birthday
- //(simply replace res/BackgroundBirthday.png and res/BackgroundEaster.png
- //with an appropriate background
- switch (season)
- {
- case SEASON_CHRISTMAS :
- fname = "christmas.css";
- break;
- case SEASON_EASTER :
- fname = "easter.css";
- break;
- case SEASON_HWBDAY :
- fname = "birthday.css";
- break;
- default :
- fname = "qt.css";
- }
-
- // load external stylesheet if there is any
- QFile extFile(dataMgr.findFileForRead("css/" + fname));
-
- QFile resFile(":/res/css/" + fname);
-
- QFile & file = (extFile.exists() ? extFile : resFile);
-
- if (file.open(QIODevice::ReadOnly | QIODevice::Text))
- style.append(file.readAll());
-
- app.form = new HWForm(NULL, style);
- app.form->show();
- return app.exec();
-}
diff --git a/QTfrontend/model/GameStyleModel.cpp b/QTfrontend/model/GameStyleModel.cpp
index 846208b..9c5bdc0 100644
--- a/QTfrontend/model/GameStyleModel.cpp
+++ b/QTfrontend/model/GameStyleModel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,14 +23,15 @@
#include <QTextStream>
+#include "physfs.h"
#include "GameStyleModel.h"
+#include "hwconsts.h"
void GameStyleModel::loadGameStyles()
{
beginResetModel();
-
// empty list, so that we can (re)fill it
QStandardItemModel::clear();
@@ -55,8 +56,7 @@ void GameStyleModel::loadGameStyles()
{
script = script.remove(".lua", Qt::CaseInsensitive);
- QFile scriptCfgFile(DataManager::instance().findFileForRead(
- QString("Scripts/Multiplayer/%2.cfg").arg(script)));
+ QFile scriptCfgFile(QString("physfs://Scripts/Multiplayer/%2.cfg").arg(script));
QString name = script;
name = name.replace("_", " ");
@@ -78,11 +78,16 @@ void GameStyleModel::loadGameStyles()
weapons.replace("_", " ");
}
- QStandardItem * item = new QStandardItem(name);
+ // detect if script is dlc
+ QString scriptPath = PHYSFS_getRealDir(QString("Scripts/Multiplayer/%1.lua").arg(script).toLocal8Bit().data());
+ bool isDLC = !scriptPath.startsWith(datadir->absolutePath());
+
+ QStandardItem * item = new QStandardItem((isDLC ? "*" : "") + name);
item->setData(script, ScriptRole);
item->setData(scheme, SchemeRole);
item->setData(weapons, WeaponsRole);
+ item->setData(isDLC, IsDlcRole);
items.append(item);
}
diff --git a/QTfrontend/model/GameStyleModel.h b/QTfrontend/model/GameStyleModel.h
index af0e13d..523bcae 100644
--- a/QTfrontend/model/GameStyleModel.h
+++ b/QTfrontend/model/GameStyleModel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@ class GameStyleModel : public QStandardItemModel
Q_OBJECT
public:
- enum DataRoles { ScriptRole = Qt::UserRole+1, SchemeRole, WeaponsRole };
+ enum DataRoles { ScriptRole = Qt::UserRole+1, SchemeRole, WeaponsRole, IsDlcRole };
public slots:
/// reloads the themes from the DataManager
diff --git a/QTfrontend/model/HatModel.cpp b/QTfrontend/model/HatModel.cpp
index 781a4cd..4188027 100644
--- a/QTfrontend/model/HatModel.cpp
+++ b/QTfrontend/model/HatModel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,29 +26,29 @@
#include <QDir>
#include <QPixmap>
#include <QPainter>
+#include <QList>
#include "hwform.h" // player hash
#include "DataManager.h"
HatModel::HatModel(QObject* parent) :
- QAbstractListModel(parent)
-{
- hats = QVector<QPair<QString, QIcon> >();
-}
+ QStandardItemModel(parent)
+{}
void HatModel::loadHats()
{
// this method resets the contents of this model (important to know for views).
- beginResetModel();
+ QStandardItemModel::beginResetModel();
+ QStandardItemModel::clear();
- // prepare hats Vector
- hats.clear();
+ // New hats to add to model
+ QList<QStandardItem *> hats;
+ // we'll need the DataManager a few times, so let's get a reference to it
DataManager & dataMgr = DataManager::instance();
- QPixmap hhpix = QPixmap(
- dataMgr.findFileForRead("Graphics/Hedgehog/Idle.png")
- ).copy(0, 0, 32, 32);
+ // Default hat icon
+ QPixmap hhpix = QPixmap("physfs://Graphics/Hedgehog/Idle.png").copy(0, 0, 32, 32);
// my reserved hats
QStringList hatsList = dataMgr.entryList(
@@ -56,7 +56,6 @@ void HatModel::loadHats()
QDir::Files,
QStringList(playerHash+"*.png")
);
-
int nReserved = hatsList.size();
// regular hats
@@ -66,21 +65,20 @@ void HatModel::loadHats()
QStringList("*.png")
)
);
-
-
int nHats = hatsList.size();
+ // Add each hat
for (int i = 0; i < nHats; i++)
{
bool isReserved = (i < nReserved);
+ if (isReserved) continue; // For some reason, reserved hats were added in 9.19-dev, so this will hide them. Uncomment to show them.
+
QString str = hatsList.at(i);
str = str.remove(QRegExp("\\.png$"));
QPixmap pix(
- dataMgr.findFileForRead(
- "Graphics/Hats/" + QString(isReserved?"Reserved/":"") + str +
+ "physfs://Graphics/Hats/" + QString(isReserved?"Reserved/":"") + str +
".png"
- )
);
// rename properly
@@ -98,51 +96,11 @@ void HatModel::loadHats()
painter.end();
if (str == "NoHat")
- hats.prepend(qMakePair(str, QIcon(tmppix)));
+ hats.prepend(new QStandardItem(QIcon(tmppix), str));
else
- hats.append(qMakePair(str, QIcon(tmppix)));
+ hats.append(new QStandardItem(QIcon(tmppix), str));
}
-
- endResetModel();
-}
-
-QVariant HatModel::headerData(int section,
- Qt::Orientation orientation, int role) const
-{
- Q_UNUSED(section);
- Q_UNUSED(orientation);
- Q_UNUSED(role);
-
- return QVariant();
-}
-
-int HatModel::rowCount(const QModelIndex &parent) const
-{
- if (parent.isValid())
- return 0;
- else
- return hats.size();
-}
-
-/*int HatModel::columnCount(const QModelIndex & parent) const
-{
- if (parent.isValid())
- return 0;
- else
- return 2;
-}
-*/
-QVariant HatModel::data(const QModelIndex &index,
- int role) const
-{
- if (!index.isValid() || index.row() < 0
- || index.row() >= hats.size()
- || (role != Qt::DisplayRole && role != Qt::DecorationRole))
- return QVariant();
-
- if (role == Qt::DisplayRole)
- return hats.at(index.row()).first;
- else // role == Qt::DecorationRole
- return hats.at(index.row()).second;
+ QStandardItemModel::appendColumn(hats);
+ QStandardItemModel::endResetModel();
}
diff --git a/QTfrontend/model/HatModel.h b/QTfrontend/model/HatModel.h
index e97977c..133554b 100644
--- a/QTfrontend/model/HatModel.h
+++ b/QTfrontend/model/HatModel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,30 +24,22 @@
#ifndef HEDGEWARS_HATMODEL_H
#define HEDGEWARS_HATMODEL_H
-#include <QAbstractListModel>
+#include <QStandardItemModel>
#include <QStringList>
#include <QVector>
#include <QPair>
#include <QIcon>
-class HatModel : public QAbstractListModel
+class HatModel : public QStandardItemModel
{
Q_OBJECT
public:
HatModel(QObject *parent = 0);
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- int rowCount(const QModelIndex & parent) const;
- //int columnCount(const QModelIndex & parent) const;
-
public slots:
/// Reloads hats using the DataManager.
void loadHats();
-
- QVariant data(const QModelIndex &index, int role) const;
- protected:
- QVector<QPair<QString, QIcon> > hats;
};
#endif // HEDGEWARS_HATMODEL_H
diff --git a/QTfrontend/model/MapModel.cpp b/QTfrontend/model/MapModel.cpp
index 76a38e8..e4dc7a6 100644
--- a/QTfrontend/model/MapModel.cpp
+++ b/QTfrontend/model/MapModel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,10 +21,18 @@
* @brief MapModel class implementation
*/
+#include <QSettings>
+
+#include "physfs.h"
#include "MapModel.h"
+#include "HWApplication.h"
+#include "hwconsts.h"
+MapModel::MapInfo MapModel::MapInfoRandom = {MapModel::GeneratedMap, "+rnd+", "", 0, "", "", ""};
+MapModel::MapInfo MapModel::MapInfoMaze = {MapModel::GeneratedMaze, "+maze+", "", 0, "", "", ""};
+MapModel::MapInfo MapModel::MapInfoDrawn = {MapModel::HandDrawnMap, "+drawn+", "", 0, "", "", ""};
-void MapModel::loadMaps()
+void MapModel::loadMaps(MapType maptype)
{
// this method resets the contents of this model (important to know for views).
beginResetModel();
@@ -39,34 +47,18 @@ void MapModel::loadMaps()
// empty list, so that we can (re)fill it
QStandardItemModel::clear();
- QList<QStandardItem *> genMaps;
- QList<QStandardItem *> missionMaps;
- QList<QStandardItem *> staticMaps;
-
- // add generated/handdrawn maps to list
- // TODO: icons for these
-
- genMaps.append(
- infoToItem(QIcon(), QComboBox::tr("generated map..."), GeneratedMap, "+rnd+"));
- genMaps.append(
- infoToItem(QIcon(), QComboBox::tr("generated maze..."), GeneratedMaze, "+maze+"));
- genMaps.append(
- infoToItem(QIcon(), QComboBox::tr("hand drawn map..."), HandDrawnMap, "+drawn+"));
-
- // only 2 map relate files are relevant:
- // - the cfg file that contains the settings/info of the map
- // - the lua file - if it exists it's a mission, otherwise it isn't
- QFile mapLuaFile;
- QFile mapCfgFile;
+ //QList<QStandardItem *> staticMaps;
+ //QList<QStandardItem *> missionMaps;
+ QList<QStandardItem *> mapList;
// add mission/static maps to lists
foreach (QString map, maps)
{
- mapCfgFile.setFileName(
- datamgr.findFileForRead(QString("Maps/%1/map.cfg").arg(map)));
- mapLuaFile.setFileName(
- datamgr.findFileForRead(QString("Maps/%1/map.lua").arg(map)));
-
+ // only 2 map relate files are relevant:
+ // - the cfg file that contains the settings/info of the map
+ // - the lua file - if it exists it's a mission, otherwise it isn't
+ QFile mapLuaFile(QString("physfs://Maps/%1/map.lua").arg(map));
+ QFile mapCfgFile(QString("physfs://Maps/%1/map.cfg").arg(map));
if (mapCfgFile.open(QFile::ReadOnly))
{
@@ -75,25 +67,43 @@ void MapModel::loadMaps()
quint32 limit = 0;
QString scheme;
QString weapons;
+ QString desc;
+ bool dlc;
+
// if there is a lua file for this map, then it's a mission
bool isMission = mapLuaFile.exists();
- MapType type = isMission?MissionMap:StaticMap;
+ MapType type = isMission ? MissionMap : StaticMap;
+
+ // if we're supposed to ignore this type, continue
+ if (type != maptype) continue;
// load map info from file
QTextStream input(&mapCfgFile);
- input >> theme;
- input >> limit;
+ theme = input.readLine();
+ limit = input.readLine().toInt();
if (isMission) { // scheme and weapons are only relevant for missions
- input >> scheme;
- input >> weapons;
+ scheme = input.readLine();
+ weapons = input.readLine();
}
mapCfgFile.close();
+ // load description (if applicable)
+ if (isMission)
+ {
+ QString locale = HWApplication::keyboardInputLocale().name();
+
+ QSettings descSettings(QString("physfs://Maps/%1/desc.txt").arg(map), QSettings::IniFormat);
+ desc = descSettings.value(locale, QString()).toString().replace("|", "\n").replace("\\,", ",");
+ }
+
+ // detect if map is dlc
+ QString mapDir = PHYSFS_getRealDir(QString("Maps/%1/map.cfg").arg(map).toLocal8Bit().data());
+ dlc = !mapDir.startsWith(datadir->absolutePath());
+
// let's use some semi-sane hedgehog limit, rather than none
if (limit == 0)
limit = 18;
-
// the default scheme/weaponset for missions.
// if empty we assume the map sets these internally -> locked
if (isMission)
@@ -109,97 +119,54 @@ void MapModel::loadMaps()
weapons.replace("_", " ");
}
- // add a mission caption prefix to missions
- if (isMission)
- {
- // TODO: icon
- caption = QComboBox::tr("Mission") + ": " + map;
- }
- else
- caption = map;
+ // caption
+ caption = map;
// we know everything there is about the map, let's get am item for it
- QStandardItem * item = infoToItem(
- QIcon(), caption, type, map, theme, limit, scheme, weapons);
+ QStandardItem * item = MapModel::infoToItem(
+ QIcon(), caption, type, map, theme, limit, scheme, weapons, desc, dlc);
// append item to the list
- if (isMission)
- missionMaps.append(item);
- else
- staticMaps.append(item);
-
+ mapList.append(item);
}
}
-
- // define a separator item
- QStandardItem separator("---");
- separator.setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole);
- separator.setFlags(separator.flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) );
-
- // create list:
- // generated+handdrawn maps, 2 saperators, missions, 1 separator, static maps
- QList<QStandardItem * > items;
- items.append(genMaps);
- items.append(separator.clone());
- items.append(separator.clone());
- items.append(missionMaps);
- items.append(separator.clone());
- items.append(staticMaps);
-
-
- // create row-index lookup table
+ // Create column-index lookup table
m_mapIndexes.clear();
- int count = items.size();
+ int count = mapList.size();
for (int i = 0; i < count; i++)
{
- QStandardItem * si = items.at(i);
+ QStandardItem * si = mapList.at(i);
QVariant v = si->data(Qt::UserRole + 1);
if (v.canConvert<MapInfo>())
m_mapIndexes.insert(v.value<MapInfo>().name, i);
}
-
- // store start-index and count of relevant types
-
- m_typeLoc.insert(GeneratedMap, QPair<int,int>(0, 1));
- m_typeLoc.insert(GeneratedMaze, QPair<int,int>(1, 1));
- m_typeLoc.insert(HandDrawnMap, QPair<int,int>(2, 1));
- // mission maps
- int startIdx = genMaps.size() + 2; // start after genMaps and 2 separators
- count = missionMaps.size();
- m_typeLoc.insert(MissionMap, QPair<int,int>(startIdx, count));
- // static maps
- startIdx += count + 1; // start after missions and 2 separators
- count = staticMaps.size();
- m_typeLoc.insert(StaticMap, QPair<int,int>(startIdx, count));
-
- // store list contents in the item model
- QStandardItemModel::appendColumn(items);
-
+ QStandardItemModel::appendColumn(mapList);
endResetModel();
}
-
-int MapModel::randomMap(MapType type) const
+bool MapModel::mapExists(const QString & map) const
{
- // return a random index for this type or -1 if none available
- QPair<int,int> loc = m_typeLoc.value(type, QPair<int,int>(-1,0));
-
- int startIdx = loc.first;
- int count = loc.second;
+ return findMap(map) >= 0;
+}
- if (count < 1)
- return -1;
- else
- return startIdx + (rand() % count);
+int MapModel::findMap(const QString & map) const
+{
+ return m_mapIndexes.value(map, -1);
}
+QStandardItem * MapModel::getMap(const QString & map)
+{
+ int loc = findMap(map);
+ if (loc < 0) return NULL;
+ return item(loc);
+}
QStandardItem * MapModel::infoToItem(
const QIcon & icon,
@@ -209,10 +176,11 @@ QStandardItem * MapModel::infoToItem(
QString theme,
quint32 limit,
QString scheme,
- QString weapons)
-const
+ QString weapons,
+ QString desc,
+ bool dlc)
{
- QStandardItem * item = new QStandardItem(icon, caption);
+ QStandardItem * item = new QStandardItem(icon, (dlc ? "*" : "") + caption);
MapInfo mapInfo;
QVariant qvar(QVariant::UserType);
@@ -222,17 +190,11 @@ const
mapInfo.limit = limit;
mapInfo.scheme = scheme;
mapInfo.weapons = weapons;
-
+ mapInfo.desc = desc.isEmpty() ? tr("No description available.") : desc;
+ mapInfo.dlc = dlc;
qvar.setValue(mapInfo);
item->setData(qvar, Qt::UserRole + 1);
return item;
}
-
-
-int MapModel::indexOf(const QString & map) const
-{
- return m_mapIndexes.value(map, -1);
-}
-
diff --git a/QTfrontend/model/MapModel.h b/QTfrontend/model/MapModel.h
index 70d0025..55c31b9 100644
--- a/QTfrontend/model/MapModel.h
+++ b/QTfrontend/model/MapModel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,32 +63,50 @@ class MapModel : public QStandardItemModel
quint32 limit; ///< The maximum allowed number of hedgehogs.
QString scheme; ///< Default scheme name or "locked", for mission-maps.
QString weapons; ///< Default weaponset name or "locked", for missions-maps.
+ QString desc; ///< The brief 1-2 sentence description of the mission, for mission-maps.
+ bool dlc; ///< True if this map was not packaged with the game
};
/**
- * @brief Returns the row-index of the given map.
- * @param map map of which to get the row-index of.
- * @return row-index of map or -1 if not available.
+ * @brief Searches maps in model to find out if one exists
+ * @param map map of which to check existence
+ * @return true if it exists
*/
- int indexOf(const QString & map) const;
+ bool mapExists(const QString & map) const;
/**
- * @brief Returns the row-index of a random map with a specified type.
- * @param type desired type of map.
- * @return row-index of a map with the desired type, -1 if none found.
+ * @brief Finds a map index (column, row) for a map name
+ * @param map map of which to find index+column
+ * @return QPair<int, int> with column, index, or (-1, -1) if map not found
*/
- int randomMap(MapType type) const;
+ //QPair<int, int> findMap(const QString & map) const;
+
+ /**
+ * @brief Finds a map index for a map name
+ * @param map map of which to find index
+ * @return int of index, or -1 if map not found
+ */
+ int findMap(const QString & map) const;
+
+ /**
+ * @brief Finds and returns a map item for a map name
+ * @param map map
+ * @return QStandardItem of map, or NULL if map not found
+ */
+ QStandardItem * getMap(const QString & map);
+
+ // Static MapInfos for drawn and generated maps
+ static MapInfo MapInfoRandom, MapInfoMaze, MapInfoDrawn;
public slots:
/// Reloads the maps using the DataManager.
- void loadMaps();
+ /// Accepts two map types: StaticMap or MissionMap.
+ void loadMaps(MapType maptype);
private:
- /// start-index and map count for each map-type.
- QMap<MapType, QPair<int,int> > m_typeLoc;
-
- /// map index lookup table
+ /// map index lookup table. QPair<int, int> contains: <column, index>
+ //QHash<QString, QPair<int, int> > m_mapIndexes;
QHash<QString, int> m_mapIndexes;
/**
@@ -102,9 +120,10 @@ class MapModel : public QStandardItemModel
* @param limit the hedgehog limit of the map.
* @param scheme mission map: default scheme name or "locked".
* @param weapons mission map: default weaponset name or "locked".
+ * @param desc mission map: description of mission.
* @return pointer to item representing the map info: at Qt::UserRole + 1.
*/
- QStandardItem * infoToItem(
+ static QStandardItem * infoToItem(
const QIcon & icon,
const QString caption,
MapType type = Invalid,
@@ -112,7 +131,9 @@ class MapModel : public QStandardItemModel
QString theme = "",
quint32 limit = 0,
QString scheme = "",
- QString weapons = "") const;
+ QString weapons = "",
+ QString desc = "",
+ bool dlc = false);
};
Q_DECLARE_METATYPE(MapModel::MapInfo)
diff --git a/QTfrontend/model/ThemeModel.cpp b/QTfrontend/model/ThemeModel.cpp
index 6a1829c..e72024f 100644
--- a/QTfrontend/model/ThemeModel.cpp
+++ b/QTfrontend/model/ThemeModel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,9 @@
* @brief ThemeModel class implementation
*/
+#include "physfs.h"
#include "ThemeModel.h"
+#include "hwconsts.h"
ThemeModel::ThemeModel(QObject *parent) :
QAbstractListModel(parent)
@@ -51,7 +53,6 @@ void ThemeModel::loadThemes()
{
beginResetModel();
-
DataManager & datamgr = DataManager::instance();
QStringList themes =
@@ -66,24 +67,30 @@ void ThemeModel::loadThemes()
foreach (QString theme, themes)
{
// themes without icon are supposed to be hidden
- QString iconpath =
- datamgr.findFileForRead(QString("Themes/%1/icon.png").arg(theme));
+ QString iconpath = QString("physfs://Themes/%1/icon.png").arg(theme);
if (!QFile::exists(iconpath))
continue;
QMap<int, QVariant> dataset;
+ // detect if theme is dlc
+ QString themeDir = PHYSFS_getRealDir(QString("Themes/%1/icon.png").arg(theme).toLocal8Bit().data());
+ bool isDLC = !themeDir.startsWith(datadir->absolutePath());
+ dataset.insert(IsDlcRole, isDLC);
+
+ // set icon path
+ dataset.insert(IconPathRole, iconpath);
+
// set name
- dataset.insert(Qt::DisplayRole, theme);
+ dataset.insert(ActualNameRole, theme);
- // load and set icon
- QIcon icon(iconpath);
- dataset.insert(Qt::DecorationRole, icon);
+ // set displayed name
+ dataset.insert(Qt::DisplayRole, (isDLC ? "*" : "") + theme);
// load and set preview icon
- QIcon preview(datamgr.findFileForRead(QString("Themes/%1/icon at 2x.png").arg(theme)));
- dataset.insert(Qt::UserRole, preview);
+ QIcon preview(QString("physfs://Themes/%1/icon@2x.png").arg(theme));
+ dataset.insert(Qt::DecorationRole, preview);
m_data.append(dataset);
}
@@ -91,7 +98,3 @@ void ThemeModel::loadThemes()
endResetModel();
}
-
-
-
-
diff --git a/QTfrontend/model/ThemeModel.h b/QTfrontend/model/ThemeModel.h
index 9db8d9f..7d6342e 100644
--- a/QTfrontend/model/ThemeModel.h
+++ b/QTfrontend/model/ThemeModel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,6 +39,7 @@ class ThemeModel : public QAbstractListModel
Q_OBJECT
public:
+ enum Roles { ActualNameRole = Qt::UserRole, IsDlcRole, IconPathRole };
explicit ThemeModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
diff --git a/QTfrontend/model/ammoSchemeModel.cpp b/QTfrontend/model/ammoSchemeModel.cpp
index a0f2536..c272893 100644
--- a/QTfrontend/model/ammoSchemeModel.cpp
+++ b/QTfrontend/model/ammoSchemeModel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -194,7 +194,7 @@ AmmoSchemeModel::AmmoSchemeModel(QObject* parent, const QString & fileName) :
<< QVariant(false) // place hog 14
<< QVariant(true) // shared ammo 15
<< QVariant(true) // disable girders 16
- << QVariant(false) // disable land objects 17
+ << QVariant(true) // disable land objects 17
<< QVariant(false) // AI survival 18
<< QVariant(false) // inf. attack 19
<< QVariant(true) // reset weps 20
@@ -407,7 +407,7 @@ AmmoSchemeModel::AmmoSchemeModel(QObject* parent, const QString & fileName) :
<< QVariant(true) // team divide 2
<< QVariant(false) // solid land 3
<< QVariant(false) // border 4
- << QVariant(true) // low gravity 5
+ << QVariant(false) // low gravity 5
<< QVariant(false) // laser sight 6
<< QVariant(false) // invulnerable 7
<< QVariant(false) // reset health 8
diff --git a/QTfrontend/model/ammoSchemeModel.h b/QTfrontend/model/ammoSchemeModel.h
index d665ad6..6067e26 100644
--- a/QTfrontend/model/ammoSchemeModel.h
+++ b/QTfrontend/model/ammoSchemeModel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/model/netserverslist.cpp b/QTfrontend/model/netserverslist.cpp
index a50e9fb..97fadec 100644
--- a/QTfrontend/model/netserverslist.cpp
+++ b/QTfrontend/model/netserverslist.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/model/netserverslist.h b/QTfrontend/model/netserverslist.h
index 2a21789..33cc34d 100644
--- a/QTfrontend/model/netserverslist.h
+++ b/QTfrontend/model/netserverslist.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/model/playerslistmodel.cpp b/QTfrontend/model/playerslistmodel.cpp
index fab1c5c..0261184 100644
--- a/QTfrontend/model/playerslistmodel.cpp
+++ b/QTfrontend/model/playerslistmodel.cpp
@@ -84,7 +84,7 @@ bool PlayersListModel::removeRows(int row, int count, const QModelIndex &parent)
}
-void PlayersListModel::addPlayer(const QString & nickname)
+void PlayersListModel::addPlayer(const QString & nickname, bool notify)
{
insertRow(rowCount());
@@ -92,11 +92,18 @@ void PlayersListModel::addPlayer(const QString & nickname)
setData(mi, nickname);
checkFriendIgnore(mi);
+
+ emit nickAddedLobby(nickname, notify);
}
-void PlayersListModel::removePlayer(const QString & nickname)
+void PlayersListModel::removePlayer(const QString & nickname, const QString &msg)
{
+ if(msg.isEmpty())
+ emit nickRemovedLobby(nickname);
+ else
+ emit nickRemovedLobby(nickname, msg);
+
QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly);
if(mil.size())
@@ -104,7 +111,7 @@ void PlayersListModel::removePlayer(const QString & nickname)
}
-void PlayersListModel::playerJoinedRoom(const QString & nickname)
+void PlayersListModel::playerJoinedRoom(const QString & nickname, bool notify)
{
QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly);
@@ -114,11 +121,15 @@ void PlayersListModel::playerJoinedRoom(const QString & nickname)
updateIcon(mil[0]);
updateSortData(mil[0]);
}
+
+ emit nickAdded(nickname, notify);
}
void PlayersListModel::playerLeftRoom(const QString & nickname)
{
+ emit nickRemoved(nickname);
+
QModelIndexList mil = match(index(0), Qt::DisplayRole, nickname, 1, Qt::MatchExactly);
if(mil.size())
diff --git a/QTfrontend/model/playerslistmodel.h b/QTfrontend/model/playerslistmodel.h
index f2d784b..ed679ef 100644
--- a/QTfrontend/model/playerslistmodel.h
+++ b/QTfrontend/model/playerslistmodel.h
@@ -41,13 +41,20 @@ public:
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
public slots:
- void addPlayer(const QString & nickname);
- void removePlayer(const QString & nickname);
- void playerJoinedRoom(const QString & nickname);
+ void addPlayer(const QString & nickname, bool notify);
+ void removePlayer(const QString & nickname, const QString & msg = QString());
+ void playerJoinedRoom(const QString & nickname, bool notify);
void playerLeftRoom(const QString & nickname);
void resetRoomFlags();
void setNickname(const QString & nickname);
+signals:
+ void nickAdded(const QString& nick, bool notifyNick);
+ void nickRemoved(const QString& nick);
+ void nickAddedLobby(const QString& nick, bool notifyNick);
+ void nickRemovedLobby(const QString& nick);
+ void nickRemovedLobby(const QString& nick, const QString& message);
+
private:
QHash<quint32, QIcon> & m_icons();
typedef QHash<int, QVariant> DataEntry;
diff --git a/QTfrontend/model/roomslistmodel.cpp b/QTfrontend/model/roomslistmodel.cpp
index ffa20e5..323468a 100644
--- a/QTfrontend/model/roomslistmodel.cpp
+++ b/QTfrontend/model/roomslistmodel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,7 +43,8 @@ RoomsListModel::RoomsListModel(QObject *parent) :
<< tr("Rules")
<< tr("Weapons");
- m_mapModel = DataManager::instance().mapModel();
+ m_staticMapModel = DataManager::instance().staticMapModel();
+ m_missionMapModel = DataManager::instance().missionMapModel();
}
@@ -134,7 +135,8 @@ QVariant RoomsListModel::data(const QModelIndex &index, int role) const
}
// prefix ? if map not available
- if ((m_mapModel->indexOf(content) < 0))
+ if (!m_staticMapModel->mapExists(content) &&
+ !m_missionMapModel->mapExists(content))
return QString ("? %1").arg(content);
}
@@ -144,10 +146,14 @@ QVariant RoomsListModel::data(const QModelIndex &index, int role) const
// dye map names red if map not available
if (role == Qt::ForegroundRole)
{
- if ((m_mapModel->indexOf(content) < 0))
- return QBrush(QColor("darkred"));
- else
+ if (content == "+rnd+" ||
+ content == "+maze+" ||
+ content == "+drawn+" ||
+ m_staticMapModel->mapExists(content) ||
+ m_missionMapModel->mapExists(content))
return QVariant();
+ else
+ return QBrush(QColor("darkred"));
}
if (role == Qt::TextAlignmentRole)
diff --git a/QTfrontend/model/roomslistmodel.h b/QTfrontend/model/roomslistmodel.h
index b4d701d..9ac1cd1 100644
--- a/QTfrontend/model/roomslistmodel.h
+++ b/QTfrontend/model/roomslistmodel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -64,7 +64,8 @@ private:
const int c_nColumns;
QList<QStringList> m_data;
QStringList m_headerData;
- MapModel * m_mapModel;
+ MapModel * m_staticMapModel;
+ MapModel * m_missionMapModel;
QStringList roomInfo2RoomRecord(const QStringList & info);
};
diff --git a/QTfrontend/net/hwmap.cpp b/QTfrontend/net/hwmap.cpp
index 98abf4d..95ff602 100644
--- a/QTfrontend/net/hwmap.cpp
+++ b/QTfrontend/net/hwmap.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Ulyanov Igor <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
#include "hwconsts.h"
#include "hwmap.h"
-HWMap::HWMap() :
- TCPBase(false)
+HWMap::HWMap(QObject * parent) :
+ TCPBase(false, parent)
{
}
@@ -29,6 +29,11 @@ HWMap::~HWMap()
{
}
+bool HWMap::couldBeRemoved()
+{
+ return !m_hasStarted;
+}
+
void HWMap::getImage(const QString & seed, int filter, MapGenerator mapgen, int maze_size, const QByteArray & drawMapData)
{
m_seed = seed;
@@ -36,15 +41,18 @@ void HWMap::getImage(const QString & seed, int filter, MapGenerator mapgen, int
m_mapgen = mapgen;
m_maze_size = maze_size;
if(mapgen == MAPGEN_DRAWN) m_drawMapData = drawMapData;
- Start();
+ Start(true);
}
QStringList HWMap::getArguments()
{
QStringList arguments;
- arguments << cfgdir->absolutePath();
+ arguments << "--internal";
+ arguments << "--port";
arguments << QString("%1").arg(ipc_port);
- arguments << "landpreview";
+ arguments << "--user-prefix";
+ arguments << cfgdir->absolutePath();
+ arguments << "--landpreview";
return arguments;
}
diff --git a/QTfrontend/net/hwmap.h b/QTfrontend/net/hwmap.h
index 04eb3a3..b948ee8 100644
--- a/QTfrontend/net/hwmap.h
+++ b/QTfrontend/net/hwmap.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,9 +39,10 @@ class HWMap : public TCPBase
Q_OBJECT
public:
- HWMap();
+ HWMap(QObject *parent = 0);
virtual ~HWMap();
void getImage(const QString & seed, int templateFilter, MapGenerator mapgen, int maze_size, const QByteArray & drawMapData);
+ bool couldBeRemoved();
protected:
virtual QStringList getArguments();
diff --git a/QTfrontend/net/netregister.cpp b/QTfrontend/net/netregister.cpp
index 4e73ee6..56d3dee 100644
--- a/QTfrontend/net/netregister.cpp
+++ b/QTfrontend/net/netregister.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/netregister.h b/QTfrontend/net/netregister.h
index 0f5d6f6..3d0dfe3 100644
--- a/QTfrontend/net/netregister.h
+++ b/QTfrontend/net/netregister.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/netserver.cpp b/QTfrontend/net/netserver.cpp
index ca6c0f4..f572da9 100644
--- a/QTfrontend/net/netserver.cpp
+++ b/QTfrontend/net/netserver.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/netserver.h b/QTfrontend/net/netserver.h
index 58d9844..d727eca 100644
--- a/QTfrontend/net/netserver.h
+++ b/QTfrontend/net/netserver.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/netudpserver.cpp b/QTfrontend/net/netudpserver.cpp
index a7b74e5..a2f9e72 100644
--- a/QTfrontend/net/netudpserver.cpp
+++ b/QTfrontend/net/netudpserver.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,13 +20,14 @@
#include <QUdpSocket>
#include "netudpserver.h"
+#include "hwconsts.h"
HWNetUdpServer::HWNetUdpServer(QObject *parent, const QString & descr, quint16 port) :
HWNetRegisterServer(parent, descr, port),
m_descr(descr)
{
pUdpSocket = new QUdpSocket(this);
- pUdpSocket->bind(46631);
+ pUdpSocket->bind(NETGAME_DEFAULT_PORT);
connect(pUdpSocket, SIGNAL(readyRead()), this, SLOT(onClientRead()));
}
diff --git a/QTfrontend/net/netudpserver.h b/QTfrontend/net/netudpserver.h
index af85034..fe20105 100644
--- a/QTfrontend/net/netudpserver.h
+++ b/QTfrontend/net/netudpserver.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/netudpwidget.cpp b/QTfrontend/net/netudpwidget.cpp
index 77cefb2..58b6a77 100644
--- a/QTfrontend/net/netudpwidget.cpp
+++ b/QTfrontend/net/netudpwidget.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <QUdpSocket>
#include "netudpwidget.h"
+#include "hwconsts.h"
HWNetUdpModel::HWNetUdpModel(QObject* parent) :
HWNetServersModel(parent)
@@ -36,7 +37,7 @@ void HWNetUdpModel::updateList()
reset();
- pUdpSocket->writeDatagram("hedgewars client", QHostAddress::Broadcast, 46631);
+ pUdpSocket->writeDatagram("hedgewars client", QHostAddress::Broadcast, NETGAME_DEFAULT_PORT);
}
void HWNetUdpModel::onClientRead()
@@ -54,7 +55,7 @@ void HWNetUdpModel::onClientRead()
if(packet.startsWith("hedgewars server"))
{
QStringList sl;
- sl << packet.remove(0, 17) << clientAddr.toString() << "46631";
+ sl << packet.remove(0, 17) << clientAddr.toString() << QString::number(NETGAME_DEFAULT_PORT);
games.append(sl);
}
}
diff --git a/QTfrontend/net/netudpwidget.h b/QTfrontend/net/netudpwidget.h
index 0dedaab..7a79d48 100644
--- a/QTfrontend/net/netudpwidget.h
+++ b/QTfrontend/net/netudpwidget.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/newnetclient.cpp b/QTfrontend/net/newnetclient.cpp
index 5f1a83d..a5b089a 100644
--- a/QTfrontend/net/newnetclient.cpp
+++ b/QTfrontend/net/newnetclient.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +28,8 @@
#include "game.h"
#include "roomslistmodel.h"
#include "playerslistmodel.h"
+#include "servermessages.h"
+#include "HWApplication.h"
char delimeter='\n';
@@ -61,6 +63,8 @@ HWNewNet::HWNewNet() :
connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect()));
connect(&NetSocket, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(displayError(QAbstractSocket::SocketError)));
+
+ connect(this, SIGNAL(messageProcessed()), this, SLOT(ClientRead()), Qt::QueuedConnection);
}
HWNewNet::~HWNewNet()
@@ -184,6 +188,8 @@ void HWNewNet::ClientRead()
{
ParseCmd(cmdbuf);
cmdbuf.clear();
+ emit messageProcessed();
+ return ;
}
else
cmdbuf << s;
@@ -241,6 +247,7 @@ void HWNewNet::ParseCmd(const QStringList & lst)
{
mynick = lst[1];
m_playersModel->setNickname(mynick);
+ m_nick_registered = false;
return ;
}
@@ -250,7 +257,7 @@ void HWNewNet::ParseCmd(const QStringList & lst)
if (lst[0] == "ERROR")
{
if (lst.size() == 2)
- emit Error(lst[1]);
+ emit Error(HWApplication::translate("server", lst[1].toAscii().constData()));
else
emit Error("Unknown error");
return;
@@ -259,7 +266,7 @@ void HWNewNet::ParseCmd(const QStringList & lst)
if (lst[0] == "WARNING")
{
if (lst.size() == 2)
- emit Warning(lst[1]);
+ emit Warning(HWApplication::translate("server", lst[1].toAscii().constData()));
else
emit Warning("Unknown warning");
return;
@@ -304,6 +311,10 @@ void HWNewNet::ParseCmd(const QStringList & lst)
QStringList tmp = lst;
tmp.removeFirst();
m_roomsListModel->setRoomsList(tmp);
+ if (m_private_game == false && m_nick_registered == false)
+ {
+ emit NickNotRegistered(mynick);
+ }
return;
}
@@ -325,10 +336,24 @@ void HWNewNet::ParseCmd(const QStringList & lst)
qWarning("Net: Empty CHAT message");
return;
}
+
+ QString action = HWProto::chatStringToAction(lst[2]);
+
if (netClientState == InLobby)
- emit chatStringLobby(lst[1], HWProto::formatChatMsgForFrontend(lst[2]));
+ {
+ if (action != NULL)
+ emit lobbyChatAction(lst[1], action);
+ else
+ emit lobbyChatMessage(lst[1], lst[2]);
+ }
else
+ {
emit chatStringFromNet(HWProto::formatChatMsg(lst[1], lst[2]));
+ if (action != NULL)
+ emit roomChatAction(lst[1], action);
+ else
+ emit roomChatMessage(lst[1], lst[2]);
+ }
return;
}
@@ -339,12 +364,13 @@ void HWNewNet::ParseCmd(const QStringList & lst)
qWarning("Net: Malformed INFO message");
return;
}
- QStringList tmp = lst;
- tmp.removeFirst();
- if (netClientState == InLobby)
- emit chatStringLobby(tmp.join("\n").prepend('\x01'));
- else
- emit chatStringFromNet(tmp.join("\n").prepend('\x01'));
+ emit playerInfo(lst[1], lst[2], lst[3], lst[4]);
+ if (netClientState != InLobby)
+ {
+ QStringList tmp = lst;
+ tmp.removeFirst();
+ emit chatStringFromNet(tmp.join(" ").prepend('\x01'));
+ }
return;
}
@@ -364,6 +390,14 @@ void HWNewNet::ParseCmd(const QStringList & lst)
return;
}
+ if (lst[0] == "BANLIST")
+ {
+ QStringList tmp = lst;
+ tmp.removeFirst();
+ emit bansList(tmp);
+ return;
+ }
+
if (lst[0] == "CLIENT_FLAGS")
{
if(lst.size() < 3 || lst[1].size() < 2)
@@ -380,17 +414,18 @@ void HWNewNet::ParseCmd(const QStringList & lst)
{
flags.remove(0, 1);
char c = flags[0].toAscii();
+ bool inRoom = (netClientState == InRoom || netClientState == InGame);
switch(c)
{
// flag indicating if a player is ready to start a game
case 'r':
+ if(inRoom)
foreach (const QString & nick, nicks)
{
if (nick == mynick)
{
- if (isChief && !setFlag) ToggleReady();
- else emit setMyReadyStatus(setFlag);
+ emit setMyReadyStatus(setFlag);
}
m_playersModel->setFlag(nick, PlayersListModel::Ready, setFlag);
}
@@ -401,14 +436,16 @@ void HWNewNet::ParseCmd(const QStringList & lst)
foreach(const QString & nick, nicks)
m_playersModel->setFlag(nick, PlayersListModel::Registered, setFlag);
break;
-
+ // flag indicating if a player has engine running
case 'g':
+ if(inRoom)
foreach(const QString & nick, nicks)
m_playersModel->setFlag(nick, PlayersListModel::InGame, setFlag);
break;
// flag indicating if a player is the host/master of the room
case 'h':
+ if(inRoom)
foreach (const QString & nick, nicks)
{
if (nick == mynick)
@@ -467,9 +504,7 @@ void HWNewNet::ParseCmd(const QStringList & lst)
emit connected();
}
- emit nickAddedLobby(lst[i], false);
- emit chatStringLobby(lst[i], tr("%1 *** %2 has joined").arg('\x03').arg("|nick|"));
- m_playersModel->addPlayer(lst[i]);
+ m_playersModel->addPlayer(lst[i], false);
}
return;
}
@@ -493,9 +528,12 @@ void HWNewNet::ParseCmd(const QStringList & lst)
QString roomName = tmp.takeFirst();
m_roomsListModel->updateRoom(roomName, tmp);
- // keep track of room name so correct name is displayed when you become room admin
+ // keep track of room name so correct name is displayed
if(myroom == roomName)
+ {
myroom = tmp[1];
+ emit roomNameUpdated(myroom);
+ }
return;
}
@@ -513,20 +551,19 @@ void HWNewNet::ParseCmd(const QStringList & lst)
qWarning("Net: Bad LOBBY:LEFT message");
return;
}
- emit nickRemovedLobby(lst[1]);
+
if (lst.size() < 3)
- emit chatStringLobby(tr("%1 *** %2 has left").arg('\x03').arg(lst[1]));
+ m_playersModel->removePlayer(lst[1]);
else
- emit chatStringLobby(lst[1], tr("%1 *** %2 has left (%3)").arg('\x03').arg("|nick|", lst[2]));
-
- m_playersModel->removePlayer(lst[1]);
+ m_playersModel->removePlayer(lst[1], lst[2]);
return;
}
if (lst[0] == "ASKPASSWORD")
{
- emit AskForPassword(mynick);
+ emit NickRegistered(mynick);
+ m_nick_registered = true;
return;
}
@@ -561,10 +598,14 @@ void HWNewNet::ParseCmd(const QStringList & lst)
if (lst[1] == "Authentication failed")
{
emit AuthFailed();
+ m_game_connected = false;
+ Disconnect();
+ //omitted 'emit disconnected()', we don't want the error message
+ return;
}
m_game_connected = false;
Disconnect();
- emit disconnected(lst[1]);
+ emit disconnected(HWApplication::translate("server", lst[1].toAscii().constData()));
return;
}
@@ -574,6 +615,18 @@ void HWNewNet::ParseCmd(const QStringList & lst)
return;
}
+ if(lst[0] == "JOINING")
+ {
+ if(lst.size() < 2)
+ {
+ qWarning("Net: Bad JOINING message");
+ return;
+ }
+
+ myroom = lst[1];
+ emit roomNameUpdated(myroom);
+ }
+
if(netClientState == InLobby && lst[0] == "JOINED")
{
if(lst.size() < 2 || lst[1] != mynick)
@@ -593,9 +646,9 @@ void HWNewNet::ParseCmd(const QStringList & lst)
emit configAsked();
}
- emit nickAdded(lst[i], isChief && (lst[i] != mynick));
+ m_playersModel->playerJoinedRoom(lst[i], isChief && (lst[i] != mynick));
+
emit chatStringFromNet(tr("%1 *** %2 has joined the room").arg('\x03').arg(lst[i]));
- m_playersModel->playerJoinedRoom(lst[i]);
}
return;
}
@@ -617,6 +670,12 @@ void HWNewNet::ParseCmd(const QStringList & lst)
return;
}
+ if (lst[0] == "ROUND_FINISHED")
+ {
+ emit FromNet(QByteArray("\x01o"));
+ return;
+ }
+
if (lst[0] == "ADD_TEAM")
{
if(lst.size() != 24)
@@ -720,9 +779,8 @@ void HWNewNet::ParseCmd(const QStringList & lst)
for(int i = 1; i < lst.size(); ++i)
{
- emit nickAdded(lst[i], isChief && (lst[i] != mynick));
emit chatStringFromNet(tr("%1 *** %2 has joined the room").arg('\x03').arg(lst[i]));
- m_playersModel->playerJoinedRoom(lst[i]);
+ m_playersModel->playerJoinedRoom(lst[i], isChief && (lst[i] != mynick));
}
return;
}
@@ -734,7 +792,7 @@ void HWNewNet::ParseCmd(const QStringList & lst)
qWarning("Net: Bad LEFT message");
return;
}
- emit nickRemoved(lst[1]);
+
if (lst.size() < 3)
emit chatStringFromNet(tr("%1 *** %2 has left").arg('\x03').arg(lst[1]));
else
@@ -787,12 +845,25 @@ void HWNewNet::onParamChanged(const QString & param, const QStringList & value)
);
}
+void HWNewNet::chatLineToNetWithEcho(const QString& str)
+{
+ if(str != "")
+ {
+ emit chatStringFromNet(HWProto::formatChatMsg(mynick, str));
+ chatLineToNet(str);
+ }
+}
+
void HWNewNet::chatLineToNet(const QString& str)
{
if(str != "")
{
RawSendNet(QString("CHAT") + delimeter + str);
- emit(chatStringFromMe(HWProto::formatChatMsg(mynick, str)));
+ QString action = HWProto::chatStringToAction(str);
+ if (action != NULL)
+ emit(roomChatAction(mynick, action));
+ else
+ emit(roomChatMessage(mynick, str));
}
}
@@ -801,7 +872,11 @@ void HWNewNet::chatLineToLobby(const QString& str)
if(str != "")
{
RawSendNet(QString("CHAT") + delimeter + str);
- emit chatStringLobby(mynick, HWProto::formatChatMsgForFrontend(str));
+ QString action = HWProto::chatStringToAction(str);
+ if (action != NULL)
+ emit(lobbyChatAction(mynick, action));
+ else
+ emit(lobbyChatMessage(mynick, str));
}
}
@@ -859,6 +934,26 @@ void HWNewNet::banPlayer(const QString & nick)
RawSendNet(QString("BAN%1%2").arg(delimeter).arg(nick));
}
+void HWNewNet::banIP(const QString & ip, const QString & reason, int seconds)
+{
+ RawSendNet(QString("BANIP%1%2%1%3%1%4").arg(delimeter).arg(ip).arg(reason).arg(seconds));
+}
+
+void HWNewNet::banNick(const QString & nick, const QString & reason, int seconds)
+{
+ RawSendNet(QString("BANNICK%1%2%1%3%1%4").arg(delimeter).arg(nick).arg(reason).arg(seconds));
+}
+
+void HWNewNet::getBanList()
+{
+ RawSendNet(QByteArray("BANLIST"));
+}
+
+void HWNewNet::removeBan(const QString & b)
+{
+ RawSendNet(QString("UNBAN%1%2").arg(delimeter).arg(b));
+}
+
void HWNewNet::kickPlayer(const QString & nick)
{
RawSendNet(QString("KICK%1%2").arg(delimeter).arg(nick));
@@ -878,6 +973,20 @@ void HWNewNet::followPlayer(const QString & nick)
}
}
+void HWNewNet::consoleCommand(const QString & cmd)
+{
+ RawSendNet(QString("CMD%1%2").arg(delimeter).arg(cmd));
+}
+
+bool HWNewNet::allPlayersReady()
+{
+ int ready = 0;
+ for (int i = 0; i < m_roomPlayersModel->rowCount(); i++)
+ if (m_roomPlayersModel->index(i, 0).data(PlayersListModel::Ready).toBool()) ready++;
+
+ return (ready == m_roomPlayersModel->rowCount());
+}
+
void HWNewNet::startGame()
{
RawSendNet(QString("START_GAME"));
@@ -899,6 +1008,11 @@ void HWNewNet::toggleRestrictTeamAdds()
RawSendNet(QString("TOGGLE_RESTRICT_TEAMS"));
}
+void HWNewNet::toggleRegisteredOnly()
+{
+ RawSendNet(QString("TOGGLE_REGISTERED_ONLY"));
+}
+
void HWNewNet::clearAccountsCache()
{
RawSendNet(QString("CLEAR_ACCOUNTS_CACHE"));
diff --git a/QTfrontend/net/newnetclient.h b/QTfrontend/net/newnetclient.h
index 7428611..09f799f 100644
--- a/QTfrontend/net/newnetclient.h
+++ b/QTfrontend/net/newnetclient.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -60,6 +60,8 @@ class HWNewNet : public QObject
RoomsListModel * roomsListModel();
QAbstractItemModel * lobbyPlayersModel();
QAbstractItemModel * roomPlayersModel();
+ bool allPlayersReady();
+ bool m_private_game;
private:
bool isChief;
@@ -69,32 +71,12 @@ class HWNewNet : public QObject
QTcpSocket NetSocket;
QString seed;
bool m_game_connected;
+ bool m_nick_registered;
RoomsListModel * m_roomsListModel;
PlayersListModel * m_playersModel;
QSortFilterProxyModel * m_lobbyPlayersModel;
QSortFilterProxyModel * m_roomPlayersModel;
- template <typename T>
- void SendCfgStrNet(T a)
- {
- QByteArray strmsg;
- strmsg.append(a);
- quint8 sz = strmsg.size();
- QByteArray enginemsg = QByteArray((char *)&sz, 1) + strmsg;
- QString _msg = delimeter + QString(enginemsg.toBase64());
- RawSendNet(_msg);
- }
-
- template <typename T>
- void SendCfgStrLoc(T a)
- {
- QByteArray strmsg;
- strmsg.append(QString(a).toUtf8());
- quint8 sz = strmsg.size();
- QByteArray enginemsg = QByteArray((char *)&sz, 1) + strmsg;
- emit FromNet(enginemsg);
- }
-
QStringList cmdbuf;
void RawSendNet(const QString & buf);
@@ -111,18 +93,16 @@ class HWNewNet : public QObject
void disconnected(const QString & reason);
void Error(const QString & errmsg);
void Warning(const QString & wrnmsg);
- void AskForPassword(const QString & nick);
+ void NickRegistered(const QString & nick);
+ void NickNotRegistered(const QString & nick);
void NickTaken(const QString & nick);
void AuthFailed();
void EnteredGame();
void LeftRoom(const QString & reason);
- void nickAdded(const QString& nick, bool notifyNick);
- void nickRemoved(const QString& nick);
- void nickAddedLobby(const QString& nick, bool notifyNick);
- void nickRemovedLobby(const QString& nick);
void FromNet(const QByteArray & buf);
void adminAccess(bool);
void roomMaster(bool);
+ void roomNameUpdated(const QString & name);
void netSchemeConfig(QStringList &);
void paramChanged(const QString & param, const QStringList & value);
@@ -133,23 +113,32 @@ class HWNewNet : public QObject
void RemoveNetTeam(const HWTeam&);
void hhnumChanged(const HWTeam&);
void teamColorChanged(const HWTeam&);
- void chatStringLobby(const QString&);
- void chatStringLobby(const QString&, const QString&);
+ void playerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo);
+ void lobbyChatMessage(const QString & nick, const QString & message);
+ void lobbyChatAction(const QString & nick, const QString & action);
+ void roomChatMessage(const QString & nick, const QString & message);
+ void roomChatAction(const QString & nick, const QString & action);
void chatStringFromNet(const QString&);
- void chatStringFromMe(const QString&);
- void chatStringFromMeLobby(const QString&);
void roomsList(const QStringList&);
void serverMessage(const QString &);
void serverMessageNew(const QString &);
void serverMessageOld(const QString &);
void latestProtocolVar(int);
+ void bansList(const QStringList &);
void setMyReadyStatus(bool isReady);
+ void messageProcessed();
+
public slots:
void ToggleReady();
void chatLineToNet(const QString& str);
+ void chatLineToNetWithEcho(const QString&);
void chatLineToLobby(const QString& str);
void SendTeamMessage(const QString& str);
void SendNet(const QByteArray & buf);
@@ -173,11 +162,17 @@ class HWNewNet : public QObject
void kickPlayer(const QString &);
void infoPlayer(const QString &);
void followPlayer(const QString &);
+ void consoleCommand(const QString &);
void startGame();
void toggleRestrictJoins();
void toggleRestrictTeamAdds();
+ void toggleRegisteredOnly();
void partRoom();
void clearAccountsCache();
+ void getBanList();
+ void removeBan(const QString &);
+ void banIP(const QString & ip, const QString & reason, int seconds);
+ void banNick(const QString & nick, const QString & reason, int seconds);
private slots:
void ClientRead();
diff --git a/QTfrontend/net/proto.cpp b/QTfrontend/net/proto.cpp
index dc090cd..4068896 100644
--- a/QTfrontend/net/proto.cpp
+++ b/QTfrontend/net/proto.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -45,11 +45,6 @@ QByteArray & HWProto::addStringListToBuffer(QByteArray & buf, const QStringList
return buf;
}
-QString HWProto::formatChatMsgForFrontend(const QString & msg)
-{
- return formatChatMsg("|nick|", msg);
-}
-
QString HWProto::formatChatMsg(const QString & nick, const QString & msg)
{
if(msg.left(4) == "/me ")
@@ -57,3 +52,11 @@ QString HWProto::formatChatMsg(const QString & nick, const QString & msg)
else
return QString("\x01%1: %2").arg(nick).arg(msg);
}
+
+QString HWProto::chatStringToAction(const QString & string)
+{
+ if(string.left(4) == "/me ")
+ return string.mid(4);
+ else
+ return NULL;
+}
diff --git a/QTfrontend/net/proto.h b/QTfrontend/net/proto.h
index edcf67a..0ed8554 100644
--- a/QTfrontend/net/proto.h
+++ b/QTfrontend/net/proto.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,6 +35,12 @@ class HWProto : public QObject
static QByteArray & addStringListToBuffer(QByteArray & buf, const QStringList & strList);
static QString formatChatMsg(const QString & nick, const QString & msg);
static QString formatChatMsgForFrontend(const QString & msg);
+ /**
+ * @brief Determines if a chat string represents a chat action and returns the action.
+ * @param string chat string
+ * @return the action-message or NULL if message is no action
+ */
+ static QString chatStringToAction(const QString & string);
};
#endif // _PROTO_H
diff --git a/QTfrontend/net/recorder.cpp b/QTfrontend/net/recorder.cpp
index 7fd07b6..1ef9c52 100644
--- a/QTfrontend/net/recorder.cpp
+++ b/QTfrontend/net/recorder.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ HWRecorder::~HWRecorder()
if (queue.empty())
numRecorders--;
else
- queue.takeFirst()->Start();
+ queue.takeFirst()->Start(false);
}
void HWRecorder::onClientDisconnect()
@@ -89,7 +89,7 @@ void HWRecorder::EncodeVideo(const QByteArray & record)
if (numRecorders < maxRecorders)
{
numRecorders++;
- Start(); // run engine
+ Start(false); // run engine
}
else
queue.push_back(this);
@@ -99,29 +99,44 @@ QStringList HWRecorder::getArguments()
{
QStringList arguments;
QRect resolution = config->rec_Resolution();
+ QString nick = config->netNick().toUtf8().toBase64();
+
+ arguments << "--internal";
+ arguments << "--port";
+ arguments << QString("%1").arg(ipc_port);
+ arguments << "--prefix";
+ arguments << datadir->absolutePath();
+ arguments << "--user-prefix";
arguments << cfgdir->absolutePath();
+ arguments << "--locale";
+ arguments << HWGame::tr("en.txt");
+ arguments << "--frame-interval";
+ arguments << QString::number(config->timerInterval());
+ arguments << "--width";
arguments << QString::number(resolution.width());
+ arguments << "--height";
arguments << QString::number(resolution.height());
- arguments << "32"; // bpp
- arguments << QString("%1").arg(ipc_port);
- arguments << "0"; // fullscreen
- arguments << "0"; // sound
- arguments << "0"; // music
- arguments << "0"; // sound volume
- arguments << QString::number(config->timerInterval());
- arguments << datadir->absolutePath();
- arguments << "0"; // fps
- arguments << (config->isAltDamageEnabled() ? "1" : "0");
- arguments << config->netNick().toUtf8().toBase64();
+ arguments << "--nosound";
+ arguments << "--raw-quality";
arguments << QString::number(config->translateQuality());
+ arguments << "--stereo";
arguments << QString::number(config->stereoMode());
- arguments << HWGame::tr("en.txt");
- arguments << QString::number(config->rec_Framerate()); // framerate numerator
- arguments << "1"; // framerate denominator
+ arguments << "--nomusic";
+ arguments << "--volume";
+ arguments << "0";
+ if (config->isAltDamageEnabled())
+ arguments << "--altdmg";
+ if (!nick.isEmpty()) {
+ arguments << "--nick";
+ arguments << nick;
+ }
+ arguments << "--recorder";
+ arguments << QString::number(config->rec_Framerate()); //cVideoFramerateNum
+ arguments << "1"; //cVideoFramerateDen
arguments << prefix;
arguments << config->AVFormat();
arguments << config->videoCodec();
-// Could use a field to use quality instead. maybe quality could override bitrate - or just pass (and set) both.
+// Could use a field to use quality instead. maybe quality could override bitrate - or just pass (and set) both.
// The library does support using both at once after all.
arguments << QString::number(config->rec_Bitrate()*1024);
arguments << (config->recordAudio() ? config->audioCodec() : "no");
diff --git a/QTfrontend/net/recorder.h b/QTfrontend/net/recorder.h
index c577dab..7dcc4c0 100644
--- a/QTfrontend/net/recorder.h
+++ b/QTfrontend/net/recorder.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/net/tcpBase.cpp b/QTfrontend/net/tcpBase.cpp
index ec73912..cf78793 100644
--- a/QTfrontend/net/tcpBase.cpp
+++ b/QTfrontend/net/tcpBase.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,23 +19,66 @@
#include "tcpBase.h"
-#include <QMessageBox>
#include <QList>
-#include <QApplication>
#include <QImage>
+#include <QThread>
#include "hwconsts.h"
+#include "MessageDialog.h"
+
+#ifdef HWLIBRARY
+extern "C" void Game(char**arguments);
+extern "C" void GenLandPreview(int port);
+
+
+EngineInstance::EngineInstance(QObject *parent)
+ : QObject(parent)
+{
+ port = 0;
+}
+
+EngineInstance::~EngineInstance()
+{
+}
+
+void EngineInstance::start()
+{
+#if 0
+ char *args[11];
+ args[0] = "65000"; //ipcPort
+ args[1] = "1024"; //cScreenWidth
+ args[2] = "768"; //cScreenHeight
+ args[3] = "0"; //cReducedQuality
+ args[4] = "en.txt"; //cLocaleFName
+ args[5] = "koda"; //UserNick
+ args[6] = "1"; //SetSound
+ args[7] = "1"; //SetMusic
+ args[8] = "0"; //cAltDamage
+ args[9]= datadir->absolutePath().toAscii().data(); //cPathPrefix
+ args[10]= NULL; //recordFileName
+ Game(args);
+#endif
+ GenLandPreview(port);
+}
+
+#endif
QList<TCPBase*> srvsList;
QPointer<QTcpServer> TCPBase::IPCServer(0);
TCPBase::~TCPBase()
{
+ // make sure this object is not in the server list anymore
+ srvsList.removeOne(this);
+
if (IPCSocket)
IPCSocket->deleteLater();
+
}
-TCPBase::TCPBase(bool demoMode) :
+TCPBase::TCPBase(bool demoMode, QObject *parent) :
+ QObject(parent),
+ m_hasStarted(false),
m_isDemoMode(demoMode),
IPCSocket(0)
{
@@ -45,16 +88,11 @@ TCPBase::TCPBase(bool demoMode) :
IPCServer->setMaxPendingConnections(1);
if (!IPCServer->listen(QHostAddress::LocalHost))
{
- QMessageBox deniedMsg(QApplication::activeWindow());
- deniedMsg.setIcon(QMessageBox::Critical);
- deniedMsg.setWindowTitle(QMessageBox::tr("TCP - Error"));
- deniedMsg.setText(QMessageBox::tr("Unable to start the server: %1.").arg(IPCServer->errorString()));
- deniedMsg.setWindowModality(Qt::WindowModal);
- deniedMsg.exec();
-
+ MessageDialog::ShowFatalMessage(tr("Unable to start server at %1.").arg(IPCServer->errorString()));
exit(0); // FIXME - should be graceful exit here (lower Critical -> Warning above when implemented)
}
}
+
ipc_port=IPCServer->serverPort();
}
@@ -71,9 +109,6 @@ void TCPBase::NewConnection()
connect(IPCSocket, SIGNAL(disconnected()), this, SLOT(ClientDisconnect()));
connect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead()));
SendToClientFirst();
-
- if(srvsList.size()==1) srvsList.pop_front();
- emit isReadyNow();
}
void TCPBase::RealStart()
@@ -81,15 +116,32 @@ void TCPBase::RealStart()
connect(IPCServer, SIGNAL(newConnection()), this, SLOT(NewConnection()));
IPCSocket = 0;
+#ifdef HWLIBRARY
+ QThread *thread = new QThread;
+ EngineInstance *instance = new EngineInstance;
+ instance->port = IPCServer->serverPort();
+
+ instance->moveToThread(thread);
+
+ connect(thread, SIGNAL(started()), instance, SLOT(start(void)));
+ connect(instance, SIGNAL(finished()), thread, SLOT(quit()));
+ connect(instance, SIGNAL(finished()), instance, SLOT(deleteLater()));
+ connect(instance, SIGNAL(finished()), thread, SLOT(deleteLater()));
+ thread->start();
+#else
QProcess * process;
- process = new QProcess;
+ process = new QProcess();
connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(StartProcessError(QProcess::ProcessError)));
QStringList arguments=getArguments();
+#ifdef DEBUG
// redirect everything written on stdout/stderr
- if(isDevBuild)
- process->setProcessChannelMode(QProcess::ForwardedChannels);
+ process->setProcessChannelMode(QProcess::ForwardedChannels);
+#endif
+
process->start(bindir->absolutePath() + "/hwengine", arguments);
+#endif
+ m_hasStarted = true;
}
void TCPBase::ClientDisconnect()
@@ -97,13 +149,9 @@ void TCPBase::ClientDisconnect()
disconnect(IPCSocket, SIGNAL(readyRead()), this, SLOT(ClientRead()));
onClientDisconnect();
- /* if(srvsList.size()==1) srvsList.pop_front();
- emit isReadyNow();*/
+ emit isReadyNow();
IPCSocket->deleteLater();
- // make sure this object is not in the server list anymore
- srvsList.removeOne(this);
-
deleteLater();
}
@@ -117,38 +165,40 @@ void TCPBase::ClientRead()
void TCPBase::StartProcessError(QProcess::ProcessError error)
{
- QMessageBox deniedMsg(QApplication::activeWindow());
- deniedMsg.setIcon(QMessageBox::Critical);
- deniedMsg.setWindowTitle(QMessageBox::tr("TCP - Error"));
- deniedMsg.setText(QMessageBox::tr("Unable to run engine at ") + bindir->absolutePath() + "/hwengine\n" +
- QMessageBox::tr("Error code: %1").arg(error));
- deniedMsg.setWindowModality(Qt::WindowModal);
- deniedMsg.exec();
-
+ MessageDialog::ShowFatalMessage(tr("Unable to run engine at %1\nError code: %2").arg(bindir->absolutePath() + "/hwengine").arg(error));
ClientDisconnect();
}
void TCPBase::tcpServerReady()
{
- disconnect(srvsList.takeFirst(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
+ disconnect(srvsList.first(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
RealStart();
}
-void TCPBase::Start()
+void TCPBase::Start(bool couldCancelPreviousRequest)
{
if(srvsList.isEmpty())
{
srvsList.push_back(this);
+ RealStart();
}
else
{
- connect(srvsList.back(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
- srvsList.push_back(this);
- return;
+ TCPBase * last = srvsList.last();
+ if(couldCancelPreviousRequest
+ && last->couldBeRemoved()
+ && (last->parent() == parent()))
+ {
+ srvsList.removeLast();
+ last->deleteLater();
+ Start(couldCancelPreviousRequest);
+ } else
+ {
+ connect(srvsList.last(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
+ srvsList.push_back(this);
+ }
}
-
- RealStart();
}
void TCPBase::onClientRead()
@@ -191,3 +241,8 @@ void TCPBase::RawSendIPC(const QByteArray & buf)
}
}
}
+
+bool TCPBase::couldBeRemoved()
+{
+ return false;
+}
diff --git a/QTfrontend/net/tcpBase.h b/QTfrontend/net/tcpBase.h
index 3837006..605ac49 100644
--- a/QTfrontend/net/tcpBase.h
+++ b/QTfrontend/net/tcpBase.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,16 +38,19 @@ class TCPBase : public QObject
Q_OBJECT
public:
- TCPBase(bool demoMode);
+ TCPBase(bool demoMode, QObject * parent = 0);
virtual ~TCPBase();
+ virtual bool couldBeRemoved();
+
signals:
void isReadyNow();
protected:
+ bool m_hasStarted;
quint16 ipc_port;
- void Start();
+ void Start(bool couldCancelPreviousRequest);
QByteArray readbuffer;
@@ -78,4 +81,21 @@ class TCPBase : public QObject
void tcpServerReady();
};
+#ifdef HWLIBRARY
+class EngineInstance : public QObject
+{
+ Q_OBJECT
+public:
+ EngineInstance(QObject *parent = 0);
+ ~EngineInstance();
+
+ int port;
+public slots:
+ void start(void);
+signals:
+ void finished(void);
+private:
+};
+#endif
+
#endif // _TCPBASE_INCLUDED
diff --git a/QTfrontend/res/NetworkPlayDisabled.png b/QTfrontend/res/NetworkPlayDisabled.png
new file mode 100644
index 0000000..ebe4fd3
Binary files /dev/null and b/QTfrontend/res/NetworkPlayDisabled.png differ
diff --git a/QTfrontend/res/Start.png b/QTfrontend/res/Start.png
new file mode 100644
index 0000000..f7564a7
Binary files /dev/null and b/QTfrontend/res/Start.png differ
diff --git a/QTfrontend/res/audio.png b/QTfrontend/res/audio.png
new file mode 100644
index 0000000..d07e8bb
Binary files /dev/null and b/QTfrontend/res/audio.png differ
diff --git a/QTfrontend/res/camera.png b/QTfrontend/res/camera.png
new file mode 100644
index 0000000..e5e4998
Binary files /dev/null and b/QTfrontend/res/camera.png differ
diff --git a/QTfrontend/res/css/chat.css b/QTfrontend/res/css/chat.css
index ea416f2..a914c7f 100644
--- a/QTfrontend/res/css/chat.css
+++ b/QTfrontend/res/css/chat.css
@@ -61,15 +61,20 @@ a { color: #c8c8ff; }
.msg_FriendChat .nick { color: #30ff30; }
.msg_UserJoin { color: #c0c0c0; }
.msg_UserJoin .nick { color: #d0d0d0; }
+.msg_UserLeave { color: #b8b8b8; }
+.msg_UserLeave .nick { color: #c8c8c8; }
.msg_FriendJoin { font-weight: bold; color: #c0f0c0; }
.msg_FriendJoin .nick { color: #d8f0d8; }
+.msg_FriendLeave { font-weight: bold; color: #ffe090; }
+.msg_FriendLeave .nick { color: #f8e878; }
.msg_UserAction { color: #ff80ff; }
.msg_UserAction .nick { color: #ffa0ff;}
.msg_FriendAction { color: #ff00ff; }
.msg_FriendAction .nick { color: #ff30ff; }
-/* uncomment next line to disable join and leave messages of non-friends */
+/* uncomment next lines to disable join and leave messages of non-friends */
/* .msg_UserJoin { display:none; } */
+/* .msg_UserLeave { display:none; } */
/* timestamps */
.timestamp {
diff --git a/QTfrontend/res/css/christmas.css b/QTfrontend/res/css/christmas.css
index b136728..763df1b 100644
--- a/QTfrontend/res/css/christmas.css
+++ b/QTfrontend/res/css/christmas.css
@@ -21,7 +21,7 @@ HWForm,QDialog {
background-image: url(":/res/BackgroundChristmas.png");
background-position: bottom center;
background-repeat: repeat-x;
-background-color: #141250;
+background-color: #0c0f28;
}
* {
diff --git a/QTfrontend/res/css/qt.css b/QTfrontend/res/css/qt.css
index 460b1e4..bd4bf93 100644
--- a/QTfrontend/res/css/qt.css
+++ b/QTfrontend/res/css/qt.css
@@ -33,7 +33,7 @@ selection-color: #00351d;
a { color:#c8c8ff; }
QLineEdit, QListWidget, QListView, QTableView, QTextBrowser, QSpinBox, QComboBox,
-QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item {
+QComboBox QAbstractItemView, QPlainTextEdit, QMenu::item, #labelLikeLineEdit {
background-color: rgba(13, 5, 68, 70%);
}
@@ -44,8 +44,8 @@ border: solid; border-width: 3px; border-color: #ffcc00;
QPushButton, QListWidget, QListView, QTableView, QLineEdit, QHeaderView,
QTextBrowser, QSpinBox, QToolBox, QComboBox, QPlainTextEdit,
QComboBox QAbstractItemView, IconedGroupBox,
-.QGroupBox, GameCFGWidget, TeamSelWidget, SelWeaponWidget,
-QTabWidget::pane, QTabBar::tab {
+.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget,
+QTabWidget::pane, QTabBar::tab, #mapPreview, #labelLikeLineEdit {
border: solid;
border-width: 3px;
border-color: #ffcc00;
@@ -56,14 +56,30 @@ QSpinBox:hover, QToolBox:hover, QComboBox:hover {
border-color: yellow;
}
+QToolButton {
+background-color: #11084A;
+}
+
+QToolButton:hover {
+background-color: #150A61;
+}
+
+QToolButton:pressed {
+background-color: #100744;
+}
+
QLineEdit, QListWidget, QListView, QTableView, QTextBrowser,
-QSpinBox, QToolBox, QPlainTextEdit {
+QSpinBox, QToolBox, QPlainTextEdit, QToolButton, #mapPreview, #labelLikeLineEdit {
border-radius: 10px;
}
+#mapPreview {
+background-color: #0d0544;
+}
+
QLineEdit, QLabel, QHeaderView, QListWidget, QListView, QTableView,
QSpinBox, QToolBox::tab, QComboBox, QComboBox QAbstractItemView,
-IconedGroupBox, .QGroupBox, GameCFGWidget, TeamSelWidget,
+IconedGroupBox, .QGroupBox, #gameStackContainer, TeamSelWidget,
SelWeaponWidget, QCheckBox, QRadioButton, QPushButton, QPlainTextEdit {
font: bold 13px;
}
@@ -72,7 +88,7 @@ background-position: bottom center;
background-repeat: repeat-x;
background-color: #000000;
}
-.QGroupBox,GameCFGWidget,TeamSelWidget,SelWeaponWidget {
+.QGroupBox, #gameStackContainer, TeamSelWidget, SelWeaponWidget {
background-position: bottom center;
background-repeat: repeat-x;
border-radius: 16px;
@@ -89,6 +105,18 @@ IconedGroupBox, QTabWidget::pane, QTabBar::tab:selected, QToolBox::tab QWidget{
background-color: #130f2c;
}
+QTabWidget::pane {
+border-radius: 8px;
+border-top-left-radius: 0px;
+}
+
+QLineEdit:disabled, QSpinBox:disabled {
+border-color: gray;
+}
+
+GameCFGWidget {
+border: none;
+}
QPushButton {
border-radius: 8px;
@@ -97,7 +125,7 @@ background-position: top left;
background-color: rgba(18, 42, 5, 70%);
}
-QPushButton:pressed{
+QPushButton:pressed, QToolButton:pressed {
border-color: white;
}
@@ -105,7 +133,6 @@ QPushButton:focus {
outline: none;
}
-
QHeaderView {
border-radius: 0;
border-width: 0;
@@ -149,9 +176,15 @@ width: 16px;
height: 10px;
}
+QLabel {
+overflow: hidden;
+}
+
QComboBox {
border-radius: 10px;
padding: 3px;
+height: 18px;
+overflow: hidden;
}
QComboBox:pressed{
border-color: white;
@@ -241,9 +274,66 @@ background-color: #ffcc00;
QSlider::handle::horizontal {
border: 0px;
-margin: -2px 0px;
-border-radius: 3px;
+margin: -8px 0px;
background-color: #ffcc00;
-width: 8px;
+width: 12px;
+height: 6px;
+border-radius: 3px;
+}
+
+HatButton, ThemeButton {
+text-align: left;
}
+#hatList, #hatList:hover, #themeList, #themeList:hover {
+border-color: #F6CB1C;
+}
+
+#hatList QScrollBar, #themeList QScrollBar {
+background-color: #130F2A;
+border-top-right-radius: 10px;
+border-bottom-right-radius: 10px;
+}
+
+#hatList, #themeList {
+border-color: #F6CB1C;
+border-width: 3px;
+border-style: solid;
+border-radius: 10px;
+border-top-left-radius: 0px;
+}
+
+#hatList::item, #themeList::item {
+background-color: #11084A;
+padding: 4px;
+border-radius: 10px;
+color: #ffcc00 !important;
+font: 8px;
+border-width: 2px;
+border-color: #11084A;
+}
+
+#hatList::item:hover, #themeList::item:hover {
+background-color: #150A61;
+}
+
+#hatList::item:selected, #themeList::item:selected {
+background-color: #150A61;
+}
+
+QDialogButtonBox QPushButton {
+padding: 3px 5px;
+}
+
+#gameCfgWidgetTabs {
+border-radius: 16px;
+border-top-left-radius: 0px;
+}
+
+TeamSelWidget, #gameStackContainer, #GBoxOptions {
+border-radius: 10px;
+}
+
+PageMultiplayer TeamSelWidget {
+min-height: 500px;
+}
diff --git a/QTfrontend/res/html/about.html b/QTfrontend/res/html/about.html
new file mode 100644
index 0000000..9200b63
--- /dev/null
+++ b/QTfrontend/res/html/about.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>Hedgewars - Authors</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<style type="text/css">
+ body { color: orange; }
+ a { color: #ffe270; }
+ a:hover { color: yellow; }
+</style>
+</head>
+<body>
+ <h2>Developers:</h2>
+ <p>
+ Engine, frontend, net server: Andrey Korotaev <<a href="mailto:unC0Rr at gmail.com">unC0Rr at gmail.com</a>><br>
+ Many frontend improvements: Igor Ulyanov <<a href="mailto:disinbox at gmail.com">disinbox at gmail.com</a>><br>
+ Many engine and frontend improvements: Derek Pomery <<a href="mailto:nemo at m8y.org">nemo at m8y.org</a>><br>
+ Drill rocket, Ballgun, RC Plane weapons: Martin Boze <<a href="mailto:afffect at gmail.com">afffect at gmail.com</a>><br>
+ Mine number and time game settings: David A. Cuadrado <<a href="mailto:krawek at gmail.com">krawek at gmail.com</a>><br>
+ Frontend improvements: Martin Minarik <<a href="mailto:ttsmj at pokec.sk">ttsmj at pokec.sk</a>><br>
+ Frontend improvements: Kristian Lehmann <<a href="mailto:email at thexception.net">email at thexception.net</a>><br>
+ Mac OS X/iPhone port, OpenGL-ES conversion: Vittorio Giovara <<a href="mailto:vittorio.giovara at gmail.com">vittorio.giovara at gmail.com</a>><br>
+ Many engine and frontend improvements (and bugs): Richard Karolyi <<a href="mailto:sheepluva at ercatec.net">sheepluva at ercatec.net</a>><br>
+ Gamepad and Lua integration: Mario Liebisch <<a href="mailto:mario.liebisch at gmail.com">mario.liebisch at gmail.com</a>><br>
+ Many engine improvements and graphics: Carlos Vives <<a href="mailto:mail at carlosvives.es">mail at carlosvives.es</a>><br>
+ Maze maps: Henning Kühn <<a href="mailto:prg at cooco.de">prg at cooco.de</a>><br>
+ Engine and frontend improvements: Henrik Rostedt <<a href="mailto:henrik.rostedt at gmail.com">henrik.rostedt at gmail.com</a>><br>
+ Lua game modes and missions: John Lambert <<a href="mailto:redgrinner at gmail.com">redgrinner at gmail.com</a>><br>
+ Frontend improvements: Mayur Pawashe <<a href="mailto:zorgiepoo at gmail.com">zorgiepoo at gmail.com</a>><br>
+ Android port: Richard Deurwaarder <<a href="mailto:xeli at xelification.com">xeli at xelification.com</a>><br>
+ Android netplay, portability abstraction: Simeon Maxein <<a href="mailto:smaxein at googlemail.com">smaxein at googlemail.com</a>><br>
+ WebGL port, some pas2c and GLES2 work: Meng Xiangyun <<a href="mailto:xymengxy at gmail.com">xymengxy at gmail.com</a>><br>
+ Video recording: Stepan Podoskin <<a href="mailto:stepik-777 at mail.ru">stepik-777 at mail.ru</a>><br>
+ Campaign support, first campaign: Szabolcs Orbàn <<a href="mailto:szabibibi at gmail.com">szabibibi at gmail.com</a>><br>
+ Keybinds, feedback, maps and hats interfaces: Drew Gottlieb <<a href="mailto:gottlieb.drew at gmail.com">gottlieb.drew at gmail.com</a>><br>
+ Login dialogs, frontend improvements: Ondrej Skopek <<a href="mailto:skopekondrej at gmail.com">skopekondrej at gmail.com</a>><br>
+ Icegun weapon: Julia Struchenko <<a href="mailto:urbertar at gmail.com">urbertar at gmail.com</a>><br>
+ </p>
+
+ <h2>Art:</h2>
+ <p>John Dum <<a href="mailto:fizzy at gmail.com">fizzy at gmail.com</a>>
+ <br>
+ Joshua Frese <<a href="mailto:joshfrese at gmail.com">joshfrese at gmail.com</a>>
+ <br>
+ Stanko TadiÄ <<a href="mailto:stanko at mfhinc.net">stanko at mfhinc.net</a>>
+ <br>
+ Julien Koesten <<a href="mailto:julienkoesten at aol.com">julienkoesten at aol.com</a>>
+ <br>
+ Joshua O'Sullivan <<a href="mailto:coheedftw at hotmail.co.uk">coheedftw at hotmail.co.uk</a>>
+ <br>
+ Nils Lück <<a href="mailto:nils.luck.design at gmail.com">nils.luck.design at gmail.com</a>>
+ <br>
+ Guillaume Englert <<a href="mailto:genglert at hybird.org">genglert at hybird.org</a>>
+ <br>
+ Hats: Trey Perry <<a href="mailto:tx.perry.j at gmail.com">tx.perry.j at gmail.com</a>>
+ </p>
+
+ <h2>Sounds:</h2>
+ <p>
+ Hedgehogs voice: Stephen Alexander <<a href="mailto:ArmagonNo1 at gmail.com">ArmagonNo1 at gmail.com</a>>
+ <br>
+ John Dum <<a href="mailto:fizzy at gmail.com">fizzy at gmail.com</a>>
+ <br>
+ Jonatan Nilsson <<a href="mailto:jonatanfan at gmail.com">jonatanfan at gmail.com</a>>
+ <br>
+ Daniel Martin <<a href="mailto:elhombresinremedio at gmail.com">elhombresinremedio at gmail.com</a>>
+ </p>
+
+ <h2>Translations:</h2><p>
+ Brazilian Portuguese: Romulo Fernandes Machado <<a href="mailto:abra185 at gmail.com">abra185 at gmail.com</a>><br>
+ Bulgarian: Svetoslav Stefanov<br>
+ Czech: Petr ÅezáÄek <<a href="mailto:rezacek at gmail.com">rezacek at gmail.com</a>><br>
+ Chinese: Jie Luo <<a href="mailto:lililjlj at gmail.com">lililjlj at gmail.com</a>><br>
+ English: Andrey Korotaev <<a href="mailto:unC0Rr at gmail.com">unC0Rr at gmail.com</a>><br>
+ Finnish: Nina Kuisma <<a href="mailto:ninnnu at gmail.com">ninnnu at gmail.com</a>><br>
+ French: Antoine Turmel <<a href="mailto:geekshadow at gmail.com">geekshadow at gmail.com</a>>, Clement Woitrain <<a href="mailto:sphrixclement at gmail.com">sphrixclement at gmail.com</a>>, Matisumi<br>
+ German: Peter Hüwe <<a href="mailto:PeterHuewe at gmx.de">PeterHuewe at gmx.de</a>>, Mario Liebisch <<a href="mailto:mario.liebisch at gmail.com">mario.liebisch at gmail.com</a>>, Richard Karolyi <<a href="mailto:sheepluva at ercatec.net">sheepluva at ercatec.net</a>><br>
+ Greek: <<a href="mailto:talos_kriti at yahoo.gr">talos_kriti at yahoo.gr</a>><br>
+ Italian: Luca Bonora <<a href="mailto:bonora.luca at gmail.com">bonora.luca at gmail.com</a>>, Marco Bresciani <<a href="mailto:m.bresciani at email.it">m.bresciani at email.it</a>><br>
+ Japanese: ADAM Etienne <<a href="mailto:etienne.adam at gmail.com">etienne.adam at gmail.com</a>>, Marco Bresciani <<a href="mailto:m.bresciani at email.it">m.bresciani at email.it</a>>, æ¢
æ´¥æ´æµ<br>
+ Korean: Anthony Bellew <<a href="mailto:anthonyreflected at gmail.com">anthonyreflected at gmail.com</a>><br>
+ Lithuanian: Lukas Urbonas <<a href="mailto:lukasu08 at gmail.com">lukasu08 at gmail.com</a>><br>
+ Polish: Maciej MroziÅski <<a href="mailto:mynick2 at o2.pl">mynick2 at o2.pl</a>>, Wojciech Latkowski <<a href="mailto:magik17l at gmail.com">magik17l at gmail.com</a>>, Piotr Mitana, Maciej Górny<br>
+ Portuguese: Fábio Canário <<a href="mailto:inufabie at gmail.com">inufabie at gmail.com</a>><br>
+ Russian: Andrey Korotaev <<a href="mailto:unC0Rr at gmail.com">unC0Rr at gmail.com</a>><br>
+ Slovak: Jose Riha<br>
+ Spanish: Carlos Vives <<a href="mailto:mail at carlosvives.es">mail at carlosvives.es</a>><br>
+ Swedish: Niklas Grahn <<a href="mailto:raewolusjoon at yaoo.com">raewolusjoon at yaoo.com</a>>, Henrik Rostedt <<a href="mailto:henrik.rostedt at gmail.com">henrik.rostedt at gmail.com</a>><br>
+ Ukrainian: Eugene V. Lyubimkin <<a href="mailto:jackyf.devel at gmail.com">jackyf.devel at gmail.com</a>>, Igor Paliychuk <<a href="mailto:mansonigor at gmail.com">mansonigor at gmail.com</a>>, Eugene Sakara <<a href="mailto:eresid at gmail.com">eresid at gmail.com</a>>
+ </p>
+
+ <h2>Special thanks:</h2><p>
+ Aleksey Andreev <<a href="mailto:blaknayabr at gmail.com">blaknayabr at gmail.com</a>><br>
+ Aleksander Rudalev <<a href="mailto:alexv at pomorsu.ru">alexv at pomorsu.ru</a>><br>
+ Natasha Korotaeva <<a href="mailto:layout at pisem.net">layout at pisem.net</a>><br>
+ Adam Higerd (aka ahigerd at FreeNode)
+ </p>
+</body>
+</html>
diff --git a/QTfrontend/res/inverse-corner-bl.png b/QTfrontend/res/inverse-corner-bl.png
new file mode 100644
index 0000000..4931636
Binary files /dev/null and b/QTfrontend/res/inverse-corner-bl.png differ
diff --git a/QTfrontend/res/splash.png b/QTfrontend/res/splash.png
new file mode 100644
index 0000000..fcc8098
Binary files /dev/null and b/QTfrontend/res/splash.png differ
diff --git a/QTfrontend/res/xml/tips.xml b/QTfrontend/res/xml/tips.xml
new file mode 100644
index 0000000..ee9f52e
--- /dev/null
+++ b/QTfrontend/res/xml/tips.xml
@@ -0,0 +1,62 @@
+# This is not xml actually, but it looks and behaves like it.
+# Including an xml library would need too much resources.
+# Tips between the platform specific tags are shown only on those platforms.
+# Do not escape characters or use the CDATA tag.
+<tips>
+ <tip>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</tip>
+ <tip>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</tip>
+ <tip>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</tip>
+ <tip>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground or miss a shot you'll reuse your rope without wasting ammo!</tip>
+ <tip>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</tip>
+ <tip>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</tip>
+ <tip>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</tip>
+ <tip>Hedgewars is free software (Open Source) we create in our spare time. If you've got problems, ask on our forums or visit our IRC room!</tip>
+ <tip>Hedgewars is free software (Open Source) we create in our spare time. If you like it, help us with a small donation or contribute your own work!</tip>
+ <tip>Hedgewars is free software (Open Source) we create in our spare time. Share it with your family and friends as you like!</tip>
+ <tip>Hedgewars is free software (Open Source) we create in our spare time, just for fun! Meet the devs in <a href="irc://irc.freenode.net/hedgewars">#hedgewars</a>!</tip>
+ <tip>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</tip>
+ <tip>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</tip>
+ <tip>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and GNU/Linux.</tip>
+ <tip>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</tip>
+ <tip>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</tip>
+ <tip>Create an account on <a href="http://www.hedgewars.org/">http://www.hedgewars.org/</a> to keep others from using your most favourite nickname while playing on the official server.</tip>
+ <tip>While playing you should give yourself a short break at least once an hour.</tip>
+ <tip>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</tip>
+ <tip>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</tip>
+ <tip>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</tip>
+ <tip>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</tip>
+ <tip>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</tip>
+ <tip>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</tip>
+ <tip>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</tip>
+ <tip>No hedgehogs were harmed in making this game.</tip>
+ <tip>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</tip>
+ <tip>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</tip>
+ <tip>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</tip>
+ <tip>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</tip>
+ <tip>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</tip>
+ <tip>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</tip>
+ <tip>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</tip>
+ <tip>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</tip>
+ <tip>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</tip>
+ <tip>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</tip>
+ <tip>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</tip>
+ <tip>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</tip>
+ <tip>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</tip>
+ <tip>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</tip>
+ <tip>Like Hedgewars? Become a fan on <a href="http://www.facebook.com/Hedgewars">Facebook</a> or follow us on <a href="http://twitter.com/hedgewars">Twitter</a></tip>
+ <tip>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</tip>
+ <tip>Keep your video card drivers up to date to avoid issues playing the game.</tip>
+ <tip>Heads or tails? Type '/rnd' in lobby and you'll find out. Also '/rnd rock paper scissors' works!</tip>
+ <tip>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</tip>
+ <windows-only>
+ <tip>The version of Hedgewars supports <a href="http://www.xfire.com">Xfire</a>. Make sure to add Hedgewars to its game list so your friends can see you playing.</tip>
+ <tip>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</tip>
+ </windows-only>
+ <mac-only>
+ <tip>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</tip>
+ </mac-only>
+ <linux-only>
+ <tip>lintip</tip>
+ <tip>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</tip>
+ </linux-only>
+</tips>
diff --git a/QTfrontend/sdlkeys.h b/QTfrontend/sdlkeys.h
index 79dd65f..7141926 100644
--- a/QTfrontend/sdlkeys.h
+++ b/QTfrontend/sdlkeys.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/servermessages.h b/QTfrontend/servermessages.h
new file mode 100644
index 0000000..a93e011
--- /dev/null
+++ b/QTfrontend/servermessages.h
@@ -0,0 +1,30 @@
+const char * serverMessages[] = {
+QT_TRANSLATE_NOOP("server", "Nickname already chosen"),
+QT_TRANSLATE_NOOP("server", "Illegal nickname"),
+QT_TRANSLATE_NOOP("server", "Protocol already known"),
+QT_TRANSLATE_NOOP("server", "Bad number"),
+QT_TRANSLATE_NOOP("server", "Nickname is already in use"),
+QT_TRANSLATE_NOOP("server", "No checker rights"),
+QT_TRANSLATE_NOOP("server", "Authentication failed"),
+QT_TRANSLATE_NOOP("server", "60 seconds cooldown after kick"),
+QT_TRANSLATE_NOOP("server", "kicked"),
+QT_TRANSLATE_NOOP("server", "Ping timeout"),
+QT_TRANSLATE_NOOP("server", "Empty config entry"),
+QT_TRANSLATE_NOOP("server", "Not room master"),
+QT_TRANSLATE_NOOP("server", "Corrupted hedgehogs info"),
+QT_TRANSLATE_NOOP("server", "too many teams"),
+QT_TRANSLATE_NOOP("server", "too many hedgehogs"),
+QT_TRANSLATE_NOOP("server", "There's already a team with same name in the list"),
+QT_TRANSLATE_NOOP("server", "round in progress"),
+QT_TRANSLATE_NOOP("server", "restricted"),
+QT_TRANSLATE_NOOP("server", "REMOVE_TEAM: no such team"),
+QT_TRANSLATE_NOOP("server", "Not team owner!"),
+QT_TRANSLATE_NOOP("server", "Less than two clans!"),
+QT_TRANSLATE_NOOP("server", "Room with such name already exists"),
+QT_TRANSLATE_NOOP("server", "Illegal room name"),
+QT_TRANSLATE_NOOP("server", "No such room"),
+QT_TRANSLATE_NOOP("server", "Joining restricted"),
+QT_TRANSLATE_NOOP("server", "Registered users only"),
+QT_TRANSLATE_NOOP("server", "You are banned in this room"),
+QT_TRANSLATE_NOOP("server", "bye")
+};
diff --git a/QTfrontend/team.cpp b/QTfrontend/team.cpp
index b16880a..0f23e5d 100644
--- a/QTfrontend/team.cpp
+++ b/QTfrontend/team.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,10 +23,12 @@
#include <QCryptographicHash>
#include <QSettings>
#include <QStandardItemModel>
+#include <QDebug>
#include "team.h"
#include "hwform.h"
#include "DataManager.h"
+#include "gameuiconfig.h"
HWTeam::HWTeam(const QString & teamname) :
QObject(0)
@@ -50,7 +52,7 @@ HWTeam::HWTeam(const QString & teamname) :
{
m_binds.append(BindAction());
m_binds[i].action = cbinds[i].action;
- m_binds[i].strbind = cbinds[i].strbind;
+ m_binds[i].strbind = QString();
}
m_rounds = 0;
m_wins = 0;
@@ -110,7 +112,7 @@ HWTeam::HWTeam() :
{
m_binds.append(BindAction());
m_binds[i].action = cbinds[i].action;
- m_binds[i].strbind = cbinds[i].strbind;
+ m_binds[i].strbind = QString();
}
m_rounds = 0;
m_wins = 0;
@@ -169,7 +171,7 @@ HWTeam & HWTeam::operator = (const HWTeam & other)
bool HWTeam::loadFromFile()
{
- QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + m_name + ".hwt", QSettings::IniFormat, 0);
+ QSettings teamfile(QString("physfs://Teams/%1.hwt").arg(m_name), QSettings::IniFormat, 0);
teamfile.setIniCodec("UTF-8");
m_name = teamfile.value("Team/Name", m_name).toString();
m_grave = teamfile.value("Team/Grave", "Statue").toString();
@@ -191,7 +193,7 @@ bool HWTeam::loadFromFile()
m_hedgehogs[i].Suicides = teamfile.value(hh + "Suicides", 0).toInt();
}
for(int i = 0; i < BINDS_NUMBER; i++)
- m_binds[i].strbind = teamfile.value(QString("Binds/%1").arg(m_binds[i].action), cbinds[i].strbind).toString();
+ m_binds[i].strbind = teamfile.value(QString("Binds/%1").arg(m_binds[i].action), QString()).toString();
for(int i = 0; i < MAX_ACHIEVEMENTS; i++)
if(achievements[i][0][0])
AchievementProgress[i] = teamfile.value(QString("Achievements/%1").arg(achievements[i][0]), 0).toUInt();
@@ -202,7 +204,7 @@ bool HWTeam::loadFromFile()
bool HWTeam::fileExists()
{
- QFile f(cfgdir->absolutePath() + "/Teams/" + m_name + ".hwt");
+ QFile f(QString("physfs://Teams/%1.hwt").arg(m_name));
return f.exists();
}
@@ -210,7 +212,7 @@ bool HWTeam::deleteFile()
{
if(m_isNetTeam)
return false;
- QFile cfgfile(cfgdir->absolutePath() + "/Teams/" + m_name + ".hwt");
+ QFile cfgfile(QString("physfs://Teams/%1.hwt").arg(m_name));
cfgfile.remove();
return true;
}
@@ -219,11 +221,14 @@ bool HWTeam::saveToFile()
{
if (OldTeamName != m_name)
{
- QFile cfgfile(cfgdir->absolutePath() + "/Teams/" + OldTeamName + ".hwt");
+ QFile cfgfile(QString("physfs://Teams/%1.hwt").arg(OldTeamName));
cfgfile.remove();
OldTeamName = m_name;
}
- QSettings teamfile(cfgdir->absolutePath() + "/Teams/" + m_name + ".hwt", QSettings::IniFormat, 0);
+
+ QString fileName = QString("physfs://Teams/%1.hwt").arg(m_name);
+ DataManager::ensureFileExists(fileName);
+ QSettings teamfile(fileName, QSettings::IniFormat, 0);
teamfile.setIniCodec("UTF-8");
teamfile.setValue("Team/Name", m_name);
teamfile.setValue("Team/Grave", m_grave);
@@ -234,6 +239,7 @@ bool HWTeam::saveToFile()
teamfile.setValue("Team/Rounds", m_rounds);
teamfile.setValue("Team/Wins", m_wins);
teamfile.setValue("Team/CampaignProgress", m_campaignProgress);
+
for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
{
QString hh = QString("Hedgehog%1/").arg(i);
@@ -251,10 +257,11 @@ bool HWTeam::saveToFile()
teamfile.setValue(QString("Achievements/%1").arg(achievements[i][0]), AchievementProgress[i]);
else
break;
+
return true;
}
-QStringList HWTeam::teamGameConfig(quint32 InitHealth) const
+QStringList HWTeam::teamGameConfig(quint32 InitHealth, GameUIConfig * config) const
{
QStringList sl;
if (m_isNetTeam)
@@ -270,9 +277,15 @@ QStringList HWTeam::teamGameConfig(quint32 InitHealth) const
sl.push_back(QString("eflag " + m_flag));
if (!m_isNetTeam)
+ {
for(int i = 0; i < BINDS_NUMBER; i++)
- if(!m_binds[i].strbind.isEmpty())
+ {
+ if(m_binds[i].strbind.isEmpty() || m_binds[i].strbind == "default")
+ sl.push_back(QString("ebind " + config->bind(i) + " " + m_binds[i].action));
+ else
sl.push_back(QString("ebind " + m_binds[i].strbind + " " + m_binds[i].action));
+ }
+ }
for (int t = 0; t < m_numHedgehogs; t++)
{
diff --git a/QTfrontend/team.h b/QTfrontend/team.h
index 8ef848f..31ea19d 100644
--- a/QTfrontend/team.h
+++ b/QTfrontend/team.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
* Copyright (c) 2007 Igor Ulyanov <iulyanov at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -93,7 +93,7 @@ class HWTeam : public QObject
void incWins();
// convert team info into strings for further computation
- QStringList teamGameConfig(quint32 InitHealth) const;
+ QStringList teamGameConfig(quint32 InitHealth, GameUIConfig * config) const;
// comparison operators
bool operator == (const HWTeam& t1) const;
diff --git a/QTfrontend/ui/dialog/ask_quit.cpp b/QTfrontend/ui/dialog/ask_quit.cpp
index 80f4010..5055a7b 100644
--- a/QTfrontend/ui/dialog/ask_quit.cpp
+++ b/QTfrontend/ui/dialog/ask_quit.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/dialog/ask_quit.h b/QTfrontend/ui/dialog/ask_quit.h
index 856b9d5..3f1b457 100644
--- a/QTfrontend/ui/dialog/ask_quit.h
+++ b/QTfrontend/ui/dialog/ask_quit.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/dialog/bandialog.cpp b/QTfrontend/ui/dialog/bandialog.cpp
new file mode 100644
index 0000000..b3a8806
--- /dev/null
+++ b/QTfrontend/ui/dialog/bandialog.cpp
@@ -0,0 +1,89 @@
+#include <QFormLayout>
+#include <QComboBox>
+#include <QRadioButton>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPushButton>
+#include <QHBoxLayout>
+#include <QMessageBox>
+#include "HWApplication.h"
+
+#include "bandialog.h"
+
+BanDialog::BanDialog(QWidget *parent) :
+ QDialog(parent)
+{
+ QFormLayout * formLayout = new QFormLayout(this);
+
+ rbIP = new QRadioButton(this);
+ rbIP->setChecked(true);
+ rbNick = new QRadioButton(this);
+ leId = new QLineEdit(this);
+ leReason = new QLineEdit(this);
+ cbTime = new QComboBox(this);
+
+ cbTime->addItem(HWApplication::tr("%1 minutes", 0, 10).arg("10"), 5 * 60);
+ cbTime->addItem(HWApplication::tr("%1 minutes", 0, 30).arg("30"), 10 * 60);
+ cbTime->addItem(HWApplication::tr("%1 hour", 0, 10).arg("10"), 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 hours", 0, 3).arg("3"), 3 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 hours", 0, 5).arg("5"), 5 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 hours", 0, 12).arg("12"), 12 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 day", 0, 1).arg("1"), 24 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 days", 0, 3).arg("3"), 72 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 days", 0, 7).arg("7"), 168 * 60 * 60);
+ cbTime->addItem(HWApplication::tr("%1 days", 0, 14).arg("14"), 336 * 60 * 60);
+ cbTime->addItem(tr("permanent"), 3650 * 24 * 60 * 60);
+ cbTime->setCurrentIndex(0);
+
+ formLayout->addRow(tr("IP"), rbIP);
+ formLayout->addRow(tr("Nick"), rbNick);
+ formLayout->addRow(tr("IP/Nick"), leId);
+ formLayout->addRow(tr("Reason"), leReason);
+ formLayout->addRow(tr("Duration"), cbTime);
+
+ formLayout->setLabelAlignment(Qt::AlignRight);
+
+ QHBoxLayout * hbox = new QHBoxLayout();
+ formLayout->addRow(hbox);
+ QPushButton * btnOk = new QPushButton(tr("Ok"), this);
+ QPushButton * btnCancel = new QPushButton(tr("Cancel"), this);
+ hbox->addStretch();
+ hbox->addWidget(btnOk);
+ hbox->addWidget(btnCancel);
+
+ connect(btnOk, SIGNAL(clicked()), this, SLOT(okClicked()));
+ connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+ this->setWindowModality(Qt::WindowModal);
+}
+
+bool BanDialog::byIP()
+{
+ return rbIP->isChecked();
+}
+
+int BanDialog::duration()
+{
+ return cbTime->itemData(cbTime->currentIndex()).toInt();
+}
+
+QString BanDialog::banId()
+{
+ return leId->text();
+}
+
+QString BanDialog::reason()
+{
+ return leReason->text().isEmpty() ? tr("you know why") : leReason->text();
+}
+
+void BanDialog::okClicked()
+{
+ if(leId->text().isEmpty())
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("Please, specify %1").arg(byIP() ? tr("IP") : tr("nickname")));
+ return;
+ }
+
+ accept();
+}
diff --git a/QTfrontend/ui/dialog/bandialog.h b/QTfrontend/ui/dialog/bandialog.h
new file mode 100644
index 0000000..28781bf
--- /dev/null
+++ b/QTfrontend/ui/dialog/bandialog.h
@@ -0,0 +1,32 @@
+#ifndef BANDIALOG_H
+#define BANDIALOG_H
+
+#include <QDialog>
+
+class QComboBox;
+class QRadioButton;
+class QLineEdit;
+
+class BanDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit BanDialog(QWidget *parent = 0);
+
+ bool byIP();
+ int duration();
+ QString banId();
+ QString reason();
+
+private:
+ QRadioButton * rbIP;
+ QRadioButton * rbNick;
+ QLineEdit * leId;
+ QLineEdit * leReason;
+ QComboBox * cbTime;
+
+private slots:
+ void okClicked();
+};
+
+#endif // BANDIALOG_H
diff --git a/QTfrontend/ui/dialog/input_ip.cpp b/QTfrontend/ui/dialog/input_ip.cpp
index aacb01e..82d4575 100644
--- a/QTfrontend/ui/dialog/input_ip.cpp
+++ b/QTfrontend/ui/dialog/input_ip.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
#include <QLabel>
#include "input_ip.h"
+#include "hwconsts.h"
HWHostPortDialog::HWHostPortDialog(QWidget* parent) : QDialog(parent)
{
@@ -66,5 +67,5 @@ HWHostPortDialog::HWHostPortDialog(QWidget* parent) : QDialog(parent)
void HWHostPortDialog::setDefaultPort()
{
- sbPort->setValue(46631);
+ sbPort->setValue(NETGAME_DEFAULT_PORT);
}
diff --git a/QTfrontend/ui/dialog/input_ip.h b/QTfrontend/ui/dialog/input_ip.h
index 9e1eaac..fc5a598 100644
--- a/QTfrontend/ui/dialog/input_ip.h
+++ b/QTfrontend/ui/dialog/input_ip.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/dialog/input_password.cpp b/QTfrontend/ui/dialog/input_password.cpp
index 2eafcc0..e1db73e 100644
--- a/QTfrontend/ui/dialog/input_password.cpp
+++ b/QTfrontend/ui/dialog/input_password.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,28 +25,41 @@
#include "input_password.h"
-HWPasswordDialog::HWPasswordDialog(QWidget* parent, const QString & label) : QDialog(parent)
+HWPasswordDialog::HWPasswordDialog(QWidget* parent) : QDialog(parent)
{
- setWindowTitle(tr("Password"));
+ setWindowTitle(tr("Login"));
QGridLayout * layout = new QGridLayout(this);
- QLabel * lbLabel = new QLabel(this);
- lbLabel->setText(label);
- layout->addWidget(lbLabel, 0, 0);
+ QLabel * titleLabel = new QLabel(this);
+ titleLabel->setText(tr("To connect to the server, please log in.\n\nIf you don't have an account on www.hedgewars.org,\njust enter your nickname."));
+ layout->addWidget(titleLabel, 0, 0);
+
+ QLabel * nickLabel = new QLabel(this);
+ nickLabel->setText(tr("Nickname:"));
+ layout->addWidget(nickLabel, 1, 0);
+
+ leNickname = new QLineEdit(this);
+ leNickname->setEchoMode(QLineEdit::Normal);
+ layout->addWidget(leNickname, 2, 0);
+
+ QLabel * passLabel = new QLabel(this);
+ passLabel->setText(tr("Password:"));
+ layout->addWidget(passLabel, 3, 0);
lePassword = new QLineEdit(this);
lePassword->setEchoMode(QLineEdit::Password);
- layout->addWidget(lePassword, 1, 0);
+ layout->addWidget(lePassword, 4, 0);
cbSave = new QCheckBox(this);
cbSave->setText(QCheckBox::tr("Save password"));
- layout->addWidget(cbSave, 2, 0);
+ layout->addWidget(cbSave, 5, 0);
QDialogButtonBox* dbbButtons = new QDialogButtonBox(this);
+ pbNewAccount = dbbButtons->addButton(QString("New Account"), QDialogButtonBox::ActionRole);
QPushButton * pbOK = dbbButtons->addButton(QDialogButtonBox::Ok);
QPushButton * pbCancel = dbbButtons->addButton(QDialogButtonBox::Cancel);
- layout->addWidget(dbbButtons, 3, 0);
+ layout->addWidget(dbbButtons, 6, 0);
connect(pbOK, SIGNAL(clicked()), this, SLOT(accept()));
connect(pbCancel, SIGNAL(clicked()), this, SLOT(reject()));
diff --git a/QTfrontend/ui/dialog/input_password.h b/QTfrontend/ui/dialog/input_password.h
index 70db544..59ce4d6 100644
--- a/QTfrontend/ui/dialog/input_password.h
+++ b/QTfrontend/ui/dialog/input_password.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,15 +23,18 @@
class QLineEdit;
class QCheckBox;
+class QPushButton;
class HWPasswordDialog : public QDialog
{
Q_OBJECT
public:
- HWPasswordDialog(QWidget* parent, const QString & label);
+ HWPasswordDialog(QWidget* parent);
QLineEdit* lePassword;
+ QLineEdit* leNickname;
QCheckBox* cbSave;
+ QPushButton * pbNewAccount;
};
diff --git a/QTfrontend/ui/dialog/upload_video.cpp b/QTfrontend/ui/dialog/upload_video.cpp
index eaa40bd..e3f0a2e 100644
--- a/QTfrontend/ui/dialog/upload_video.cpp
+++ b/QTfrontend/ui/dialog/upload_video.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/dialog/upload_video.h b/QTfrontend/ui/dialog/upload_video.h
index 8803f1c..fd5eee7 100644
--- a/QTfrontend/ui/dialog/upload_video.h
+++ b/QTfrontend/ui/dialog/upload_video.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/mouseoverfilter.cpp b/QTfrontend/ui/mouseoverfilter.cpp
index 03c0277..41d9ec0 100644
--- a/QTfrontend/ui/mouseoverfilter.cpp
+++ b/QTfrontend/ui/mouseoverfilter.cpp
@@ -5,6 +5,7 @@
#include <QLabel>
#include <QLineEdit>
#include <QCheckBox>
+#include <QListView>
#include "mouseoverfilter.h"
#include "ui/page/AbstractPage.h"
@@ -31,6 +32,10 @@ bool MouseOverFilter::eventFilter( QObject *dist, QEvent *event )
abstractpage->setButtonDescription(widget->whatsThis());
else if (widget->toolTip() != NULL)
abstractpage->setButtonDescription(widget->toolTip());
+ }
+ else if (event->type() == QEvent::FocusIn)
+ {
+ abstractpage = qobject_cast<AbstractPage*>(ui->Pages->currentWidget());
// play a sound when mouse hovers certain ui elements
QPushButton * button = dynamic_cast<QPushButton*>(dist);
@@ -39,10 +44,10 @@ bool MouseOverFilter::eventFilter( QObject *dist, QEvent *event )
QComboBox * droplist = dynamic_cast<QComboBox*>(dist);
QSlider * slider = dynamic_cast<QSlider*>(dist);
QTabWidget * tab = dynamic_cast<QTabWidget*>(dist);
- if (HWForm::config->isFrontendSoundEnabled() && (button || textfield || checkbox || droplist || slider || tab))
+ QListView * listview = dynamic_cast<QListView*>(dist);
+ if (button || textfield || checkbox || droplist || slider || tab || listview)
{
- DataManager & dataMgr = DataManager::instance();
- SDLInteraction::instance().playSoundFile(dataMgr.findFileForRead("Sounds/steps.ogg"));
+ SDLInteraction::instance().playSoundFile("/Sounds/steps.ogg");
}
return true;
@@ -51,9 +56,9 @@ bool MouseOverFilter::eventFilter( QObject *dist, QEvent *event )
{
abstractpage = qobject_cast<AbstractPage*>(ui->Pages->currentWidget());
- if (abstractpage->getDefautDescription() != NULL)
+ if (abstractpage->getDefaultDescription() != NULL)
{
- abstractpage->setButtonDescription( * abstractpage->getDefautDescription());
+ abstractpage->setButtonDescription( * abstractpage->getDefaultDescription());
}
else
abstractpage->setButtonDescription("");
diff --git a/QTfrontend/ui/page/AbstractPage.cpp b/QTfrontend/ui/page/AbstractPage.cpp
index b19ffbe..464eeb6 100644
--- a/QTfrontend/ui/page/AbstractPage.cpp
+++ b/QTfrontend/ui/page/AbstractPage.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include <QLabel>
#include <QSize>
#include <QFontMetricsF>
+#include <QDebug>
#include "qpushbuttonwithsound.h"
@@ -39,27 +40,36 @@ AbstractPage::AbstractPage(QWidget* parent)
void AbstractPage::initPage()
{
QGridLayout * pageLayout = new QGridLayout(this);
+ QHBoxLayout * bottomLeftLayout = new QHBoxLayout();
+ pageLayout->addLayout(bottomLeftLayout, 1, 0);
// stretch grid space for body and footer
- pageLayout->setColumnStretch(0,0);
- pageLayout->setColumnStretch(1,1);
+ pageLayout->setColumnStretch(0,1);
+ pageLayout->setColumnStretch(1,2);
+ pageLayout->setColumnStretch(2,1);
pageLayout->setRowStretch(0,1);
pageLayout->setRowStretch(1,0);
// add back/exit button
btnBack = formattedButton(":/res/Exit.png", true);
btnBack->setWhatsThis(tr("Go back"));
- pageLayout->addWidget(btnBack, 1, 0, 1, 1, Qt::AlignLeft | Qt::AlignBottom);
+ bottomLeftLayout->addWidget(btnBack, 0, Qt::AlignBottom);
// add body layout as defined by the subclass
pageLayout->addLayout(bodyLayoutDefinition(), 0, 0, 1, 3);
+ // add left footer layout
+ QLayout * flld = footerLayoutLeftDefinition();
+ if (flld != NULL)
+ bottomLeftLayout->addLayout(flld, 0);
+
descLabel = new QLabel();
descLabel->setAlignment(Qt::AlignCenter);
descLabel->setWordWrap(true);
descLabel->setOpenExternalLinks(true);
descLabel->setFixedHeight(50);
descLabel->setStyleSheet("font-size: 16px");
+ bottomLeftLayout->addWidget(descLabel);
pageLayout->addWidget(descLabel, 1, 1);
// add footer layout
@@ -67,6 +77,8 @@ void AbstractPage::initPage()
if (fld != NULL)
pageLayout->addLayout(fld, 1, 2);
+ bottomLeftLayout->addStretch(1);
+
// connect signals
connect(btnBack, SIGNAL(clicked()), this, SIGNAL(goBack()));
connectSignals();
@@ -146,13 +158,23 @@ void AbstractPage::setButtonDescription(QString desc)
descLabel->setText(desc);
}
-void AbstractPage::setDefautDescription(QString text)
+void AbstractPage::setDefaultDescription(QString text)
{
*defautDesc = text;
descLabel->setText(text);
}
-QString * AbstractPage::getDefautDescription()
+QString * AbstractPage::getDefaultDescription()
{
return defautDesc;
}
+
+void AbstractPage::triggerPageEnter()
+{
+ emit pageEnter();
+}
+
+void AbstractPage::triggerPageLeave()
+{
+ emit pageLeave();
+}
diff --git a/QTfrontend/ui/page/AbstractPage.h b/QTfrontend/ui/page/AbstractPage.h
index a9d1566..5ce203e 100644
--- a/QTfrontend/ui/page/AbstractPage.h
+++ b/QTfrontend/ui/page/AbstractPage.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -70,20 +70,43 @@ class AbstractPage : public QWidget
*
* @param text the defaut desc
*/
- void setDefautDescription(QString text);
+ void setDefaultDescription(QString text);
/**
* @brief Get the desc defaut text
*/
- QString * getDefautDescription();
+ QString * getDefaultDescription();
signals:
+
/**
* @brief This signal is emitted when going back to the previous is
* requested - e.g. when the back-button is clicked.
*/
void goBack();
+ /**
+ * @brief This signal is emitted when the page is displayed
+ */
+ void pageEnter();
+
+ /**
+ * @brief This signal is emitted when this page is left
+ */
+ void pageLeave();
+
+ public slots:
+
+ /**
+ * @brief This slot is called to trigger this page's pageEnter signal
+ */
+ void triggerPageEnter();
+
+ /**
+ * @brief This slot is called to trigger this page's pageLeave signal
+ */
+ void triggerPageLeave();
+
protected:
/**
* @brief Class constructor
@@ -121,6 +144,17 @@ class AbstractPage : public QWidget
* @brief Used during page construction.
* You can implement this method in your subclass.
*
+ * Use it to define layout (not behavior) of the page's footer to the left of the help text.
+ */
+ virtual QLayout * footerLayoutLeftDefinition()
+ {
+ return NULL;
+ };
+
+ /**
+ * @brief Used during page construction.
+ * You can implement this method in your subclass.
+ *
* This is a good place to connect signals within your page in order
* to get the desired page behavior.<br />
* Keep in mind not to expose twidgets as public!
diff --git a/QTfrontend/ui/page/pageadmin.cpp b/QTfrontend/ui/page/pageadmin.cpp
index c3cd710..83e87e3 100644
--- a/QTfrontend/ui/page/pageadmin.cpp
+++ b/QTfrontend/ui/page/pageadmin.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,56 +22,98 @@
#include <QSpinBox>
#include <QPushButton>
#include <QTextBrowser>
+#include <QTableWidget>
+#include <QHeaderView>
#include "pageadmin.h"
#include "chatwidget.h"
+#include "bandialog.h"
QLayout * PageAdmin::bodyLayoutDefinition()
{
- QGridLayout * pageLayout = new QGridLayout();
-
- // 0
- pbAsk = addButton(tr("Fetch data"), pageLayout, 0, 0, 1, 3);
-
- // 1
- QLabel * lblSMN = new QLabel(this);
- lblSMN->setText(tr("Server message for latest version:"));
- pageLayout->addWidget(lblSMN, 1, 0);
-
- leServerMessageNew = new QLineEdit(this);
- pageLayout->addWidget(leServerMessageNew, 1, 1);
-
- // 2
- QLabel * lblSMO = new QLabel(this);
- lblSMO->setText(tr("Server message for previous versions:"));
- pageLayout->addWidget(lblSMO, 2, 0);
-
- leServerMessageOld = new QLineEdit(this);
- pageLayout->addWidget(leServerMessageOld, 2, 1);
-
- // 3
- QLabel * lblP = new QLabel(this);
- lblP->setText(tr("Latest version protocol number:"));
- pageLayout->addWidget(lblP, 3, 0);
-
- sbProtocol = new QSpinBox(this);
- pageLayout->addWidget(sbProtocol, 3, 1);
-
- // 4
- QLabel * lblPreview = new QLabel(this);
- lblPreview->setText(tr("MOTD preview:"));
- pageLayout->addWidget(lblPreview, 4, 0);
-
- tb = new QTextBrowser(this);
- tb->setOpenExternalLinks(true);
- tb->document()->setDefaultStyleSheet(HWChatWidget::styleSheet());
- pageLayout->addWidget(tb, 4, 1, 1, 2);
-
- // 5
- pbClearAccountsCache = addButton(tr("Clear Accounts Cache"), pageLayout, 5, 0);
-
- // 6
- pbSetSM = addButton(tr("Set data"), pageLayout, 6, 0, 1, 3);
+ QVBoxLayout * pageLayout = new QVBoxLayout();
+
+ QTabWidget * tabs = new QTabWidget(this);
+ pageLayout->addWidget(tabs);
+ QWidget * page1 = new QWidget(this);
+ QWidget * page2 = new QWidget(this);
+ tabs->addTab(page1, tr("General"));
+ tabs->addTab(page2, tr("Bans"));
+
+ // page 1
+ {
+ QGridLayout * tab1Layout = new QGridLayout(page1);
+
+ // 0
+ pbAsk = addButton(tr("Fetch data"), tab1Layout, 0, 0, 1, 3);
+
+ // 1
+ QLabel * lblSMN = new QLabel(this);
+ lblSMN->setText(tr("Server message for latest version:"));
+ tab1Layout->addWidget(lblSMN, 1, 0);
+
+ leServerMessageNew = new QLineEdit(this);
+ tab1Layout->addWidget(leServerMessageNew, 1, 1);
+
+ // 2
+ QLabel * lblSMO = new QLabel(this);
+ lblSMO->setText(tr("Server message for previous versions:"));
+ tab1Layout->addWidget(lblSMO, 2, 0);
+
+ leServerMessageOld = new QLineEdit(this);
+ tab1Layout->addWidget(leServerMessageOld, 2, 1);
+
+ // 3
+ QLabel * lblP = new QLabel(this);
+ lblP->setText(tr("Latest version protocol number:"));
+ tab1Layout->addWidget(lblP, 3, 0);
+
+ sbProtocol = new QSpinBox(this);
+ tab1Layout->addWidget(sbProtocol, 3, 1);
+
+ // 4
+ QLabel * lblPreview = new QLabel(this);
+ lblPreview->setText(tr("MOTD preview:"));
+ tab1Layout->addWidget(lblPreview, 4, 0);
+
+ tb = new QTextBrowser(this);
+ tb->setOpenExternalLinks(true);
+ tb->document()->setDefaultStyleSheet(HWChatWidget::styleSheet());
+ tab1Layout->addWidget(tb, 4, 1, 1, 2);
+
+ // 5
+ pbClearAccountsCache = addButton(tr("Clear Accounts Cache"), tab1Layout, 5, 0);
+
+ // 6
+ pbSetSM = addButton(tr("Set data"), tab1Layout, 6, 0, 1, 3);
+ }
+
+ // page 2
+ {
+ QGridLayout * tab2Layout = new QGridLayout(page2);
+ twBans = new QTableWidget(this);
+ twBans->setColumnCount(3);
+ twBans->setHorizontalHeaderLabels(QStringList()
+ << tr("IP/Nick")
+ << tr("Expiration")
+ << tr("Reason")
+ );
+ twBans->horizontalHeader()->setResizeMode(2, QHeaderView::Stretch);
+ twBans->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ twBans->setSelectionBehavior(QAbstractItemView::SelectRows);
+ twBans->setSelectionMode(QAbstractItemView::SingleSelection);
+ twBans->setAlternatingRowColors(true);
+ tab2Layout->addWidget(twBans, 0, 1, 4, 1);
+
+ QPushButton * btnRefresh = addButton(tr("Refresh"), tab2Layout, 0, 0);
+ QPushButton * btnAdd = addButton(tr("Add"), tab2Layout, 1, 0);
+ QPushButton * btnRemove = addButton(tr("Remove"), tab2Layout, 2, 0);
+
+ connect(btnRefresh, SIGNAL(clicked()), this, SIGNAL(bansListRequest()));
+ connect(btnRefresh, SIGNAL(clicked()), this, SLOT(onRefreshClicked()));
+ connect(btnAdd, SIGNAL(clicked()), this, SLOT(onAddClicked()));
+ connect(btnRemove, SIGNAL(clicked()), this, SLOT(onRemoveClicked()));
+ }
return pageLayout;
}
@@ -106,7 +148,64 @@ void PageAdmin::serverMessageOld(const QString & str)
{
leServerMessageOld->setText(str);
}
+
void PageAdmin::protocol(int proto)
{
sbProtocol->setValue(proto);
}
+
+void PageAdmin::onAddClicked()
+{
+ BanDialog dialog(this);
+
+ if(dialog.exec())
+ {
+ if(dialog.byIP())
+ {
+ emit banIP(dialog.banId(), dialog.reason(), dialog.duration());
+ } else
+ {
+ emit banNick(dialog.banId(), dialog.reason(), dialog.duration());
+ }
+
+ emit bansListRequest();
+ }
+}
+
+void PageAdmin::onRemoveClicked()
+{
+ QList<QTableWidgetItem *> sel = twBans->selectedItems();
+
+ if(sel.size())
+ {
+ emit removeBan(twBans->item(sel[0]->row(), 0)->data(Qt::DisplayRole).toString());
+ emit bansListRequest();
+ }
+}
+
+void PageAdmin::setBansList(const QStringList & bans)
+{
+ if(bans.size() % 4)
+ return;
+
+ twBans->setRowCount(bans.size() / 4);
+
+ for(int i = 0; i < bans.size(); i += 4)
+ {
+ if(!twBans->item(i / 4, 0))
+ {
+ twBans->setItem(i / 4, 0, new QTableWidgetItem());
+ twBans->setItem(i / 4, 1, new QTableWidgetItem());
+ twBans->setItem(i / 4, 2, new QTableWidgetItem());
+ }
+
+ twBans->item(i / 4, 0)->setData(Qt::DisplayRole, bans[i + 1]);
+ twBans->item(i / 4, 1)->setData(Qt::DisplayRole, bans[i + 3]);
+ twBans->item(i / 4, 2)->setData(Qt::DisplayRole, bans[i + 2]);
+ }
+}
+
+void PageAdmin::onRefreshClicked()
+{
+ twBans->setRowCount(0);
+}
diff --git a/QTfrontend/ui/page/pageadmin.h b/QTfrontend/ui/page/pageadmin.h
index 28e52c6..eef80c9 100644
--- a/QTfrontend/ui/page/pageadmin.h
+++ b/QTfrontend/ui/page/pageadmin.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,6 +21,8 @@
#include "AbstractPage.h"
+class QTableWidget;
+
class PageAdmin : public AbstractPage
{
Q_OBJECT
@@ -32,6 +34,7 @@ class PageAdmin : public AbstractPage
void serverMessageNew(const QString & str);
void serverMessageOld(const QString & str);
void protocol(int proto);
+ void setBansList(const QStringList & bans);
signals:
void setServerMessageNew(const QString & str);
@@ -39,6 +42,10 @@ class PageAdmin : public AbstractPage
void setProtocol(int proto);
void askServerVars();
void clearAccountsCache();
+ void bansListRequest();
+ void removeBan(const QString &);
+ void banIP(const QString & ip, const QString & reason, int seconds);
+ void banNick(const QString & nick, const QString & reason, int seconds);
protected:
QLayout * bodyLayoutDefinition();
@@ -52,9 +59,13 @@ class PageAdmin : public AbstractPage
QSpinBox * sbProtocol;
QTextBrowser * tb;
QPushButton * pbClearAccountsCache;
+ QTableWidget * twBans;
private slots:
void smChanged();
+ void onAddClicked();
+ void onRemoveClicked();
+ void onRefreshClicked();
};
#endif
diff --git a/QTfrontend/ui/page/pagecampaign.cpp b/QTfrontend/ui/page/pagecampaign.cpp
index eb7192a..41c03b3 100644
--- a/QTfrontend/ui/page/pagecampaign.cpp
+++ b/QTfrontend/ui/page/pagecampaign.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagecampaign.h b/QTfrontend/ui/page/pagecampaign.h
index c12551f..9c58ea3 100644
--- a/QTfrontend/ui/page/pagecampaign.h
+++ b/QTfrontend/ui/page/pagecampaign.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageconnecting.cpp b/QTfrontend/ui/page/pageconnecting.cpp
index d82f45d..178aca3 100644
--- a/QTfrontend/ui/page/pageconnecting.cpp
+++ b/QTfrontend/ui/page/pageconnecting.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageconnecting.h b/QTfrontend/ui/page/pageconnecting.h
index 3eb445d..cbfb91c 100644
--- a/QTfrontend/ui/page/pageconnecting.h
+++ b/QTfrontend/ui/page/pageconnecting.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagedata.cpp b/QTfrontend/ui/page/pagedata.cpp
index 4f4057e..2779356 100644
--- a/QTfrontend/ui/page/pagedata.cpp
+++ b/QTfrontend/ui/page/pagedata.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,9 +31,7 @@
#include "databrowser.h"
#include "hwconsts.h"
#include "DataManager.h"
-
-#include "quazip.h"
-#include "quazipfile.h"
+#include "FileEngine.h"
QLayout * PageDataDownload::bodyLayoutDefinition()
{
@@ -62,7 +60,10 @@ PageDataDownload::PageDataDownload(QWidget* parent) : AbstractPage(parent)
web->setOpenLinks(false);
// fetchList();
-
+ web->setHtml(QString(
+ "<center><h2>Hedgewars Downloadable Content</h2><br><br>"
+ "<i>%1</i></center>")
+ .arg(tr("Loading, please wait.")));
m_contentDownloaded = false;
}
@@ -74,7 +75,7 @@ void PageDataDownload::request(const QUrl &url)
else
finalUrl = url;
- if(url.path().endsWith(".zip"))
+ if(url.path().endsWith(".hwp") || url.path().endsWith(".zip"))
{
qWarning() << "Download Request" << url.toString();
QString fileName = QFileInfo(url.toString()).fileName();
@@ -108,8 +109,7 @@ void PageDataDownload::pageDownloaded()
{
QNetworkReply * reply = qobject_cast<QNetworkReply *>(sender());
- if(reply)
- {
+ if (reply && (reply->error() == QNetworkReply::NoError)) {
QString html = QString::fromUtf8(reply->readAll());
int begin = html.indexOf("<!-- BEGIN -->");
int end = html.indexOf("<!-- END -->");
@@ -119,7 +119,11 @@ void PageDataDownload::pageDownloaded()
html.remove(0, begin);
}
web->setHtml(html);
- }
+ } else
+ web->setHtml(QString(
+ "<center><h2>Hedgewars Downloadable Content</h2><br><br>"
+ "<p><i><h4>%1</i></h4></p></center>")
+ .arg(tr("This page requires an internet connection.")));
}
void PageDataDownload::fileDownloaded()
@@ -128,7 +132,6 @@ void PageDataDownload::fileDownloaded()
if(reply)
{
- QByteArray fileContents = reply->readAll();
QProgressBar *progressBar = progressBars.value(reply, 0);
if(progressBar)
@@ -137,7 +140,26 @@ void PageDataDownload::fileDownloaded()
progressBar->deleteLater();
}
- extractDataPack(&fileContents);
+ QDir extractDir(*cfgdir);
+ extractDir.cd("Data");
+
+ QString fileName = extractDir.filePath(QFileInfo(reply->url().path()).fileName());
+ if(fileName.endsWith(".zip"))
+ fileName = fileName.left(fileName.length() - 4) + ".hwp";
+
+ QFile out(fileName);
+ if(!out.open(QFile::WriteOnly))
+ {
+ qWarning() << "out.open():" << out.errorString();
+ return ;
+ }
+
+ out.write(reply->readAll());
+
+ out.close();
+
+ // now mount it
+ FileEngineHandler::mount(fileName);
}
}
@@ -162,83 +184,6 @@ void PageDataDownload::fetchList()
request(QUrl("http://hedgewars.org/content.html"));
}
-bool PageDataDownload::extractDataPack(QByteArray * buf)
-{
- QBuffer buffer;
- buffer.setBuffer(buf);
-
- QuaZip zip;
- zip.setIoDevice(&buffer);
- if(!zip.open(QuaZip::mdUnzip))
- {
- qWarning("testRead(): zip.open(): %d", zip.getZipError());
- return false;
- }
-
- QuaZipFile file(&zip);
-
- QDir extractDir(*cfgdir);
- extractDir.cd("Data");
-
- for(bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
- {
- if(!file.open(QIODevice::ReadOnly))
- {
- qWarning("file.open(): %d", file.getZipError());
- return false;
- }
-
-
- QString fileName = file.getActualFileName();
- QString filePath = extractDir.filePath(fileName);
- if (fileName.endsWith("/"))
- {
- QFileInfo fi(filePath);
- QDir().mkpath(fi.filePath());
- }
- else
- {
- qDebug() << "Extracting" << filePath;
- QFile out(filePath);
- if(!out.open(QFile::WriteOnly))
- {
- qWarning() << "out.open():" << out.errorString();
- return false;
- }
-
- out.write(file.readAll());
-
- out.close();
-
- if(file.getZipError() != UNZ_OK)
- {
- qWarning("file.getFileName(): %d", file.getZipError());
- return false;
- }
-
- if(!file.atEnd())
- {
- qWarning("read all but not EOF");
- return false;
- }
-
- m_contentDownloaded = true;
- }
-
- file.close();
-
- if(file.getZipError()!=UNZ_OK)
- {
- qWarning("file.close(): %d", file.getZipError());
- return false;
- }
- }
-
- zip.close();
-
- return true;
-}
-
void PageDataDownload::onPageLeave()
{
diff --git a/QTfrontend/ui/page/pagedata.h b/QTfrontend/ui/page/pagedata.h
index fd59988..317e7e4 100644
--- a/QTfrontend/ui/page/pagedata.h
+++ b/QTfrontend/ui/page/pagedata.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,8 +48,6 @@ class PageDataDownload : public AbstractPage
bool m_contentDownloaded; ///< true if something was downloaded since last page leave
- bool extractDataPack(QByteArray * buf);
-
private slots:
void request(const QUrl &url);
diff --git a/QTfrontend/ui/page/pagedrawmap.cpp b/QTfrontend/ui/page/pagedrawmap.cpp
index 86d105b..6183714 100644
--- a/QTfrontend/ui/page/pagedrawmap.cpp
+++ b/QTfrontend/ui/page/pagedrawmap.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagedrawmap.h b/QTfrontend/ui/page/pagedrawmap.h
index c971fab..6a1b355 100644
--- a/QTfrontend/ui/page/pagedrawmap.h
+++ b/QTfrontend/ui/page/pagedrawmap.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageeditteam.cpp b/QTfrontend/ui/page/pageeditteam.cpp
index 787921e..3d63ee4 100644
--- a/QTfrontend/ui/page/pageeditteam.cpp
+++ b/QTfrontend/ui/page/pageeditteam.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,25 +30,26 @@
#include <QDebug>
#include "SquareLabel.h"
#include "HWApplication.h"
+#include "keybinder.h"
#include "DataManager.h"
-#include "HatModel.h"
+#include "hatbutton.h"
#include "pageeditteam.h"
QLayout * PageEditTeam::bodyLayoutDefinition()
{
QGridLayout * pageLayout = new QGridLayout();
- QTabWidget * tbw = new QTabWidget();
+ tbw = new QTabWidget();
QWidget * page1 = new QWidget(this);
- QWidget * page2 = new QWidget(this);
+ binder = new KeyBinder(this, tr("Select an action to choose a custom key bind for this team"), tr("Use my default"), tr("Reset all binds"));
+ connect(binder, SIGNAL(resetAllBinds()), this, SLOT(resetAllBinds()));
tbw->addTab(page1, tr("General"));
- tbw->addTab(page2, tr("Advanced"));
+ tbw->addTab(binder, tr("Custom Controls"));
pageLayout->addWidget(tbw, 0, 0, 1, 3);
QHBoxLayout * page1Layout = new QHBoxLayout(page1);
page1Layout->setAlignment(Qt::AlignTop);
- QGridLayout * page2Layout = new QGridLayout(page2);
// ====== Page 1 ======
QVBoxLayout * vbox1 = new QVBoxLayout();
@@ -61,27 +62,33 @@ QLayout * PageEditTeam::bodyLayoutDefinition()
GBoxHedgehogs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QGridLayout * GBHLayout = new QGridLayout(GBoxHedgehogs);
- HatModel * hatModel = DataManager::instance().hatModel();
+
+ GBHLayout->addWidget(new QLabel(tr("Hat")), 0, 0);
+ GBHLayout->addWidget(new QLabel(tr("Name")), 0, 1);
for(int i = 0; i < HEDGEHOGS_PER_TEAM; i++)
{
- HHHats[i] = new QComboBox(GBoxHedgehogs);
- HHHats[i]->setModel(hatModel);
- HHHats[i]->setIconSize(QSize(32, 37));
- //HHHats[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
- //HHHats[i]->setModelColumn(1);
- //HHHats[i]->setMinimumWidth(132);
- GBHLayout->addWidget(HHHats[i], i, 0);
+ HHHats[i] = new HatButton(GBoxHedgehogs);
+ GBHLayout->addWidget(HHHats[i], i + 1, 0);
HHNameEdit[i] = new QLineEdit(GBoxHedgehogs);
HHNameEdit[i]->setMaxLength(64);
HHNameEdit[i]->setMinimumWidth(120);
- GBHLayout->addWidget(HHNameEdit[i], i, 1);
-
- btnRandomHogName[i] = addButton(":/res/dice.png", GBHLayout, i, 3, 1, 1, true);
+ HHNameEdit[i]->setFixedHeight(36);
+ HHNameEdit[i]->setWhatsThis(tr("This hedgehog's name"));
+ HHNameEdit[i]->setStyleSheet("padding: 6px;");
+ GBHLayout->addWidget(HHNameEdit[i], i + 1, 1);
+
+ btnRandomHogName[i] = addButton(":/res/dice.png", GBHLayout, i + 1, 3, 1, 1, true);
+ btnRandomHogName[i]->setFixedHeight(HHNameEdit[i]->height());
+ btnRandomHogName[i]->setWhatsThis(tr("Randomize this hedgehog's name"));
}
- btnRandomTeam = addButton(QPushButton::tr("Random Team"), GBHLayout, 9, 0);
+ btnRandomTeam = new QPushButton();
+ btnRandomTeam->setText(tr("Random Team"));
+ btnRandomTeam->setStyleSheet("padding: 6px 10px;");
+ GBHLayout->addWidget(btnRandomTeam, 9, 0, 1, 4, Qt::AlignCenter);
+ btnRandomTeam->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
vbox1->addWidget(GBoxHedgehogs);
@@ -157,52 +164,6 @@ QLayout * PageEditTeam::bodyLayoutDefinition()
vbox1->addStretch();
vbox2->addStretch();
-// ====== Page 2 ======
- GBoxBinds = new QGroupBox(this);
- GBoxBinds->setTitle(QGroupBox::tr("Key binds"));
- QGridLayout * GBBLayout = new QGridLayout(GBoxBinds);
- BindsBox = new QToolBox(GBoxBinds);
- BindsBox->setLineWidth(0);
- GBBLayout->addWidget(BindsBox);
- page2Layout->addWidget(GBoxBinds, 0, 0);
-
- quint16 i = 0;
- quint16 num = 0;
- QWidget * curW = NULL;
- QGridLayout * pagelayout = NULL;
- QLabel* l = NULL;
- while (i < BINDS_NUMBER)
- {
- if(cbinds[i].category != NULL)
- {
- if(curW != NULL)
- {
- l = new QLabel(curW);
- l->setText("");
- pagelayout->addWidget(l, num++, 0, 1, 2);
- }
- curW = new QWidget(this);
- BindsBox->addItem(curW, HWApplication::translate("binds (categories)", cbinds[i].category));
- pagelayout = new QGridLayout(curW);
- num = 0;
- }
- if(cbinds[i].description != NULL)
- {
- l = new QLabel(curW);
- l->setText((num > 0 ? QString("\n") : QString("")) + HWApplication::translate("binds (descriptions)", cbinds[i].description));
- pagelayout->addWidget(l, num++, 0, 1, 2);
- }
-
- l = new QLabel(curW);
- l->setText(HWApplication::translate("binds", cbinds[i].name));
- l->setAlignment(Qt::AlignRight);
- pagelayout->addWidget(l, num, 0);
-
- CBBind[i] = new QComboBox(curW);
- CBBind[i]->setModel(DataManager::instance().bindsModel());
- pagelayout->addWidget(CBBind[i++], num++, 1);
- }
-
return pageLayout;
}
@@ -213,7 +174,7 @@ QLayout * PageEditTeam::footerLayoutDefinition()
void PageEditTeam::connectSignals()
{
- connect(this, SIGNAL(goBack()), this, SLOT(saveTeam()));
+ connect(this, SIGNAL(pageLeave()), this, SLOT(saveTeam()));
signalMapper1 = new QSignalMapper(this);
signalMapper2 = new QSignalMapper(this);
@@ -270,7 +231,7 @@ PageEditTeam::PageEditTeam(QWidget* parent) :
foreach (QString file, list)
{
- QPixmap pix(dataMgr.findFileForRead("Graphics/Graves/" + file));
+ QPixmap pix("physfs://Graphics/Graves/" + file);
if ((pix.height() > 32) || pix.width() > 32)
pix = pix.copy(0, 0, 32, 32);
QIcon icon(pix);
@@ -297,7 +258,7 @@ PageEditTeam::PageEditTeam(QWidget* parent) :
list.removeAt(idx);
// add the default flag
- QPixmap hwFlag(dataMgr.findFileForRead("Graphics/Flags/hedgewars.png"));
+ QPixmap hwFlag("physfs://Graphics/Flags/hedgewars.png");
CBFlag->addItem(QIcon(hwFlag.copy(0, 0, 22, 15)), "Hedgewars", "hedgewars");
// add seperator after
@@ -308,7 +269,7 @@ PageEditTeam::PageEditTeam(QWidget* parent) :
// add all country flags
foreach (const QString & file, list)
{
- QIcon icon(QPixmap(dataMgr.findFileForRead("Graphics/Flags/" + file)));
+ QIcon icon(QPixmap("physfs://Graphics/Flags/" + file));
QString flag = QString(file).remove(pngSuffix);
@@ -337,8 +298,7 @@ void PageEditTeam::fixHHname(int idx)
void PageEditTeam::CBFort_activated(const QString & fortname)
{
- DataManager & dataMgr = DataManager::instance();
- QPixmap pix(dataMgr.findFileForRead("Forts/" + fortname + "L.png"));
+ QPixmap pix("physfs://Forts/" + fortname + "L.png");
FortPreview->setPixmap(pix);
}
@@ -360,10 +320,8 @@ void PageEditTeam::testSound()
);
if (!list.isEmpty())
- SDLInteraction::instance().playSoundFile(
- dataMgr.findFileForRead(voiceDir + "/" +
- list[rand() % list.size()])
- );
+ SDLInteraction::instance().playSoundFile("/" + voiceDir + "/" +
+ list[rand() % list.size()]);
}
void PageEditTeam::createTeam(const QString & name, const QString & playerHash)
@@ -410,6 +368,9 @@ void PageEditTeam::setRandomName(int hh_index)
void PageEditTeam::loadTeam(const HWTeam & team)
{
+ tbw->setCurrentIndex(0);
+ binder->resetInterface();
+
TeamNameEdit->setText(team.name());
CBTeamLvl->setCurrentIndex(team.difficulty());
@@ -422,7 +383,7 @@ void PageEditTeam::loadTeam(const HWTeam & team)
if (hh.Hat.startsWith("Reserved"))
hh.Hat = "Reserved "+hh.Hat.remove(0,40);
- HHHats[i]->setCurrentIndex(HHHats[i]->findData(hh.Hat, Qt::DisplayRole));
+ HHHats[i]->setCurrentHat(hh.Hat);
}
CBGrave->setCurrentIndex(CBGrave->findText(team.grave()));
@@ -434,10 +395,12 @@ void PageEditTeam::loadTeam(const HWTeam & team)
QStandardItemModel * binds = DataManager::instance().bindsModel();
for(int i = 0; i < BINDS_NUMBER; i++)
{
+ if (team.keyBind(i).isEmpty()) continue;
+
QModelIndexList mdl = binds->match(binds->index(0, 0), Qt::UserRole + 1, team.keyBind(i), 1, Qt::MatchExactly);
if(mdl.size() == 1)
- CBBind[i]->setCurrentIndex(mdl[0].row());
+ binder->setBindIndex(i, mdl[0].row());
else
qDebug() << "Binds: cannot find" << team.keyBind(i);
}
@@ -452,7 +415,7 @@ HWTeam PageEditTeam::data()
{
HWHog hh;
hh.Name = HHNameEdit[i]->text();
- hh.Hat = HHHats[i]->currentText();
+ hh.Hat = HHHats[i]->currentHat();
if (hh.Hat.startsWith("Reserved"))
hh.Hat = "Reserved"+m_playerHash+hh.Hat.remove(0,9);
@@ -468,7 +431,7 @@ HWTeam PageEditTeam::data()
QStandardItemModel * binds = DataManager::instance().bindsModel();
for(int i = 0; i < BINDS_NUMBER; i++)
{
- team.bindKey(i, binds->index(CBBind[i]->currentIndex(), 0).data(Qt::UserRole + 1).toString());
+ team.bindKey(i, binds->index(binder->bindIndex(i), 0).data(Qt::UserRole + 1).toString());
}
return team;
@@ -478,3 +441,10 @@ void PageEditTeam::saveTeam()
{
data().saveToFile();
}
+
+// When the "Use default for all binds" is pressed...
+void PageEditTeam::resetAllBinds()
+{
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ binder->setBindIndex(i, 0);
+}
diff --git a/QTfrontend/ui/page/pageeditteam.h b/QTfrontend/ui/page/pageeditteam.h
index b44a19d..ce2c36a 100644
--- a/QTfrontend/ui/page/pageeditteam.h
+++ b/QTfrontend/ui/page/pageeditteam.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +28,8 @@
#include "team.h"
class SquareLabel;
+class KeyBinder;
+class HatButton;
class PageEditTeam : public AbstractPage
{
@@ -44,6 +46,7 @@ class PageEditTeam : public AbstractPage
void CBFort_activated(const QString & gravename);
private:
+ QTabWidget * tbw;
QSignalMapper* signalMapper1;
QSignalMapper* signalMapper2;
QGroupBox *GBoxHedgehogs;
@@ -59,10 +62,10 @@ class PageEditTeam : public AbstractPage
QToolBox *BindsBox;
QLineEdit * TeamNameEdit;
QLineEdit * HHNameEdit[HEDGEHOGS_PER_TEAM];
- QComboBox * HHHats[HEDGEHOGS_PER_TEAM];
- QComboBox * CBBind[BINDS_NUMBER];
+ HatButton * HHHats[HEDGEHOGS_PER_TEAM];
HWTeam data();
QString m_playerHash;
+ KeyBinder * binder;
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
@@ -85,6 +88,7 @@ class PageEditTeam : public AbstractPage
void testSound();
void fixHHname(int idx);
+ void resetAllBinds();
};
#endif
diff --git a/QTfrontend/ui/page/pagefeedback.cpp b/QTfrontend/ui/page/pagefeedback.cpp
deleted file mode 100644
index 29fd27c..0000000
--- a/QTfrontend/ui/page/pagefeedback.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <QHBoxLayout>
-#include <QLineEdit>
-#include <QTextBrowser>
-#include <QLabel>
-
-#include "pagefeedback.h"
-#include "hwconsts.h"
-
-QLayout * PageFeedback::bodyLayoutDefinition()
-{
- QVBoxLayout * pageLayout = new QVBoxLayout();
- QHBoxLayout * summaryLayout = new QHBoxLayout();
-
- info = new QLabel();
- info->setText(
- "<style type=\"text/css\">"
- "a { color: #ffcc00; }"
- "</style>"
- "<div align=\"center\"><h1>Please give us a feedback!</h1>"
- "<h3>We are always happy about suggestions, ideas or bug reports.<h3>"
- "<h4>The feedback will be posted as a new issue on our Google Code page.<h4>"
- "</div>"
- );
- pageLayout->addWidget(info);
-
- label_summary = new QLabel();
- label_summary->setText(QLabel::tr("Summary "));
- summaryLayout->addWidget(label_summary);
- summary = new QLineEdit();
- summaryLayout->addWidget(summary);
- pageLayout->addLayout(summaryLayout);
-
- label_description = new QLabel();
- label_description->setText(QLabel::tr("Description"));
- pageLayout->addWidget(label_description, 0, Qt::AlignHCenter);
- description = new QTextBrowser();
- description->setReadOnly(false);
- pageLayout->addWidget(description);
-
- return pageLayout;
-}
-
-QLayout * PageFeedback::footerLayoutDefinition()
-{
- QHBoxLayout * bottomLayout = new QHBoxLayout();
-
- bottomLayout->setStretch(0,1);
- //TODO: create logo for send button
- BtnSend = addButton("Send", bottomLayout, 0, false);
- bottomLayout->insertStretch(0);
-
- return bottomLayout;
-}
-
-void PageFeedback::connectSignals()
-{
- //TODO
-}
-
-PageFeedback::PageFeedback(QWidget* parent) : AbstractPage(parent)
-{
- initPage();
-
-}
diff --git a/QTfrontend/ui/page/pagefeedback.h b/QTfrontend/ui/page/pagefeedback.h
deleted file mode 100644
index 6621686..0000000
--- a/QTfrontend/ui/page/pagefeedback.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef PAGE_FEEDBACK_H
-#define PAGE_FEEDBACK_H
-
-#include "AbstractPage.h"
-
-class PageFeedback : public AbstractPage
-{
- Q_OBJECT
-
- public:
- PageFeedback(QWidget * parent = 0);
-
- QPushButton * BtnSend;
- QLineEdit * summary;
- QTextBrowser * description;
- QLabel * info;
- QLabel * label_summary;
- QLabel * label_description;
-
- private:
- QLayout * bodyLayoutDefinition();
- QLayout * footerLayoutDefinition();
- void connectSignals();
-};
-
-#endif
diff --git a/QTfrontend/ui/page/pagegamestats.cpp b/QTfrontend/ui/page/pagegamestats.cpp
index 8903c56..a997275 100644
--- a/QTfrontend/ui/page/pagegamestats.cpp
+++ b/QTfrontend/ui/page/pagegamestats.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -97,20 +97,35 @@ QLayout * PageGameStats::bodyLayoutDefinition()
return pageLayout;
}
+//TODO button placement, image etc
QLayout * PageGameStats::footerLayoutDefinition()
{
QHBoxLayout * bottomLayout = new QHBoxLayout();
-
- btnSave = addButton(":/res/Save.png", bottomLayout, 0, true);
+
+ mainNote = new QLabel(this);
+ mainNote->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ mainNote->setWordWrap(true);
+
+ bottomLayout->addWidget(mainNote, 0);
+ bottomLayout->setStretch(0,1);
+
+ btnRestart = addButton(":/res/Start.png", bottomLayout, 1, true);
+ btnRestart->setWhatsThis(tr("Play again"));
+ btnRestart->setFixedWidth(58);
+ btnRestart->setFixedHeight(81);
+ btnRestart->setStyleSheet("QPushButton{margin-top:24px}");
+ btnSave = addButton(":/res/Save.png", bottomLayout, 2, true);
+ btnSave->setWhatsThis(tr("Save"));
btnSave->setStyleSheet("QPushButton{margin: 24px 0 0 0;}");
- bottomLayout->setAlignment(btnSave, Qt::AlignRight | Qt::AlignBottom);
return bottomLayout;
}
void PageGameStats::connectSignals()
{
+ connect(this, SIGNAL(pageEnter()), this, SLOT(renderStats()));
connect(btnSave, SIGNAL(clicked()), this, SIGNAL(saveDemoRequested()));
+ connect(btnRestart, SIGNAL(clicked()), this, SIGNAL(restartGameRequested()));
}
PageGameStats::PageGameStats(QWidget* parent) : AbstractPage(parent)
@@ -132,6 +147,11 @@ void PageGameStats::clear()
lastColor = 0;
}
+void PageGameStats::restartBtnVisible(bool visible)
+{
+ btnRestart->setVisible(visible);
+}
+
void PageGameStats::renderStats()
{
QGraphicsScene * scene = new QGraphicsScene();
diff --git a/QTfrontend/ui/page/pagegamestats.h b/QTfrontend/ui/page/pagegamestats.h
index 90fa19f..ace9134 100644
--- a/QTfrontend/ui/page/pagegamestats.h
+++ b/QTfrontend/ui/page/pagegamestats.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,6 +44,8 @@ class PageGameStats : public AbstractPage
PageGameStats(QWidget* parent = 0);
QPushButton *btnSave;
+ QPushButton *btnRestart;
+ QLabel *mainNote;
QLabel *labelGameStats;
QLabel *labelGameWin;
QLabel *labelGameRank;
@@ -53,9 +55,11 @@ class PageGameStats : public AbstractPage
void GameStats(char type, const QString & info);
void clear();
void renderStats();
+ void restartBtnVisible(bool visible);
signals:
void saveDemoRequested();
+ void restartGameRequested();
private:
void AddStatText(const QString & msg);
diff --git a/QTfrontend/ui/page/pageinfo.cpp b/QTfrontend/ui/page/pageinfo.cpp
index 01448f5..abb7c18 100644
--- a/QTfrontend/ui/page/pageinfo.cpp
+++ b/QTfrontend/ui/page/pageinfo.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageinfo.h b/QTfrontend/ui/page/pageinfo.h
index c5f90d8..7f0887d 100644
--- a/QTfrontend/ui/page/pageinfo.h
+++ b/QTfrontend/ui/page/pageinfo.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageingame.cpp b/QTfrontend/ui/page/pageingame.cpp
index 1ec1b65..725893a 100644
--- a/QTfrontend/ui/page/pageingame.cpp
+++ b/QTfrontend/ui/page/pageingame.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageingame.h b/QTfrontend/ui/page/pageingame.h
index ff1f325..5644d33 100644
--- a/QTfrontend/ui/page/pageingame.h
+++ b/QTfrontend/ui/page/pageingame.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagemain.cpp b/QTfrontend/ui/page/pagemain.cpp
index ac88d4c..8364bd2 100644
--- a/QTfrontend/ui/page/pagemain.cpp
+++ b/QTfrontend/ui/page/pagemain.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,30 +42,48 @@ QLayout * PageMain::bodyLayoutDefinition()
pageLayout->setRowStretch(4, 1);
BtnSinglePlayer = addButton(":/res/LocalPlay.png", pageLayout, 2, 0, 1, 2, true);
- BtnSinglePlayer->setToolTip(tr("Local Game"));
BtnSinglePlayer->setWhatsThis(tr("Play a game on a single computer"));
pageLayout->setAlignment(BtnSinglePlayer, Qt::AlignHCenter);
+ //BtnNet = addButton(":/res/NetworkPlay.png", (QBoxLayout*)netLayout, 1, true);
BtnNet = addButton(":/res/NetworkPlay.png", pageLayout, 2, 2, 1, 2, true);
- BtnNet->setToolTip(tr("Network Game"));
BtnNet->setWhatsThis(tr("Play a game across a network"));
pageLayout->setAlignment(BtnNet, Qt::AlignHCenter);
+ originalNetworkIcon = BtnNet->icon();
+ disabledNetworkIcon = QIcon(":/res/NetworkPlayDisabled.png");
+
+ //QWidget *netLayoutWidget = new QWidget();
+ QVBoxLayout *netLayout = new QVBoxLayout(BtnNet);
+ //pageLayout->addWidget(netLayoutWidget, 2, 2, 1, 2);
+ //netLayoutWidget->setStyleSheet("background: green;");
+ //netLayoutWidget->setFixedSize(314, 260);
+ netLayout->setSpacing(20);
+ netLayout->setAlignment(Qt::AlignHCenter);
+
+ BtnNetLocal = addButton(tr("Play local network game"), (QBoxLayout*)netLayout, 0, false);
+ BtnNetLocal->setWhatsThis(tr("Play a game across a local area network"));
+ BtnNetLocal->setFixedSize(BtnNet->width() - 50, 60);
+ BtnNetLocal->setVisible(false);
+
+ BtnNetOfficial = addButton(tr("Play official network game"), (QBoxLayout*)netLayout, 0, false);
+ BtnNetOfficial->setWhatsThis(tr("Play a game on an official server"));
+ BtnNetOfficial->setFixedSize(BtnNet->width() - 50, 60);
+ BtnNetOfficial->setVisible(false);
+
// button order matters for overlapping (what's on top and what isn't)
BtnInfo = addButton(":/res/HedgewarsTitle.png", pageLayout, 0, 0, 1, 4, true);
BtnInfo->setStyleSheet("border: transparent;background: transparent;");
- //BtnInfo->setToolTip(tr("Credits")); //tooltip looks horrible with transparent background buttons
BtnInfo->setWhatsThis(tr("Read about who is behind the Hedgewars Project"));
pageLayout->setAlignment(BtnInfo, Qt::AlignHCenter);
-#if 0
- BtnFeedback = addButton("Feedback", pageLayout, 4, 0, 1, 4, false);
+ BtnFeedback = addButton(tr("Feedback"), pageLayout, 4, 0, 1, 4, false);
+ BtnFeedback->setStyleSheet("padding: 5px 10px");
BtnFeedback->setWhatsThis(tr("Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars"));
pageLayout->setAlignment(BtnFeedback, Qt::AlignHCenter);
-#endif
BtnDataDownload = addButton(tr("Downloadable Content"), pageLayout, 5, 0, 1, 4, false);
- //BtnDataDownload->setToolTip(tr(Downloadable Content"));
+ BtnDataDownload->setStyleSheet("padding: 5px 10px");
BtnDataDownload->setWhatsThis(tr("Access the user created content downloadable from our website"));
pageLayout->setAlignment(BtnDataDownload, Qt::AlignHCenter);
@@ -101,86 +119,80 @@ QLayout * PageMain::footerLayoutDefinition()
void PageMain::connectSignals()
{
- //TODO
+ connect(BtnNet, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice()));
+ //connect(BtnNetLocal, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice()));
+ //connect(BtnNetOfficial, SIGNAL(clicked()), this, SLOT(toggleNetworkChoice()));
+ // TODO: add signal-forwarding required by (currently missing) encapsulation
}
PageMain::PageMain(QWidget* parent) : AbstractPage(parent)
{
initPage();
- if(frontendEffects) setAttribute(Qt::WA_NoSystemBackground, true);
+ if(frontendEffects)
+ setAttribute(Qt::WA_NoSystemBackground, true);
mainNote->setOpenExternalLinks(true);
- if(!isDevBuild)
- {
- setDefautDescription(QLabel::tr("Tip: ") + randomTip());
- }
- else
- {
- setDefautDescription(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!"));
- }
+#ifdef DEBUG
+ setDefaultDescription(QLabel::tr("This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!"));
+#else
+ setDefaultDescription(QLabel::tr("Tip: ") + randomTip());
+#endif
}
QString PageMain::randomTip() const
{
- QStringList Tips;
- Tips << tr("Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.", "Tips");
- Tips << tr("Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.", "Tips");
- Tips << tr("If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!", "Tips");
- Tips << tr("Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!", "Tips");
- Tips << tr("If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.", "Tips");
- Tips << tr("You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.", "Tips");
- Tips << tr("By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.", "Tips");
- Tips << tr("Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!", "Tips");
- Tips << tr("Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!", "Tips");
- Tips << tr("Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!", "Tips");
- Tips << tr("Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!", "Tips");
- Tips << tr("From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.", "Tips");
- Tips << tr("Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!", "Tips");
- Tips << tr("Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.", "Tips");
- Tips << tr("Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.", "Tips");
- Tips << tr("Connect one or more gamepads before starting the game to be able to assign their controls to your teams.", "Tips");
- Tips << tr("Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.", "Tips").arg("<a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a>");
- Tips << tr("While playing you should give yourself a short break at least once an hour.", "Tips");
- Tips << tr("If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.", "Tips");
- Tips << tr("If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.", "Tips");
- Tips << tr("We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!", "Tips");
- Tips << tr("Especially while playing online be polite and always remember there might be some minors playing with or against you as well!", "Tips");
- Tips << tr("Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!", "Tips");
- Tips << tr("The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.", "Tips");
- Tips << tr("You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!", "Tips");
- Tips << tr("Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.", "Tips");
- Tips << tr("No hedgehogs were harmed in making this game.", "Tips");
- Tips << tr("There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.", "Tips");
- Tips << tr("Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.", "Tips");
- Tips << tr("Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.", "Tips");
- Tips << tr("Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.", "Tips");
- Tips << tr("The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.", "Tips");
- Tips << tr("The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.", "Tips");
- Tips << tr("The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.", "Tips");
- Tips << tr("Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.", "Tips");
- Tips << tr("The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.", "Tips");
- Tips << tr("If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.", "Tips");
- Tips << tr("The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.", "Tips");
- Tips << tr("The Flame Thrower is a weapon but it can be used for tunnel digging as well.", "Tips");
- Tips << tr("Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.", "Tips");
- Tips << tr("Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.", "Tips");
- Tips << tr("Like Hedgewars? Become a fan on %1 or follow us on %2!", "Tips").arg("<a href=\"http://www.facebook.com/Hedgewars\">Facebook</a>").arg("<a href=\"http://twitter.com/hedgewars\">Twitter</a>");
- Tips << tr("Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.", "Tips");
- Tips << tr("Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!", "Tips");
- // The following tip will require links to app store entries first.
- //Tips << tr("Want to play Hedgewars any time? Grab the Mobile version for %1 and %2.", "Tips").arg("").arg("");
- // the ios version is located here: http://itunes.apple.com/us/app/hedgewars/id391234866
- Tips << tr("Keep your video card drivers up to date to avoid issues playing the game.", "Tips");
- Tips << tr("You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.", "Tips");
#ifdef _WIN32
- Tips << tr("You can find your Hedgewars configuration files under \"My Documents\\Hedgewars\". Create backups or take the files with you, but don't edit them by hand.", "Tips");
+ int platform = 1;
#elif defined __APPLE__
- Tips << tr("You can find your Hedgewars configuration files under \"Library/Application Support/Hedgewars\" in your home directory. Create backups or take the files with you, but don't edit them by hand.", "Tips");
+ int platform = 2;
#else
- Tips << tr("You can find your Hedgewars configuration files under \".hedgewars\" in your home directory. Create backups or take the files with you, but don't edit them by hand.", "Tips");
+ int platform = 3;
#endif
+ QStringList Tips;
+ QFile file(":/res/xml/tips.xml");
+ file.open(QIODevice::ReadOnly);
+ QTextStream in(&file);
+ QString line = in.readLine();
+ int tip_platform = 0;
+ while (!line.isNull()) {
+ if(line.contains("<windows-only>", Qt::CaseSensitive))
+ tip_platform = 1;
+ if(line.contains("<mac-only>", Qt::CaseSensitive))
+ tip_platform = 2;
+ if(line.contains("<linux-only>", Qt::CaseSensitive))
+ tip_platform = 3;
+ if(line.contains("</windows-only>", Qt::CaseSensitive) ||
+ line.contains("</mac-only>", Qt::CaseSensitive) ||
+ line.contains("</linux-only>", Qt::CaseSensitive)) {
+ tip_platform = 0;
+ }
+ QStringList split_string = line.split(QRegExp("</?tip>"));
+ if((tip_platform == platform || tip_platform == 0) && split_string.size() != 1)
+ Tips << tr(split_string[1].toLatin1().data(), "Tips");
+ line = in.readLine();
+ }
+ // The following tip will require links to app store entries first.
+ //Tips << tr("Want to play Hedgewars any time? Grab the Mobile version for %1 and %2.", "Tips").arg("").arg("");
+ // the ios version is located here: http://itunes.apple.com/us/app/hedgewars/id391234866
+ file.close();
return Tips[QTime(0, 0, 0).secsTo(QTime::currentTime()) % Tips.length()];
}
+
+void PageMain::toggleNetworkChoice()
+{
+ bool visible = BtnNetLocal->isVisible();
+ BtnNetLocal->setVisible(!visible);
+ BtnNetOfficial->setVisible(!visible);
+ if (visible) BtnNet->setIcon(originalNetworkIcon);
+ else BtnNet->setIcon(disabledNetworkIcon);
+}
+
+void PageMain::resetNetworkChoice()
+{
+ BtnNetLocal->setVisible(false);
+ BtnNetOfficial->setVisible(false);
+ BtnNet->setIcon(originalNetworkIcon);
+}
diff --git a/QTfrontend/ui/page/pagemain.h b/QTfrontend/ui/page/pagemain.h
index ea579e0..f7e3a23 100644
--- a/QTfrontend/ui/page/pagemain.h
+++ b/QTfrontend/ui/page/pagemain.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,15 +21,20 @@
#include "AbstractPage.h"
+class QIcon;
+
class PageMain : public AbstractPage
{
- Q_OBJECT
+ Q_OBJECT
public:
PageMain(QWidget * parent = 0);
+ void resetNetworkChoice();
QPushButton * BtnSinglePlayer;
QPushButton * BtnNet;
+ QPushButton * BtnNetLocal;
+ QPushButton * BtnNetOfficial;
QPushButton * BtnSetup;
QPushButton * BtnFeedback;
QPushButton * BtnInfo;
@@ -41,8 +46,12 @@ class PageMain : public AbstractPage
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
void connectSignals();
+ QIcon originalNetworkIcon, disabledNetworkIcon;
QString randomTip() const;
+
+ private slots:
+ void toggleNetworkChoice();
};
#endif
diff --git a/QTfrontend/ui/page/pagemultiplayer.cpp b/QTfrontend/ui/page/pagemultiplayer.cpp
index 7e456bc..307d77e 100644
--- a/QTfrontend/ui/page/pagemultiplayer.cpp
+++ b/QTfrontend/ui/page/pagemultiplayer.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,29 +31,41 @@
QLayout * PageMultiplayer::bodyLayoutDefinition()
{
- QGridLayout * pageLayout = new QGridLayout();
+ QHBoxLayout * pageLayout = new QHBoxLayout();
gameCFG = new GameCFGWidget(this);
- pageLayout->addWidget(gameCFG, 0, 0, 1, 2);
-
- btnSetup = new QPushButton(this);
- btnSetup->setText(QPushButton::tr("Setup"));
- pageLayout->addWidget(btnSetup, 1, 0, 1, 2);
-
- pageLayout->setRowStretch(2, 1);
+ pageLayout->addWidget(gameCFG, 3, Qt::AlignTop);
teamsSelect = new TeamSelWidget(this);
- pageLayout->addWidget(teamsSelect, 0, 2, 3, 2);
+ pageLayout->addWidget(teamsSelect, 2, Qt::AlignTop);
return pageLayout;
}
+QLayout * PageMultiplayer::footerLayoutLeftDefinition()
+{
+ QHBoxLayout * bottomLeftLayout = new QHBoxLayout();
+
+ btnSetup = addButton(":/res/Settings.png", bottomLeftLayout, 0, true);
+ btnSetup->setWhatsThis(tr("Edit game preferences"));
+
+ return bottomLeftLayout;
+}
+
QLayout * PageMultiplayer::footerLayoutDefinition()
{
QHBoxLayout * footerLayout = new QHBoxLayout();
- BtnStartMPGame = formattedButton(tr("Start"));
- BtnStartMPGame->setMinimumWidth(180);
+ const QIcon& lp = QIcon(":/res/Start.png");
+ QSize sz = lp.actualSize(QSize(65535, 65535));
+ BtnStartMPGame = new QPushButton();
+ BtnStartMPGame->setText(tr("Start"));
+ BtnStartMPGame->setMinimumWidth(sz.width() + 60);
+ BtnStartMPGame->setIcon(lp);
+ BtnStartMPGame->setFixedHeight(50);
+ BtnStartMPGame->setIconSize(sz);
+ BtnStartMPGame->setFlat(true);
+ BtnStartMPGame->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
footerLayout->addStretch();
footerLayout->addWidget(BtnStartMPGame);
diff --git a/QTfrontend/ui/page/pagemultiplayer.h b/QTfrontend/ui/page/pagemultiplayer.h
index b39b195..ea5eb63 100644
--- a/QTfrontend/ui/page/pagemultiplayer.h
+++ b/QTfrontend/ui/page/pagemultiplayer.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@ class PageMultiplayer : public AbstractPage
private:
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
+ QLayout * footerLayoutLeftDefinition();
void connectSignals();
QPushButton * btnSetup;
diff --git a/QTfrontend/ui/page/pagenet.cpp b/QTfrontend/ui/page/pagenet.cpp
index 3c2179e..b6b844d 100644
--- a/QTfrontend/ui/page/pagenet.cpp
+++ b/QTfrontend/ui/page/pagenet.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -72,7 +72,12 @@ QLayout * PageNet::footerLayoutDefinition()
BtnNetSvrStart = formattedButton(QPushButton::tr("Start server"));
BtnNetSvrStart->setMinimumWidth(180);
- BtnNetSvrStart->setVisible(haveServer);
+ QString serverPath = bindir->absolutePath() + "/hedgewars-server";
+#ifdef Q_WS_WIN
+ serverPath += + ".exe";
+#endif
+ QFile server(serverPath);
+ BtnNetSvrStart->setVisible(server.exists());
footerLayout->addStretch();
footerLayout->addWidget(BtnNetSvrStart);
diff --git a/QTfrontend/ui/page/pagenet.h b/QTfrontend/ui/page/pagenet.h
index 37cf17a..5fef4e1 100644
--- a/QTfrontend/ui/page/pagenet.h
+++ b/QTfrontend/ui/page/pagenet.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagenetgame.cpp b/QTfrontend/ui/page/pagenetgame.cpp
index 4566f6e..c7061a3 100644
--- a/QTfrontend/ui/page/pagenetgame.cpp
+++ b/QTfrontend/ui/page/pagenetgame.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,69 +22,130 @@
#include <QAction>
#include <QMenu>
#include <QMessageBox>
+#include <QSettings>
#include "pagenetgame.h"
#include "gamecfgwidget.h"
#include "teamselect.h"
#include "chatwidget.h"
+const int cutoffHeight = 688; /* Don't make this number below 605, or else it'll
+ let the GameCFGWidget shrink too much before switching to tabbed mode. */
+
QLayout * PageNetGame::bodyLayoutDefinition()
{
QGridLayout * pageLayout = new QGridLayout();
pageLayout->setSizeConstraint(QLayout::SetMinimumSize);
- //pageLayout->setSpacing(1);
- pageLayout->setColumnStretch(0, 50);
- pageLayout->setColumnStretch(1, 50);
-
- // chatwidget
- pChatWidget = new HWChatWidget(this, m_gameSettings, true);
- pChatWidget->setShowFollow(false); // don't show follow in nicks' context menus
- pChatWidget->setIgnoreListKick(true); // kick ignored players automatically
- pageLayout->addWidget(pChatWidget, 2, 0, 1, 2);
- pageLayout->setRowStretch(1, 100);
- pageLayout->setRowStretch(2, 100);
+ pageLayout->setColumnStretch(0, 1);
+ pageLayout->setColumnStretch(1, 1);
+ pageLayout->setRowStretch(0, 0);
+ pageLayout->setRowStretch(1, 0);
+ pageLayout->setRowStretch(2, 1);
+
+ // Room config
+
+ QHBoxLayout * roomConfigLayout = new QHBoxLayout();
+ pageLayout->addLayout(roomConfigLayout, 0, 0, 1, 2);
+ roomConfigLayout->setSpacing(0);
+
+ leRoomName = new HistoryLineEdit(this, 10);
+ leRoomName->setMaxLength(60);
+ leRoomName->setMinimumWidth(400);
+ leRoomName->setMaximumWidth(600);
+ leRoomName->setFixedHeight(30);
+ leRoomName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ leRoomName->setStyleSheet("border-right: 0; padding-left: 4px; border-top-right-radius: 0px; border-bottom-right-radius: 0px;");
+ roomConfigLayout->addWidget(leRoomName, 100);
+
+ BtnUpdate = new QPushButton();
+ BtnUpdate->setEnabled(false);
+ BtnUpdate->setText(tr("Update"));
+ BtnUpdate->setFixedHeight(leRoomName->height() - 0);
+ BtnUpdate->setStyleSheet("border-top-left-radius: 0px; border-bottom-left-radius: 0px; padding: auto 4px;");
+ roomConfigLayout->addWidget(BtnUpdate, 0);
+
+ lblRoomNameReadOnly = new QLabel();
+ lblRoomNameReadOnly->setMinimumWidth(400);
+ lblRoomNameReadOnly->setMaximumWidth(600);
+ lblRoomNameReadOnly->setFixedHeight(30);
+ lblRoomNameReadOnly->setObjectName("labelLikeLineEdit");
+ lblRoomNameReadOnly->setStyleSheet("font: 12px;");
+ lblRoomNameReadOnly->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ lblRoomNameReadOnly->setVisible(false);
+ roomConfigLayout->addWidget(lblRoomNameReadOnly, 100);
+
+ roomConfigLayout->addSpacing(10);
+
+ BtnMaster = new QPushButton();
+ BtnMaster->setText(tr("Room controls"));
+ BtnMaster->setFixedHeight(leRoomName->height() - 0);
+ BtnMaster->setStyleSheet("QPushButton { padding: auto 4px; } QPushButton:pressed { background-color: #ffcc00; border-color: #ffcc00; border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; color: #11084A; }");
+ roomConfigLayout->addWidget(BtnMaster, 0);
+
+ roomConfigLayout->addStretch(1);
+
+ // Game config
pGameCFG = new GameCFGWidget(this);
- pageLayout->addWidget(pGameCFG, 0, 0);
+ pageLayout->addWidget(pGameCFG, 1, 0);
- btnSetup = new QPushButton(this);
- btnSetup->setText(QPushButton::tr("Setup"));
- pageLayout->addWidget(btnSetup, 1, 0);
+ // Teams
pNetTeamsWidget = new TeamSelWidget(this);
pNetTeamsWidget->setAcceptOuter(true);
- pageLayout->addWidget(pNetTeamsWidget, 0, 1, 2, 1);
+ pNetTeamsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ pageLayout->addWidget(pNetTeamsWidget, 1, 1);
+
+ // Chat
+
+ chatWidget = new HWChatWidget(this, true);
+ chatWidget->setShowFollow(false); // don't show follow in nicks' context menus
+ chatWidget->setIgnoreListKick(true); // kick ignored players automatically
+ chatWidget->setMinimumHeight(50);
+ chatWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ pageLayout->addWidget(chatWidget, 2, 0, 1, 2);
return pageLayout;
}
+QLayout * PageNetGame::footerLayoutLeftDefinition()
+{
+ QHBoxLayout * bottomLeftLayout = new QHBoxLayout();
+
+ btnSetup = addButton(":/res/Settings.png", bottomLeftLayout, 0, true);
+ btnSetup->setWhatsThis(tr("Edit game preferences"));
+
+ return bottomLeftLayout;
+}
+
QLayout * PageNetGame::footerLayoutDefinition()
{
QHBoxLayout * bottomLayout = new QHBoxLayout;
- leRoomName = new HistoryLineEdit(this,10);
- leRoomName->setMaxLength(60);
- leRoomName->setMinimumWidth(200);
- leRoomName->setMaximumWidth(400);
+ // Ready button
- //Button to signify whether the player is ready to start playing
BtnGo = new QPushButton(this);
- BtnGo->setToolTip(QPushButton::tr("Ready"));
BtnGo->setIcon(QIcon(":/res/lightbulb_off.png"));
BtnGo->setIconSize(QSize(25, 34));
BtnGo->setMinimumWidth(50);
BtnGo->setMinimumHeight(50);
- bottomLayout->addWidget(leRoomName);
- BtnUpdate = addButton(QAction::tr("Update"), bottomLayout, 1);
-
bottomLayout->addStretch();
bottomLayout->addWidget(BtnGo);
- BtnMaster = addButton(tr("Control"), bottomLayout, 3);
- bottomLayout->insertStretch(3, 100);
+ // Start button
- BtnStart = addButton(QAction::tr("Start"), bottomLayout, 3);
+ const QIcon& lp = QIcon(":/res/Start.png");
+ QSize sz = lp.actualSize(QSize(65535, 65535));
+ BtnStart = new QPushButton();
+ BtnStart->setText(tr("Start"));
+ BtnStart->setMinimumWidth(sz.width() + 60);
+ BtnStart->setIcon(lp);
+ BtnStart->setFixedHeight(50);
+ BtnStart->setIconSize(sz);
+ BtnStart->setFlat(true);
+ BtnStart->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ bottomLayout->addWidget(BtnStart);
return bottomLayout;
}
@@ -94,12 +155,13 @@ void PageNetGame::connectSignals()
connect(btnSetup, SIGNAL(clicked()), this, SIGNAL(SetupClicked()));
connect(BtnUpdate, SIGNAL(clicked()), this, SLOT(onUpdateClick()));
+ connect(leRoomName, SIGNAL(returnPressed()), this, SLOT(onUpdateClick()));
+
+ connect(leRoomName, SIGNAL(textChanged(const QString &)), this, SLOT(onRoomNameEdited()));
}
-PageNetGame::PageNetGame(QWidget* parent, QSettings * gameSettings) : AbstractPage(parent)
+PageNetGame::PageNetGame(QWidget* parent) : AbstractPage(parent)
{
- m_gameSettings = gameSettings;
-
initPage();
QMenu * menu = new QMenu(BtnMaster);
@@ -108,29 +170,47 @@ PageNetGame::PageNetGame(QWidget* parent, QSettings * gameSettings) : AbstractPa
restrictJoins->setCheckable(true);
restrictTeamAdds = new QAction(QAction::tr("Restrict Team Additions"), menu);
restrictTeamAdds->setCheckable(true);
- //menu->addAction(startGame);
+ restrictUnregistered = new QAction(QAction::tr("Restrict Unregistered Players Join"), menu);
+ restrictUnregistered->setCheckable(true);
menu->addAction(restrictJoins);
menu->addAction(restrictTeamAdds);
+ menu->addAction(restrictUnregistered);
BtnMaster->setMenu(menu);
+ if (height() < cutoffHeight)
+ pGameCFG->setTabbed(true);
}
+void PageNetGame::resizeEvent(QResizeEvent * event)
+{
+ int oldHeight = event->oldSize().height();
+ int newHeight = event->size().height();
+
+ if (newHeight < cutoffHeight && oldHeight >= cutoffHeight)
+ {
+ pGameCFG->setTabbed(true);
+ }
+ else if (newHeight >= cutoffHeight && oldHeight < cutoffHeight)
+ {
+ pGameCFG->setTabbed(false);
+ }
+}
void PageNetGame::displayError(const QString & message)
{
- pChatWidget->displayError(message);
+ chatWidget->displayError(message);
}
void PageNetGame::displayNotice(const QString & message)
{
- pChatWidget->displayNotice(message);
+ chatWidget->displayNotice(message);
}
void PageNetGame::displayWarning(const QString & message)
{
- pChatWidget->displayWarning(message);
+ chatWidget->displayWarning(message);
}
@@ -142,12 +222,19 @@ void PageNetGame::setReadyStatus(bool isReady)
BtnGo->setIcon(QIcon(":/res/lightbulb_off.png"));
}
+void PageNetGame::onRoomNameEdited()
+{
+ BtnUpdate->setEnabled(true);
+}
+
void PageNetGame::onUpdateClick()
{
if (!leRoomName->text().trimmed().isEmpty())
{
- emit askForUpdateRoomName(leRoomName->text());
+ m_gameSettings->setValue("frontend/lastroomname", leRoomName->text());
leRoomName->rememberCurrentText();
+ BtnUpdate->setEnabled(false);
+ emit askForUpdateRoomName(leRoomName->text());
}
else
{
@@ -158,6 +245,7 @@ void PageNetGame::onUpdateClick()
roomMsg.setText(QMessageBox::tr("Please enter room name"));
roomMsg.setWindowModality(Qt::WindowModal);
roomMsg.exec();
+ leRoomName->setFocus();
}
}
@@ -166,6 +254,8 @@ void PageNetGame::setRoomName(const QString & roomName)
{
leRoomName->setText(roomName);
leRoomName->rememberCurrentText();
+ lblRoomNameReadOnly->setText(roomName);
+ BtnUpdate->setEnabled(false);
}
void PageNetGame::setMasterMode(bool isMaster)
@@ -174,9 +264,17 @@ void PageNetGame::setMasterMode(bool isMaster)
BtnStart->setVisible(isMaster);
BtnUpdate->setVisible(isMaster);
leRoomName->setVisible(isMaster);
+ lblRoomNameReadOnly->setVisible(!isMaster);
+ pGameCFG->setMaster(isMaster);
+ repaint();
}
void PageNetGame::setUser(const QString & nickname)
{
- pChatWidget->setUser(nickname);
+ chatWidget->setUser(nickname);
+}
+
+void PageNetGame::setSettings(QSettings *settings)
+{
+ m_gameSettings = settings;
}
diff --git a/QTfrontend/ui/page/pagenetgame.h b/QTfrontend/ui/page/pagenetgame.h
index 128a7f6..9860b75 100644
--- a/QTfrontend/ui/page/pagenetgame.h
+++ b/QTfrontend/ui/page/pagenetgame.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,19 +26,16 @@
class HWChatWidget;
class TeamSelWidget;
class GameCFGWidget;
+class QSettings;
class PageNetGame : public AbstractPage
{
Q_OBJECT
public:
- PageNetGame(QWidget* parent, QSettings * gameSettings);
+ PageNetGame(QWidget* parent);
- /**
- * Sets the room name to display.
- * @param roomName room name to be displayed.
- */
- void setRoomName(const QString & roomName);
+ void setSettings(QSettings * settings);
void displayError(const QString & message);
void displayNotice(const QString & message);
@@ -48,34 +45,43 @@ class PageNetGame : public AbstractPage
QPushButton *BtnMaster;
QPushButton *BtnStart;
QPushButton *BtnUpdate;
+ HistoryLineEdit *leRoomName;
QAction * restrictJoins;
QAction * restrictTeamAdds;
+ QAction * restrictUnregistered;
- HWChatWidget* pChatWidget;
+ HWChatWidget* chatWidget;
TeamSelWidget* pNetTeamsWidget;
GameCFGWidget* pGameCFG;
public slots:
+ void setRoomName(const QString & roomName);
void setReadyStatus(bool isReady);
void setUser(const QString & nickname);
void onUpdateClick();
void setMasterMode(bool isMaster);
+ private slots:
+ void onRoomNameEdited();
+
signals:
void SetupClicked();
void askForUpdateRoomName(const QString &);
+ protected:
+ void resizeEvent(QResizeEvent * event);
+
private:
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
+ QLayout * footerLayoutLeftDefinition();
void connectSignals();
QSettings * m_gameSettings;
-
- HistoryLineEdit * leRoomName;
QPushButton * btnSetup;
+ QLabel * lblRoomNameReadOnly;
};
#endif
diff --git a/QTfrontend/ui/page/pagenetserver.cpp b/QTfrontend/ui/page/pagenetserver.cpp
index e7a11fa..377e408 100644
--- a/QTfrontend/ui/page/pagenetserver.cpp
+++ b/QTfrontend/ui/page/pagenetserver.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,8 +24,13 @@
#include <QLabel>
#include <QLineEdit>
#include <QSpinBox>
+#include <QTcpSocket>
+#include <QHostAddress>
+#include <QClipboard>
#include "pagenetserver.h"
+#include "hwconsts.h"
+#include "HWApplication.h"
QLayout * PageNetServer::bodyLayoutDefinition()
{
@@ -59,14 +64,31 @@ QLayout * PageNetServer::bodyLayoutDefinition()
gbLayout->addWidget(labelPort, 1, 0);
sbPort = new QSpinBox(gb);
- sbPort->setMinimum(0);
+ sbPort->setMinimum(1024);
sbPort->setMaximum(65535);
gbLayout->addWidget(sbPort, 1, 1);
BtnDefault = new QPushButton(gb);
- BtnDefault->setText(QPushButton::tr("default"));
+ BtnDefault->setMinimumWidth(50);
+ BtnDefault->setText(QPushButton::tr("Reset"));
+ BtnDefault->setWhatsThis(QPushButton::tr("Set the default server port for Hedgewars"));
gbLayout->addWidget(BtnDefault, 1, 2);
+ BtnShare = new QPushButton(gb);
+ BtnShare->setText(QPushButton::tr("Invite your friends to your server in just 1 click!"));
+ BtnShare->setWhatsThis(QPushButton::tr("Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you."));
+ gbLayout->addWidget(BtnShare, 2, 1);
+
+ labelURL = new QLabel(gb);
+ labelURL->setText(
+ "<style type=\"text/css\"> a { color: #ffcc00; } </style>"
+ "<div align=\"center\">"
+ "<a href=\"https://code.google.com/p/hedgewars/wiki/HWPlaySchemeSyntax\">" +
+ tr("Click here for details") +
+ "</a></div>");
+ labelURL->setOpenExternalLinks(true);
+ gbLayout->addWidget(labelURL, 3, 1);
+
return pageLayout;
}
@@ -75,6 +97,7 @@ QLayout * PageNetServer::footerLayoutDefinition()
QHBoxLayout * bottomLayout = new QHBoxLayout();
BtnStart = formattedButton(QPushButton::tr("Start"));
+ BtnStart->setWhatsThis(QPushButton::tr("Start private server"));
BtnStart->setMinimumWidth(180);
bottomLayout->addStretch();
@@ -86,6 +109,7 @@ QLayout * PageNetServer::footerLayoutDefinition()
void PageNetServer::connectSignals()
{
connect(BtnDefault, SIGNAL(clicked()), this, SLOT(setDefaultPort()));
+ connect(BtnShare, SIGNAL(clicked()), this, SLOT(copyUrl()));
}
PageNetServer::PageNetServer(QWidget* parent) : AbstractPage(parent)
@@ -95,5 +119,29 @@ PageNetServer::PageNetServer(QWidget* parent) : AbstractPage(parent)
void PageNetServer::setDefaultPort()
{
- sbPort->setValue(46631);
+ sbPort->setValue(NETGAME_DEFAULT_PORT);
+}
+
+// This function assumes that the user wants to share his server while connected to
+// the Internet and that he/she is using direct access (eg no NATs). To determine the
+// IP we briefly connect to Hedgewars website and fallback to user intervention
+// after 4 seconds of timeout.
+void PageNetServer::copyUrl()
+{
+ QString address = "hwplay://";
+
+ QTcpSocket socket;
+ socket.connectToHost("www.hedgewars.org", 80);
+ if (socket.waitForConnected(4000))
+ address += socket.localAddress().toString();
+ else
+ address += "<" + tr("Insert your address here") + ">";
+
+ if (sbPort->value() != NETGAME_DEFAULT_PORT)
+ address += ":" + QString::number(sbPort->value());
+
+ QClipboard *clipboard = HWApplication::clipboard();
+ clipboard->setText(address);
+ qDebug() << address << "copied to clipboard";
}
+
diff --git a/QTfrontend/ui/page/pagenetserver.h b/QTfrontend/ui/page/pagenetserver.h
index 63e66ac..6b6f94d 100644
--- a/QTfrontend/ui/page/pagenetserver.h
+++ b/QTfrontend/ui/page/pagenetserver.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,9 +30,11 @@ class PageNetServer : public AbstractPage
QPushButton *BtnStart;
QPushButton *BtnDefault;
+ QPushButton *BtnShare;
QLabel *labelSD;
- QLineEdit *leServerDescr;
QLabel *labelPort;
+ QLabel *labelURL;
+ QLineEdit *leServerDescr;
QSpinBox *sbPort;
protected:
@@ -42,6 +44,7 @@ class PageNetServer : public AbstractPage
private slots:
void setDefaultPort();
+ void copyUrl();
};
#endif
diff --git a/QTfrontend/ui/page/pagenettype.cpp b/QTfrontend/ui/page/pagenettype.cpp
deleted file mode 100644
index 8133f27..0000000
--- a/QTfrontend/ui/page/pagenettype.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <QGridLayout>
-#include <QPushButton>
-
-#include "pagenettype.h"
-
-
-QLayout * PageNetType::bodyLayoutDefinition()
-{
- QGridLayout * pageLayout = new QGridLayout();
- pageLayout->setRowStretch(0, 10);
- pageLayout->setRowStretch(3, 10);
-
- pageLayout->setColumnStretch(1, 10);
- pageLayout->setColumnStretch(2, 20);
- pageLayout->setColumnStretch(3, 10);
-
- BtnLAN = addButton(tr("LAN game"), pageLayout, 1, 2);
- BtnLAN->setWhatsThis(tr("Join or host your own game server in a Local Area Network."));
- BtnOfficialServer = addButton(tr("Official server"), pageLayout, 2, 2);
- BtnOfficialServer->setWhatsThis(tr("Join hundreds of players online!"));
-
- // hack: temporary deactivated - requires server modifications that aren't backward compatible (yet)
- //BtnOfficialServer->setEnabled(false);
-
- return pageLayout;
-}
-
-PageNetType::PageNetType(QWidget* parent) : AbstractPage(parent)
-{
- initPage();
-}
diff --git a/QTfrontend/ui/page/pagenettype.h b/QTfrontend/ui/page/pagenettype.h
deleted file mode 100644
index dfce272..0000000
--- a/QTfrontend/ui/page/pagenettype.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef PAGE_NETTYPE_H
-#define PAGE_NETTYPE_H
-
-#include "AbstractPage.h"
-
-class PageNetType : public AbstractPage
-{
- Q_OBJECT
-
- public:
- PageNetType(QWidget* parent = 0);
-
- QPushButton * BtnLAN;
- QPushButton * BtnOfficialServer;
-
- protected:
- QLayout * bodyLayoutDefinition();
-};
-
-#endif
diff --git a/QTfrontend/ui/page/pageoptions.cpp b/QTfrontend/ui/page/pageoptions.cpp
index cf7a55c..1266da9 100644
--- a/QTfrontend/ui/page/pageoptions.cpp
+++ b/QTfrontend/ui/page/pageoptions.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,20 +23,62 @@
#include <QComboBox>
#include <QCheckBox>
#include <QLabel>
+#include <QTableWidget>
#include <QLineEdit>
#include <QSpinBox>
#include <QTextBrowser>
-#include <QTableWidget>
+#include <QScrollArea>
+#include <QHeaderView>
#include <QSlider>
#include <QSignalMapper>
#include <QColorDialog>
#include <QStandardItemModel>
+#include <QDebug>
#include "pageoptions.h"
+#include "gameuiconfig.h"
#include "hwconsts.h"
#include "fpsedit.h"
-#include "igbox.h"
#include "DataManager.h"
+#include "LibavInteraction.h"
+#include "AutoUpdater.h"
+#include "HWApplication.h"
+#include "keybinder.h"
+
+#ifdef __APPLE__
+#ifdef SPARKLE_ENABLED
+#include "SparkleAutoUpdater.h"
+#endif
+#endif
+
+const int OPTION_BOX_SPACING = 10;
+
+OptionGroupBox::OptionGroupBox(const QString & iconName,
+ const QString & title,
+ QWidget * parent) : IconedGroupBox(parent)
+{
+ setIcon(QIcon(iconName));
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ setTitle(title);
+ setMinimumWidth(300);
+ m_layout = new QGridLayout(this);
+ m_layout->setColumnStretch(0, 0);
+ m_layout->setColumnStretch(1, 1);
+}
+
+QGridLayout * OptionGroupBox::layout()
+{
+ return m_layout;
+}
+
+void OptionGroupBox::addDivider()
+{
+ QFrame * hr = new QFrame(this);
+ hr->setFrameStyle(QFrame::HLine);
+ hr->setLineWidth(3);
+ hr->setFixedHeight(10);
+ m_layout->addWidget(hr, m_layout->rowCount(), 0, 1, m_layout->columnCount());
+}
// TODO cleanup
QLayout * PageOptions::bodyLayoutDefinition()
@@ -45,270 +87,229 @@ QLayout * PageOptions::bodyLayoutDefinition()
QTabWidget * tabs = new QTabWidget(this);
pageLayout->addWidget(tabs);
- QWidget * page1 = new QWidget(this);
- QWidget * page2 = new QWidget(this);
- tabs->addTab(page1, tr("General"));
- tabs->addTab(page2, tr("Advanced"));
- { // page 1
- QGridLayout * page1Layout = new QGridLayout(page1);
- //gbTBLayout->setMargin(0);
- page1Layout->setSpacing(0);
- page1Layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ binder = new KeyBinder(this, tr("Select an action to change what key controls it"), tr("Reset to default"), tr("Reset all binds"));
+ connect(binder, SIGNAL(bindUpdate(int)), this, SLOT(bindUpdated(int)));
+ connect(binder, SIGNAL(resetAllBinds()), this, SLOT(resetAllBinds()));
- QPixmap pmNew(":/res/new.png");
- QPixmap pmEdit(":/res/edit.png");
- QPixmap pmDelete(":/res/delete.png");
+ QWidget * pageGame = new QWidget(this);
+ tabs->addTab(pageGame, tr("Game"));
- {
- teamsBox = new IconedGroupBox(this);
- //teamsBox->setContentTopPadding(0);
- //teamsBox->setAttribute(Qt::WA_PaintOnScreen, true);
- teamsBox->setIcon(QIcon(":/res/teamicon.png"));
- teamsBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- teamsBox->setTitle(QGroupBox::tr("Teams"));
+ QWidget * pageGraphics = new QWidget(this);
+ tabs->addTab(pageGraphics, tr("Graphics"));
+
+ QWidget * pageAudio = new QWidget(this);
+ tabs->addTab(pageAudio, tr("Audio"));
+
+ binderTab = tabs->addTab(binder, tr("Controls"));
+
+#ifdef VIDEOREC
+ QWidget * pageVideoRec = new QWidget(this);
+ tabs->addTab(pageVideoRec, tr("Video Recording"));
+#endif
+
+ QWidget * pageNetwork = new QWidget(this);
+ tabs->addTab(pageNetwork, tr("Network"));
+
+ QWidget * pageAdvanced = new QWidget(this);
+ tabs->addTab(pageAdvanced, tr("Advanced"));
+
+ connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabIndexChanged(int)));
- QGridLayout * GBTlayout = new QGridLayout(teamsBox);
+ QPixmap pmNew(":/res/new.png");
+ QPixmap pmEdit(":/res/edit.png");
+ QPixmap pmDelete(":/res/delete.png");
- CBTeamName = new QComboBox(teamsBox);
- GBTlayout->addWidget(CBTeamName, 0, 0);
+ { // game page
+ QVBoxLayout * leftColumn, * rightColumn;
+ setupTabPage(pageGame, &leftColumn, &rightColumn);
- BtnNewTeam = new QPushButton(teamsBox);
- BtnNewTeam->setToolTip(tr("New team"));
+ { // group: Teams
+ OptionGroupBox * groupTeams = new OptionGroupBox(":/res/teamicon.png", tr("Teams"), this);
+ groupTeams->setMinimumWidth(400);
+ rightColumn->addWidget(groupTeams);
+
+ groupTeams->layout()->setColumnStretch(0, 1);
+
+ CBTeamName = new QComboBox(groupTeams);
+ groupTeams->layout()->addWidget(CBTeamName, 0, 0);
+
+ BtnNewTeam = new QPushButton(groupTeams);
+ BtnNewTeam->setWhatsThis(tr("New team"));
BtnNewTeam->setIconSize(pmNew.size());
BtnNewTeam->setIcon(pmNew);
BtnNewTeam->setMaximumWidth(pmNew.width() + 6);
connect(BtnNewTeam, SIGNAL(clicked()), this, SIGNAL(newTeamRequested()));
- GBTlayout->addWidget(BtnNewTeam, 0, 1);
+ groupTeams->layout()->addWidget(BtnNewTeam, 0, 1);
- BtnEditTeam = new QPushButton(teamsBox);
- BtnEditTeam->setToolTip(tr("Edit team"));
+ BtnEditTeam = new QPushButton(groupTeams);
+ BtnEditTeam->setWhatsThis(tr("Edit team"));
BtnEditTeam->setIconSize(pmEdit.size());
BtnEditTeam->setIcon(pmEdit);
BtnEditTeam->setMaximumWidth(pmEdit.width() + 6);
connect(BtnEditTeam, SIGNAL(clicked()), this, SLOT(requestEditSelectedTeam()));
- GBTlayout->addWidget(BtnEditTeam, 0, 2);
+ groupTeams->layout()->addWidget(BtnEditTeam, 0, 2);
- BtnDeleteTeam = new QPushButton(teamsBox);
- BtnDeleteTeam->setToolTip(tr("Delete team"));
+ BtnDeleteTeam = new QPushButton(groupTeams);
+ BtnDeleteTeam->setWhatsThis(tr("Delete team"));
BtnDeleteTeam->setIconSize(pmDelete.size());
BtnDeleteTeam->setIcon(pmDelete);
BtnDeleteTeam->setMaximumWidth(pmDelete.width() + 6);
connect(BtnDeleteTeam, SIGNAL(clicked()), this, SLOT(requestDeleteSelectedTeam()));
- GBTlayout->addWidget(BtnDeleteTeam, 0, 3);
+ groupTeams->layout()->addWidget(BtnDeleteTeam, 0, 3);
- LblNoEditTeam = new QLabel(teamsBox);
+ LblNoEditTeam = new QLabel(groupTeams);
LblNoEditTeam->setText(tr("You can't edit teams from team selection. Go back to main menu to add, edit or delete teams."));
LblNoEditTeam->setWordWrap(true);
LblNoEditTeam->setVisible(false);
- GBTlayout->addWidget(LblNoEditTeam, 0, 0);
-
- page1Layout->addWidget(teamsBox, 0, 0);
+ groupTeams->layout()->addWidget(LblNoEditTeam, 1, 0, 1, 4);
}
- {
- IconedGroupBox* groupWeapons = new IconedGroupBox(this);
+ { // group: schemes
+ OptionGroupBox * groupSchemes = new OptionGroupBox(":/res/weaponsicon.png", tr("Schemes"), this);
+ leftColumn->addWidget(groupSchemes);
- //groupWeapons->setContentTopPadding(0);
- //groupWeapons->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- groupWeapons->setIcon(QIcon(":/res/weaponsicon.png"));
- groupWeapons->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- groupWeapons->setTitle(QGroupBox::tr("Schemes and Weapons"));
- QGridLayout * WeaponsLayout = new QGridLayout(groupWeapons);
+ groupSchemes->layout()->setColumnStretch(0, 1);
- QLabel* SchemeLabel = new QLabel(groupWeapons);
- SchemeLabel->setText(QLabel::tr("Game scheme"));
- WeaponsLayout->addWidget(SchemeLabel, 1, 0);
+ SchemesName = new QComboBox(groupSchemes);
+ groupSchemes->layout()->addWidget(SchemesName, 0, 0);
- SchemesName = new QComboBox(groupWeapons);
- WeaponsLayout->addWidget(SchemesName, 1, 1);
-
- SchemeNew = new QPushButton(groupWeapons);
+ SchemeNew = new QPushButton(groupSchemes);
SchemeNew->setWhatsThis(tr("New scheme"));
SchemeNew->setIconSize(pmNew.size());
SchemeNew->setIcon(pmNew);
SchemeNew->setMaximumWidth(pmNew.width() + 6);
- WeaponsLayout->addWidget(SchemeNew, 1, 2);
+ groupSchemes->layout()->addWidget(SchemeNew, 0, 1);
- SchemeEdit = new QPushButton(groupWeapons);
+ SchemeEdit = new QPushButton(groupSchemes);
SchemeEdit->setWhatsThis(tr("Edit scheme"));
SchemeEdit->setIconSize(pmEdit.size());
SchemeEdit->setIcon(pmEdit);
SchemeEdit->setMaximumWidth(pmEdit.width() + 6);
- WeaponsLayout->addWidget(SchemeEdit, 1, 3);
+ groupSchemes->layout()->addWidget(SchemeEdit, 0, 2);
- SchemeDelete = new QPushButton(groupWeapons);
+ SchemeDelete = new QPushButton(groupSchemes);
SchemeDelete->setWhatsThis(tr("Delete scheme"));
SchemeDelete->setIconSize(pmDelete.size());
SchemeDelete->setIcon(pmDelete);
SchemeDelete->setMaximumWidth(pmDelete.width() + 6);
- WeaponsLayout->addWidget(SchemeDelete, 1, 4);
+ groupSchemes->layout()->addWidget(SchemeDelete, 0, 3);
+ }
- QLabel* WeaponLabel = new QLabel(groupWeapons);
- WeaponLabel->setText(QLabel::tr("Weapons"));
- WeaponsLayout->addWidget(WeaponLabel, 2, 0);
+ { // group: weapons
+ OptionGroupBox * groupWeapons = new OptionGroupBox(":/res/weaponsicon.png", tr("Weapons"), this);
+ leftColumn->addWidget(groupWeapons);
+
+ groupWeapons->layout()->setColumnStretch(0, 1);
WeaponsName = new QComboBox(groupWeapons);
- WeaponsLayout->addWidget(WeaponsName, 2, 1);
+ groupWeapons->layout()->addWidget(WeaponsName, 0, 0);
WeaponNew = new QPushButton(groupWeapons);
WeaponNew->setWhatsThis(tr("New weapon set"));
WeaponNew->setIconSize(pmNew.size());
WeaponNew->setIcon(pmNew);
WeaponNew->setMaximumWidth(pmNew.width() + 6);
- WeaponsLayout->addWidget(WeaponNew, 2, 2);
+ groupWeapons->layout()->addWidget(WeaponNew, 0, 1);
WeaponEdit = new QPushButton(groupWeapons);
WeaponEdit->setWhatsThis(tr("Edit weapon set"));
WeaponEdit->setIconSize(pmEdit.size());
WeaponEdit->setIcon(pmEdit);
WeaponEdit->setMaximumWidth(pmEdit.width() + 6);
- WeaponsLayout->addWidget(WeaponEdit, 2, 3);
+ groupWeapons->layout()->addWidget(WeaponEdit, 0, 2);
WeaponDelete = new QPushButton(groupWeapons);
WeaponDelete->setWhatsThis(tr("Delete weapon set"));
WeaponDelete->setIconSize(pmDelete.size());
WeaponDelete->setIcon(pmDelete);
WeaponDelete->setMaximumWidth(pmDelete.width() + 6);
- WeaponsLayout->addWidget(WeaponDelete, 2, 4);
-
- page1Layout->addWidget(groupWeapons, 1, 0);
+ groupWeapons->layout()->addWidget(WeaponDelete, 0, 3);
}
- {
- IconedGroupBox* groupMisc = new IconedGroupBox(this);
- //groupMisc->setContentTopPadding(0);
- //groupMisc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
- groupMisc->setIcon(QIcon(":/res/miscicon.png"));
- //groupMisc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- groupMisc->setTitle(QGroupBox::tr("Misc"));
- QGridLayout * MiscLayout = new QGridLayout(groupMisc);
-
- // Label for "Language"
- QLabel *labelLanguage = new QLabel(groupMisc);
- labelLanguage->setText(QLabel::tr("Locale") + " *");
- MiscLayout->addWidget(labelLanguage, 0, 0);
+ leftColumn->addStretch(1);
+ rightColumn->addStretch(1);
+ }
- // List of installed languages
- CBLanguage = new QComboBox(groupMisc);
- QDir tmpdir;
- tmpdir.cd(cfgdir->absolutePath());
- tmpdir.cd("Data/Locale");
- tmpdir.setFilter(QDir::Files);
- QStringList locs = tmpdir.entryList(QStringList("hedgewars_*.qm"));
- CBLanguage->addItem(QComboBox::tr("(System default)"), QString(""));
- for(int i = 0; i < locs.count(); i++)
- {
- QLocale loc(locs[i].replace(QRegExp("hedgewars_(.*)\\.qm"), "\\1"));
- CBLanguage->addItem(QLocale::languageToString(loc.language()) + " (" + QLocale::countryToString(loc.country()) + ")", loc.name());
- }
+ { // graphics page
+ QVBoxLayout * leftColumn, * rightColumn;
+ setupTabPage(pageGraphics, &leftColumn, &rightColumn);
- tmpdir.cd(datadir->absolutePath());
- tmpdir.cd("Locale");
- tmpdir.setFilter(QDir::Files);
- QStringList tmplist = tmpdir.entryList(QStringList("hedgewars_*.qm"));
- for(int i = 0; i < tmplist.count(); i++)
- {
- if (locs.contains(tmplist[i])) continue;
- QLocale loc(tmplist[i].replace(QRegExp("hedgewars_(.*)\\.qm"), "\\1"));
- CBLanguage->addItem(QLocale::languageToString(loc.language()) + " (" + QLocale::countryToString(loc.country()) + ")", loc.name());
- }
+ { // group: game
+ OptionGroupBox * groupGame = new OptionGroupBox(":/res/graphicsicon.png", tr("Game"), this);
+ leftColumn->addWidget(groupGame);
- MiscLayout->addWidget(CBLanguage, 0, 1);
+ groupGame->layout()->setColumnStretch(0, 0);
+ groupGame->layout()->setColumnStretch(1, 0);
+ groupGame->layout()->setColumnStretch(2, 1);
- // Label and field for net nick
- labelNN = new QLabel(groupMisc);
- labelNN->setText(QLabel::tr("Nickname"));
- MiscLayout->addWidget(labelNN, 1, 0);
+ // Fullscreen
- editNetNick = new QLineEdit(groupMisc);
- editNetNick->setMaxLength(20);
- editNetNick->setText(QLineEdit::tr("anonymous"));
- MiscLayout->addWidget(editNetNick, 1, 1);
+ CBFullscreen = new QCheckBox(groupGame);
+ groupGame->layout()->addWidget(CBFullscreen, 0, 0, 1, 2);
+ CBFullscreen->setText(QLabel::tr("Fullscreen"));
- // checkbox and field for password
- CBSavePassword = new QCheckBox(groupMisc);
- CBSavePassword->setText(QCheckBox::tr("Save password"));
- MiscLayout->addWidget(CBSavePassword, 2, 0);
+ // Fullscreen resolution
- editNetPassword = new QLineEdit(groupMisc);
- editNetPassword->setEchoMode(QLineEdit::Password);
- MiscLayout->addWidget(editNetPassword, 2, 1);
+ lblFullScreenRes = new QLabel(groupGame);
+ lblFullScreenRes->setText(QLabel::tr("Fullscreen Resolution"));
+ groupGame->layout()->addWidget(lblFullScreenRes, 1, 0);
- #ifdef __APPLE__
- #ifdef SPARKLE_ENABLED
- CBAutoUpdate = new QCheckBox(groupMisc);
- CBAutoUpdate->setText(QCheckBox::tr("Check for updates at startup"));
- MiscLayout->addWidget(CBAutoUpdate, 7, 0, 1, 3);
- #endif
- #endif
- page1Layout->addWidget(groupMisc, 2, 0);
- }
+ CBResolution = new QComboBox(groupGame);
+ CBResolution->setFixedWidth(200);
+ groupGame->layout()->addWidget(CBResolution, 1, 1, Qt::AlignLeft);
- {
- AGGroupBox = new IconedGroupBox(this);
- //AGGroupBox->setContentTopPadding(0);
- AGGroupBox->setIcon(QIcon(":/res/graphicsicon.png"));
- //AGGroupBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
- AGGroupBox->setTitle(QGroupBox::tr("Audio/Graphic options"));
-
- QVBoxLayout * GBAlayout = new QVBoxLayout(AGGroupBox);
- QHBoxLayout * GBAreslayout = new QHBoxLayout(0);
- QHBoxLayout * GBAstereolayout = new QHBoxLayout(0);
- QHBoxLayout * GBAqualayout = new QHBoxLayout(0);
-
- CBFrontendFullscreen = new QCheckBox(AGGroupBox);
- CBFrontendFullscreen->setText(QCheckBox::tr("Frontend fullscreen"));
- GBAlayout->addWidget(CBFrontendFullscreen);
-
- CBFrontendEffects = new QCheckBox(AGGroupBox);
- CBFrontendEffects->setText(QCheckBox::tr("Frontend effects"));
- GBAlayout->addWidget(CBFrontendEffects);
-
- CBEnableFrontendSound = new QCheckBox(AGGroupBox);
- CBEnableFrontendSound->setText(QCheckBox::tr("Enable frontend sounds"));
- GBAlayout->addWidget(CBEnableFrontendSound);
-
- CBEnableFrontendMusic = new QCheckBox(AGGroupBox);
- CBEnableFrontendMusic->setText(QCheckBox::tr("Enable frontend music"));
- GBAlayout->addWidget(CBEnableFrontendMusic);
-
- QFrame * hr = new QFrame(AGGroupBox);
- hr->setFrameStyle(QFrame::HLine);
- hr->setLineWidth(3);
- hr->setFixedHeight(10);
- GBAlayout->addWidget(hr);
-
- QLabel * resolution = new QLabel(AGGroupBox);
- resolution->setText(QLabel::tr("Resolution"));
- GBAreslayout->addWidget(resolution);
-
- CBResolution = new QComboBox(AGGroupBox);
- GBAreslayout->addWidget(CBResolution);
- GBAlayout->addLayout(GBAreslayout);
-
- CBFullscreen = new QCheckBox(AGGroupBox);
- CBFullscreen->setText(QCheckBox::tr("Fullscreen"));
- GBAreslayout->addWidget(CBFullscreen);
-
- QLabel * quality = new QLabel(AGGroupBox);
- quality->setText(QLabel::tr("Quality"));
- quality->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- GBAqualayout->addWidget(quality);
-
- SLQuality = new QSlider(Qt::Horizontal, AGGroupBox);
+ // Windowed resolution
+
+ lblWinScreenRes = new QLabel(groupGame);
+ lblWinScreenRes->setText(QLabel::tr("Windowed Resolution"));
+ groupGame->layout()->addWidget(lblWinScreenRes, 2, 0);
+
+ winResContainer = new QWidget();
+ QHBoxLayout * winResLayout = new QHBoxLayout(winResContainer);
+ winResLayout->setSpacing(0);
+ groupGame->layout()->addWidget(winResContainer, 2, 1);
+
+ QLabel *winLabelX = new QLabel(groupGame);
+ winLabelX->setText("x"); // decorational x
+ winLabelX->setFixedWidth(40);
+ winLabelX->setAlignment(Qt::AlignCenter);
+
+ // TODO: less random max. also:
+ // make some min/max-consts, shared with engine?
+ windowWidthEdit = new QSpinBox(groupGame);
+ windowWidthEdit->setRange(640, 102400);
+ windowWidthEdit->setFixedSize(55, CBResolution->height());
+ windowHeightEdit = new QSpinBox(groupGame);
+ windowHeightEdit->setRange(480, 102400);
+ windowHeightEdit->setFixedSize(55, CBResolution->height());
+
+ winResLayout->addWidget(windowWidthEdit, 0);
+ winResLayout->addWidget(winLabelX, 0);
+ winResLayout->addWidget(windowHeightEdit, 0);
+ winResLayout->addStretch(1);
+
+ // Quality
+
+ QLabel * lblQuality = new QLabel(groupGame);
+ lblQuality->setText(QLabel::tr("Quality"));
+ lblQuality->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ groupGame->layout()->addWidget(lblQuality, 3, 0);
+
+ SLQuality = new QSlider(Qt::Horizontal, groupGame);
SLQuality->setTickPosition(QSlider::TicksBelow);
SLQuality->setMaximum(5);
SLQuality->setMinimum(0);
SLQuality->setFixedWidth(150);
- GBAqualayout->addWidget(SLQuality);
- GBAlayout->addLayout(GBAqualayout);
+ groupGame->layout()->addWidget(SLQuality, 3, 1, Qt::AlignLeft);
+
+ // Stereo spacing
- QLabel * stereo = new QLabel(AGGroupBox);
- stereo->setText(QLabel::tr("Stereo rendering"));
- GBAstereolayout->addWidget(stereo);
+ QLabel * lblStereo = new QLabel(groupGame);
+ lblStereo->setText(QLabel::tr("Stereo rendering"));
+ groupGame->layout()->addWidget(lblStereo, 4, 0);
- CBStereoMode = new QComboBox(AGGroupBox);
+ CBStereoMode = new QComboBox(groupGame);
CBStereoMode->addItem(QComboBox::tr("Disabled"));
CBStereoMode->addItem(QComboBox::tr("Red/Cyan"));
CBStereoMode->addItem(QComboBox::tr("Cyan/Red"));
@@ -316,74 +317,84 @@ QLayout * PageOptions::bodyLayoutDefinition()
CBStereoMode->addItem(QComboBox::tr("Blue/Red"));
CBStereoMode->addItem(QComboBox::tr("Red/Green"));
CBStereoMode->addItem(QComboBox::tr("Green/Red"));
- CBStereoMode->addItem(QComboBox::tr("Side-by-side"));
- CBStereoMode->addItem(QComboBox::tr("Top-Bottom"));
- CBStereoMode->addItem(QComboBox::tr("Wiggle"));
CBStereoMode->addItem(QComboBox::tr("Red/Cyan grayscale"));
CBStereoMode->addItem(QComboBox::tr("Cyan/Red grayscale"));
CBStereoMode->addItem(QComboBox::tr("Red/Blue grayscale"));
CBStereoMode->addItem(QComboBox::tr("Blue/Red grayscale"));
CBStereoMode->addItem(QComboBox::tr("Red/Green grayscale"));
CBStereoMode->addItem(QComboBox::tr("Green/Red grayscale"));
+ CBStereoMode->addItem(QComboBox::tr("Side-by-side"));
+ CBStereoMode->addItem(QComboBox::tr("Top-Bottom"));
+ CBStereoMode->setFixedWidth(CBResolution->width());
+ groupGame->layout()->addWidget(CBStereoMode, 4, 1);
- GBAstereolayout->addWidget(CBStereoMode);
- GBAlayout->addLayout(GBAstereolayout);
+ // Divider
- hr = new QFrame(AGGroupBox);
- hr->setFrameStyle(QFrame::HLine);
- hr->setLineWidth(3);
- hr->setFixedHeight(10);
- GBAlayout->addWidget(hr);
+ groupGame->addDivider(); // row 5
- QGridLayout * GBAvollayout = new QGridLayout();
- QLabel * vol = new QLabel(AGGroupBox);
- vol->setText(QLabel::tr("Initial sound volume"));
- GBAvollayout->addWidget(vol, 0, 0, 1, 2);
- GBAlayout->addLayout(GBAvollayout);
- volumeBox = new QSpinBox(AGGroupBox);
- volumeBox->setRange(0, 100);
- volumeBox->setSingleStep(5);
- GBAvollayout->addWidget(volumeBox, 0, 2);
-
- CBEnableSound = new QCheckBox(AGGroupBox);
- CBEnableSound->setText(QCheckBox::tr("Enable sound"));
- GBAvollayout->addWidget(CBEnableSound, 1, 0, 1, 1);
-
- CBEnableMusic = new QCheckBox(AGGroupBox);
- CBEnableMusic->setText(QCheckBox::tr("Enable music"));
- GBAvollayout->addWidget(CBEnableMusic, 1, 1, 1, 2);
-
- GBAvollayout->setSizeConstraint(QLayout::SetMinimumSize);
-
- hr = new QFrame(AGGroupBox);
- hr->setFrameStyle(QFrame::HLine);
- hr->setLineWidth(3);
- hr->setFixedHeight(10);
- GBAlayout->addWidget(hr);
-
- CBAltDamage = new QCheckBox(AGGroupBox);
+ // FPS limit
+
+ QHBoxLayout * fpsLayout = new QHBoxLayout();
+ groupGame->layout()->addLayout(fpsLayout, 6, 0, 1, 2);
+ QLabel * maxfps = new QLabel(groupGame);
+ maxfps->setText(QLabel::tr("FPS limit"));
+ fpsLayout->addWidget(maxfps);
+ fpsLayout->addSpacing(30);
+ fpsedit = new FPSEdit(groupGame);
+ fpsLayout->addWidget(fpsedit);
+
+ // Show FPS
+
+ CBShowFPS = new QCheckBox(groupGame);
+ CBShowFPS->setText(QCheckBox::tr("Show FPS"));
+ fpsLayout->addWidget(CBShowFPS);
+ fpsLayout->addStretch(1);
+
+ // Divider
+
+ groupGame->addDivider(); // row 7
+
+ // Alternative damage show
+
+ CBAltDamage = new QCheckBox(groupGame);
CBAltDamage->setText(QCheckBox::tr("Alternative damage show"));
- GBAlayout->addWidget(CBAltDamage);
+ groupGame->layout()->addWidget(CBAltDamage, 8, 0, 1, 2);
- page1Layout->addWidget(AGGroupBox, 0, 1, 3, 1);
+ // Show ammo menu tooltips
+
+ WeaponTooltip = new QCheckBox(groupGame);
+ WeaponTooltip->setText(QCheckBox::tr("Show ammo menu tooltips"));
+ groupGame->layout()->addWidget(WeaponTooltip, 9, 0, 1, 2);
}
- page1Layout->addWidget(new QWidget(this), 3, 0);
+ { // group: frontend
+ OptionGroupBox * groupFrontend = new OptionGroupBox(":/res/graphicsicon.png", tr("Frontend"), this);
+ rightColumn->addWidget(groupFrontend);
- }
+ // Fullscreen
- { // page 2
- QGridLayout * page2Layout = new QGridLayout(page2);
+ CBFrontendFullscreen = new QCheckBox(groupFrontend);
+ CBFrontendFullscreen->setText(QCheckBox::tr("Fullscreen"));
+ groupFrontend->layout()->addWidget(CBFrontendFullscreen, 0, 0);
- {
- IconedGroupBox * gbColors = new IconedGroupBox(this);
- gbColors->setIcon(QIcon(":/res/lightbulb_on.png"));
- gbColors->setTitle(QGroupBox::tr("Custom colors"));
- page2Layout->addWidget(gbColors, 0, 0);
- QGridLayout * gbCLayout = new QGridLayout(gbColors);
+ // Visual effects
- QSignalMapper * mapper = new QSignalMapper(this);
+ CBFrontendEffects = new QCheckBox(groupFrontend);
+ CBFrontendEffects->setText(QCheckBox::tr("Visual effects"));
+ groupFrontend->layout()->addWidget(CBFrontendEffects, 1, 0);
+ }
+
+ { // group: colors
+ OptionGroupBox * groupColors = new OptionGroupBox(":/res/lightbulb_on.png", tr("Custom colors"), this);
+ rightColumn->addWidget(groupColors);
+
+ groupColors->layout()->setColumnStretch(0, 1);
+ groupColors->layout()->setColumnStretch(1, 1);
+ groupColors->layout()->setColumnStretch(2, 1);
+
+ // Color buttons
+ QSignalMapper * mapper = new QSignalMapper(this);
QStandardItemModel * model = DataManager::instance().colorsModel();
connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(onColorModelDataChanged(QModelIndex,QModelIndex)));
@@ -391,7 +402,7 @@ QLayout * PageOptions::bodyLayoutDefinition()
{
QPushButton * btn = new QPushButton(this);
btn->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
- gbCLayout->addWidget(btn, i / 3, i % 3);
+ groupColors->layout()->addWidget(btn, i / 3, i % 3);
btn->setStyleSheet(QString("background: %1").arg(model->item(i)->data().value<QColor>().name()));
m_colorButtons.append(btn);
connect(btn, SIGNAL(clicked()), mapper, SLOT(map()));
@@ -400,103 +411,379 @@ QLayout * PageOptions::bodyLayoutDefinition()
connect(mapper, SIGNAL(mapped(int)), this, SLOT(colorButtonClicked(int)));
+ // Reset default colors
+
QPushButton * btn = new QPushButton(this);
- gbCLayout->addWidget(btn, (model->rowCount() - 1) / 3 + 1, 0, 1, 3);
+ groupColors->layout()->addWidget(btn, (model->rowCount() - 1) / 3 + 1, 0, 1, 3);
btn->setText(tr("Reset to default colors"));
connect(btn, SIGNAL(clicked()), &DataManager::instance(), SLOT(resetColors()));
}
- {
- IconedGroupBox * gbMisc = new IconedGroupBox(this);
- gbMisc->setIcon(QIcon(":/res/Settings.png"));
- gbMisc->setTitle(QGroupBox::tr("Miscellaneous"));
- page2Layout->addWidget(gbMisc, 0, 1);
- QVBoxLayout * gbCLayout = new QVBoxLayout(gbMisc);
-
- QHBoxLayout * GBAfpslayout = new QHBoxLayout(0);
- QLabel * maxfps = new QLabel(AGGroupBox);
- maxfps->setText(QLabel::tr("FPS limit"));
- GBAfpslayout->addWidget(maxfps);
- fpsedit = new FPSEdit(AGGroupBox);
- GBAfpslayout->addWidget(fpsedit);
+ leftColumn->addStretch(1);
+ rightColumn->addStretch(1);
+ }
- CBShowFPS = new QCheckBox(AGGroupBox);
- CBShowFPS->setText(QCheckBox::tr("Show FPS"));
- GBAfpslayout->addWidget(CBShowFPS);
+ { // audio page
+ QVBoxLayout * leftColumn, * rightColumn;
+ setupTabPage(pageAudio, &leftColumn, &rightColumn);
- gbCLayout->addLayout(GBAfpslayout);
+ { // group: game
+ OptionGroupBox * groupGame = new OptionGroupBox(":/res/audio.png", tr("Game audio"), this);
+ leftColumn->addWidget(groupGame);
+ groupGame->layout()->setColumnStretch(1, 0);
+ groupGame->layout()->setColumnStretch(2, 1);
+ // Initial sound volume
- WeaponTooltip = new QCheckBox(this);
- WeaponTooltip->setText(QCheckBox::tr("Show ammo menu tooltips"));
- gbCLayout->addWidget(WeaponTooltip);
+ QLabel * vol = new QLabel(groupGame);
+ vol->setText(QLabel::tr("Initial sound volume"));
+ groupGame->layout()->addWidget(vol, 0, 0);
+ SLVolume = new QSlider(Qt::Horizontal, groupGame);
+ SLVolume->setTickPosition(QSlider::TicksBelow);
+ SLVolume->setMaximum(100);
+ SLVolume->setMinimum(0);
+ SLVolume->setFixedWidth(150);
+ groupGame->layout()->addWidget(SLVolume, 0, 1, 1, 2);
- CBNameWithDate = new QCheckBox(this);
- CBNameWithDate->setText(QCheckBox::tr("Append date and time to record file name"));
- gbCLayout->addWidget(CBNameWithDate);
+ lblVolumeLevel = new QLabel(groupGame);
+ lblVolumeLevel->setFixedWidth(40);
+ groupGame->layout()->addWidget(lblVolumeLevel, 0, 3);
- BtnAssociateFiles = new QPushButton(this);
- BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions"));
- BtnAssociateFiles->setVisible(!custom_data && !custom_config);
- gbCLayout->addWidget(BtnAssociateFiles);
+ // Sound
+
+ CBSound = new QCheckBox(groupGame);
+ CBSound->setText(QCheckBox::tr("Sound"));
+ CBSound->setWhatsThis(QCheckBox::tr("In-game sound effects"));
+ groupGame->layout()->addWidget(CBSound, 1, 1);
+
+ // Music
+
+ CBMusic = new QCheckBox(groupGame);
+ CBMusic->setText(QCheckBox::tr("Music"));
+ CBMusic->setWhatsThis(QCheckBox::tr("In-game music"));
+ groupGame->layout()->addWidget(CBMusic, 1, 2, 1, 2, Qt::AlignLeft);
}
- {
- IconedGroupBox * gbProxy = new IconedGroupBox(this);
- gbProxy->setIcon(QIcon(":/res/Settings.png"));
- gbProxy->setTitle(QGroupBox::tr("Proxy settings"));
- page2Layout->addWidget(gbProxy, 1, 0);
- QGridLayout * gbLayout = new QGridLayout(gbProxy);
+ { // group: frontend
+ OptionGroupBox * groupFrontend = new OptionGroupBox(":/res/audio.png", tr("Frontend audio"), this);
+ rightColumn->addWidget(groupFrontend);
+
+ CBFrontendSound = new QCheckBox(groupFrontend);
+ CBFrontendSound->setText(QCheckBox::tr("Sound"));
+ CBFrontendSound->setWhatsThis(QCheckBox::tr("Frontend sound effects"));
+ groupFrontend->layout()->addWidget(CBFrontendSound, 0, 0);
+
+ CBFrontendMusic = new QCheckBox(groupFrontend);
+ CBFrontendMusic->setText(QCheckBox::tr("Music"));
+ CBFrontendMusic->setWhatsThis(QCheckBox::tr("Frontend music"));
+ groupFrontend->layout()->addWidget(CBFrontendMusic, 0, 1);
+ }
+
+ leftColumn->addStretch(1);
+ rightColumn->addStretch(1);
+ }
+
+ { // network page
+ QVBoxLayout * leftColumn, * rightColumn;
+ setupTabPage(pageNetwork, &leftColumn, &rightColumn);
+
+ { // group: account
+ OptionGroupBox * groupAccount = new OptionGroupBox(":/res/teamicon.png", tr("Account"), this);
+ leftColumn->addWidget(groupAccount);
+
+ // Label and field for net nick
+
+ labelNN = new QLabel(groupAccount);
+ labelNN->setText(QLabel::tr("Nickname"));
+ groupAccount->layout()->addWidget(labelNN, 0, 0);
+
+ editNetNick = new QLineEdit(groupAccount);
+ editNetNick->setMaxLength(20);
+ editNetNick->setText(QLineEdit::tr("anonymous"));
+ groupAccount->layout()->addWidget(editNetNick, 0, 1);
+
+ // Checkbox and field for password
+
+ CBSavePassword = new QCheckBox(groupAccount);
+ CBSavePassword->setText(QCheckBox::tr("Save password"));
+ groupAccount->layout()->addWidget(CBSavePassword, 1, 0);
+
+ editNetPassword = new QLineEdit(groupAccount);
+ editNetPassword->setEchoMode(QLineEdit::Password);
+ groupAccount->layout()->addWidget(editNetPassword, 1, 1);
+ }
+
+ { // group: proxy
+ OptionGroupBox * groupProxy = new OptionGroupBox(":/res/net.png", tr("Proxy settings"), this);
+ rightColumn->addWidget(groupProxy);
+
+ // Labels
QStringList sl;
- sl
- << tr("Proxy host")
- << tr("Proxy port")
- << tr("Proxy login")
- << tr("Proxy password")
- ;
+ sl << tr("Proxy host")
+ << tr("Proxy port")
+ << tr("Proxy login")
+ << tr("Proxy password");
+
for(int i = 0; i < sl.size(); ++i)
{
- QLabel * l = new QLabel(gbProxy);
+ QLabel * l = new QLabel(groupProxy);
l->setText(sl[i]);
- gbLayout->addWidget(l, i + 1, 0);
+ groupProxy->layout()->addWidget(l, i + 1, 0);
}
- cbProxyType = new QComboBox(gbProxy);
+ // Proxy type
+
+ cbProxyType = new QComboBox(groupProxy);
cbProxyType->addItems(QStringList()
<< tr("No proxy")
<< tr("System proxy settings")
<< tr("Socks5 proxy")
<< tr("HTTP proxy"));
- gbLayout->addWidget(cbProxyType, 0, 1);
+ groupProxy->layout()->addWidget(cbProxyType, 0, 0, 1, 2);
+
+ // Proxy
- leProxy = new QLineEdit(gbProxy);
- gbLayout->addWidget(leProxy, 1, 1);
+ leProxy = new QLineEdit(groupProxy);
+ groupProxy->layout()->addWidget(leProxy, 1, 1);
- sbProxyPort = new QSpinBox(gbProxy);
+ // Proxy
+
+ sbProxyPort = new QSpinBox(groupProxy);
sbProxyPort->setMaximum(65535);
- gbLayout->addWidget(sbProxyPort, 2, 1);
+ groupProxy->layout()->addWidget(sbProxyPort, 2, 1);
- leProxyLogin = new QLineEdit(gbProxy);
- gbLayout->addWidget(leProxyLogin, 3, 1);
+ leProxyLogin = new QLineEdit(groupProxy);
+ groupProxy->layout()->addWidget(leProxyLogin, 3, 1);
- leProxyPassword = new QLineEdit(gbProxy);
+ leProxyPassword = new QLineEdit(groupProxy);
leProxyPassword->setEchoMode(QLineEdit::Password);
- gbLayout->addWidget(leProxyPassword, 4, 1);
+ groupProxy->layout()->addWidget(leProxyPassword, 4, 1);
connect(cbProxyType, SIGNAL(currentIndexChanged(int)), this, SLOT(onProxyTypeChanged()));
onProxyTypeChanged();
}
- page2Layout->addWidget(new QWidget(this), 2, 0);
+ leftColumn->addStretch(1);
+ rightColumn->addStretch(1);
}
+ { // advanced page
+ QVBoxLayout * leftColumn, * rightColumn;
+ setupTabPage(pageAdvanced, &leftColumn, &rightColumn);
+
+ { // group: miscellaneous
+ OptionGroupBox * groupMisc = new OptionGroupBox(":/res/Settings.png", tr("Miscellaneous"), this);
+ leftColumn->addWidget(groupMisc);
+
+ // Language
+
+ QLabel *labelLanguage = new QLabel(groupMisc);
+ labelLanguage->setText(QLabel::tr("Locale"));
+ groupMisc->layout()->addWidget(labelLanguage, 0, 0);
+
+ CBLanguage = new QComboBox(groupMisc);
+ groupMisc->layout()->addWidget(CBLanguage, 0, 1);
+ QStringList locs = DataManager::instance().entryList("Locale", QDir::Files, QStringList("hedgewars_*.qm"));
+ CBLanguage->addItem(QComboBox::tr("(System default)"), QString());
+ for(int i = 0; i < locs.count(); i++)
+ {
+ QString lname = locs[i].replace(QRegExp("hedgewars_(.*)\\.qm"), "\\1");
+ QLocale loc(lname);
+ CBLanguage->addItem(QLocale::languageToString(loc.language()) + " (" + QLocale::countryToString(loc.country()) + ")", lname);
+ }
+
+ QLabel *restartNoticeLabel = new QLabel(groupMisc);
+ restartNoticeLabel->setText(QLabel::tr("This setting will be effective at next restart."));
+ groupMisc->layout()->addWidget(restartNoticeLabel, 1, 1);
+
+
+ // Divider
+
+ groupMisc->addDivider(); // row 1
+
+ // Append date and time to record file name
+
+ CBNameWithDate = new QCheckBox(groupMisc);
+ CBNameWithDate->setText(QCheckBox::tr("Append date and time to record file name"));
+ groupMisc->layout()->addWidget(CBNameWithDate, 3, 0, 1, 2);
+
+ // Associate file extensions
+
+ BtnAssociateFiles = new QPushButton(groupMisc);
+ BtnAssociateFiles->setText(QPushButton::tr("Associate file extensions"));
+ BtnAssociateFiles->setVisible(!custom_data && !custom_config);
+ groupMisc->layout()->addWidget(BtnAssociateFiles, 4, 0, 1, 2);
+ }
+
+#ifdef __APPLE__
+#ifdef SPARKLE_ENABLED
+ { // group: updates
+ OptionGroupBox * groupUpdates = new OptionGroupBox(":/res/net.png", tr("Updates"), this);
+ rightColumn->addWidget(groupUpdates);
+
+ // Check for updates at startup
+
+ CBAutoUpdate = new QCheckBox(groupUpdates);
+ CBAutoUpdate->setText(QCheckBox::tr("Check for updates at startup"));
+ groupUpdates->layout()->addWidget(CBAutoUpdate, 0, 0);
+
+ // Check for updates now
+
+ btnUpdateNow = new QPushButton(groupUpdates);
+ connect(btnUpdateNow, SIGNAL(clicked()), this, SLOT(checkForUpdates()));
+ btnUpdateNow->setWhatsThis(tr("Check for updates"));
+ btnUpdateNow->setText("Check now");
+ btnUpdateNow->setFixedSize(130, 30);
+ groupUpdates->layout()->addWidget(btnUpdateNow, 0, 1);
+ }
+#endif
+#endif
+
+ leftColumn->addStretch(1);
+ rightColumn->addStretch(1);
+ }
+
+#ifdef VIDEOREC
+ { // video recording page
+ OptionGroupBox * groupVideoRec = new OptionGroupBox(":/res/camera.png", tr("Video recording options"), this);
+ groupVideoRec->setMinimumWidth(500);
+ groupVideoRec->setMaximumWidth(650);
+ QHBoxLayout * layoutVideoRec = new QHBoxLayout(pageVideoRec);
+ layoutVideoRec->addWidget(groupVideoRec, 1, Qt::AlignTop | Qt::AlignHCenter);
+
+ // label for format
+
+ QLabel *labelFormat = new QLabel(groupVideoRec);
+ labelFormat->setText(QLabel::tr("Format"));
+ groupVideoRec->layout()->addWidget(labelFormat, 0, 0);
+
+ // list of supported formats
+
+ comboAVFormats = new QComboBox(groupVideoRec);
+ groupVideoRec->layout()->addWidget(comboAVFormats, 0, 1, 1, 4);
+ LibavInteraction::instance().fillFormats(comboAVFormats);
+
+ // separator
+
+ QFrame * hr = new QFrame(groupVideoRec);
+ hr->setFrameStyle(QFrame::HLine);
+ hr->setLineWidth(3);
+ hr->setFixedHeight(10);
+ groupVideoRec->layout()->addWidget(hr, 1, 0, 1, 5);
+
+ // label for audio codec
+
+ QLabel *labelACodec = new QLabel(groupVideoRec);
+ labelACodec->setText(QLabel::tr("Audio codec"));
+ groupVideoRec->layout()->addWidget(labelACodec, 2, 0);
+
+ // list of supported audio codecs
+
+ comboAudioCodecs = new QComboBox(groupVideoRec);
+ groupVideoRec->layout()->addWidget(comboAudioCodecs, 2, 1, 1, 3);
+
+ // checkbox 'record audio'
+
+ checkRecordAudio = new QCheckBox(groupVideoRec);
+ checkRecordAudio->setText(QCheckBox::tr("Record audio"));
+ groupVideoRec->layout()->addWidget(checkRecordAudio, 2, 4);
+
+ // separator
+
+ hr = new QFrame(groupVideoRec);
+ hr->setFrameStyle(QFrame::HLine);
+ hr->setLineWidth(3);
+ hr->setFixedHeight(10);
+ groupVideoRec->layout()->addWidget(hr, 3, 0, 1, 5);
+
+ // label for video codec
+
+ QLabel *labelVCodec = new QLabel(groupVideoRec);
+ labelVCodec->setText(QLabel::tr("Video codec"));
+ groupVideoRec->layout()->addWidget(labelVCodec, 4, 0);
+
+ // list of supported video codecs
+
+ comboVideoCodecs = new QComboBox(groupVideoRec);
+ groupVideoRec->layout()->addWidget(comboVideoCodecs, 4, 1, 1, 4);
+
+ // label for resolution
+
+ QLabel *labelRes = new QLabel(groupVideoRec);
+ labelRes->setText(QLabel::tr("Resolution"));
+ groupVideoRec->layout()->addWidget(labelRes, 5, 0);
+
+ // width
+
+ widthEdit = new QLineEdit(groupVideoRec);
+ widthEdit->setValidator(new QIntValidator(this));
+ groupVideoRec->layout()->addWidget(widthEdit, 5, 1);
+
+ // x
+
+ QLabel *labelX = new QLabel(groupVideoRec);
+ labelX->setText("X");
+ groupVideoRec->layout()->addWidget(labelX, 5, 2);
+
+ // height
+
+ heightEdit = new QLineEdit(groupVideoRec);
+ heightEdit->setValidator(new QIntValidator(groupVideoRec));
+ groupVideoRec->layout()->addWidget(heightEdit, 5, 3);
+
+ // checkbox 'use game resolution'
+
+ checkUseGameRes = new QCheckBox(groupVideoRec);
+ checkUseGameRes->setText(QCheckBox::tr("Use game resolution"));
+ groupVideoRec->layout()->addWidget(checkUseGameRes, 5, 4);
+
+ // label for framerate
+
+ QLabel *labelFramerate = new QLabel(groupVideoRec);
+ labelFramerate->setText(QLabel::tr("Framerate"));
+ groupVideoRec->layout()->addWidget(labelFramerate, 6, 0);
+
+ framerateBox = new QComboBox(groupVideoRec);
+ framerateBox->addItem("24 fps", 24);
+ framerateBox->addItem("25 fps", 25);
+ framerateBox->addItem("30 fps", 30);
+ framerateBox->addItem("50 fps", 50);
+ framerateBox->addItem("60 fps", 60);
+ groupVideoRec->layout()->addWidget(framerateBox, 6, 1);
+
+ // label for Bitrate
+
+ QLabel *labelBitrate = new QLabel(groupVideoRec);
+ labelBitrate->setText(QLabel::tr("Bitrate (Kbps)"));
+ groupVideoRec->layout()->addWidget(labelBitrate, 6, 2);
+
+ // bitrate
+
+ bitrateBox = new QSpinBox(groupVideoRec);
+ bitrateBox->setRange(100, 5000);
+ bitrateBox->setSingleStep(100);
+ groupVideoRec->layout()->addWidget(bitrateBox, 6, 3);
+
+ // button 'set default options'
+
+ btnDefaults = new QPushButton(groupVideoRec);
+ btnDefaults->setText(QPushButton::tr("Set default options"));
+ btnDefaults->setWhatsThis(QPushButton::tr("Restore default coding parameters"));
+ groupVideoRec->layout()->addWidget(btnDefaults, 7, 0, 1, 5);
+ }
+#endif
+
previousQuality = this->SLQuality->value();
previousResolutionIndex = this->CBResolution->currentIndex();
previousFullscreenValue = this->CBFullscreen->isChecked();
+ setFullscreen(CBFullscreen->isChecked());
+ setVolume(SLVolume->value());
+
+ // mutually exclude window and fullscreen resolution
return pageLayout;
}
@@ -507,6 +794,14 @@ QLayout * PageOptions::footerLayoutDefinition()
void PageOptions::connectSignals()
{
+#ifdef VIDEOREC
+ connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int)));
+ connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int)));
+ connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int)));
+ connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions()));
+#endif
+ //connect(this, SIGNAL(pageEnter()), this, SLOT(setTeamOptionsEnabled()));
+ connect(SLVolume, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int)));
connect(SLQuality, SIGNAL(valueChanged(int)), this, SLOT(setQuality(int)));
connect(CBResolution, SIGNAL(currentIndexChanged(int)), this, SLOT(setResolution(int)));
connect(CBFullscreen, SIGNAL(stateChanged(int)), this, SLOT(setFullscreen(int)));
@@ -515,7 +810,27 @@ void PageOptions::connectSignals()
connect(CBSavePassword, SIGNAL(stateChanged(int)), this, SLOT(savePwdChanged(int)));
}
-PageOptions::PageOptions(QWidget* parent) : AbstractPage(parent)
+void PageOptions::setVolume(int volume)
+{
+ lblVolumeLevel->setText(QString("%1\%").arg(volume));
+}
+
+void PageOptions::setupTabPage(QWidget * tabpage, QVBoxLayout ** leftColumn, QVBoxLayout ** rightColumn)
+{
+ QHBoxLayout * twoColumns = new QHBoxLayout(tabpage);
+ twoColumns->setSpacing(0);
+ *leftColumn = new QVBoxLayout();
+ *rightColumn = new QVBoxLayout();
+ (*leftColumn)->setSpacing(OPTION_BOX_SPACING);
+ (*rightColumn)->setSpacing(OPTION_BOX_SPACING);
+ twoColumns->addStretch(4);
+ twoColumns->addLayout(*leftColumn, 0);
+ twoColumns->addStretch(1);
+ twoColumns->addLayout(*rightColumn, 0);
+ twoColumns->addStretch(4);
+}
+
+PageOptions::PageOptions(QWidget* parent) : AbstractPage(parent), config(0)
{
initPage();
}
@@ -528,16 +843,16 @@ void PageOptions::forceFullscreen(int index)
{
this->SLQuality->setValue(this->SLQuality->maximum());
this->SLQuality->setEnabled(false);
- this->CBFullscreen->setEnabled(!forced);
this->CBFullscreen->setChecked(forced ? true : previousFullscreenValue);
+ setFullscreen(forced ? true : previousFullscreenValue);
this->CBResolution->setCurrentIndex(forced ? 0 : previousResolutionIndex);
}
else
{
this->SLQuality->setEnabled(true);
- this->CBFullscreen->setEnabled(true);
this->SLQuality->setValue(previousQuality);
this->CBFullscreen->setChecked(previousFullscreenValue);
+ setFullscreen(previousFullscreenValue);
this->CBResolution->setCurrentIndex(previousResolutionIndex);
}
}
@@ -555,6 +870,11 @@ void PageOptions::setFullscreen(int state)
{
Q_UNUSED(state);
+ lblFullScreenRes->setVisible(state);
+ CBResolution->setVisible(state);
+ lblWinScreenRes->setVisible(!state);
+ winResContainer->setVisible(!state);
+
int index = this->CBStereoMode->currentIndex();
if (index != 7 && index != 8 && index != 9)
previousFullscreenValue = this->CBFullscreen->isChecked();
@@ -634,3 +954,199 @@ void PageOptions::onProxyTypeChanged()
leProxyLogin->setEnabled(b);
leProxyPassword->setEnabled(b);
}
+
+// Video Recording
+
+void PageOptions::setConfig(GameUIConfig * config)
+{
+ this->config = config;
+}
+
+// user changed file format, we need to update list of codecs
+void PageOptions::changeAVFormat(int index)
+{
+ // remember selected codecs
+ QString prevVCodec = videoCodec();
+ QString prevACodec = audioCodec();
+
+ // clear lists of codecs
+ comboVideoCodecs->clear();
+ comboAudioCodecs->clear();
+
+ // get list of codecs for specified format
+ LibavInteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs);
+
+ // disable audio if there is no audio codec
+ if (comboAudioCodecs->count() == 0)
+ {
+ checkRecordAudio->setChecked(false);
+ checkRecordAudio->setEnabled(false);
+ }
+ else
+ checkRecordAudio->setEnabled(true);
+
+ // restore selected codecs if possible
+ int iVCodec = comboVideoCodecs->findData(prevVCodec);
+ if (iVCodec != -1)
+ comboVideoCodecs->setCurrentIndex(iVCodec);
+ int iACodec = comboAudioCodecs->findData(prevACodec);
+ if (iACodec != -1)
+ comboAudioCodecs->setCurrentIndex(iACodec);
+}
+
+// user switched checkbox 'use game resolution'
+void PageOptions::changeUseGameRes(int state)
+{
+ if (state && config)
+ {
+ // set resolution to game resolution
+ QRect resolution = config->vid_Resolution();
+ widthEdit->setText(QString::number(resolution.width()));
+ heightEdit->setText(QString::number(resolution.height()));
+ }
+ widthEdit->setEnabled(!state);
+ heightEdit->setEnabled(!state);
+}
+
+// user switched checkbox 'record audio'
+void PageOptions::changeRecordAudio(int state)
+{
+ comboAudioCodecs->setEnabled(!!state);
+}
+
+void PageOptions::setDefaultCodecs()
+{
+ // VLC should be able to handle any of these configurations
+ // Quicktime X only opens the first one
+ // Windows Media Player TODO
+ if (tryCodecs("mp4", "libx264", "aac"))
+ return;
+ if (tryCodecs("mp4", "libx264", "libfaac"))
+ return;
+ if (tryCodecs("mp4", "libx264", "libmp3lame"))
+ return;
+ if (tryCodecs("mp4", "libx264", "mp2"))
+ return;
+ if (tryCodecs("avi", "libxvid", "libmp3lame"))
+ return;
+ if (tryCodecs("avi", "libxvid", "ac3_fixed"))
+ return;
+ if (tryCodecs("avi", "libxvid", "mp2"))
+ return;
+ if (tryCodecs("avi", "mpeg4", "libmp3lame"))
+ return;
+ if (tryCodecs("avi", "mpeg4", "ac3_fixed"))
+ return;
+ if (tryCodecs("avi", "mpeg4", "mp2"))
+ return;
+
+ // this shouldn't happen, just in case
+ if (tryCodecs("ogg", "libtheora", "libvorbis"))
+ return;
+ tryCodecs("ogg", "libtheora", "flac");
+}
+
+void PageOptions::setDefaultOptions()
+{
+ framerateBox->setCurrentIndex(2);
+ bitrateBox->setValue(1000);
+ checkRecordAudio->setChecked(true);
+ checkUseGameRes->setChecked(true);
+ setDefaultCodecs();
+}
+
+void PageOptions::checkForUpdates()
+{
+ AutoUpdater *updater = NULL;
+
+#ifdef __APPLE__
+#ifdef SPARKLE_ENABLED
+ updater = new SparkleAutoUpdater();
+#endif
+#endif
+
+ if (updater)
+ {
+ updater->checkForUpdatesNow();
+ delete updater;
+ }
+}
+
+bool PageOptions::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec)
+{
+ // first we should change format
+ int iFormat = comboAVFormats->findData(format);
+ if (iFormat == -1)
+ return false;
+ comboAVFormats->setCurrentIndex(iFormat);
+ // format was changed, so lists of codecs were automatically updated to codecs supported by this format
+
+ // try to find video codec
+ int iVCodec = comboVideoCodecs->findData(vcodec);
+ if (iVCodec == -1)
+ return false;
+ comboVideoCodecs->setCurrentIndex(iVCodec);
+
+ // try to find audio codec
+ int iACodec = comboAudioCodecs->findData(acodec);
+ if (iACodec == -1 && checkRecordAudio->isChecked())
+ return false;
+ if (iACodec != -1)
+ comboAudioCodecs->setCurrentIndex(iACodec);
+
+ return true;
+}
+
+// When the current tab is switched
+void PageOptions::tabIndexChanged(int index)
+{
+ if (index == binderTab) // Switched to bind tab
+ {
+ binder->resetInterface();
+
+ if (!config) return;
+
+ QStandardItemModel * binds = DataManager::instance().bindsModel();
+ for(int i = 0; i < BINDS_NUMBER; i++)
+ {
+ QString value = config->bind(i);
+ QModelIndexList mdl = binds->match(binds->index(0, 0), Qt::UserRole + 1, value, 1, Qt::MatchExactly);
+ if(mdl.size() == 1) binder->setBindIndex(i, mdl[0].row());
+ }
+ }
+
+ currentTab = index;
+}
+
+// When a key bind combobox is changed
+void PageOptions::bindUpdated(int bindID)
+{
+ int bindIndex = binder->bindIndex(bindID);
+
+ if (bindIndex == 0) bindIndex = resetBindToDefault(bindID);
+
+ // Save bind
+ QStandardItemModel * binds = DataManager::instance().bindsModel();
+ QString strbind = binds->index(binder->bindIndex(bindID), 0).data(Qt::UserRole + 1).toString();
+ config->setBind(bindID, strbind);
+}
+
+// Changes a key bind (bindID) to its default value. This updates the bind's combo-box in the UI.
+// Returns: The bind model index of the default.
+int PageOptions::resetBindToDefault(int bindID)
+{
+ QStandardItemModel * binds = DataManager::instance().bindsModel();
+ QModelIndexList mdl = binds->match(binds->index(0, 0), Qt::UserRole + 1, cbinds[bindID].strbind, 1, Qt::MatchExactly);
+ if(mdl.size() == 1) binder->setBindIndex(bindID, mdl[0].row());
+ return mdl[0].row();
+}
+
+// Called when "reset all binds" button is pressed
+void PageOptions::resetAllBinds()
+{
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ resetBindToDefault(i);
+ bindUpdated(i);
+ }
+}
diff --git a/QTfrontend/ui/page/pageoptions.h b/QTfrontend/ui/page/pageoptions.h
index 68cbe51..3041969 100644
--- a/QTfrontend/ui/page/pageoptions.h
+++ b/QTfrontend/ui/page/pageoptions.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,11 +19,32 @@
#ifndef PAGE_OPTIONS_H
#define PAGE_OPTIONS_H
+#include "igbox.h"
#include "AbstractPage.h"
+#include <QString>
+
+class GameUIConfig;
class FPSEdit;
-class IconedGroupBox;
class QSignalMapper;
+class KeyBinder;
+class QGridLayout;
+
+// Let's stay D-R-Y
+class OptionGroupBox : public IconedGroupBox
+{
+ Q_OBJECT
+
+ public:
+ OptionGroupBox(const QString & iconName,
+ const QString & title,
+ QWidget * parent = 0);
+ QGridLayout * layout();
+ void addDivider();
+
+ private:
+ QGridLayout * m_layout;
+};
class PageOptions : public AbstractPage
{
@@ -56,11 +77,13 @@ class PageOptions : public AbstractPage
QComboBox *CBTeamName;
IconedGroupBox *AGGroupBox;
QComboBox *CBResolution;
+ QSpinBox *windowWidthEdit;
+ QSpinBox *windowHeightEdit;
QComboBox *CBStereoMode;
- QCheckBox *CBEnableSound;
- QCheckBox *CBEnableFrontendSound;
- QCheckBox *CBEnableMusic;
- QCheckBox *CBEnableFrontendMusic;
+ QCheckBox *CBFrontendSound;
+ QCheckBox *CBFrontendMusic;
+ QCheckBox *CBSound;
+ QCheckBox *CBMusic;
QCheckBox *CBFullscreen;
QCheckBox *CBFrontendFullscreen;
QCheckBox *CBShowFPS;
@@ -69,11 +92,13 @@ class PageOptions : public AbstractPage
QCheckBox *CBNameWithDate;
#ifdef __APPLE__
QCheckBox *CBAutoUpdate;
+ QPushButton *BtnUpdateNow;
#endif
FPSEdit *fpsedit;
QLabel *labelNN;
- QSpinBox * volumeBox;
+ QSlider *SLVolume;
+ QLabel *lblVolumeLevel;
QLineEdit *editNetNick;
QLineEdit *editNetPassword;
QSlider *SLQuality;
@@ -84,6 +109,26 @@ class PageOptions : public AbstractPage
QLineEdit * leProxyLogin;
QLineEdit * leProxyPassword;
+ QComboBox *framerateBox;
+ QSpinBox *bitrateBox;
+ QLineEdit *widthEdit;
+ QLineEdit *heightEdit;
+ QCheckBox *checkUseGameRes;
+ QCheckBox *checkRecordAudio;
+
+ QString format()
+ { return comboAVFormats->itemData(comboAVFormats->currentIndex()).toString(); }
+
+ QString videoCodec()
+ { return comboVideoCodecs->itemData(comboVideoCodecs->currentIndex()).toString(); }
+
+ QString audioCodec()
+ { return comboAudioCodecs->itemData(comboAudioCodecs->currentIndex()).toString(); }
+
+ void setDefaultCodecs();
+ bool tryCodecs(const QString & format, const QString & vcodec, const QString & acodec);
+ void setConfig(GameUIConfig * config);
+
void setTeamOptionsEnabled(bool enabled);
signals:
@@ -96,6 +141,8 @@ class PageOptions : public AbstractPage
QLayout * bodyLayoutDefinition();
QLayout * footerLayoutDefinition();
void connectSignals();
+ int resetBindToDefault(int bindID);
+ void setupTabPage(QWidget * tabpage, QVBoxLayout ** leftColumn, QVBoxLayout ** rightColumn);
bool previousFullscreenValue;
int previousResolutionIndex;
@@ -106,6 +153,20 @@ class PageOptions : public AbstractPage
QPushButton *BtnDeleteTeam;
QList<QPushButton *> m_colorButtons;
+ QComboBox *comboAVFormats;
+ QComboBox *comboVideoCodecs;
+ QComboBox *comboAudioCodecs;
+ QPushButton *btnDefaults;
+ QPushButton *btnUpdateNow;
+ GameUIConfig * config;
+ KeyBinder * binder;
+ int currentTab;
+ int binderTab;
+
+ QLabel * lblFullScreenRes;
+ QLabel * lblWinScreenRes;
+ QWidget * winResContainer;
+
private slots:
void forceFullscreen(int index);
void setFullscreen(int state);
@@ -118,6 +179,17 @@ class PageOptions : public AbstractPage
void colorButtonClicked(int i);
void onColorModelDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight);
void onProxyTypeChanged();
+ void changeAVFormat(int index);
+ void changeUseGameRes(int state);
+ void changeRecordAudio(int state);
+ void checkForUpdates();
+ void tabIndexChanged(int);
+ void bindUpdated(int bindID);
+ void resetAllBinds();
+ void setVolume(int);
+
+ public slots:
+ void setDefaultOptions();
};
#endif
diff --git a/QTfrontend/ui/page/pageplayrecord.cpp b/QTfrontend/ui/page/pageplayrecord.cpp
index 20f5e4e..5a94707 100644
--- a/QTfrontend/ui/page/pageplayrecord.cpp
+++ b/QTfrontend/ui/page/pageplayrecord.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageplayrecord.h b/QTfrontend/ui/page/pageplayrecord.h
index f1bffcc..2c22e2c 100644
--- a/QTfrontend/ui/page/pageplayrecord.h
+++ b/QTfrontend/ui/page/pageplayrecord.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageroomslist.cpp b/QTfrontend/ui/page/pageroomslist.cpp
index 7724eb3..a1ea0ee 100644
--- a/QTfrontend/ui/page/pageroomslist.cpp
+++ b/QTfrontend/ui/page/pageroomslist.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,102 +16,199 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
-#include <QGridLayout>
+#include <QVBoxLayout>
#include <QHBoxLayout>
+#include <QGridLayout>
#include <QPushButton>
#include <QComboBox>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QHeaderView>
-#include <QTableView>
+#include <QGroupBox>
+#include <QMenu>
+#include <QDebug>
+#include <QSplitter>
#include <QSortFilterProxyModel>
#include "roomslistmodel.h"
#include "ammoSchemeModel.h"
-#include "pageroomslist.h"
#include "hwconsts.h"
#include "chatwidget.h"
+#include "roomnameprompt.h"
+#include "lineeditcursor.h"
+#include "pageroomslist.h"
+
+void RoomTableView::moveDown()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier));
+}
+
+void RoomTableView::moveUp()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier));
+}
QLayout * PageRoomsList::bodyLayoutDefinition()
{
- QGridLayout * pageLayout = new QGridLayout();
-
- QHBoxLayout * newRoomLayout = new QHBoxLayout();
- QLabel * roomNameLabel = new QLabel(this);
- roomNameLabel->setText(tr("Room Name:"));
- roomName = new QLineEdit(this);
- roomName->setMaxLength(60);
- newRoomLayout->addWidget(roomNameLabel);
- newRoomLayout->addWidget(roomName);
- pageLayout->addLayout(newRoomLayout, 0, 0, 1, 2);
-
- roomsList = new QTableView(this);
+ QVBoxLayout * pageLayout = new QVBoxLayout();
+ pageLayout->setSpacing(0);
+
+ QGridLayout * topLayout = new QGridLayout();
+ topLayout->setSpacing(0);
+ pageLayout->addLayout(topLayout, 0);
+
+ // Help/prompt message at top
+ QLabel * lblDesc = new QLabel(tr("Search for a room:"));
+ lblDesc->setObjectName("lblDesc");
+ lblDesc->setStyleSheet("#lblDesc { color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-top-left-radius: 10px; padding: 4px 10px;}");
+ lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ lblDesc->setFixedHeight(24);
+ lblDesc->setMinimumWidth(0);
+
+ // Search text box
+ QWidget * searchContainer = new QWidget();
+ searchContainer->setFixedHeight(24);
+ searchContainer->setObjectName("searchContainer");
+ searchContainer->setStyleSheet("#searchContainer { background: #F6CB1C; border-top-right-radius: 10px; padding: 3px; }");
+ searchContainer->setFixedWidth(200);
+ searchText = new LineEditCursor(searchContainer);
+ searchText->setFixedWidth(200);
+ searchText->setMaxLength(60);
+ searchText->setFixedHeight(22);
+ searchText->setStyleSheet("LineEditCursor { border-width: 0px; border-radius: 6px; margin-top: 3px; margin-right: 3px; padding-left: 4px; padding-bottom: 2px; background-color: rgb(23, 11, 54); } LineEditCursor:hover, LineEditCursor:focus { background-color: rgb(13, 5, 68); }");
+
+ // Corner widget
+ QLabel * corner = new QLabel();
+ corner->setPixmap(QPixmap(QString::fromUtf8(":/res/inverse-corner-bl.png")));
+ corner->setFixedSize(10, 10);
+
+ const QIcon& lp = QIcon(":/res/new.png");
+ //QSize sz = lp.actualSize(QSize(65535, 65535));
+ BtnCreate = new QPushButton();
+ BtnCreate->setText(tr("Create room"));
+ BtnCreate->setIcon(lp);
+ BtnCreate->setStyleSheet("padding: 4px 8px; margin-bottom: 6px;");
+
+ BtnJoin = new QPushButton(tr("Join room"));
+ BtnJoin->setStyleSheet("padding: 4px 8px; margin-bottom: 6px; margin-left: 6px;");
+ BtnJoin->setEnabled(false);
+
+ // Add widgets to top layout
+ topLayout->addWidget(lblDesc, 1, 0);
+ topLayout->addWidget(searchContainer, 1, 1);
+ topLayout->addWidget(corner, 1, 2, Qt::AlignBottom);
+ topLayout->addWidget(BtnCreate, 0, 4, 2, 1);
+ topLayout->addWidget(BtnJoin, 0, 5, 2, 1);
+
+ // Top layout stretch
+ topLayout->setRowStretch(0, 1);
+ topLayout->setRowStretch(1, 0);
+ topLayout->setColumnStretch(3, 1);
+
+ // Rooms list and chat with splitter
+ m_splitter = new QSplitter();
+ m_splitter->setChildrenCollapsible(false);
+ pageLayout->addWidget(m_splitter, 100);
+
+ // Room list
+ QWidget * roomsListWidget = new QWidget(this);
+ m_splitter->setOrientation(Qt::Vertical);
+ m_splitter->addWidget(roomsListWidget);
+
+ QVBoxLayout * roomsLayout = new QVBoxLayout(roomsListWidget);
+ roomsLayout->setMargin(0);
+
+ roomsList = new RoomTableView(this);
roomsList->setSelectionBehavior(QAbstractItemView::SelectRows);
roomsList->verticalHeader()->setVisible(false);
roomsList->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
roomsList->setAlternatingRowColors(true);
roomsList->setShowGrid(false);
roomsList->setSelectionMode(QAbstractItemView::SingleSelection);
- pageLayout->addWidget(roomsList, 1, 0, 3, 2);
- pageLayout->setRowStretch(2, 100);
+ roomsList->setStyleSheet("QTableView { border-top-left-radius: 0px; }");
+ roomsList->setFocusPolicy(Qt::NoFocus);
+ roomsLayout->addWidget(roomsList, 200);
+
+ // Room filters container
+
+ QWidget * filtersContainer = new QWidget();
+ filtersContainer->setMaximumWidth(800);
+ filtersContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ roomsLayout->addSpacing(7);
+ roomsLayout->addWidget(filtersContainer, 0, Qt::AlignHCenter);
+ roomsLayout->addSpacing(7);
+
+ QHBoxLayout * filterLayout = new QHBoxLayout(filtersContainer);
+ filterLayout->setSpacing(0);
+ filterLayout->setMargin(0);
- QHBoxLayout * filterLayout = new QHBoxLayout();
+ const int filterSpacing = 20;
- QLabel * stateLabel = new QLabel(this);
- CBState = new QComboBox(this);
+ // State button
- filterLayout->addWidget(stateLabel);
- filterLayout->addWidget(CBState);
- filterLayout->addStretch(1);
+ QPushButton * btnState = new QPushButton(tr("Room state"));
+ btnState->setStyleSheet("QPushButton { padding: 2px 4px; } QPushButton:pressed { background-color: #ffcc00; border-color: #ffcc00; border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; color: #11084A; }");
+ btnState->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
+ filterLayout->addWidget(btnState);
+ filterLayout->addSpacing(filterSpacing);
+
+ // State menu
+
+ QMenu * stateMenu = new QMenu(btnState);
+ showGamesInLobby = new QAction(QAction::tr("Show games in lobby"), stateMenu);
+ showGamesInLobby->setCheckable(true);
+ showGamesInLobby->setChecked(true);
+ showGamesInProgress = new QAction(QAction::tr("Show games in-progress"), stateMenu);
+ showGamesInProgress->setCheckable(true);
+ showGamesInProgress->setChecked(true);
+ stateMenu->addAction(showGamesInLobby);
+ stateMenu->addAction(showGamesInProgress);
+ btnState->setMenu(stateMenu);
+
+ // Rules dropdown
- QLabel * ruleLabel = new QLabel(this);
- ruleLabel->setText(tr("Rules:"));
CBRules = new QComboBox(this);
+ CBRules->setStyleSheet("QComboBox { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 2px; }");
+
+ QLabel * ruleLabel = new QLabel(tr("Rules:"), this);
+ ruleLabel->setFixedHeight(CBRules->height());
+ ruleLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ ruleLabel->setStyleSheet("border: solid; border-width: 3px; border-right-width: 0px; border-color: #ffcc00; border-top-left-radius: 10px; border-bottom-left-radius: 10px; background-color: rgba(13, 5, 68, 70%);");
filterLayout->addWidget(ruleLabel);
filterLayout->addWidget(CBRules);
- filterLayout->addStretch(1);
+ filterLayout->addSpacing(filterSpacing);
+
+ // Weapons dropdown
- QLabel * weaponLabel = new QLabel(this);
- weaponLabel->setText(tr("Weapons:"));
CBWeapons = new QComboBox(this);
+ CBWeapons->setStyleSheet("QComboBox { border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left-width: 2px; }");
+
+ QLabel * weaponLabel = new QLabel(tr("Weapons:"), this);
+ weaponLabel->setFixedHeight(CBWeapons->height());
+ weaponLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ weaponLabel->setStyleSheet("border: solid; border-width: 3px; border-right-width: 0px; border-color: #ffcc00; border-top-left-radius: 10px; border-bottom-left-radius: 10px; background-color: rgba(13, 5, 68, 70%);");
filterLayout->addWidget(weaponLabel);
filterLayout->addWidget(CBWeapons);
- filterLayout->addStretch(1);
-
- QLabel * searchLabel = new QLabel(this);
- searchLabel->setText(tr("Search:"));
- searchText = new QLineEdit(this);
- searchText->setMaxLength(60);
- searchText->setMinimumWidth(100);
- searchText->setMaximumWidth(360);
- filterLayout->addWidget(searchLabel);
- filterLayout->addWidget(searchText);
- filterLayout->setStretchFactor(searchText, 2);
+ filterLayout->addSpacing(filterSpacing);
- pageLayout->addLayout(filterLayout, 4, 0, 1, 2);
+ // Clear filters button
- chatWidget = new HWChatWidget(this, m_gameSettings, false);
- pageLayout->addWidget(chatWidget, 5, 0, 1, 3);
- pageLayout->setRowStretch(5, 350);
+ BtnClear = addButton(tr("Clear filters"), filterLayout, 0);
+ weaponLabel->setFixedHeight(CBWeapons->height());
+ BtnClear->setStyleSheet("padding: 4px;");
- BtnCreate = addButton(tr("Create"), pageLayout, 0, 2);
- BtnJoin = addButton(tr("Join"), pageLayout, 1, 2);
- BtnClear = addButton(tr("Clear"), pageLayout, 4, 2);
+ // Lobby chat
- // strech all but the buttons column
- pageLayout->setColumnStretch(0, 1);
- pageLayout->setColumnStretch(1, 1);
- pageLayout->setColumnStretch(2, 0);
+ chatWidget = new HWChatWidget(this, false);
+ m_splitter->addWidget(chatWidget);
CBRules->addItem(QComboBox::tr("Any"));
- CBState->addItem(QComboBox::tr("Any"));
- CBState->addItem(QComboBox::tr("In lobby"));
- CBState->addItem(QComboBox::tr("In progress"));
return pageLayout;
}
@@ -120,18 +217,9 @@ QLayout * PageRoomsList::footerLayoutDefinition()
{
QHBoxLayout * bottomLayout = new QHBoxLayout();
- lblCount = new QLabel(this);
- bottomLayout->addWidget(lblCount, 0, Qt::AlignHCenter);
- bottomLayout->setStretchFactor(lblCount, 1);
- lblCount->setText("?");
- lblCount->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
-
- BtnAdmin = addButton(tr("Admin features"), bottomLayout, 1);
- BtnAdmin->setMinimumWidth(160);
-
- // strech left part
- bottomLayout->setStretch(0, 1);
- bottomLayout->setStretch(1, 0);
+ BtnAdmin = addButton(tr("Admin features"), bottomLayout, 0);
+ BtnAdmin->setStyleSheet("padding: 4px auto;");
+ BtnAdmin->setWhatsThis(tr("Open server administration page"));
return bottomLayout;
}
@@ -143,24 +231,46 @@ void PageRoomsList::connectSignals()
connect(BtnCreate, SIGNAL(clicked()), this, SLOT(onCreateClick()));
connect(BtnJoin, SIGNAL(clicked()), this, SLOT(onJoinClick()));
connect(BtnClear, SIGNAL(clicked()), this, SLOT(onClearClick()));
+ connect(searchText, SIGNAL(moveUp()), this, SLOT(moveSelectionUp()));
+ connect(searchText, SIGNAL(moveDown()), this, SLOT(moveSelectionDown()));
+ connect(searchText, SIGNAL(returnPressed()), this, SLOT(onJoinClick()));
connect(roomsList, SIGNAL(doubleClicked (const QModelIndex &)), this, SLOT(onJoinClick()));
- connect(CBState, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged()));
+ connect(roomsList, SIGNAL(clicked (const QModelIndex &)), searchText, SLOT(setFocus()));
+ connect(showGamesInLobby, SIGNAL(triggered()), this, SLOT(onFilterChanged()));
+ connect(showGamesInProgress, SIGNAL(triggered()), this, SLOT(onFilterChanged()));
connect(CBRules, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged()));
connect(CBWeapons, SIGNAL(currentIndexChanged (int)), this, SLOT(onFilterChanged()));
connect(searchText, SIGNAL(textChanged (const QString &)), this, SLOT(onFilterChanged()));
connect(this, SIGNAL(askJoinConfirmation (const QString &)), this, SLOT(onJoinConfirmation(const QString &)), Qt::QueuedConnection);
+ // Set focus on search box
+ connect(this, SIGNAL(pageEnter()), searchText, SLOT(setFocus()));
+
// sorting
connect(roomsList->horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)),
this, SLOT(onSortIndicatorChanged(int, Qt::SortOrder)));
}
+void PageRoomsList::moveSelectionUp()
+{
+ roomsList->moveUp();
+}
-PageRoomsList::PageRoomsList(QWidget* parent, QSettings * gameSettings) :
- AbstractPage(parent)
+void PageRoomsList::moveSelectionDown()
{
- m_gameSettings = gameSettings;
+ roomsList->moveDown();
+}
+
+void PageRoomsList::roomSelectionChanged(const QModelIndex & current, const QModelIndex & previous)
+{
+ Q_UNUSED(previous);
+ BtnJoin->setEnabled(current.isValid());
+}
+
+PageRoomsList::PageRoomsList(QWidget* parent) :
+ AbstractPage(parent)
+{
roomsModel = NULL;
stateFilteredModel = NULL;
schemeFilteredModel = NULL;
@@ -421,16 +531,21 @@ void PageRoomsList::setRoomsList(const QStringList & list)
void PageRoomsList::onCreateClick()
{
- if (roomName->text().size())
- emit askForCreateRoom(roomName->text());
+ RoomNamePrompt prompt(parentWidget()->parentWidget(), m_gameSettings->value("frontend/lastroomname", QString()).toString());
+ connect(&prompt, SIGNAL(roomNameChosen(const QString &)), this, SLOT(onRoomNameChosen(const QString &)));
+ prompt.exec();
+}
+
+void PageRoomsList::onRoomNameChosen(const QString & roomName)
+{
+ if (!roomName.trimmed().isEmpty())
+ {
+ m_gameSettings->setValue("frontend/lastroomname", roomName);
+ emit askForCreateRoom(roomName);
+ }
else
{
- QMessageBox roomNameMsg(this);
- roomNameMsg.setIcon(QMessageBox::Warning);
- roomNameMsg.setWindowTitle(QMessageBox::tr("Room Name - Error"));
- roomNameMsg.setText(QMessageBox::tr("Please enter room name"));
- roomNameMsg.setWindowModality(Qt::WindowModal);
- roomNameMsg.exec();
+ onCreateClick();
}
}
@@ -465,10 +580,12 @@ void PageRoomsList::onRefreshClick()
void PageRoomsList::onClearClick()
{
- CBState->setCurrentIndex(0);
+ showGamesInLobby->setChecked(true);
+ showGamesInProgress->setChecked(true);
CBRules->setCurrentIndex(0);
CBWeapons->setCurrentIndex(0);
searchText->clear();
+ searchText->setFocus();
}
void PageRoomsList::onJoinConfirmation(const QString & room)
@@ -489,7 +606,7 @@ void PageRoomsList::onJoinConfirmation(const QString & room)
void PageRoomsList::updateNickCounter(int cnt)
{
- lblCount->setText(tr("%1 players online", 0, cnt).arg(cnt));
+ setDefaultDescription(tr("%1 players online", 0, cnt).arg(cnt));
}
void PageRoomsList::setUser(const QString & nickname)
@@ -533,6 +650,12 @@ void PageRoomsList::setModel(RoomsListModel * model)
// let the table view display the last model in the filter chain
roomsList->setModel(roomsModel);
+
+ // When the data changes
+ connect(roomsModel, SIGNAL(layoutChanged()), roomsList, SLOT(repaint()));
+
+ // When a selection changes
+ connect(roomsList->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(roomSelectionChanged(const QModelIndex &, const QModelIndex &)));
}
stateFilteredModel->setSourceModel(model);
@@ -561,6 +684,8 @@ void PageRoomsList::setModel(RoomsListModel * model)
this, SLOT(saveHeaderState()));
connect(roomsList->horizontalHeader(), SIGNAL(sectionResized(int, int, int)),
this, SLOT(saveHeaderState()));
+
+ roomsList->repaint();
}
@@ -591,13 +716,15 @@ void PageRoomsList::onFilterChanged()
roomsModel->setFilterWildcard(QString("*%1*").arg(searchText->text()));
- int stateIdx = CBState->currentIndex();
- // any = 0, in lobby/false = 1, in progress/true = 2
+ bool stateLobby = showGamesInLobby->isChecked();
+ bool stateProgress = showGamesInProgress->isChecked();
- if (stateIdx == 0)
+ if (stateLobby && stateProgress)
stateFilteredModel->setFilterWildcard("*"); // "any"
+ else if (stateLobby != stateProgress)
+ stateFilteredModel->setFilterFixedString(QString(stateProgress));
else
- stateFilteredModel->setFilterFixedString(QString(stateIdx == 2));
+ stateFilteredModel->setFilterFixedString(QString("none")); // Basically, none.
if (CBRules->currentIndex() == 0)
schemeFilteredModel->setFilterWildcard("*"); // "any"
@@ -612,17 +739,31 @@ void PageRoomsList::onFilterChanged()
QString("*%1*").arg(CBWeapons->currentText()));
}
+void PageRoomsList::setSettings(QSettings *settings)
+{
+ m_gameSettings = settings;
+}
bool PageRoomsList::restoreHeaderState()
{
- if (!m_gameSettings->contains("frontend/roomslist_header"))
- return false;
- return roomsList->horizontalHeader()->restoreState(QByteArray::fromBase64(
- (m_gameSettings->value("frontend/roomslist_header").toString().toAscii())));
+ if (m_gameSettings->contains("frontend/roomslist_splitter"))
+ {
+ m_splitter->restoreState(QByteArray::fromBase64(
+ (m_gameSettings->value("frontend/roomslist_splitter").toByteArray())));
+ }
+
+ if (m_gameSettings->contains("frontend/roomslist_header"))
+ {
+ return roomsList->horizontalHeader()->restoreState(QByteArray::fromBase64(
+ (m_gameSettings->value("frontend/roomslist_header").toByteArray())));
+ } else return false;
}
void PageRoomsList::saveHeaderState()
{
m_gameSettings->setValue("frontend/roomslist_header",
QString(roomsList->horizontalHeader()->saveState().toBase64()));
+
+ m_gameSettings->setValue("frontend/roomslist_splitter",
+ QString(m_splitter->saveState().toBase64()));
}
diff --git a/QTfrontend/ui/page/pageroomslist.h b/QTfrontend/ui/page/pageroomslist.h
index 80f28dd..16c2d67 100644
--- a/QTfrontend/ui/page/pageroomslist.h
+++ b/QTfrontend/ui/page/pageroomslist.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
#ifndef PAGE_ROOMLIST_H
#define PAGE_ROOMLIST_H
+#include <QTableView>
#include "AbstractPage.h"
class HWChatWidget;
@@ -26,20 +27,31 @@ class AmmoSchemeModel;
class QTableView;
class RoomsListModel;
class QSortFilterProxyModel;
+class QSplitter;
+
+class RoomTableView : public QTableView
+{
+ friend class PageRoomsList;
+
+ public:
+ RoomTableView(QWidget* parent = 0) : QTableView(parent){}
+ void moveUp();
+ void moveDown();
+};
class PageRoomsList : public AbstractPage
{
Q_OBJECT
public:
- PageRoomsList(QWidget* parent, QSettings * config);
+ PageRoomsList(QWidget* parent);
void displayError(const QString & message);
void displayNotice(const QString & message);
void displayWarning(const QString & message);
+ void setSettings(QSettings * settings);
- QLineEdit * roomName;
QLineEdit * searchText;
- QTableView * roomsList;
+ RoomTableView * roomsList;
QPushButton * BtnCreate;
QPushButton * BtnJoin;
QPushButton * BtnAdmin;
@@ -77,6 +89,10 @@ class PageRoomsList : public AbstractPage
void onSortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
void onFilterChanged();
void saveHeaderState();
+ void onRoomNameChosen(const QString &);
+ void roomSelectionChanged(const QModelIndex &, const QModelIndex &);
+ void moveSelectionUp();
+ void moveSelectionDown();
private:
QSettings * m_gameSettings;
@@ -84,6 +100,9 @@ class PageRoomsList : public AbstractPage
QSortFilterProxyModel * stateFilteredModel;
QSortFilterProxyModel * schemeFilteredModel;
QSortFilterProxyModel * weaponsFilteredModel;
+ QAction * showGamesInLobby;
+ QAction * showGamesInProgress;
+ QSplitter * m_splitter;
AmmoSchemeModel * ammoSchemeModel;
diff --git a/QTfrontend/ui/page/pagescheme.cpp b/QTfrontend/ui/page/pagescheme.cpp
index 56d371a..022b7c3 100644
--- a/QTfrontend/ui/page/pagescheme.cpp
+++ b/QTfrontend/ui/page/pagescheme.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -68,127 +68,102 @@ QLayout * PageScheme::bodyLayoutDefinition()
// Left
TBW_mode_Forts = new ToggleButtonWidget(gbGameModes, ":/res/btnForts at 2x.png");
- TBW_mode_Forts->setToolTip("<b>" + ToggleButtonWidget::tr("Fort Mode") + "</b>");
TBW_mode_Forts->setWhatsThis(tr("Defend your fort and destroy the opponents, two team colours max!"));
glGMLayout->addWidget(TBW_mode_Forts,0,0,1,1);
TBW_teamsDivide = new ToggleButtonWidget(gbGameModes, ":/res/btnTeamsDivide at 2x.png");
- TBW_teamsDivide->setToolTip("<b>" + ToggleButtonWidget::tr("Divide Teams") + "</b>");
TBW_teamsDivide->setWhatsThis(tr("Teams will start on opposite sides of the terrain, two team colours max!"));
glGMLayout->addWidget(TBW_teamsDivide,0,1,1,1);
TBW_solid = new ToggleButtonWidget(gbGameModes, ":/res/btnSolid at 2x.png");
- TBW_solid->setToolTip("<b>" + ToggleButtonWidget::tr("Solid Land") + "</b>");
TBW_solid->setWhatsThis(tr("Land can not be destroyed!"));
glGMLayout->addWidget(TBW_solid,0,2,1,1);
TBW_border = new ToggleButtonWidget(gbGameModes, ":/res/btnBorder at 2x.png");
- TBW_border->setToolTip("<b>" + ToggleButtonWidget::tr("Add Border") + "</b>");
TBW_border->setWhatsThis(tr("Add an indestructible border around the terrain"));
glGMLayout->addWidget(TBW_border,0,3,1,1);
TBW_lowGravity = new ToggleButtonWidget(gbGameModes, ":/res/btnLowGravity at 2x.png");
- TBW_lowGravity->setToolTip("<b>" + ToggleButtonWidget::tr("Low Gravity") + "</b>");
TBW_lowGravity->setWhatsThis(tr("Lower gravity"));
glGMLayout->addWidget(TBW_lowGravity,0,4,1,1);
TBW_laserSight = new ToggleButtonWidget(gbGameModes, ":/res/btnLaserSight at 2x.png");
- TBW_laserSight->setToolTip("<b>" + ToggleButtonWidget::tr("Laser Sight") + "</b>");
TBW_laserSight->setWhatsThis(tr("Assisted aiming with laser sight"));
glGMLayout->addWidget(TBW_laserSight,1,0,1,1);
TBW_invulnerable = new ToggleButtonWidget(gbGameModes, ":/res/btnInvulnerable at 2x.png");
- TBW_invulnerable->setToolTip("<b>" + ToggleButtonWidget::tr("Invulnerable") + "</b>");
TBW_invulnerable->setWhatsThis(tr("All hogs have a personal forcefield"));
glGMLayout->addWidget(TBW_invulnerable,1,1,1,1);
TBW_resethealth = new ToggleButtonWidget(gbGameModes, ":/res/btnResetHealth at 2x.png");
- TBW_resethealth->setToolTip("<b>" + ToggleButtonWidget::tr("Reset Health") + "</b>");
TBW_resethealth->setWhatsThis(tr("All (living) hedgehogs are fully restored at the end of turn"));
glGMLayout->addWidget(TBW_resethealth,1,2,1,1);
TBW_vampiric = new ToggleButtonWidget(gbGameModes, ":/res/btnVampiric at 2x.png");
- TBW_vampiric->setToolTip("<b>" + ToggleButtonWidget::tr("Vampirism") + "</b>");
TBW_vampiric->setWhatsThis(tr("Gain 80% of the damage you do back in health"));
glGMLayout->addWidget(TBW_vampiric,1,3,1,1);
TBW_karma = new ToggleButtonWidget(gbGameModes, ":/res/btnKarma at 2x.png");
- TBW_karma->setToolTip("<b>" + ToggleButtonWidget::tr("Karma") + "</b>");
TBW_karma->setWhatsThis(tr("Share your opponents pain, share their damage"));
glGMLayout->addWidget(TBW_karma,1,4,1,1);
TBW_artillery = new ToggleButtonWidget(gbGameModes, ":/res/btnArtillery at 2x.png");
- TBW_artillery->setToolTip("<b>" + ToggleButtonWidget::tr("Artillery") + "</b>");
TBW_artillery->setWhatsThis(tr("Your hogs are unable to move, put your artillery skills to the test"));
glGMLayout->addWidget(TBW_artillery,2,0,1,1);
TBW_randomorder = new ToggleButtonWidget(gbGameModes, ":/res/btnRandomOrder at 2x.png");
- TBW_randomorder->setToolTip("<b>" + ToggleButtonWidget::tr("Random Order") + "</b>");
TBW_randomorder->setWhatsThis(tr("Order of play is random instead of in room order."));
glGMLayout->addWidget(TBW_randomorder,2,1,1,1);
TBW_king = new ToggleButtonWidget(gbGameModes, ":/res/btnKing at 2x.png");
- TBW_king->setToolTip("<b>" + ToggleButtonWidget::tr("King") + "</b>");
TBW_king->setWhatsThis(tr("Play with a King. If he dies, your side dies."));
glGMLayout->addWidget(TBW_king,2,2,1,1);
TBW_placehog = new ToggleButtonWidget(gbGameModes, ":/res/btnPlaceHog at 2x.png");
- TBW_placehog->setToolTip("<b>" + ToggleButtonWidget::tr("Place Hedgehogs") + "</b>");
TBW_placehog->setWhatsThis(tr("Take turns placing your hedgehogs before the start of play."));
glGMLayout->addWidget(TBW_placehog,2,3,1,1);
TBW_sharedammo = new ToggleButtonWidget(gbGameModes, ":/res/btnSharedAmmo at 2x.png");
- TBW_sharedammo->setToolTip("<b>" + ToggleButtonWidget::tr("Clan Shares Ammo") + "</b>");
TBW_sharedammo->setWhatsThis(tr("Ammo is shared between all teams that share a colour."));
glGMLayout->addWidget(TBW_sharedammo,2,4,1,1);
TBW_disablegirders = new ToggleButtonWidget(gbGameModes, ":/res/btnDisableGirders at 2x.png");
- TBW_disablegirders->setToolTip("<b>" + ToggleButtonWidget::tr("Disable Girders") + "</b>");
TBW_disablegirders->setWhatsThis(tr("Disable girders when generating random maps."));
glGMLayout->addWidget(TBW_disablegirders,3,0,1,1);
TBW_disablelandobjects = new ToggleButtonWidget(gbGameModes, ":/res/btnDisableLandObjects at 2x.png");
- TBW_disablelandobjects->setToolTip("<b>" + ToggleButtonWidget::tr("Disable Land Objects") + "</b>");
TBW_disablelandobjects->setWhatsThis(tr("Disable land objects when generating random maps."));
glGMLayout->addWidget(TBW_disablelandobjects,3,1,1,1);
TBW_aisurvival = new ToggleButtonWidget(gbGameModes, ":/res/btnAISurvival at 2x.png");
- TBW_aisurvival->setToolTip("<b>" + ToggleButtonWidget::tr("AI Survival Mode") + "</b>");
TBW_aisurvival->setWhatsThis(tr("AI respawns on death."));
glGMLayout->addWidget(TBW_aisurvival,3,2,1,1);
TBW_infattack = new ToggleButtonWidget(gbGameModes, ":/res/btnInfAttack at 2x.png");
- TBW_infattack->setToolTip("<b>" + ToggleButtonWidget::tr("Unlimited Attacks") + "</b>");
TBW_infattack->setWhatsThis(tr("Attacking does not end your turn."));
glGMLayout->addWidget(TBW_infattack,3,3,1,1);
TBW_resetweps = new ToggleButtonWidget(gbGameModes, ":/res/btnResetWeps at 2x.png");
- TBW_resetweps->setToolTip("<b>" + ToggleButtonWidget::tr("Reset Weapons") + "</b>");
TBW_resetweps->setWhatsThis(tr("Weapons are reset to starting values each turn."));
glGMLayout->addWidget(TBW_resetweps,3,4,1,1);
TBW_perhogammo = new ToggleButtonWidget(gbGameModes, ":/res/btnPerHogAmmo at 2x.png");
- TBW_perhogammo->setToolTip("<b>" + ToggleButtonWidget::tr("Per Hedgehog Ammo") + "</b>");
TBW_perhogammo->setWhatsThis(tr("Each hedgehog has its own ammo. It does not share with the team."));
glGMLayout->addWidget(TBW_perhogammo,4,0,1,1);
TBW_nowind = new ToggleButtonWidget(gbGameModes, ":/res/btnNoWind at 2x.png");
- TBW_nowind->setToolTip("<b>" + ToggleButtonWidget::tr("Disable Wind") + "</b>");
TBW_nowind->setWhatsThis(tr("You will not have to worry about wind anymore."));
glGMLayout->addWidget(TBW_nowind,4,1,1,1);
TBW_morewind = new ToggleButtonWidget(gbGameModes, ":/res/btnMoreWind at 2x.png");
- TBW_morewind->setToolTip("<b>" + ToggleButtonWidget::tr("More Wind") + "</b>");
TBW_morewind->setWhatsThis(tr("Wind will affect almost everything."));
glGMLayout->addWidget(TBW_morewind,4,2,1,1);
TBW_tagteam = new ToggleButtonWidget(gbGameModes, ":/res/btnTagTeam at 2x.png");
- TBW_tagteam->setToolTip("<b>" + ToggleButtonWidget::tr("Tag Team") + "</b>");
TBW_tagteam->setWhatsThis(tr("Teams in each clan take successive turns sharing their turn time."));
glGMLayout->addWidget(TBW_tagteam,4,3,1,1);
TBW_bottomborder = new ToggleButtonWidget(gbGameModes, ":/res/btnBottomBorder at 2x.png");
- TBW_bottomborder->setToolTip("<b>" + ToggleButtonWidget::tr("Add Bottom Border") + "</b>");
TBW_bottomborder->setWhatsThis(tr("Add an indestructible border along the bottom"));
glGMLayout->addWidget(TBW_bottomborder,4,4,1,1);
diff --git a/QTfrontend/ui/page/pagescheme.h b/QTfrontend/ui/page/pagescheme.h
index 615f5cf..2972612 100644
--- a/QTfrontend/ui/page/pagescheme.h
+++ b/QTfrontend/ui/page/pagescheme.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageselectweapon.cpp b/QTfrontend/ui/page/pageselectweapon.cpp
index 9a4524a..a330437 100644
--- a/QTfrontend/ui/page/pageselectweapon.cpp
+++ b/QTfrontend/ui/page/pageselectweapon.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pageselectweapon.h b/QTfrontend/ui/page/pageselectweapon.h
index f0372c8..d280e2a 100644
--- a/QTfrontend/ui/page/pageselectweapon.h
+++ b/QTfrontend/ui/page/pageselectweapon.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagesingleplayer.cpp b/QTfrontend/ui/page/pagesingleplayer.cpp
index f8dfdb3..5cd36d7 100644
--- a/QTfrontend/ui/page/pagesingleplayer.cpp
+++ b/QTfrontend/ui/page/pagesingleplayer.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,22 +36,18 @@ QLayout * PageSinglePlayer::bodyLayoutDefinition()
topLine->addStretch();
BtnSimpleGamePage = addButton(":/res/SimpleGame.png", topLine, 0, true);
- BtnSimpleGamePage->setToolTip(tr("Simple Game"));
BtnSimpleGamePage->setWhatsThis(tr("Play a quick game against the computer with random settings"));
topLine->addSpacing(60);
BtnMultiplayer = addButton(":/res/Multiplayer.png", topLine, 1, true);
- BtnMultiplayer->setToolTip(tr("Multiplayer"));
BtnMultiplayer->setWhatsThis(tr("Play a hotseat game against your friends, or AI teams"));
topLine->addStretch();
BtnCampaignPage = addButton(":/res/Campaign.png", middleLine, 0, true);
- BtnCampaignPage->setToolTip(tr("Campaign Mode"));
BtnCampaignPage->setWhatsThis(tr("Campaign Mode"));
BtnCampaignPage->setVisible(true);
BtnTrainPage = addButton(":/res/Trainings.png", middleLine, 1, true);
- BtnTrainPage->setToolTip(tr("Training Mode"));
BtnTrainPage->setWhatsThis(tr("Practice your skills in a range of training missions"));
return vLayout;
@@ -63,11 +59,9 @@ QLayout * PageSinglePlayer::footerLayoutDefinition()
bottomLine->addStretch();
BtnDemos = addButton(":/res/Record.png", bottomLine, 1, true);
- BtnDemos->setToolTip(tr("Demos"));
BtnDemos->setWhatsThis(tr("Watch recorded demos"));
BtnLoad = addButton(":/res/Load.png", bottomLine, 2, true);
BtnLoad->setStyleSheet("QPushButton{margin: 24px 0 0 0;}");
- BtnLoad->setToolTip(tr("Load"));
BtnLoad->setWhatsThis(tr("Load a previously saved game"));
bottomLine->setStretch(1,0);
diff --git a/QTfrontend/ui/page/pagesingleplayer.h b/QTfrontend/ui/page/pagesingleplayer.h
index cd73c8b..be36716 100644
--- a/QTfrontend/ui/page/pagesingleplayer.h
+++ b/QTfrontend/ui/page/pagesingleplayer.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagetraining.cpp b/QTfrontend/ui/page/pagetraining.cpp
index 6b66241..2df187e 100644
--- a/QTfrontend/ui/page/pagetraining.cpp
+++ b/QTfrontend/ui/page/pagetraining.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -118,24 +118,22 @@ PageTraining::PageTraining(QWidget* parent) : AbstractPage(parent)
DataManager & dataMgr = DataManager::instance();
// get locale
- QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini",
+ QSettings settings(dataMgr.settingsFileName(),
QSettings::IniFormat);
QString loc = settings.value("misc/locale", "").toString();
if (loc.isEmpty())
loc = QLocale::system().name();
- QString infoFile = dataMgr.findFileForRead(
- QString("Locale/missions_" + loc + ".txt"));
+ QString infoFile = QString("physfs://Locale/missions_" + loc + ".txt");
// if file is non-existant try with language only
if (!QFile::exists(infoFile))
- infoFile = dataMgr.findFileForRead(QString(
- "Locale/missions_" + loc.remove(QRegExp("_.*$")) + ".txt"));
+ infoFile = QString("physfs://Locale/missions_" + loc.remove(QRegExp("_.*$")) + ".txt");
// fallback if file for current locale is non-existant
if (!QFile::exists(infoFile))
- infoFile = dataMgr.findFileForRead(QString("Locale/missions_en.txt"));
+ infoFile = QString("physfs://Locale/missions_en.txt");
// preload mission info for current locale
@@ -186,15 +184,12 @@ void PageTraining::startSelected()
void PageTraining::updateInfo()
{
- DataManager & dataMgr = DataManager::instance();
-
if (lstMissions->currentItem())
{
// TODO also use .pngs in userdata folder
- QString thumbFile = dataMgr.findFileForRead(
- "Graphics/Missions/Training/" +
+ QString thumbFile = "physfs://Graphics/Missions/Training/" +
lstMissions->currentItem()->data(Qt::UserRole).toString() +
- "@2x.png");
+ "@2x.png";
if (QFile::exists(thumbFile))
btnPreview->setIcon(QIcon(thumbFile));
diff --git a/QTfrontend/ui/page/pagetraining.h b/QTfrontend/ui/page/pagetraining.h
index 9f37275..ebe330a 100644
--- a/QTfrontend/ui/page/pagetraining.h
+++ b/QTfrontend/ui/page/pagetraining.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/page/pagevideos.cpp b/QTfrontend/ui/page/pagevideos.cpp
index c6be006..11fd625 100644
--- a/QTfrontend/ui/page/pagevideos.cpp
+++ b/QTfrontend/ui/page/pagevideos.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -109,119 +109,6 @@ QLayout * PageVideos::bodyLayoutDefinition()
QGridLayout * pPageLayout = new QGridLayout();
pPageLayout->setColumnStretch(0, 1);
pPageLayout->setColumnStretch(1, 2);
- pPageLayout->setRowStretch(0, 1);
- pPageLayout->setRowStretch(1, 1);
-
- // options
- {
- IconedGroupBox* pOptionsGroup = new IconedGroupBox(this);
- pOptionsGroup->setIcon(QIcon(":/res/Settings.png")); // FIXME
- pOptionsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- pOptionsGroup->setTitle(QGroupBox::tr("Video recording options"));
- QGridLayout * pOptLayout = new QGridLayout(pOptionsGroup);
-
- // label for format
- QLabel *labelFormat = new QLabel(pOptionsGroup);
- labelFormat->setText(QLabel::tr("Format"));
- pOptLayout->addWidget(labelFormat, 0, 0);
-
- // list of supported formats
- comboAVFormats = new QComboBox(pOptionsGroup);
- pOptLayout->addWidget(comboAVFormats, 0, 1, 1, 4);
- LibavInteraction::instance().fillFormats(comboAVFormats);
-
- // separator
- QFrame * hr = new QFrame(pOptionsGroup);
- hr->setFrameStyle(QFrame::HLine);
- hr->setLineWidth(3);
- hr->setFixedHeight(10);
- pOptLayout->addWidget(hr, 1, 0, 1, 5);
-
- // label for audio codec
- QLabel *labelACodec = new QLabel(pOptionsGroup);
- labelACodec->setText(QLabel::tr("Audio codec"));
- pOptLayout->addWidget(labelACodec, 2, 0);
-
- // list of supported audio codecs
- comboAudioCodecs = new QComboBox(pOptionsGroup);
- pOptLayout->addWidget(comboAudioCodecs, 2, 1, 1, 3);
-
- // checkbox 'record audio'
- checkRecordAudio = new QCheckBox(pOptionsGroup);
- checkRecordAudio->setText(QCheckBox::tr("Record audio"));
- pOptLayout->addWidget(checkRecordAudio, 2, 4);
-
- // separator
- hr = new QFrame(pOptionsGroup);
- hr->setFrameStyle(QFrame::HLine);
- hr->setLineWidth(3);
- hr->setFixedHeight(10);
- pOptLayout->addWidget(hr, 3, 0, 1, 5);
-
- // label for video codec
- QLabel *labelVCodec = new QLabel(pOptionsGroup);
- labelVCodec->setText(QLabel::tr("Video codec"));
- pOptLayout->addWidget(labelVCodec, 4, 0);
-
- // list of supported video codecs
- comboVideoCodecs = new QComboBox(pOptionsGroup);
- pOptLayout->addWidget(comboVideoCodecs, 4, 1, 1, 4);
-
- // label for resolution
- QLabel *labelRes = new QLabel(pOptionsGroup);
- labelRes->setText(QLabel::tr("Resolution"));
- pOptLayout->addWidget(labelRes, 5, 0);
-
- // width
- widthEdit = new QLineEdit(pOptionsGroup);
- widthEdit->setValidator(new QIntValidator(this));
- pOptLayout->addWidget(widthEdit, 5, 1);
-
- // x
- QLabel *labelX = new QLabel(pOptionsGroup);
- labelX->setText("X");
- pOptLayout->addWidget(labelX, 5, 2);
-
- // height
- heightEdit = new QLineEdit(pOptionsGroup);
- heightEdit->setValidator(new QIntValidator(pOptionsGroup));
- pOptLayout->addWidget(heightEdit, 5, 3);
-
- // checkbox 'use game resolution'
- checkUseGameRes = new QCheckBox(pOptionsGroup);
- checkUseGameRes->setText(QCheckBox::tr("Use game resolution"));
- pOptLayout->addWidget(checkUseGameRes, 5, 4);
-
- // label for framerate
- QLabel *labelFramerate = new QLabel(pOptionsGroup);
- labelFramerate->setText(QLabel::tr("Framerate"));
- pOptLayout->addWidget(labelFramerate, 6, 0);
-
- // framerate
- framerateBox = new QSpinBox(pOptionsGroup);
- framerateBox->setRange(1, 200);
- framerateBox->setSingleStep(1);
- pOptLayout->addWidget(framerateBox, 6, 1);
-
- // label for Bitrate
- QLabel *labelBitrate = new QLabel(pOptionsGroup);
- labelBitrate->setText(QLabel::tr("Bitrate (Kbps)"));
- pOptLayout->addWidget(labelBitrate, 6, 2);
-
- // bitrate
- bitrateBox = new QSpinBox(pOptionsGroup);
- bitrateBox->setRange(100, 5000);
- bitrateBox->setSingleStep(100);
- pOptLayout->addWidget(bitrateBox, 6, 3);
-
- // button 'set default options'
- btnDefaults = new QPushButton(pOptionsGroup);
- btnDefaults->setText(QPushButton::tr("Set default options"));
- btnDefaults->setWhatsThis(QPushButton::tr("Restore default coding parameters"));
- pOptLayout->addWidget(btnDefaults, 7, 0, 1, 5);
-
- pPageLayout->addWidget(pOptionsGroup, 1, 0);
- }
// list of videos
{
@@ -257,7 +144,7 @@ QLayout * PageVideos::bodyLayoutDefinition()
box->addWidget(filesTable);
box->addWidget(btnOpenDir);
- pPageLayout->addWidget(pTableGroup, 0, 1, 2, 1);
+ pPageLayout->addWidget(pTableGroup, 0, 1);
}
// description
@@ -267,7 +154,6 @@ QLayout * PageVideos::bodyLayoutDefinition()
pDescGroup->setTitle(QGroupBox::tr("Description"));
QVBoxLayout* pDescLayout = new QVBoxLayout(pDescGroup);
- QHBoxLayout* pTopDescLayout = new QHBoxLayout(0); // picture and text
QHBoxLayout* pBottomDescLayout = new QHBoxLayout(0); // buttons
// label with thumbnail picture
@@ -282,18 +168,19 @@ QLayout * PageVideos::bodyLayoutDefinition()
"border-radius: 4px;"
"}" );
clearThumbnail();
- pTopDescLayout->addWidget(labelThumbnail, 2);
// label with file description
labelDesc = new QLabel(pDescGroup);
labelDesc->setAlignment(Qt::AlignLeft | Qt::AlignTop);
labelDesc->setTextInteractionFlags(Qt::TextSelectableByMouse |
- Qt::TextSelectableByKeyboard |
+ Qt::TextSelectableByKeyboard |
Qt::LinksAccessibleByMouse |
Qt::LinksAccessibleByKeyboard);
labelDesc->setTextFormat(Qt::RichText);
+ labelDesc->setWordWrap(true);
labelDesc->setOpenExternalLinks(true);
- pTopDescLayout->addWidget(labelDesc, 1);
+ //labelDesc->setMinimumSize(ThumbnailSize);
+ //pTopDescLayout->addWidget(labelDesc, 1);
// buttons: play and delete
btnPlay = new QPushButton(QPushButton::tr("Play"), pDescGroup);
@@ -309,10 +196,10 @@ QLayout * PageVideos::bodyLayoutDefinition()
btnToYouTube->setWhatsThis(QPushButton::tr("Upload this video to your Youtube account"));
pBottomDescLayout->addWidget(btnToYouTube);
- pDescLayout->addStretch(1);
- pDescLayout->addLayout(pTopDescLayout, 0);
- pDescLayout->addStretch(1);
+ pDescLayout->addWidget(labelThumbnail, 0);
+ pDescLayout->addWidget(labelDesc, 0);
pDescLayout->addLayout(pBottomDescLayout, 0);
+ pDescLayout->addStretch(1);
pPageLayout->addWidget(pDescGroup, 0, 0);
}
@@ -327,10 +214,6 @@ QLayout * PageVideos::footerLayoutDefinition()
void PageVideos::connectSignals()
{
- connect(checkUseGameRes, SIGNAL(stateChanged(int)), this, SLOT(changeUseGameRes(int)));
- connect(checkRecordAudio, SIGNAL(stateChanged(int)), this, SLOT(changeRecordAudio(int)));
- connect(comboAVFormats, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAVFormat(int)));
- connect(btnDefaults, SIGNAL(clicked()), this, SLOT(setDefaultOptions()));
connect(filesTable, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(cellDoubleClicked(int, int)));
connect(filesTable, SIGNAL(cellChanged(int,int)), this, SLOT(cellChanged(int, int)));
connect(filesTable, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(currentCellChanged()));
@@ -362,124 +245,6 @@ void PageVideos::init(GameUIConfig * config)
startEncoding(); // this is for videos recorded from demos which were executed directly (without frontend)
}
-// user changed file format, we need to update list of codecs
-void PageVideos::changeAVFormat(int index)
-{
- // remember selected codecs
- QString prevVCodec = videoCodec();
- QString prevACodec = audioCodec();
-
- // clear lists of codecs
- comboVideoCodecs->clear();
- comboAudioCodecs->clear();
-
- // get list of codecs for specified format
- LibavInteraction::instance().fillCodecs(comboAVFormats->itemData(index).toString(), comboVideoCodecs, comboAudioCodecs);
-
- // disable audio if there is no audio codec
- if (comboAudioCodecs->count() == 0)
- {
- checkRecordAudio->setChecked(false);
- checkRecordAudio->setEnabled(false);
- }
- else
- checkRecordAudio->setEnabled(true);
-
- // restore selected codecs if possible
- int iVCodec = comboVideoCodecs->findData(prevVCodec);
- if (iVCodec != -1)
- comboVideoCodecs->setCurrentIndex(iVCodec);
- int iACodec = comboAudioCodecs->findData(prevACodec);
- if (iACodec != -1)
- comboAudioCodecs->setCurrentIndex(iACodec);
-}
-
-// user switched checkbox 'use game resolution'
-void PageVideos::changeUseGameRes(int state)
-{
- if (state && config)
- {
- // set resolution to game resolution
- QRect resolution = config->vid_Resolution();
- widthEdit->setText(QString::number(resolution.width()));
- heightEdit->setText(QString::number(resolution.height()));
- }
- widthEdit->setEnabled(!state);
- heightEdit->setEnabled(!state);
-}
-
-// user switched checkbox 'record audio'
-void PageVideos::changeRecordAudio(int state)
-{
- comboAudioCodecs->setEnabled(!!state);
-}
-
-void PageVideos::setDefaultCodecs()
-{
- // VLC should be able to handle any of these configurations
- // Quicktime X only opens the first one
- // Windows Media Player TODO
- if (tryCodecs("mp4", "libx264", "aac"))
- return;
- if (tryCodecs("mp4", "libx264", "libfaac"))
- return;
- if (tryCodecs("mp4", "libx264", "libmp3lame"))
- return;
- if (tryCodecs("mp4", "libx264", "mp2"))
- return;
- if (tryCodecs("avi", "libxvid", "libmp3lame"))
- return;
- if (tryCodecs("avi", "libxvid", "ac3_fixed"))
- return;
- if (tryCodecs("avi", "libxvid", "mp2"))
- return;
- if (tryCodecs("avi", "mpeg4", "libmp3lame"))
- return;
- if (tryCodecs("avi", "mpeg4", "ac3_fixed"))
- return;
- if (tryCodecs("avi", "mpeg4", "mp2"))
- return;
-
- // this shouldn't happen, just in case
- if (tryCodecs("ogg", "libtheora", "libvorbis"))
- return;
- tryCodecs("ogg", "libtheora", "flac");
-}
-
-void PageVideos::setDefaultOptions()
-{
- framerateBox->setValue(30);
- bitrateBox->setValue(1000);
- checkRecordAudio->setChecked(true);
- checkUseGameRes->setChecked(true);
- setDefaultCodecs();
-}
-
-bool PageVideos::tryCodecs(const QString & format, const QString & vcodec, const QString & acodec)
-{
- // first we should change format
- int iFormat = comboAVFormats->findData(format);
- if (iFormat == -1)
- return false;
- comboAVFormats->setCurrentIndex(iFormat);
- // format was changed, so lists of codecs were automatically updated to codecs supported by this format
-
- // try to find video codec
- int iVCodec = comboVideoCodecs->findData(vcodec);
- if (iVCodec == -1)
- return false;
- comboVideoCodecs->setCurrentIndex(iVCodec);
-
- // try to find audio codec
- int iACodec = comboAudioCodecs->findData(acodec);
- if (iACodec == -1 && checkRecordAudio->isChecked())
- return false;
- if (iACodec != -1)
- comboAudioCodecs->setCurrentIndex(iACodec);
-
- return true;
-}
-
// get file size as string
static QString FileSizeStr(const QString & path)
{
@@ -743,8 +508,8 @@ void PageVideos::updateDescription()
else
{
QString path = item->path();
- desc += tr("Date: ") + QFileInfo(path).created().toString(Qt::DefaultLocaleLongDate) + '\n';
- desc += tr("Size: ") + FileSizeStr(path) + '\n';
+ desc += tr("Date: %1\n").arg(QFileInfo(path).created().toString(Qt::DefaultLocaleLongDate));
+ desc += tr("Size: %1\n").arg(FileSizeStr(path));
if (item->desc.isEmpty())
{
// Extract description from file;
@@ -1096,7 +861,7 @@ void PageVideos::uploadToYouTube()
int row = filesTable->currentRow();
VideoItem * item = nameItem(row);
- if (item->pUploading)
+ if (item->pUploading) //Act as 'cancel uploading' button
{
// ask user if (s)he is serious
QMessageBox reallyStopMsg(this);
@@ -1108,9 +873,10 @@ void PageVideos::uploadToYouTube()
if (reallyStopMsg.exec() != QMessageBox::Ok)
return;
- item->pUploading->deleteLater();
+ item->pUploading->abort();
+ btnToYouTube->setText(QPushButton::tr("Upload to YouTube"));
filesTable->setCellWidget(row, vcProgress, NULL); // remove progress bar
- numUploads--;
+ //numUploads--;
return;
}
diff --git a/QTfrontend/ui/page/pagevideos.h b/QTfrontend/ui/page/pagevideos.h
index ef35318..0135d06 100644
--- a/QTfrontend/ui/page/pagevideos.h
+++ b/QTfrontend/ui/page/pagevideos.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,24 +36,6 @@ class PageVideos : public AbstractPage
public:
PageVideos(QWidget* parent = 0);
- QSpinBox *framerateBox;
- QSpinBox *bitrateBox;
- QLineEdit *widthEdit;
- QLineEdit *heightEdit;
- QCheckBox *checkUseGameRes;
- QCheckBox *checkRecordAudio;
-
- QString format()
- { return comboAVFormats->itemData(comboAVFormats->currentIndex()).toString(); }
-
- QString videoCodec()
- { return comboVideoCodecs->itemData(comboVideoCodecs->currentIndex()).toString(); }
-
- QString audioCodec()
- { return comboAudioCodecs->itemData(comboAudioCodecs->currentIndex()).toString(); }
-
- void setDefaultCodecs();
- bool tryCodecs(const QString & format, const QString & vcodec, const QString & acodec);
void addRecorder(HWRecorder* pRecorder);
bool tryQuit(HWForm *form);
QString getVideosInProgress(); // get multi-line string with list of videos in progress
@@ -83,12 +65,6 @@ class PageVideos : public AbstractPage
GameUIConfig * config;
QNetworkAccessManager* netManager;
- // options group
- QComboBox *comboAVFormats;
- QComboBox *comboVideoCodecs;
- QComboBox *comboAudioCodecs;
- QPushButton *btnDefaults;
-
// file list group
QTableWidget *filesTable;
QPushButton *btnOpenDir;
@@ -105,10 +81,6 @@ class PageVideos : public AbstractPage
int numRecorders, numUploads;
private slots:
- void changeAVFormat(int index);
- void changeUseGameRes(int state);
- void changeRecordAudio(int state);
- void setDefaultOptions();
void encodingFinished(bool success);
void updateProgress(float value);
void cellDoubleClicked(int row, int column);
diff --git a/QTfrontend/ui/widget/FreqSpinBox.cpp b/QTfrontend/ui/widget/FreqSpinBox.cpp
index 64202d0..9e3865d 100644
--- a/QTfrontend/ui/widget/FreqSpinBox.cpp
+++ b/QTfrontend/ui/widget/FreqSpinBox.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/FreqSpinBox.h b/QTfrontend/ui/widget/FreqSpinBox.h
index 6bd7a84..299e93c 100644
--- a/QTfrontend/ui/widget/FreqSpinBox.h
+++ b/QTfrontend/ui/widget/FreqSpinBox.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/HistoryLineEdit.cpp b/QTfrontend/ui/widget/HistoryLineEdit.cpp
index 3280c4b..9e25b59 100644
--- a/QTfrontend/ui/widget/HistoryLineEdit.cpp
+++ b/QTfrontend/ui/widget/HistoryLineEdit.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/HistoryLineEdit.h b/QTfrontend/ui/widget/HistoryLineEdit.h
index 3b8f365..176264e 100644
--- a/QTfrontend/ui/widget/HistoryLineEdit.h
+++ b/QTfrontend/ui/widget/HistoryLineEdit.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/SmartLineEdit.cpp b/QTfrontend/ui/widget/SmartLineEdit.cpp
index 70002f1..c937062 100644
--- a/QTfrontend/ui/widget/SmartLineEdit.cpp
+++ b/QTfrontend/ui/widget/SmartLineEdit.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/SmartLineEdit.h b/QTfrontend/ui/widget/SmartLineEdit.h
index 05bcfe6..569b070 100644
--- a/QTfrontend/ui/widget/SmartLineEdit.h
+++ b/QTfrontend/ui/widget/SmartLineEdit.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/SquareLabel.cpp b/QTfrontend/ui/widget/SquareLabel.cpp
index 183eaba..d667d2e 100644
--- a/QTfrontend/ui/widget/SquareLabel.cpp
+++ b/QTfrontend/ui/widget/SquareLabel.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/SquareLabel.h b/QTfrontend/ui/widget/SquareLabel.h
index 5cb8538..3c73195 100644
--- a/QTfrontend/ui/widget/SquareLabel.h
+++ b/QTfrontend/ui/widget/SquareLabel.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/about.cpp b/QTfrontend/ui/widget/about.cpp
index 37a1e9d..c3fa10f 100644
--- a/QTfrontend/ui/widget/about.cpp
+++ b/QTfrontend/ui/widget/about.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +21,23 @@
#include <QList>
#include <QUrl>
#include <QRegExp>
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QMessageBox>
+#include <QNetworkReply>
+#include <QDebug>
#include "hwconsts.h"
#include "SDLInteraction.h"
+#include "SDL.h"
+#include "SDL_version.h"
+#include "physfs.h"
+
+#ifdef VIDEOREC
+extern "C"
+{
+#include "libavutil/avutil.h"
+}
+#endif
#include "about.h"
@@ -31,6 +46,9 @@ About::About(QWidget * parent) :
{
QGridLayout *mainLayout = new QGridLayout(this);
+ QVBoxLayout * leftLayout = new QVBoxLayout();
+ mainLayout->addLayout(leftLayout, 0, 0, 2, 1);
+
QLabel *imageLabel = new QLabel;
QImage image(":/res/Hedgehog.png");
imageLabel->setPixmap(QPixmap::fromImage(image));
@@ -40,7 +58,7 @@ About::About(QWidget * parent) :
imageLabel->setMinimumHeight(30);
imageLabel->setMaximumHeight(300);
- mainLayout->addWidget(imageLabel, 0, 0, 2, 1);
+ leftLayout->addWidget(imageLabel, 0, Qt::AlignHCenter);
QLabel *lbl1 = new QLabel(this);
lbl1->setOpenExternalLinks(true);
@@ -49,109 +67,59 @@ About::About(QWidget * parent) :
"a { color: #ffcc00; }"
// "a:hover { color: yellow; }"
"</style>"
- "<div align=\"center\"><h1>Hedgewars</h1>"
- "<h3>" + QLabel::tr("Version") + " " + *cVersionString + "</h3>"
- "<p><a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a></p><br>" +
- QLabel::tr("This program is distributed under the GNU General Public License v2") +
+ "<div align=\"center\"><h1>Hedgewars " + *cVersionString + "</h1>"
+ "<h3>" + QLabel::tr("Revision") + " " + *cRevisionString + " (" + *cHashString + ")</h3>"
+ "<p><a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a></p>" +
+ QLabel::tr("This program is distributed under the %1").arg("<a \
+ href=\"http://www.gnu.org/licenses/gpl-2.0.html\">GNU GPL v2</a>") +
"</div>"
);
lbl1->setWordWrap(true);
mainLayout->addWidget(lbl1, 0, 1);
lbl2 = new QTextBrowser(this);
-
lbl2->setOpenExternalLinks(true);
- lbl2->setText(
- "<style type=\"text/css\">"
- "a { color: #ffcc00; }"
-// "a:hover { color: yellow; }"
- "</style>" +
- QString("<h2>") +
- QLabel::tr("Developers:") +
- "</h2><p>"
- "Engine, frontend, net server: Andrey Korotaev <<a href=\"mailto:unC0Rr at gmail.com\">unC0Rr at gmail.com</a>><br>"
- "Many frontend improvements: Igor Ulyanov <<a href=\"mailto:disinbox at gmail.com\">disinbox at gmail.com</a>><br>"
- "Many engine and frontend improvements: Derek Pomery <<a href=\"mailto:nemo at m8y.org\">nemo at m8y.org</a>><br>"
- "Drill rocket, Ballgun, RC Plane weapons: Martin Boze <<a href=\"mailto:afffect at gmail.com\">afffect at gmail.com</a>><br>"
- "Mine number and time game settings: David A. Cuadrado <<a href=\"mailto:krawek at gmail.com\">krawek at gmail.com</a>><br>"
- "Frontend improvements: Martin Minarik <<a href=\"mailto:ttsmj at pokec.sk\">ttsmj at pokec.sk</a>><br>"
- "Frontend improvements: Kristian Lehmann <<a href=\"mailto:email at thexception.net\">email at thexception.net</a>><br>"
- "Mac OS X/iPhone port, OpenGL-ES conversion: Vittorio Giovara <<a href=\"mailto:vittorio.giovara at gmail.com\">vittorio.giovara at gmail.com</a>><br>"
- "Many engine and frontend improvements (and bugs): Richard Karolyi <<a href=\"mailto:sheepluva@" "ercatec.net\">sheepluva@" "ercatec.net</a>><br>"
- "Gamepad and Lua integration: Mario Liebisch <<a href=\"mailto:mario.liebisch at gmail.com\">mario.liebisch at gmail.com</a>><br>"
- "Many engine improvements and graphics: Carlos Vives <<a href=\"mailto:mail at carlosvives.es\">mail at carlosvives.es</a>><br>"
- "Maze maps: Henning Kühn <<a href=\"mailto:prg at cooco.de\">prg at cooco.de</a>><br>"
- "Engine and frontend improvements: Henrik Rostedt <<a href=\"mailto:henrik.rostedt at gmail.com\">henrik.rostedt at gmail.com</a>><br>"
- "Lua game modes and missions: John Lambert <<a href=\"mailto:redgrinner at gmail.com\">redgrinner at gmail.com</a>><br>"
- "Frontend improvements: Mayur Pawashe <<a href=\"mailto:zorgiepoo at gmail.com\">zorgiepoo at gmail.com</a>><br>"
- "Android port: Richard Deurwaarder <<a href=\"mailto:xeli at xelification.com\">xeli at xelification.com</a>><br>"
- "Android netplay, portability abstraction: Simeon Maxein <<a href=\"mailto:smaxein at googlemail.com\">smaxein at googlemail.com</a>><br>"
- "WebGL port, some pas2c and GLES2 work: Meng Xiangyun <<a href=\"mailto:xymengxy at gmail.com\">xymengxy at gmail.com</a>><br>"
- "Video recording: Stepan Podoskin <<a href=\"mailto:stepik-777 at mail.ru\">stepik-777 at mail.ru</a>><br>"
- "Campaign support, first campaign: Szabolcs Orbàn <<a href=\"mailto:szabibibi at gmail.com\">szabibibi at gmail.com</a>><br>"
- "</p><h2>" +
-
- QLabel::tr("Art:") + "</h2>"
- + QString::fromUtf8(
- "<p>John Dum <<a href=\"mailto:fizzy at gmail.com\">fizzy at gmail.com</a>>"
- "<br>"
- "Joshua Frese <<a href=\"mailto:joshfrese at gmail.com\">joshfrese at gmail.com</a>>"
- "<br>"
- "Stanko TadiÄ <<a href=\"mailto:stanko at mfhinc.net\">stanko at mfhinc.net</a>>"
- "<br>"
- "Julien Koesten <<a href=\"mailto:julienkoesten at aol.com\">julienkoesten at aol.com</a>>"
- "<br>"
- "Joshua O'Sullivan <<a href=\"mailto:coheedftw at hotmail.co.uk\">coheedftw at hotmail.co.uk</a>>"
- "<br>"
- "Nils Lück <<a href=\"mailto:nils.luck.design at gmail.com\">nils.luck.design at gmail.com</a>>"
- "<br>"
- "Guillaume Englert <<a href=\"mailto:genglert at hybird.org\">genglert at hybird.org</a>>"
- "<br>"
- "Hats: Trey Perry <<a href=\"mailto:tx.perry.j at gmail.com\">tx.perry.j at gmail.com</a>>"
- "</p><h2>") +
- QLabel::tr("Sounds:") + "</h2>"
- "Hedgehogs voice: Stephen Alexander <<a href=\"mailto:ArmagonNo1 at gmail.com\">ArmagonNo1 at gmail.com</a>>"
- "<br>"
- "John Dum <<a href=\"mailto:fizzy at gmail.com\">fizzy at gmail.com</a>>"
- "<br>"
- "Jonatan Nilsson <<a href=\"mailto:jonatanfan at gmail.com\">jonatanfan at gmail.com</a>>"
- "<br>"
- "Daniel Martin <<a href=\"mailto:elhombresinremedio at gmail.com\">elhombresinremedio at gmail.com</a>>"
- "</p><h2>" +
-
- QLabel::tr("Translations:") + "</h2><p>"
- + QString::fromUtf8(
- "Brazilian Portuguese: Romulo Fernandes Machado <<a href=\"mailto:abra185 at gmail.com\">abra185 at gmail.com</a>><br>"
- "Bulgarian: Svetoslav Stefanov<br>"
- "Czech: Petr ÅezáÄek <<a href=\"mailto:rezacek at gmail.com\">rezacek at gmail.com</a>><br>"
- "Chinese: Jie Luo <<a href=\"mailto:lililjlj at gmail.com\">lililjlj at gmail.com</a>><br>"
- "English: Andrey Korotaev <<a href=\"mailto:unC0Rr at gmail.com\">unC0Rr at gmail.com</a>><br>"
- "Finnish: Nina Kuisma <<a href=\"mailto:ninnnu at gmail.com\">ninnnu at gmail.com</a>><br>"
- "French: Antoine Turmel <<a href=\"mailto:geekshadow at gmail.com\">geekshadow at gmail.com</a>>, Clement Woitrain <<a href=\"mailto:sphrixclement at gmail.com\">sphrixclement at gmail.com</a>><br>"
- "German: Peter Hüwe <<a href=\"mailto:PeterHuewe at gmx.de\">PeterHuewe at gmx.de</a>>, Mario Liebisch <<a href=\"mailto:mario.liebisch at gmail.com\">mario.liebisch at gmail.com</a>>, Richard Karolyi <<a href=\"mailto:sheepluva@" "ercatec.net\">sheepluva@" "ercatec.net</a>><br>"
- "Greek: <<a href=\"mailto:talos_kriti at yahoo.gr\">talos_kriti at yahoo.gr</a>><br>"
- "Italian: Luca Bonora <<a href=\"mailto:bonora.luca at gmail.com\">bonora.luca at gmail.com</a>>, Marco Bresciani<br>"
- "Japanese: ADAM Etienne <<a href=\"mailto:etienne.adam at gmail.com\">etienne.adam at gmail.com</a>><br>"
- "Korean: Anthony Bellew <<a href=\"mailto:anthonyreflected at gmail.com\">anthonyreflected at gmail.com</a>><br>"
- "Lithuanian: Lukas Urbonas <<a href=\"mailto:lukasu08 at gmail.com\">lukasu08 at gmail.com</a>><br>"
- "Polish: Maciej MroziÅski <<a href=\"mailto:mynick2 at o2.pl\">mynick2 at o2.pl</a>>, Wojciech Latkowski <<a href=\"mailto:magik17l at gmail.com\">magik17l at gmail.com</a>>, Piotr Mitana, Maciej Górny<br>"
- "Portuguese: Fábio Canário <<a href=\"mailto:inufabie at gmail.com\">inufabie at gmail.com</a>><br>"
- "Russian: Andrey Korotaev <<a href=\"mailto:unC0Rr at gmail.com\">unC0Rr at gmail.com</a>><br>"
- "Slovak: Jose Riha<br>"
- "Spanish: Carlos Vives <<a href=\"mailto:mail at carlosvives.es\">mail at carlosvives.es</a>><br>"
- "Swedish: Niklas Grahn <<a href=\"mailto:raewolusjoon at yaoo.com\">raewolusjoon at yaoo.com</a>>, Henrik Rostedt <<a href=\"mailto:henrik.rostedt at gmail.com\">henrik.rostedt at gmail.com</a>><br>"
- "Ukrainian: Eugene V. Lyubimkin <<a href=\"mailto:jackyf.devel at gmail.com\">jackyf.devel at gmail.com</a>>, Igor Paliychuk <<a href=\"mailto:mansonigor at gmail.com\">mansonigor at gmail.com</a>>, Eugene Sakara <<a href=\"mailto:eresid at gmail.com\">eresid at gmail.com</a>>"
- "</p><h2>") +
-
- QLabel::tr("Special thanks:") + "</h2><p>"
- "Aleksey Andreev <<a href=\"mailto:blaknayabr at gmail.com\">blaknayabr at gmail.com</a>><br>"
- "Aleksander Rudalev <<a href=\"mailto:alexv at pomorsu.ru\">alexv at pomorsu.ru</a>><br>"
- "Natasha Korotaeva <<a href=\"mailto:layout at pisem.net\">layout at pisem.net</a>><br>"
- "Adam Higerd (aka ahigerd at FreeNode)"
- "</p>"
- );
+ QUrl localpage = QUrl::fromLocalFile(":/res/html/about.html");
+ lbl2->setSource(localpage); //sets the source of the label from the file above
mainLayout->addWidget(lbl2, 1, 1);
+ /* Library information */
+
+ QString libinfo = "<style type=text/css>a:link { color: #FFFF6E; }</style>";
+
+#ifdef __GNUC__
+ libinfo.append(QString("<a href=\"http://gcc.gnu.org\">GCC</a> %1<br>").arg(__VERSION__));
+#else
+ libinfo.append(QString(tr("Unknown Compiler")).arg(__VERSION__) + QString("<br>"));
+#endif
+
+ libinfo.append(QString("<a href=\"http://www.libsdl.org/\">SDL</a> version: %1.%2.%3<br>")
+ .arg(SDL_MAJOR_VERSION)
+ .arg(SDL_MINOR_VERSION)
+ .arg(SDL_PATCHLEVEL));
+
+ libinfo.append(QString("<a href=\"http://qt-project.org/\">Qt</a> version: %1<br>").arg(QT_VERSION_STR));
+
+#ifdef VIDEOREC
+ libinfo.append(QString("<a href=\"http://libav.org\">Libav</a> version: %1.%2.%3<br>")
+ .arg(LIBAVUTIL_VERSION_MAJOR)
+ .arg(LIBAVUTIL_VERSION_MINOR)
+ .arg(LIBAVUTIL_VERSION_MICRO));
+#endif
+
+ libinfo.append(QString("<a href=\"http://icculus.org/physfs/\">PhysFS</a> version: %1.%2.%3<br>")
+ .arg(PHYSFS_VER_MAJOR)
+ .arg(PHYSFS_VER_MINOR)
+ .arg(PHYSFS_VER_PATCH));
+
+ QLabel * lblLibInfo = new QLabel();
+ lblLibInfo->setOpenExternalLinks(true);
+ lblLibInfo->setText(libinfo);
+ lblLibInfo->setWordWrap(true);
+ lblLibInfo->setMaximumWidth(280);
+ leftLayout->addWidget(lblLibInfo, 0, Qt::AlignHCenter);
+ leftLayout->addStretch(1);
+
setAcceptDrops(true);
}
diff --git a/QTfrontend/ui/widget/about.h b/QTfrontend/ui/widget/about.h
index 80ef9b3..e569fd9 100644
--- a/QTfrontend/ui/widget/about.h
+++ b/QTfrontend/ui/widget/about.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,7 +23,6 @@
#include <QDropEvent>
#include <QTextBrowser>
-
class About : public QWidget
{
Q_OBJECT
diff --git a/QTfrontend/ui/widget/bgwidget.cpp b/QTfrontend/ui/widget/bgwidget.cpp
index c23cad2..70e4559 100644
--- a/QTfrontend/ui/widget/bgwidget.cpp
+++ b/QTfrontend/ui/widget/bgwidget.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Kristian Lehmann <email at thexception.net>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -176,6 +176,8 @@ void BGWidget::animate()
int ydiff = newPos.y() - oldPos.y();
update(oldPos.x(), oldPos.y(), xdiff+sprite.width(), ydiff+sprite.height());
}
+
+ //repaint(); // Repaint every frame. Prevents ghosting of widgets if widgets resize in runtime.
}
void BGWidget::startAnimation()
diff --git a/QTfrontend/ui/widget/bgwidget.h b/QTfrontend/ui/widget/bgwidget.h
index f3b49be..18a7e7b 100644
--- a/QTfrontend/ui/widget/bgwidget.h
+++ b/QTfrontend/ui/widget/bgwidget.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Kristian Lehmann <email at thexception.net>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/chatwidget.cpp b/QTfrontend/ui/widget/chatwidget.cpp
index 9c91e11..528c087 100644
--- a/QTfrontend/ui/widget/chatwidget.cpp
+++ b/QTfrontend/ui/widget/chatwidget.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,12 +31,13 @@
#include <QModelIndexList>
#include <QSortFilterProxyModel>
#include <QMenu>
+#include <QScrollBar>
#include "DataManager.h"
#include "hwconsts.h"
#include "gameuiconfig.h"
#include "playerslistmodel.h"
-
+#include "HWApplication.h"
#include "chatwidget.h"
@@ -64,7 +65,7 @@ void HWChatWidget::setStyleSheet(const QString & styleSheet)
if (orgStyleSheet.isEmpty())
{
// load external stylesheet if there is any
- QFile extFile(DataManager::instance().findFileForRead("css/chat.css"));
+ QFile extFile("physfs://css/chat.css");
QFile resFile(":/res/css/chat.css");
@@ -156,28 +157,22 @@ void HWChatWidget::setStyleSheet(const QString & styleSheet)
void HWChatWidget::displayError(const QString & message)
{
addLine("msg_Error", " !!! " + message);
- // scroll to the end
- chatText->moveCursor(QTextCursor::End);
}
void HWChatWidget::displayNotice(const QString & message)
{
addLine("msg_Notice", " *** " + message);
- // scroll to the end
- chatText->moveCursor(QTextCursor::End);
}
void HWChatWidget::displayWarning(const QString & message)
{
addLine("msg_Warning", " *!* " + message);
- // scroll to the end
- chatText->moveCursor(QTextCursor::End);
}
-HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notify) :
+HWChatWidget::HWChatWidget(QWidget* parent, bool notify) :
QWidget(parent),
mainLayout(this)
{
@@ -187,45 +182,54 @@ HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notif
m_isAdmin = false;
m_autoKickEnabled = false;
- if(gameSettings->value("frontend/sound", true).toBool())
- {
- QStringList vpList =
- QStringList() << "Classic" << "Default" << "Mobster" << "Russian";
-
- foreach (QString vp, vpList)
- {
- m_helloSounds.append(DataManager::instance().findFileForRead(
- QString("Sounds/voices/%1/Hello.ogg").arg(vp)));
- }
-
- m_hilightSound = DataManager::instance().findFileForRead(
- "Sounds/beep.ogg");
+ QStringList vpList =
+ QStringList() << "Classic" << "Default" << "Mobster" << "Russian";
+ foreach (const QString & vp, vpList)
+ {
+ m_helloSounds.append(QString("/Sounds/voices/%1/Hello.ogg").arg(vp));
}
- mainLayout.setSpacing(1);
- mainLayout.setMargin(1);
- mainLayout.setSizeConstraint(QLayout::SetMinimumSize);
- mainLayout.setColumnStretch(0, 76);
- mainLayout.setColumnStretch(1, 24);
+ m_hilightSound = "/Sounds/beep.ogg";
- chatEditLine = new SmartLineEdit(this);
- chatEditLine->setMaxLength(300);
- connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+ mainLayout.setMargin(0);
- mainLayout.addWidget(chatEditLine, 2, 0);
+ QWidget * leftSideContainer = new QWidget();
+ leftSideContainer->setObjectName("leftSideContainer");
+ leftSideContainer->setStyleSheet("#leftSideContainer { border-width: 0px; background-color: #ffcc00; border-radius: 10px;} QTextBrowser, SmartLineEdit { background-color: rgb(13, 5, 68); }");
+ QVBoxLayout * leftSide = new QVBoxLayout(leftSideContainer);
+ leftSide->setSpacing(3);
+ leftSide->setMargin(3);
+ mainLayout.addWidget(leftSideContainer, 76);
- chatText = new QTextBrowser(this);
+ // Chat view
+ chatText = new QTextBrowser(this);
chatText->document()->setDefaultStyleSheet(styleSheet());
-
chatText->setMinimumHeight(20);
chatText->setMinimumWidth(10);
chatText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
chatText->setOpenLinks(false);
+ chatText->setStyleSheet("QTextBrowser { background-color: rgb(23, 11, 54); border-width: 0px; }");
connect(chatText, SIGNAL(anchorClicked(const QUrl&)),
this, SLOT(linkClicked(const QUrl&)));
- mainLayout.addWidget(chatText, 0, 0, 2, 1);
+ leftSide->addWidget(chatText, 1);
+
+ // Input box
+
+ // Normal: rgb(23, 11, 54)
+ // Hover: rgb(13, 5, 68)
+
+ chatEditLine = new SmartLineEdit();
+ chatEditLine->setMaxLength(300);
+ chatEditLine->setStyleSheet("SmartLineEdit { background-color: rgb(23, 11, 54); padding: 2px 8px; border-width: 0px; border-radius: 7px; } SmartLineEdit:hover, SmartLineEdit:focus { background-color: rgb(13, 5, 68); }");
+ chatEditLine->setFixedHeight(24);
+ chatEditLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+
+ leftSide->addWidget(chatEditLine, 0);
+
+ // Nickname list
chatNicks = new QListView(this);
chatNicks->setIconSize(QSize(24, 16));
@@ -241,7 +245,8 @@ HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notif
connect(chatNicks, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(nicksContextMenuRequested(QPoint)));
- mainLayout.addWidget(chatNicks, 0, 1, 3, 1);
+ mainLayout.addSpacing(0);
+ mainLayout.addWidget(chatNicks, 24);
// the userData is used to flag things that are even available when user
// is offline
@@ -283,12 +288,16 @@ HWChatWidget::HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notif
clear();
}
+void HWChatWidget::setSettings(QSettings * settings)
+{
+ gameSettings = settings;
+}
void HWChatWidget::linkClicked(const QUrl & link)
{
- if (link.scheme() == "http")
+ if ((link.scheme() == "http") or (link.scheme() == "https"))
QDesktopServices::openUrl(link);
- if (link.scheme() == "hwnick")
+ else if (link.scheme() == "hwnick")
{
// decode nick
QString nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery()));
@@ -359,15 +368,43 @@ QString HWChatWidget::linkedNick(const QString & nickname)
return QString("<span class=\"nick\">%1</span>").arg(Qt::escape(nickname));
}
+const QRegExp HWChatWidget::URLREGEXP = QRegExp("(http(s)?://)?(www\\.)?((hedgewars\\.org|code\\.google\\.com|googlecode\\.com|hh\\.unit22\\.org)(/[^ ]*)?)");
-void HWChatWidget::onChatString(const QString& str)
+bool HWChatWidget::containsHighlight(const QString & sender, const QString & message)
{
- onChatString("", str);
+ if ((sender != m_userNick) && (!m_userNick.isEmpty()))
+ {
+ QString lcStr = message.toLower();
+
+ foreach (const QRegExp & hl, m_highlights)
+ {
+ if (lcStr.contains(hl))
+ return true;
+ }
+ }
+ return false;
}
-const QRegExp HWChatWidget::URLREGEXP = QRegExp("(http://)?(www\\.)?(hedgewars\\.org(/[^ ]*)?)");
+QString HWChatWidget::messageToHTML(const QString & message)
+{
+ QString formattedStr = Qt::escape(message);
+ // link some urls
+ formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http\\2://\\4\">\\4</a>");
+ return formattedStr;
+}
-void HWChatWidget::onChatString(const QString& nick, const QString& str)
+void HWChatWidget::onChatAction(const QString & nick, const QString & action)
+{
+ printChatString(nick, "* " + linkedNick(nick) + " " + messageToHTML(action), "Action", containsHighlight(nick, action));
+}
+
+void HWChatWidget::onChatMessage(const QString & nick, const QString & message)
+{
+ printChatString(nick, linkedNick(nick) + ": " + messageToHTML(message), "Chat", containsHighlight(nick, message));
+}
+
+void HWChatWidget::printChatString(
+ const QString & nick, const QString & str, const QString & cssClassPart, bool highlight)
{
QSortFilterProxyModel * playersSortFilterModel = qobject_cast<QSortFilterProxyModel *>(chatNicks->model());
if(!playersSortFilterModel)
@@ -378,58 +415,15 @@ void HWChatWidget::onChatString(const QString& nick, const QString& str)
if(!players)
return;
- if (!nick.isEmpty())
- {
- // don't show chat lines that are from ignored nicks
- if (players->isFlagSet(nick, PlayersListModel::Ignore))
- return;
- }
+ // don't show chat lines that are from ignored nicks
+ if (players->isFlagSet(nick, PlayersListModel::Ignore))
+ return;
bool isFriend = (!nick.isEmpty()) && players->isFlagSet(nick, PlayersListModel::Friend);
- QString formattedStr = Qt::escape(str.mid(1));
- // make hedgewars.org urls actual links
- formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http://\\3\">\\3</a>");
-
- // link the nick
- if(!nick.isEmpty())
- formattedStr.replace("|nick|", linkedNick(nick));
-
- QString cssClass("msg_UserChat");
-
- // check first character for color code and set color properly
- char c = str[0].toAscii();
- switch (c)
- {
- case 3:
- cssClass = (isFriend ? "msg_FriendJoin" : "msg_UserJoin");
- break;
- case 2:
- cssClass = (isFriend ? "msg_FriendAction" : "msg_UserAction");
- break;
- default:
- if (isFriend)
- cssClass = "msg_FriendChat";
- }
-
- bool isHL = false;
-
- if ((c != 3) && (!nick.isEmpty()) &&
- (nick != m_userNick) && (!m_userNick.isEmpty()))
- {
- QString lcStr = str.toLower();
-
- foreach (const QRegExp & hl, m_highlights)
- {
- if (lcStr.contains(hl))
- {
- isHL = true;
- break;
- }
- }
- }
+ QString cssClass = (isFriend ? "msg_Friend" : "msg_User") + cssClassPart;
- addLine(cssClass, formattedStr, isHL);
+ addLine(cssClass, str, highlight);
}
void HWChatWidget::addLine(const QString & cssClass, QString line, bool isHighlight)
@@ -437,6 +431,8 @@ void HWChatWidget::addLine(const QString & cssClass, QString line, bool isHighli
if (s_displayNone->contains(cssClass))
return; // the css forbids us to display this line
+ beforeContentAdd();
+
if (chatStrings.size() > 250)
chatStrings.removeFirst();
@@ -453,17 +449,20 @@ void HWChatWidget::addLine(const QString & cssClass, QString line, bool isHighli
{
line = QString("<span class=\"highlight\">%1</span>").arg(line);
SDLInteraction::instance().playSoundFile(m_hilightSound);
+ HWApplication::alert(this, 800);
}
chatStrings.append(line);
chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
- chatText->moveCursor(QTextCursor::End);
+ afterContentAdd();
}
void HWChatWidget::onServerMessage(const QString& str)
{
+ beforeContentAdd();
+
if (chatStrings.size() > 250)
chatStrings.removeFirst();
@@ -471,7 +470,7 @@ void HWChatWidget::onServerMessage(const QString& str)
chatText->setHtml("<html><body>"+chatStrings.join("<br>")+"</body></html>");
- chatText->moveCursor(QTextCursor::End);
+ afterContentAdd();
}
@@ -499,7 +498,10 @@ void HWChatWidget::nickAdded(const QString & nick, bool notifyNick)
emit nickCountUpdate(chatNicks->model()->rowCount());
- if(notifyNick && notify && gameSettings->value("frontend/sound", true).toBool())
+ if (!isIgnored)
+ printChatString(nick, QString("*** ") + tr("%1 has joined").arg(linkedNick(nick)), "Join", false);
+
+ if (notifyNick && notify && (m_helloSounds.size() > 0))
{
SDLInteraction::instance().playSoundFile(
m_helloSounds.at(rand() % m_helloSounds.size()));
@@ -508,9 +510,19 @@ void HWChatWidget::nickAdded(const QString & nick, bool notifyNick)
void HWChatWidget::nickRemoved(const QString& nick)
{
+ nickRemoved(nick, "");
+}
+
+void HWChatWidget::nickRemoved(const QString& nick, const QString & message)
+{
chatEditLine->removeNickname(nick);
emit nickCountUpdate(chatNicks->model()->rowCount());
+
+ if (message.isEmpty())
+ printChatString(nick, QString("*** ") + tr("%1 has left").arg(linkedNick(nick)), "Leave", false);
+ else
+ printChatString(nick, QString("*** ") + tr("%1 has left (%2)").arg(linkedNick(nick)).arg(messageToHTML(message)), "Leave", false);
}
void HWChatWidget::clear()
@@ -569,6 +581,19 @@ void HWChatWidget::clear()
}
}
+void HWChatWidget::onPlayerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo)
+{
+ addLine("msg_PlayerInfo", QString(" >>> %1 - <span class=\"ipaddress\">%2</span> <span class=\"version\">%3</span> <span class=\"location\">%4</span>")
+ .arg(linkedNick(nick))
+ .arg(ip)
+ .arg(version)
+ .arg(roomInfo));
+}
+
void HWChatWidget::onKick()
{
QModelIndexList mil = chatNicks->selectionModel()->selectedRows();
@@ -762,8 +787,7 @@ void HWChatWidget::discardStyleSheet()
void HWChatWidget::saveStyleSheet()
{
- QString dest =
- DataManager::instance().findFileForWrite("css/chat.css");
+ QString dest = "physfs://css/chat.css";
QFile file(dest);
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
@@ -801,11 +825,7 @@ bool HWChatWidget::parseCommand(const QString & line)
else if (tline == "/saveStyleSheet")
saveStyleSheet();
else
- {
- static QRegExp post("\\s.*$");
- tline.remove(post);
- displayWarning(tr("%1 is not a valid command!").arg(tline));
- }
+ emit consoleCommand(tline.mid(1));
return true;
}
@@ -892,3 +912,21 @@ void HWChatWidget::nicksContextMenuRequested(const QPoint &pos)
m_nicksMenu->popup(chatNicks->mapToGlobal(pos));
}
+
+void HWChatWidget::beforeContentAdd()
+{
+ m_scrollBarPos = chatText->verticalScrollBar()->value();
+ m_scrollToBottom = m_scrollBarPos == chatText->verticalScrollBar()->maximum();
+}
+
+void HWChatWidget::afterContentAdd()
+{
+ if(m_scrollToBottom)
+ {
+ chatText->verticalScrollBar()->setValue(chatText->verticalScrollBar()->maximum());
+ chatText->moveCursor(QTextCursor::End);
+ } else
+ {
+ chatText->verticalScrollBar()->setValue(m_scrollBarPos);
+ }
+}
diff --git a/QTfrontend/ui/widget/chatwidget.h b/QTfrontend/ui/widget/chatwidget.h
index bdc168c..5220948 100644
--- a/QTfrontend/ui/widget/chatwidget.h
+++ b/QTfrontend/ui/widget/chatwidget.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ class HWChatWidget : public QWidget
Q_OBJECT
public:
- HWChatWidget(QWidget* parent, QSettings * gameSettings, bool notify);
+ HWChatWidget(QWidget* parent, bool notify);
void setIgnoreListKick(bool enabled); ///< automatically kick people on ignore list (if possible)
void setShowFollow(bool enabled);
static const QString & styleSheet();
@@ -63,6 +63,7 @@ class HWChatWidget : public QWidget
void displayWarning(const QString & message);
void setUser(const QString & nickname);
void setUsersModel(QAbstractItemModel * model);
+ void setSettings(QSettings * settings);
protected:
virtual void dragEnterEvent(QDragEnterEvent * event);
@@ -82,15 +83,42 @@ class HWChatWidget : public QWidget
void discardStyleSheet();
void saveStyleSheet();
QString linkedNick(const QString & nickname);
+ void beforeContentAdd();
+ void afterContentAdd();
+
+ /**
+ * @brief Checks whether the message contains a highlight.
+ * @param sender the sender of the message
+ * @param message the message
+ * @return true if the sender is somebody else and the message contains a highlight, otherwise false
+ */
+ bool containsHighlight(const QString & sender, const QString & message);
+ /**
+ * @brief Escapes HTML chars in the message and converts URls to HTML links.
+ * @param message the message to be converted to HTML
+ * @return the HTML message
+ */
+ QString messageToHTML(const QString & message);
+ void printChatString(
+ const QString & nick,
+ const QString & str,
+ const QString & cssClassPart,
+ bool highlight);
public slots:
- void onChatString(const QString& str);
- void onChatString(const QString& nick, const QString& str);
+ void onChatAction(const QString & nick, const QString & str);
+ void onChatMessage(const QString & nick, const QString & str);
void onServerMessage(const QString& str);
void nickAdded(const QString& nick, bool notifyNick);
void nickRemoved(const QString& nick);
+ void nickRemoved(const QString& nick, const QString& message);
void clear();
void adminAccess(bool);
+ void onPlayerInfo(
+ const QString & nick,
+ const QString & ip,
+ const QString & version,
+ const QString & roomInfo);
signals:
void chatLine(const QString& str);
@@ -99,10 +127,11 @@ class HWChatWidget : public QWidget
void info(const QString & str);
void follow(const QString &);
void nickCountUpdate(int cnt);
+ void consoleCommand(const QString & command);
private:
bool m_isAdmin;
- QGridLayout mainLayout;
+ QHBoxLayout mainLayout;
QTextBrowser* chatText;
QStringList chatStrings;
QListView* chatNicks;
@@ -122,6 +151,8 @@ class HWChatWidget : public QWidget
QList<QRegExp> m_highlights; ///< regular expressions used for highlighting
bool notify;
bool m_autoKickEnabled;
+ bool m_scrollToBottom;
+ int m_scrollBarPos;
private slots:
void returnPressed();
diff --git a/QTfrontend/ui/widget/colorwidget.h b/QTfrontend/ui/widget/colorwidget.h
index 4d2acb4..155c60d 100644
--- a/QTfrontend/ui/widget/colorwidget.h
+++ b/QTfrontend/ui/widget/colorwidget.h
@@ -13,7 +13,7 @@ class QStandardItemModel;
class ColorWidget : public QFrame
{
Q_OBJECT
-
+
public:
explicit ColorWidget(QStandardItemModel *colorsModel, QWidget *parent = 0);
~ColorWidget();
@@ -24,7 +24,7 @@ public:
signals:
void colorChanged(int color);
-
+
private:
int m_color;
QStandardItemModel * m_colorsModel;
diff --git a/QTfrontend/ui/widget/databrowser.cpp b/QTfrontend/ui/widget/databrowser.cpp
index 6ac4f2e..60d6219 100644
--- a/QTfrontend/ui/widget/databrowser.cpp
+++ b/QTfrontend/ui/widget/databrowser.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/databrowser.h b/QTfrontend/ui/widget/databrowser.h
index 8068f5e..64b68fb 100644
--- a/QTfrontend/ui/widget/databrowser.h
+++ b/QTfrontend/ui/widget/databrowser.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/drawmapwidget.cpp b/QTfrontend/ui/widget/drawmapwidget.cpp
index ce5bbf9..a5252b9 100644
--- a/QTfrontend/ui/widget/drawmapwidget.cpp
+++ b/QTfrontend/ui/widget/drawmapwidget.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/drawmapwidget.h b/QTfrontend/ui/widget/drawmapwidget.h
index 767337a..be63597 100644
--- a/QTfrontend/ui/widget/drawmapwidget.h
+++ b/QTfrontend/ui/widget/drawmapwidget.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/feedbackdialog.cpp b/QTfrontend/ui/widget/feedbackdialog.cpp
new file mode 100644
index 0000000..cd34d99
--- /dev/null
+++ b/QTfrontend/ui/widget/feedbackdialog.cpp
@@ -0,0 +1,503 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QHBoxLayout>
+#include <QLineEdit>
+#include <QTextBrowser>
+#include <QLabel>
+#include <QHttp>
+#include <QSysInfo>
+#include <QDebug>
+#include <QBuffer>
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QNetworkReply>
+#include <QProcess>
+#include <QMessageBox>
+#include <QCheckBox>
+#include <QByteArray>
+
+#include <string>
+
+#ifdef Q_WS_WIN
+#define WINVER 0x0500
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#endif
+
+#ifdef Q_WS_MAC
+#include <sys/sysctl.h>
+#ifndef _SC_NPROCESSORS_ONLN
+#define _SC_NPROCESSORS_ONLN 58
+#endif
+#endif
+
+#include <stdint.h>
+
+#include "AbstractPage.h"
+#include "hwconsts.h"
+#include "feedbackdialog.h"
+
+FeedbackDialog::FeedbackDialog(QWidget * parent) : QDialog(parent)
+{
+ setModal(true);
+ setWindowFlags(Qt::Sheet);
+ setWindowModality(Qt::WindowModal);
+ setMinimumSize(700, 460);
+ resize(700, 460);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ netManager = NULL;
+ GenerateSpecs();
+
+ /* Top layout */
+
+ QVBoxLayout * pageLayout = new QVBoxLayout();
+ QHBoxLayout * summaryLayout = new QHBoxLayout();
+ QHBoxLayout * emailLayout = new QHBoxLayout();
+ QHBoxLayout * descriptionLayout = new QHBoxLayout();
+ QHBoxLayout * combinedTopLayout = new QHBoxLayout();
+ QHBoxLayout * systemLayout = new QHBoxLayout();
+
+ info = new QLabel();
+ info->setText(QString(
+ "<style type=\"text/css\">"
+ "a { color: #fc0; }"
+ "b { color: #0df; }"
+ "</style>"
+ "<div align=\"center\"><h1>%1</h1>"
+ "<h3>%2<h3>"
+ "<h4>%3 <a href=\"http://code.google.com/p/hedgewars/wiki/KnownBugs\">known bugs</a><h4>"
+ "<h4>%4<h4>"
+ "</div>")
+ .arg(tr("Send us feedback!"))
+ .arg(tr("We are always happy about suggestions, ideas, or bug reports."))
+ .arg(tr("If you found a bug, you can see if it's already been reported here: "))
+ .arg(tr("Your email address is optional, but necessary if you want us to get back at you."))
+ );
+ info->setOpenExternalLinks(true);
+ pageLayout->addWidget(info);
+
+ QVBoxLayout * summaryEmailLayout = new QVBoxLayout();
+
+ const int labelWidth = 90;
+
+ label_email = new QLabel();
+ label_email->setText(QLabel::tr("Your Email"));
+ label_email->setFixedWidth(labelWidth);
+ emailLayout->addWidget(label_email);
+ email = new QLineEdit();
+ emailLayout->addWidget(email);
+ summaryEmailLayout->addLayout(emailLayout);
+
+ label_summary = new QLabel();
+ label_summary->setText(QLabel::tr("Summary"));
+ label_summary->setFixedWidth(labelWidth);
+ summaryLayout->addWidget(label_summary);
+ summary = new QLineEdit();
+ summaryLayout->addWidget(summary);
+ summaryEmailLayout->addLayout(summaryLayout);
+
+ combinedTopLayout->addLayout(summaryEmailLayout);
+
+ CheckSendSpecs = new QCheckBox();
+ CheckSendSpecs->setText(QLabel::tr("Send system information"));
+ CheckSendSpecs->setChecked(true);
+ systemLayout->addWidget(CheckSendSpecs);
+ BtnViewInfo = new QPushButton(tr("View"));
+ systemLayout->addWidget(BtnViewInfo, 1);
+ BtnViewInfo->setFixedSize(60, 30);
+ connect(BtnViewInfo, SIGNAL(clicked()), this, SLOT(ShowSpecs()));
+ combinedTopLayout->addLayout(systemLayout);
+
+ combinedTopLayout->setStretch(0, 1);
+ combinedTopLayout->insertSpacing(1, 20);
+
+ pageLayout->addLayout(combinedTopLayout);
+
+ label_description = new QLabel();
+ label_description->setText(QLabel::tr("Description"));
+ label_description->setFixedWidth(labelWidth);
+ descriptionLayout->addWidget(label_description, 0, Qt::AlignTop);
+ description = new QTextBrowser();
+ description->setReadOnly(false);
+ descriptionLayout->addWidget(description);
+ pageLayout->addLayout(descriptionLayout);
+
+ /* Bottom layout */
+
+ QHBoxLayout * bottomLayout = new QHBoxLayout();
+ QHBoxLayout * captchaLayout = new QHBoxLayout();
+ QVBoxLayout * captchaInputLayout = new QVBoxLayout();
+
+ QPushButton * BtnCancel = new QPushButton(tr("Cancel"));
+ bottomLayout->addWidget(BtnCancel, 0);
+ BtnCancel->setFixedSize(100, 40);
+ connect(BtnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+ bottomLayout->insertStretch(1);
+
+ label_captcha = new QLabel();
+ label_captcha->setStyleSheet("border: 3px solid #ffcc00; border-radius: 4px");
+ label_captcha->setText("loading<br>captcha");
+ label_captcha->setFixedSize(200, 50);
+ captchaLayout->addWidget(label_captcha);
+
+ label_captcha_input = new QLabel();
+ label_captcha_input->setText(QLabel::tr("Type the security code:"));
+ captchaInputLayout->addWidget(label_captcha_input);
+ captchaInputLayout->setAlignment(label_captcha, Qt::AlignBottom);
+ captcha_code = new QLineEdit();
+ captcha_code->setFixedSize(165, 30);
+ captchaInputLayout->addWidget(captcha_code);
+ captchaInputLayout->setAlignment(captcha_code, Qt::AlignTop);
+ captchaLayout->addLayout(captchaInputLayout);
+ captchaLayout->setAlignment(captchaInputLayout, Qt::AlignLeft);
+
+ bottomLayout->addLayout(captchaLayout);
+ bottomLayout->addSpacing(40);
+
+ // TODO: Set green arrow icon for send button (:/res/Start.png)
+ BtnSend = new QPushButton(tr("Send Feedback"));
+ bottomLayout->addWidget(BtnSend, 0);
+ BtnSend->setFixedSize(120, 40);
+ connect(BtnSend, SIGNAL(clicked()), this, SLOT(SendFeedback()));
+
+ bottomLayout->setStretchFactor(captchaLayout, 0);
+ bottomLayout->setStretchFactor(BtnSend, 1);
+
+ QVBoxLayout * dialogLayout = new QVBoxLayout(this);
+ dialogLayout->addLayout(pageLayout, 1);
+ dialogLayout->addLayout(bottomLayout);
+
+ LoadCaptchaImage();
+}
+
+void FeedbackDialog::GenerateSpecs()
+{
+ // Gather some information about the system and embed it into the report
+ QDesktopWidget* screen = QApplication::desktop();
+ QString os_version = "Operating system: ";
+ QString qt_version = QString("Qt version: ") + QT_VERSION_STR + QString("\n");
+ QString total_ram = "Total RAM: ";
+ QString number_of_cores = "Number of cores: ";
+ QString compiler_bits = "Compiler architecture: ";
+ QString compiler_version = "Compiler version: ";
+ QString kernel_line = "Kernel: ";
+ QString screen_size = "Size of the screen(s): " +
+ QString::number(screen->width()) + "x" + QString::number(screen->height()) + "\n";
+ QString number_of_screens = "Number of screens: " + QString::number(screen->screenCount()) + "\n";
+ QString processor_name = "Processor: ";
+
+ // platform specific code
+#ifdef Q_WS_MACX
+ number_of_cores += QString::number(sysconf(_SC_NPROCESSORS_ONLN)) + "\n";
+
+ uint64_t memsize;
+ size_t len = sizeof(memsize);
+ static int mib_s[2] = { CTL_HW, HW_MEMSIZE };
+ if (sysctl (mib_s, 2, &memsize, &len, NULL, 0) == 0)
+ total_ram += QString::number(memsize/1024/1024) + " MB\n";
+ else
+ total_ram += "Error getting total RAM information\n";
+
+ int mib[] = {CTL_KERN, KERN_OSRELEASE};
+ sysctl(mib, sizeof mib / sizeof(int), NULL, &len, NULL, 0);
+
+ char *kernelVersion = (char *)malloc(sizeof(char)*len);
+ sysctl(mib, sizeof mib / sizeof(int), kernelVersion, &len, NULL, 0);
+
+ QString kernelVersionStr = QString(kernelVersion);
+ free(kernelVersion);
+ int major_version = kernelVersionStr.split(".").first().toUInt() - 4;
+ int minor_version = kernelVersionStr.split(".").at(1).toUInt();
+ os_version += QString("Mac OS X 10.%1.%2").arg(major_version).arg(minor_version) + " ";
+
+ switch(major_version)
+ {
+ case 4: os_version += "\"Tiger\"\n"; break;
+ case 5: os_version += "\"Leopard\"\n"; break;
+ case 6: os_version += "\"Snow Leopard\"\n"; break;
+ case 7: os_version += "\"Lion\"\n"; break;
+ case 8: os_version += "\"Mountain Lion\"\n"; break;
+ default: os_version += "\"Unknown version\"\n"; break;
+ }
+#endif
+#ifdef Q_WS_WIN
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ number_of_cores += QString::number(sysinfo.dwNumberOfProcessors) + "\n";
+ MEMORYSTATUSEX status;
+ status.dwLength = sizeof(status);
+ GlobalMemoryStatusEx(&status);
+ total_ram += QString::number(status.ullTotalPhys/1024/1024) + " MB\n";
+
+ switch(QSysInfo::windowsVersion())
+ {
+ case QSysInfo::WV_NT: os_version += "Windows NT\n"; break;
+ case QSysInfo::WV_2000: os_version += "Windows 2000\n"; break;
+ case QSysInfo::WV_XP: os_version += "Windows XP\n"; break;
+ case QSysInfo::WV_2003: os_version += "Windows Server 2003\n"; break;
+ case QSysInfo::WV_VISTA: os_version += "Windows Vista\n"; break;
+ case QSysInfo::WV_WINDOWS7: os_version += "Windows 7\n"; break;
+ //case QSysInfo::WV_WINDOWS8: os_version += "Windows 8\n"; break; //QT 5+
+ default: os_version += "Windows (Unknown version)\n"; break;
+ }
+ kernel_line += "Windows kernel\n";
+#endif
+#ifdef Q_WS_X11
+ number_of_cores += QString::number(sysconf(_SC_NPROCESSORS_ONLN)) + "\n";
+ long pages = sysconf(_SC_PHYS_PAGES),
+/*
+#ifndef Q_OS_FREEBSD
+ available_pages = sysconf(_SC_AVPHYS_PAGES),
+#else
+ available_pages = 0,
+#endif*/
+ page_size = sysconf(_SC_PAGE_SIZE);
+ total_ram += QString::number(pages*page_size/1024/1024) + " MB\n";
+ os_version += "GNU/Linux or BSD\n";
+#endif
+
+ // uname -a
+#if defined(Q_WS_X11) || defined(Q_WS_MACX)
+ QProcess *process = new QProcess();
+ QStringList arguments = QStringList("-a");
+ process->start("uname", arguments);
+ if (process->waitForFinished())
+ kernel_line += QString(process->readAll());
+ delete process;
+#endif
+
+#if (!defined(Q_WS_MACX) && defined(__i386__)) || defined(__x86_64__)
+ // cpu info
+ quint32 registers[4];
+ quint32 i;
+
+ i = 0x80000002;
+ asm volatile
+ ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3])
+ : "a" (i), "c" (0));
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4);
+ i = 0x80000003;
+ asm volatile
+ ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3])
+ : "a" (i), "c" (0));
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4);
+ i = 0x80000004;
+ asm volatile
+ ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3])
+ : "a" (i), "c" (0));
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4);
+ processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4);
+ processor_name += "\n";
+#else
+ processor_name += "Unknown";
+#endif
+
+ // compiler
+#ifdef __GNUC__
+ compiler_version += "GCC " + QString(__VERSION__) + "\n";
+#else
+ compiler_version += "Unknown\n";
+#endif
+
+ if(sizeof(void*) == 4)
+ compiler_bits += "i386\n";
+ else if(sizeof(void*) == 8)
+ compiler_bits += "x86_64\n";
+
+ // concat system info
+ specs = qt_version
+ + os_version
+ + total_ram
+ + screen_size
+ + number_of_screens
+ + processor_name
+ + number_of_cores
+ + compiler_version
+ + compiler_bits
+ + kernel_line;
+}
+
+void FeedbackDialog::ShowErrorMessage(const QString & msg)
+{
+ QMessageBox msgMsg(this);
+ msgMsg.setIcon(QMessageBox::Warning);
+ msgMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Error"));
+ msgMsg.setText(msg);
+ msgMsg.setWindowModality(Qt::WindowModal);
+ msgMsg.exec();
+}
+
+void FeedbackDialog::ShowSpecs()
+{
+ QMessageBox msgMsg(this);
+ msgMsg.setIcon(QMessageBox::Information);
+ msgMsg.setWindowTitle(QMessageBox::tr("System Information Preview"));
+ msgMsg.setText(specs);
+ msgMsg.setTextFormat(Qt::PlainText);
+ msgMsg.setWindowModality(Qt::WindowModal);
+ msgMsg.setStyleSheet("background: #0A0533;");
+ msgMsg.exec();
+}
+
+void FeedbackDialog::NetReply(QNetworkReply *reply)
+{
+ if (reply == genCaptchaRequest)
+ {
+ if (reply->error() != QNetworkReply::NoError)
+ {
+ qDebug() << "Error generating captcha image: " << reply->errorString();
+ ShowErrorMessage(QMessageBox::tr("Failed to generate captcha"));
+ return;
+ }
+
+ bool okay;
+ QByteArray body = reply->readAll();
+ captchaID = QString(body).toInt(&okay);
+
+ if (!okay)
+ {
+ qDebug() << "Failed to get captcha ID: " << body;
+ ShowErrorMessage(QMessageBox::tr("Failed to generate captcha"));
+ return;
+ }
+
+ QString url = "http://hedgewars.org/feedback/?captcha&id=";
+ url += QString::number(captchaID);
+
+ QNetworkAccessManager *netManager = GetNetManager();
+ QUrl captchaURL(url);
+ QNetworkRequest req(captchaURL);
+ captchaImageRequest = netManager->get(req);
+ }
+ else if (reply == captchaImageRequest)
+ {
+ if (reply->error() != QNetworkReply::NoError)
+ {
+ qDebug() << "Error loading captcha image: " << reply->errorString();
+ ShowErrorMessage(QMessageBox::tr("Failed to download captcha"));
+ return;
+ }
+
+ QByteArray imageData = reply->readAll();
+ QPixmap pixmap;
+ pixmap.loadFromData(imageData);
+ label_captcha->setPixmap(pixmap);
+ captcha_code->setText("");
+ }
+}
+
+QNetworkAccessManager * FeedbackDialog::GetNetManager()
+{
+ if (netManager) return netManager;
+ netManager = new QNetworkAccessManager(this);
+ connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(NetReply(QNetworkReply*)));
+ return netManager;
+}
+
+void FeedbackDialog::LoadCaptchaImage()
+{
+ QNetworkAccessManager *netManager = GetNetManager();
+ QUrl captchaURL("http://hedgewars.org/feedback/?gencaptcha");
+ QNetworkRequest req(captchaURL);
+ genCaptchaRequest = netManager->get(req);
+}
+
+void FeedbackDialog::finishedSlot(QNetworkReply* reply)
+{
+ if (reply && reply->error() == QNetworkReply::NoError)
+ {
+ QMessageBox infoMsg(this);
+ infoMsg.setIcon(QMessageBox::Information);
+ infoMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Success"));
+ infoMsg.setText(reply->readAll());
+ infoMsg.setWindowModality(Qt::WindowModal);
+ infoMsg.exec();
+
+ accept();
+
+ return;
+ }
+ else
+ {
+ ShowErrorMessage(QString("Error: ") + reply->readAll());
+ LoadCaptchaImage();
+ }
+}
+
+void FeedbackDialog::SendFeedback()
+{
+ // Get form data
+
+ QString summary = this->summary->text();
+ QString description = this->description->toPlainText();
+ QString email = this->email->text();
+ QString captchaCode = this->captcha_code->text();
+ QString captchaID = QString::number(this->captchaID);
+ QString version = "HedgewarsFoundation-Hedgewars-v" + *cVersionString + "_r" +
+ *cRevisionString + "|" + *cHashString;
+
+ if (summary.isEmpty() || description.isEmpty())
+ {
+ ShowErrorMessage(QMessageBox::tr("Please fill out all fields. Email is optional."));
+ return;
+ }
+
+ // Submit issue to PHP script
+
+ QByteArray body;
+ body.append("captcha=");
+ body.append(captchaID);
+ body.append("&code=");
+ body.append(captchaCode);
+ body.append("&version=");
+ body.append(QUrl::toPercentEncoding(version));
+ body.append("&title=");
+ body.append(QUrl::toPercentEncoding(summary));
+ body.append("&body=");
+ body.append(QUrl::toPercentEncoding(description));
+ body.append("&email=");
+ body.append(QUrl::toPercentEncoding(email));
+ if (CheckSendSpecs->isChecked())
+ {
+ body.append("&specs=");
+ body.append(QUrl::toPercentEncoding(specs));
+ }
+
+ nam = new QNetworkAccessManager(this);
+ connect(nam, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(finishedSlot(QNetworkReply*)));
+
+ QNetworkRequest header(QUrl("http://hedgewars.org/feedback/?submit"));
+ header.setRawHeader("Content-Length", QString::number(body.size()).toAscii());
+ header.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
+
+ nam->post(header, body);
+}
diff --git a/QTfrontend/ui/widget/feedbackdialog.h b/QTfrontend/ui/widget/feedbackdialog.h
new file mode 100644
index 0000000..940bffb
--- /dev/null
+++ b/QTfrontend/ui/widget/feedbackdialog.h
@@ -0,0 +1,75 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef FEEDBACKDIALOG_H
+#define FEEDBACKDIALOG_H
+
+#include <QDialog>
+
+class QNetworkReply;
+class QNetworkAccessManager;
+class QCheckBox;
+class QLineEdit;
+class QTextBrowser;
+class QLabel;
+
+class FeedbackDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ FeedbackDialog(QWidget * parent = 0);
+ void EmbedSystemInfo();
+ void LoadCaptchaImage();
+
+ QPushButton * BtnSend;
+ QPushButton * BtnViewInfo;
+ QCheckBox * CheckSendSpecs;
+ QLineEdit * summary;
+ QTextBrowser * description;
+ QLabel * info;
+ QLabel * label_summary;
+ QLabel * label_description;
+ QLabel * label_captcha;
+ QLabel * label_email;
+ QLabel * label_captcha_input;
+ QLineEdit * captcha_code;
+ QLineEdit * email;
+ int captchaID;
+ QString specs;
+
+ private:
+ void GenerateSpecs();
+ QLayout * bodyLayoutDefinition();
+ QLayout * footerLayoutDefinition();
+ QNetworkAccessManager * GetNetManager();
+ void ShowErrorMessage(const QString & msg);
+
+ QNetworkAccessManager * netManager;
+ QNetworkReply * captchaImageRequest;
+ QNetworkReply * genCaptchaRequest;
+ QNetworkAccessManager * nam;
+
+ private slots:
+ virtual void NetReply(QNetworkReply*);
+ virtual void ShowSpecs();
+ void SendFeedback();
+ void finishedSlot(QNetworkReply* reply);
+};
+
+#endif // FEEDBACKDIALOG_H
diff --git a/QTfrontend/ui/widget/fpsedit.cpp b/QTfrontend/ui/widget/fpsedit.cpp
index c6fad53..644a652 100644
--- a/QTfrontend/ui/widget/fpsedit.cpp
+++ b/QTfrontend/ui/widget/fpsedit.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/fpsedit.h b/QTfrontend/ui/widget/fpsedit.h
index 7429b4c..a9dfdbe 100644
--- a/QTfrontend/ui/widget/fpsedit.h
+++ b/QTfrontend/ui/widget/fpsedit.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/frameTeam.cpp b/QTfrontend/ui/widget/frameTeam.cpp
index 1af51e0..dee79c1 100644
--- a/QTfrontend/ui/widget/frameTeam.cpp
+++ b/QTfrontend/ui/widget/frameTeam.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/frameTeam.h b/QTfrontend/ui/widget/frameTeam.h
index 85e5897..2e83f00 100644
--- a/QTfrontend/ui/widget/frameTeam.h
+++ b/QTfrontend/ui/widget/frameTeam.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/gamecfgwidget.cpp b/QTfrontend/ui/widget/gamecfgwidget.cpp
index f465fe3..bd44f43 100644
--- a/QTfrontend/ui/widget/gamecfgwidget.cpp
+++ b/QTfrontend/ui/widget/gamecfgwidget.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,11 @@
#include <QLabel>
#include <QMessageBox>
#include <QTableView>
+#include <QScrollBar>
+#include <QTabWidget>
#include <QPushButton>
+#include <QDebug>
+#include <QList>
#include "gamecfgwidget.h"
#include "igbox.h"
@@ -33,6 +37,7 @@
#include "ammoSchemeModel.h"
#include "proto.h"
#include "GameStyleModel.h"
+#include "themeprompt.h"
GameCFGWidget::GameCFGWidget(QWidget* parent) :
QGroupBox(parent)
@@ -40,28 +45,76 @@ GameCFGWidget::GameCFGWidget(QWidget* parent) :
, seedRegexp("\\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\\}")
{
mainLayout.setMargin(0);
-// mainLayout.setSizeConstraint(QLayout::SetMinimumSize);
+ setMinimumHeight(310);
+ setMaximumHeight(447);
+ setMinimumWidth(470);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ m_master = true;
- pMapContainer = new HWMapContainer(this);
- mainLayout.addWidget(pMapContainer, 0, 0);
+ // Easy containers for the map/game options in either stacked or tabbed mode
- IconedGroupBox *GBoxOptions = new IconedGroupBox(this);
- GBoxOptions->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
- mainLayout.addWidget(GBoxOptions, 1, 0);
+ mapContainerFree = new QWidget();
+ mapContainerTabbed = new QWidget();
+ optionsContainerFree = new QWidget();
+ optionsContainerTabbed = new QWidget();
+ tabbed = false;
- QGridLayout *GBoxOptionsLayout = new QGridLayout(GBoxOptions);
+ // Container for when in tabbed mode
- GBoxOptions->setTitle(tr("Game Options"));
- GBoxOptionsLayout->addWidget(new QLabel(QLabel::tr("Style"), GBoxOptions), 1, 0);
+ tabs = new QTabWidget(this);
+ tabs->setFixedWidth(470);
+ tabs->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+ tabs->addTab(mapContainerTabbed, tr("Map"));
+ tabs->addTab(optionsContainerTabbed, tr("Game options"));
+ tabs->setObjectName("gameCfgWidgetTabs");
+ mainLayout.addWidget(tabs, 1);
+ tabs->setVisible(false);
- Scripts = new QComboBox(GBoxOptions);
+ // Container for when in stacked mode
+
+ StackContainer = new QWidget();
+ StackContainer->setObjectName("gameStackContainer");
+ mainLayout.addWidget(StackContainer, 1);
+ QVBoxLayout * stackLayout = new QVBoxLayout(StackContainer);
+
+ // Map options
+
+ pMapContainer = new HWMapContainer(mapContainerFree);
+ stackLayout->addWidget(mapContainerFree, 0, Qt::AlignHCenter);
+ pMapContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ pMapContainer->setFixedSize(width() - 14, 278);
+ mapContainerFree->setFixedSize(pMapContainer->width(), pMapContainer->height());
+
+ // Horizontal divider
+
+ QFrame * divider = new QFrame();
+ divider->setFrameShape(QFrame::HLine);
+ divider->setFrameShadow(QFrame::Plain);
+ stackLayout->addWidget(divider, 0, Qt::AlignBottom);
+ //stackLayout->setRowMinimumHeight(1, 10);
+
+ // Game options
+
+ optionsContainerTabbed->setContentsMargins(0, 0, 0, 0);
+ optionsContainerFree->setFixedSize(width() - 14, 140);
+ stackLayout->addWidget(optionsContainerFree, 0, Qt::AlignHCenter);
+
+ OptionsInnerContainer = new QWidget(optionsContainerFree);
+ m_childWidgets << OptionsInnerContainer;
+ OptionsInnerContainer->setFixedSize(optionsContainerFree->width(), optionsContainerFree->height());
+ OptionsInnerContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ GBoxOptionsLayout = new QGridLayout(OptionsInnerContainer);
+
+ GBoxOptionsLayout->addWidget(new QLabel(QLabel::tr("Style"), this), 1, 0);
+
+ Scripts = new QComboBox(this);
GBoxOptionsLayout->addWidget(Scripts, 1, 1);
Scripts->setModel(DataManager::instance().gameStyleModel());
m_curScript = Scripts->currentText();
connect(Scripts, SIGNAL(currentIndexChanged(int)), this, SLOT(scriptChanged(int)));
- QWidget *SchemeWidget = new QWidget(GBoxOptions);
+ QWidget *SchemeWidget = new QWidget(this);
GBoxOptionsLayout->addWidget(SchemeWidget, 2, 0, 1, 2);
QGridLayout *SchemeWidgetLayout = new QGridLayout(SchemeWidget);
@@ -76,7 +129,7 @@ GameCFGWidget::GameCFGWidget(QWidget* parent) :
QPixmap pmEdit(":/res/edit.png");
QPushButton * goToSchemePage = new QPushButton(SchemeWidget);
- goToSchemePage->setToolTip(tr("Edit schemes"));
+ goToSchemePage->setWhatsThis(tr("Edit schemes"));
goToSchemePage->setIconSize(pmEdit.size());
goToSchemePage->setIcon(pmEdit);
goToSchemePage->setMaximumWidth(pmEdit.width() + 6);
@@ -91,7 +144,7 @@ GameCFGWidget::GameCFGWidget(QWidget* parent) :
connect(WeaponsName, SIGNAL(currentIndexChanged(int)), this, SLOT(ammoChanged(int)));
QPushButton * goToWeaponPage = new QPushButton(SchemeWidget);
- goToWeaponPage->setToolTip(tr("Edit weapons"));
+ goToWeaponPage->setWhatsThis(tr("Edit weapons"));
goToWeaponPage->setIconSize(pmEdit.size());
goToWeaponPage->setIcon(pmEdit);
goToWeaponPage->setMaximumWidth(pmEdit.width() + 6);
@@ -99,7 +152,7 @@ GameCFGWidget::GameCFGWidget(QWidget* parent) :
connect(goToWeaponPage, SIGNAL(clicked()), this, SLOT(jumpToWeapons()));
bindEntries = new QCheckBox(SchemeWidget);
- bindEntries->setToolTip(tr("When this option is enabled selecting a game scheme will auto-select a weapon"));
+ bindEntries->setWhatsThis(tr("Game scheme will auto-select a weapon"));
bindEntries->setChecked(true);
bindEntries->setMaximumWidth(42);
bindEntries->setStyleSheet( "QCheckBox::indicator:checked { image: url(\":/res/lock.png\"); }"
@@ -118,6 +171,42 @@ GameCFGWidget::GameCFGWidget(QWidget* parent) :
connect(&DataManager::instance(), SIGNAL(updated()), this, SLOT(updateModelViews()));
}
+void GameCFGWidget::setTabbed(bool tabbed)
+{
+ if (tabbed && !this->tabbed)
+ { // Make tabbed
+ tabs->setCurrentIndex(0);
+ StackContainer->setVisible(false);
+ tabs->setVisible(true);
+ pMapContainer->setParent(mapContainerTabbed);
+ OptionsInnerContainer->setParent(optionsContainerTabbed);
+ pMapContainer->setVisible(true);
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
+ this->tabbed = true;
+ }
+ else if (!tabbed && this->tabbed)
+ { // Make stacked
+ pMapContainer->setParent(mapContainerFree);
+ OptionsInnerContainer->setParent(optionsContainerFree);
+ tabs->setVisible(false);
+ StackContainer->setVisible(true);
+ pMapContainer->setVisible(true);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ this->tabbed = false;
+ }
+
+ // Restore scrollbar palettes, since Qt seems to forget them easily when switching parents
+ QList<QScrollBar *> allSBars = findChildren<QScrollBar *>();
+ QPalette pal = palette();
+ pal.setColor(QPalette::WindowText, QColor(0xff, 0xcc, 0x00));
+ pal.setColor(QPalette::Button, QColor(0x00, 0x35, 0x1d));
+ pal.setColor(QPalette::Base, QColor(0x00, 0x35, 0x1d));
+ pal.setColor(QPalette::Window, QColor(0x00, 0x00, 0x00));
+
+ for (int i = 0; i < allSBars.size(); ++i)
+ allSBars.at(i)->setPalette(pal);
+}
+
void GameCFGWidget::jumpToSchemes()
{
emit goToSchemes(GameSchemes->currentIndex());
@@ -186,7 +275,7 @@ quint32 GameCFGWidget::getGameFlags() const
if (schemeData(24).toBool())
result |= 0x02000000; // tag team
if (schemeData(25).toBool())
- result |= 0x04000000; // bottom border
+ result |= 0x04000000; // bottom
return result;
}
@@ -235,6 +324,8 @@ QByteArray GameCFGWidget::getFullConfig() const
bcfg << QString("e$template_filter %1").arg(pMapContainer->getTemplateFilter()).toUtf8();
bcfg << QString("e$mapgen %1").arg(mapgen).toUtf8();
+
+
switch (mapgen)
{
case MAPGEN_MAZE:
@@ -271,7 +362,7 @@ void GameCFGWidget::setNetAmmo(const QString& name, const QString& ammo)
bool illegal = ammo.size() != cDefaultAmmoStore->size();
if (illegal)
{
- QMessageBox illegalMsg(this);
+ QMessageBox illegalMsg(parentWidget());
illegalMsg.setIcon(QMessageBox::Warning);
illegalMsg.setWindowTitle(QMessageBox::tr("Error"));
illegalMsg.setText(QMessageBox::tr("Cannot use the ammo '%1'!").arg(name));
@@ -325,10 +416,6 @@ void GameCFGWidget::setParam(const QString & param, const QStringList & slValue)
if (param == "SEED")
{
pMapContainer->setSeed(value);
- if (!seedRegexp.exactMatch(value))
- {
- pMapContainer->seedEdit->setVisible(true);
- }
return;
}
if (param == "THEME")
@@ -377,8 +464,6 @@ void GameCFGWidget::setParam(const QString & param, const QStringList & slValue)
if (param == "FULLMAPCONFIG")
{
QString seed = slValue[3];
- if (!seedRegexp.exactMatch(seed))
- pMapContainer->seedEdit->setVisible(true);
pMapContainer->setAllMapParameters(
slValue[0],
@@ -514,7 +599,7 @@ void GameCFGWidget::scriptChanged(int index)
GameSchemes->setEnabled(false);
GameSchemes->setCurrentIndex(GameSchemes->findText("Default"));
}
- else
+ else if (m_master)
{
GameSchemes->setEnabled(true);
int num = GameSchemes->findText(scheme);
@@ -529,7 +614,7 @@ void GameCFGWidget::scriptChanged(int index)
WeaponsName->setEnabled(false);
WeaponsName->setCurrentIndex(WeaponsName->findText("Default"));
}
- else
+ else if (m_master)
{
WeaponsName->setEnabled(true);
int num = WeaponsName->findText(weapons);
@@ -586,3 +671,19 @@ void GameCFGWidget::updateModelViews()
Scripts->setCurrentIndex(0);
}
}
+
+bool GameCFGWidget::isMaster()
+{
+ return m_master;
+}
+
+void GameCFGWidget::setMaster(bool master)
+{
+ if (master == m_master) return;
+ m_master = master;
+
+ pMapContainer->setMaster(master);
+
+ foreach (QWidget *widget, m_childWidgets)
+ widget->setEnabled(master);
+}
diff --git a/QTfrontend/ui/widget/gamecfgwidget.h b/QTfrontend/ui/widget/gamecfgwidget.h
index ab5aa5b..6c46d2f 100644
--- a/QTfrontend/ui/widget/gamecfgwidget.h
+++ b/QTfrontend/ui/widget/gamecfgwidget.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,11 +31,14 @@ class QCheckBox;
class QVBoxLayout;
class QLabel;
class QTableView;
+class QTabWidget;
class GameCFGWidget : public QGroupBox
{
Q_OBJECT
+ Q_PROPERTY(bool master READ isMaster WRITE setMaster)
+
public:
GameCFGWidget(QWidget* parent);
quint32 getGameFlags() const;
@@ -47,11 +50,14 @@ class GameCFGWidget : public QGroupBox
HWMapContainer* pMapContainer;
QTableView * tv;
QVariant schemeData(int column) const;
+ bool isMaster();
public slots:
void setParam(const QString & param, const QStringList & value);
void fullNetConfig();
void resendSchemeData();
+ void setMaster(bool master);
+ void setTabbed(bool tabbed);
signals:
void paramChanged(const QString & param, const QStringList & value);
@@ -75,12 +81,24 @@ class GameCFGWidget : public QGroupBox
void updateModelViews();
private:
- QGridLayout mainLayout;
+ QVBoxLayout mainLayout;
QCheckBox * bindEntries;
QString curNetAmmoName;
QString curNetAmmo;
QRegExp seedRegexp;
QString m_curScript;
+ bool m_master;
+ QList<QWidget *> m_childWidgets;
+ QGridLayout * GBoxOptionsLayout;
+ QWidget * OptionsInnerContainer;
+ QWidget * StackContainer;
+
+ QWidget * mapContainerFree;
+ QWidget * mapContainerTabbed;
+ QWidget * optionsContainerFree;
+ QWidget * optionsContainerTabbed;
+ bool tabbed;
+ QTabWidget * tabs;
void setNetAmmo(const QString& name, const QString& ammo);
diff --git a/QTfrontend/ui/widget/hatbutton.cpp b/QTfrontend/ui/widget/hatbutton.cpp
new file mode 100644
index 0000000..04280a3
--- /dev/null
+++ b/QTfrontend/ui/widget/hatbutton.cpp
@@ -0,0 +1,72 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QDebug>
+
+#include "hatprompt.h"
+#include "DataManager.h"
+#include "HatModel.h"
+#include "hatbutton.h"
+
+HatButton::HatButton(QWidget* parent) : QPushButton(parent)
+{
+ setIconSize(QSize(32, 37));
+ setFixedSize(44, 44);
+
+ m_hatModel = DataManager::instance().hatModel();
+ connect(this, SIGNAL(clicked()), this, SLOT(showPrompt()));
+
+ setCurrentIndex(0);
+}
+
+void HatButton::setCurrentIndex(int index)
+{
+ m_hat = m_hatModel->index(index, 0);
+ setWhatsThis(QString(tr("Change hat (%1)")).arg(m_hat.data(Qt::DisplayRole).toString()));
+ setToolTip(m_hat.data(Qt::DisplayRole).toString());
+ setIcon(m_hat.data(Qt::DecorationRole).value<QIcon>());
+}
+
+int HatButton::currentIndex()
+{
+ return m_hat.row();
+}
+
+void HatButton::setCurrentHat(const QString & name)
+{
+ QList<QStandardItem *> hats = m_hatModel->findItems(name);
+
+ if (hats.count() > 0)
+ setCurrentIndex(hats[0]->row());
+}
+
+QString HatButton::currentHat() const
+{
+ return m_hat.data(Qt::DisplayRole).toString();
+}
+
+void HatButton::showPrompt()
+{
+ HatPrompt prompt(currentIndex(), this);
+ int hatID = prompt.exec() - 1; // Since 0 means canceled, so all indexes are +1'd
+ if (hatID < 0) return;
+
+ setCurrentIndex(hatID);
+ emit currentIndexChanged(hatID);
+ emit currentHatChanged(currentHat());
+}
diff --git a/QTfrontend/ui/widget/hatbutton.h b/QTfrontend/ui/widget/hatbutton.h
new file mode 100644
index 0000000..84d3798
--- /dev/null
+++ b/QTfrontend/ui/widget/hatbutton.h
@@ -0,0 +1,55 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef HATBUTTON_H
+#define HATBUTTON_H
+
+#include <QPushButton>
+#include <QString>
+#include <QModelIndex>
+
+class HatModel;
+
+class HatButton : public QPushButton
+{
+ Q_OBJECT
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex)
+ Q_PROPERTY(QString currentHat READ currentHat WRITE setCurrentHat)
+
+ public:
+ HatButton(QWidget* parent);
+ int currentIndex();
+ QString currentHat() const;
+
+ private:
+ QModelIndex m_hat;
+ HatModel * m_hatModel;
+
+ signals:
+ void currentIndexChanged(int);
+ void currentHatChanged(const QString &);
+
+ public slots:
+ void setCurrentIndex(int index);
+ void setCurrentHat(const QString & name);
+
+ private slots:
+ void showPrompt();
+};
+
+#endif // HATBUTTON_H
diff --git a/QTfrontend/ui/widget/hatprompt.cpp b/QTfrontend/ui/widget/hatprompt.cpp
new file mode 100644
index 0000000..7d1e397
--- /dev/null
+++ b/QTfrontend/ui/widget/hatprompt.cpp
@@ -0,0 +1,185 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QDialog>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QScrollArea>
+#include <QPushButton>
+#include <QToolButton>
+#include <QWidgetItem>
+#include <QModelIndex>
+#include <QListView>
+#include <QLineEdit>
+#include <QLabel>
+#include <QSortFilterProxyModel>
+#include <QDebug>
+
+#include "DataManager.h"
+#include "lineeditcursor.h"
+#include "HatModel.h"
+#include "hatprompt.h"
+
+void HatListView::moveUp()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier));
+}
+
+void HatListView::moveDown()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier));
+}
+
+void HatListView::moveLeft()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveLeft, Qt::NoModifier));
+}
+
+void HatListView::moveRight()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveRight, Qt::NoModifier));
+}
+
+HatPrompt::HatPrompt(int currentIndex, QWidget* parent) : QDialog(parent)
+{
+ setModal(true);
+ setWindowFlags(Qt::Sheet);
+ setWindowModality(Qt::WindowModal);
+ setMinimumSize(550, 430);
+ resize(550, 430);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ setStyleSheet("QPushButton { padding: 5px; margin-top: 10px; }");
+
+ // Hat model, and a model for setting a filter
+ HatModel * hatModel = DataManager::instance().hatModel();
+ filterModel = new QSortFilterProxyModel();
+ filterModel->setSourceModel(hatModel);
+ filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+ // Grid
+ QGridLayout * dialogLayout = new QGridLayout(this);
+ dialogLayout->setSpacing(0);
+ dialogLayout->setColumnStretch(1, 1);
+
+ QHBoxLayout * topLayout = new QHBoxLayout();
+
+ // Help/prompt message at top
+ QLabel * lblDesc = new QLabel(tr("Search for a hat:"));
+ lblDesc->setObjectName("lblDesc");
+ lblDesc->setStyleSheet("#lblDesc { color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-top-left-radius: 10px; padding: 4px 10px;}");
+ lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ lblDesc->setFixedHeight(24);
+ lblDesc->setMinimumWidth(0);
+
+ // Filter text box
+ QWidget * filterContainer = new QWidget();
+ filterContainer->setFixedHeight(24);
+ filterContainer->setObjectName("filterContainer");
+ filterContainer->setStyleSheet("#filterContainer { background: #F6CB1C; border-top-right-radius: 10px; padding: 3px; }");
+ filterContainer->setFixedWidth(150);
+ txtFilter = new LineEditCursor(filterContainer);
+ txtFilter->setFixedWidth(150);
+ txtFilter->setFocus();
+ txtFilter->setFixedHeight(22);
+ txtFilter->setStyleSheet("LineEditCursor { border-width: 0px; border-radius: 6px; margin-top: 3px; margin-right: 3px; padding-left: 4px; padding-bottom: 2px; background-color: rgb(23, 11, 54); } LineEditCursor:hover, LineEditCursor:focus { background-color: rgb(13, 5, 68); }");
+ connect(txtFilter, SIGNAL(textChanged(const QString &)), this, SLOT(filterChanged(const QString &)));
+ connect(txtFilter, SIGNAL(moveUp()), this, SLOT(moveUp()));
+ connect(txtFilter, SIGNAL(moveDown()), this, SLOT(moveDown()));
+ connect(txtFilter, SIGNAL(moveLeft()), this, SLOT(moveLeft()));
+ connect(txtFilter, SIGNAL(moveRight()), this, SLOT(moveRight()));
+
+ // Corner widget
+ QLabel * corner = new QLabel();
+ corner->setPixmap(QPixmap(QString::fromUtf8(":/res/inverse-corner-bl.png")));
+ corner->setFixedSize(10, 10);
+
+ // Add widgets to top layout
+ topLayout->addWidget(lblDesc);
+ topLayout->addWidget(filterContainer);
+ topLayout->addWidget(corner, 0, Qt::AlignBottom);
+ topLayout->addStretch(1);
+
+ // Cancel button (closes dialog)
+ QPushButton * btnCancel = new QPushButton(tr("Cancel"));
+ connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+ // Select button
+ QPushButton * btnSelect = new QPushButton(tr("Use selected hat"));
+ btnSelect->setDefault(true);
+ connect(btnSelect, SIGNAL(clicked()), this, SLOT(onAccepted()));
+
+ // Add hats
+ list = new HatListView();
+ list->setModel(filterModel);
+ list->setViewMode(QListView::IconMode);
+ list->setResizeMode(QListView::Adjust);
+ list->setMovement(QListView::Static);
+ list->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ list->setSpacing(8);
+ list->setWordWrap(true);
+ list->setSelectionMode(QAbstractItemView::SingleSelection);
+ list->setObjectName("hatList");
+ list->setCurrentIndex(filterModel->index(currentIndex, 0));
+ connect(list, SIGNAL(activated(const QModelIndex &)), this, SLOT(hatChosen(const QModelIndex &)));
+ connect(list, SIGNAL(clicked(const QModelIndex &)), this, SLOT(hatChosen(const QModelIndex &)));
+
+ // Add elements to layouts
+ dialogLayout->addLayout(topLayout, 0, 0, 1, 3);
+ dialogLayout->addWidget(list, 1, 0, 1, 3);
+ dialogLayout->addWidget(btnCancel, 2, 0, 1, 1, Qt::AlignLeft);
+ dialogLayout->addWidget(btnSelect, 2, 2, 1, 1, Qt::AlignRight);
+}
+
+void HatPrompt::moveUp()
+{
+ list->moveUp();
+}
+
+void HatPrompt::moveDown()
+{
+ list->moveDown();
+}
+
+void HatPrompt::moveLeft()
+{
+ list->moveLeft();
+}
+
+void HatPrompt::moveRight()
+{
+ list->moveRight();
+}
+
+void HatPrompt::onAccepted()
+{
+ hatChosen(list->currentIndex());
+}
+
+// When a hat is selected
+void HatPrompt::hatChosen(const QModelIndex & index)
+{
+ done(filterModel->mapToSource(index).row() + 1); // Since returning 0 means canceled
+}
+
+// When the text in the filter text box is changed
+void HatPrompt::filterChanged(const QString & text)
+{
+ filterModel->setFilterFixedString(text);
+ list->setCurrentIndex(filterModel->index(0, 0));
+}
diff --git a/QTfrontend/ui/widget/hatprompt.h b/QTfrontend/ui/widget/hatprompt.h
new file mode 100644
index 0000000..2b71338
--- /dev/null
+++ b/QTfrontend/ui/widget/hatprompt.h
@@ -0,0 +1,65 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef HATPROMPT_H
+#define HATPROMPT_H
+
+#include <QWidget>
+#include <QDialog>
+#include <QListView>
+
+class QLineEdit;
+class QModelIndex;
+class QSortFilterProxyModel;
+class LineEditCursor;
+
+class HatListView : public QListView
+{
+ friend class HatPrompt;
+
+ public:
+ HatListView(QWidget* parent = 0) : QListView(parent){}
+ void moveUp();
+ void moveDown();
+ void moveLeft();
+ void moveRight();
+};
+
+class HatPrompt : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ HatPrompt(int currentIndex = 0, QWidget* parent = 0);
+
+ private:
+ LineEditCursor * txtFilter;
+ HatListView * list;
+ QSortFilterProxyModel * filterModel;
+
+ private slots:
+ void onAccepted();
+ void hatChosen(const QModelIndex & index);
+ void filterChanged(const QString & text);
+ void moveUp();
+ void moveDown();
+ void moveLeft();
+ void moveRight();
+};
+
+#endif // HATPROMPT_H
diff --git a/QTfrontend/ui/widget/hedgehogerWidget.cpp b/QTfrontend/ui/widget/hedgehogerWidget.cpp
index 6d78ffa..6c1f5ea 100644
--- a/QTfrontend/ui/widget/hedgehogerWidget.cpp
+++ b/QTfrontend/ui/widget/hedgehogerWidget.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Ulyanov Igor <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/hedgehogerWidget.h b/QTfrontend/ui/widget/hedgehogerWidget.h
index 29daae4..7cce781 100644
--- a/QTfrontend/ui/widget/hedgehogerWidget.h
+++ b/QTfrontend/ui/widget/hedgehogerWidget.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Ulyanov Igor <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/igbox.cpp b/QTfrontend/ui/widget/igbox.cpp
index fbdbfbc..18326ad 100644
--- a/QTfrontend/ui/widget/igbox.cpp
+++ b/QTfrontend/ui/widget/igbox.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/igbox.h b/QTfrontend/ui/widget/igbox.h
index 3feaf7f..fa59c5f 100644
--- a/QTfrontend/ui/widget/igbox.h
+++ b/QTfrontend/ui/widget/igbox.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/keybinder.cpp b/QTfrontend/ui/widget/keybinder.cpp
new file mode 100644
index 0000000..70b70ba
--- /dev/null
+++ b/QTfrontend/ui/widget/keybinder.cpp
@@ -0,0 +1,301 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "keybinder.h"
+#include "HWApplication.h"
+#include "DataManager.h"
+#include <QHBoxLayout>
+#include <QScrollArea>
+#include <QTableWidget>
+#include <QTableWidgetItem>
+#include <QStandardItemModel>
+#include <QAbstractItemModel>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QPushButton>
+#include <QHeaderView>
+#include <QComboBox>
+#include <QLabel>
+#include <QFrame>
+#include <QDebug>
+
+KeyBinder::KeyBinder(QWidget * parent, const QString & helpText, const QString & defaultText, const QString & resetButtonText) : QWidget(parent)
+{
+ this->defaultText = defaultText;
+ enableSignal = false;
+
+ // Two-column tab layout
+ QHBoxLayout * pageKeysLayout = new QHBoxLayout(this);
+ pageKeysLayout->setSpacing(0);
+ pageKeysLayout->setContentsMargins(0, 0, 0, 0);
+
+ // Table for category list
+ QVBoxLayout * catListContainer = new QVBoxLayout();
+ catListContainer->setContentsMargins(10, 10, 10, 10);
+ catList = new QListWidget();
+ catList->setFixedWidth(180);
+ catList->setStyleSheet("QListWidget::item { font-size: 14px; } QListWidget:hover { border-color: #F6CB1C; } QListWidget::item:selected { background: #150A61; color: yellow; }");
+ catList->setFocusPolicy(Qt::NoFocus);
+ connect(catList, SIGNAL(currentRowChanged(int)), this, SLOT(changeBindingsPage(int)));
+ catListContainer->addWidget(catList);
+ pageKeysLayout->addLayout(catListContainer);
+
+ // Reset all binds button
+ if (!resetButtonText.isEmpty())
+ {
+ QPushButton * btnResetAll = new QPushButton(resetButtonText);
+ catListContainer->addWidget(btnResetAll);
+ btnResetAll->setFixedHeight(40);
+ catListContainer->setStretch(1, 0);
+ catListContainer->setSpacing(10);
+ connect(btnResetAll, SIGNAL(clicked()), this, SIGNAL(resetAllBinds()));
+ }
+
+ // Container for pages of key bindings
+ QWidget * bindingsPagesContainer = new QWidget();
+ QVBoxLayout * rightLayout = new QVBoxLayout(bindingsPagesContainer);
+
+ // Scroll area for key bindings
+ QScrollArea * scrollArea = new QScrollArea();
+ scrollArea->setContentsMargins(0, 0, 0, 0);
+ scrollArea->setWidget(bindingsPagesContainer);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setFrameShape(QFrame::NoFrame);
+ scrollArea->setStyleSheet("background: #130F2A;");
+
+ // Add key binding pages to bindings tab
+ pageKeysLayout->addWidget(scrollArea);
+ pageKeysLayout->setStretch(1, 1);
+
+ // Custom help text
+ QLabel * helpLabel = new QLabel();
+ helpLabel->setText(helpText);
+ helpLabel->setStyleSheet("color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-radius: 10px; padding: auto 20px;");
+ helpLabel->setFixedHeight(24);
+ rightLayout->addWidget(helpLabel, 0, Qt::AlignCenter);
+
+ // Category list and bind table row heights
+ const int rowHeight = 20;
+ QSize catSize, headerSize;
+ catSize.setHeight(36);
+ headerSize.setHeight(24);
+
+ // Category list header
+ QListWidgetItem * catListHeader = new QListWidgetItem(tr("Category"));
+ catListHeader->setSizeHint(headerSize);
+ catListHeader->setFlags(Qt::NoItemFlags);
+ catListHeader->setForeground(QBrush(QColor("#130F2A")));
+ catListHeader->setBackground(QBrush(QColor("#F6CB1C")));
+ catListHeader->setTextAlignment(Qt::AlignCenter);
+ catList->addItem(catListHeader);
+
+ // Populate
+ bindingsPages = new QHBoxLayout();
+ bindingsPages->setContentsMargins(0, 0, 0, 0);
+ rightLayout->addLayout(bindingsPages);
+ QWidget * curPage = NULL;
+ QVBoxLayout * curLayout = NULL;
+ QTableWidget * curTable = NULL;
+ bool bFirstPage = true;
+ selectedBindTable = NULL;
+ bindComboBoxCellMappings = new QHash<QObject *, QTableWidgetItem *>();
+ bindCellComboBoxMappings = new QHash<QTableWidgetItem *, QComboBox *>();
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ if (cbinds[i].category != NULL)
+ {
+ // Add stretch at end of previous layout
+ if (curLayout != NULL) curLayout->insertStretch(-1, 1);
+
+ // Category list item
+ QListWidgetItem * catItem = new QListWidgetItem(HWApplication::translate("binds (categories)", cbinds[i].category));
+ catItem->setSizeHint(catSize);
+ catList->addItem(catItem);
+
+ // Create new page
+ curPage = new QWidget();
+ curLayout = new QVBoxLayout(curPage);
+ curLayout->setSpacing(2);
+ bindingsPages->addWidget(curPage);
+ if (!bFirstPage) curPage->setVisible(false);
+ }
+
+ // Description
+ if (cbinds[i].description != NULL)
+ {
+ QLabel * desc = new QLabel(HWApplication::translate("binds (descriptions)", cbinds[i].description));
+ curLayout->addWidget(desc, 0);
+ QFrame * divider = new QFrame();
+ divider->setFrameShape(QFrame::HLine);
+ divider->setFrameShadow(QFrame::Plain);
+ curLayout->addWidget(divider, 0);
+ }
+
+ // New table
+ if (cbinds[i].category != NULL || cbinds[i].description != NULL)
+ {
+ curTable = new QTableWidget(0, 2);
+ curTable->verticalHeader()->setVisible(false);
+ curTable->horizontalHeader()->setVisible(false);
+ curTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
+ curTable->verticalHeader()->setDefaultSectionSize(rowHeight);
+ curTable->setShowGrid(false);
+ curTable->setStyleSheet("QTableWidget { border: none; } ");
+ curTable->setSelectionBehavior(QAbstractItemView::SelectRows);
+ curTable->setSelectionMode(QAbstractItemView::SingleSelection);
+ curTable->setFocusPolicy(Qt::NoFocus);
+ connect(curTable, SIGNAL(itemSelectionChanged()), this, SLOT(bindSelectionChanged()));
+ connect(curTable, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(bindCellClicked(QTableWidgetItem *)));
+ curLayout->addWidget(curTable, 0);
+ }
+
+ // Hidden combo box
+ QComboBox * comboBox = CBBind[i] = new QComboBox(curTable);
+ comboBox->setModel((QAbstractItemModel*)DataManager::instance().bindsModel());
+ comboBox->setVisible(false);
+ comboBox->setFixedWidth(200);
+
+ // Table row
+ int row = curTable->rowCount();
+ QTableWidgetItem * nameCell = new QTableWidgetItem(HWApplication::translate("binds", cbinds[i].name));
+ nameCell->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ curTable->insertRow(row);
+ curTable->setItem(row, 0, nameCell);
+ QTableWidgetItem * bindCell = new QTableWidgetItem(comboBox->currentText());
+ bindCell->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ curTable->setItem(row, 1, bindCell);
+ curTable->resizeColumnsToContents();
+ curTable->setFixedHeight(curTable->verticalHeader()->length() + 10);
+
+ // Updates the text in the table cell
+ connect(comboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(bindChanged(const QString &)));
+
+ // Map combo box and that row's cells to each other
+ bindComboBoxCellMappings->insert(comboBox, bindCell);
+ bindCellComboBoxMappings->insert(nameCell, comboBox);
+ bindCellComboBoxMappings->insert(bindCell, comboBox);
+ }
+
+ // Add stretch at end of last layout
+ if (curLayout != NULL) curLayout->insertStretch(-1, 1);
+
+ // Go to first page
+ catList->setCurrentItem(catList->item(1));
+
+ enableSignal = true;
+}
+
+KeyBinder::~KeyBinder()
+{
+ delete bindComboBoxCellMappings;
+ delete bindCellComboBoxMappings;
+}
+
+// Switches between different pages of key binds
+void KeyBinder::changeBindingsPage(int page)
+{
+ page--; // Disregard first item (the list header)
+ int pages = bindingsPages->count();
+ for (int i = 0; i < pages; i++)
+ bindingsPages->itemAt(i)->widget()->setVisible(false);
+ bindingsPages->itemAt(page)->widget()->setVisible(true);
+}
+
+// When a key bind combobox value is changed, updates the table cell text
+void KeyBinder::bindChanged(const QString & text)
+{
+ bindComboBoxCellMappings->value(sender())->setText(text);
+
+ if (enableSignal)
+ {
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ if (CBBind[i] == sender())
+ {
+ emit bindUpdate(i);
+ break;
+ }
+ }
+ }
+}
+
+// When a row in a key bind table is clicked, this shows the popup
+void KeyBinder::bindCellClicked(QTableWidgetItem * item)
+{
+ QComboBox * box = bindCellComboBoxMappings->value(item);
+ QTableWidget * table = item->tableWidget();
+ QFrame * frame = box->findChild<QFrame*>();
+
+ box->showPopup();
+ frame->move(
+ frame->x() + table->horizontalHeader()->sectionSize(0),
+ frame->y() + (table->verticalHeader()->defaultSectionSize() * item->row())
+ );
+}
+
+// When a new row in a bind table is *selected*, this clears selection in any other table
+void KeyBinder::bindSelectionChanged()
+{
+ QTableWidget * theSender = (QTableWidget*)sender();
+ if (theSender != selectedBindTable)
+ {
+ if (selectedBindTable != NULL)
+ selectedBindTable->clearSelection();
+ selectedBindTable = theSender;
+ }
+}
+
+// Set a combobox's index
+void KeyBinder::setBindIndex(int keyIndex, int bindIndex)
+{
+ enableSignal = false;
+ CBBind[keyIndex]->setCurrentIndex(bindIndex);
+ enableSignal = true;
+}
+
+// Return a combobox's selected index
+int KeyBinder::bindIndex(int keyIndex)
+{
+ return CBBind[keyIndex]->currentIndex();
+}
+
+// Clears selection and goes to first category
+void KeyBinder::resetInterface()
+{
+ enableSignal = false;
+
+ catList->setCurrentItem(catList->item(1));
+ changeBindingsPage(1);
+ if (selectedBindTable != NULL)
+ {
+ selectedBindTable->clearSelection();
+ selectedBindTable = NULL;
+ }
+
+ // Default bind text
+ DataManager::instance().bindsModel()->item(0)->setData(defaultText, Qt::DisplayRole);
+ for (int i = 0; i < BINDS_NUMBER; i++)
+ {
+ CBBind[i]->setModel(DataManager::instance().bindsModel());
+ CBBind[i]->setCurrentIndex(0);
+ bindComboBoxCellMappings->value(CBBind[i])->setText(defaultText);
+ }
+
+ enableSignal = true;
+}
diff --git a/QTfrontend/ui/widget/keybinder.h b/QTfrontend/ui/widget/keybinder.h
new file mode 100644
index 0000000..9fc8493
--- /dev/null
+++ b/QTfrontend/ui/widget/keybinder.h
@@ -0,0 +1,68 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef _KEY_BINDER_H
+#define _KEY_BINDER_H
+
+#include <QWidget>
+#include <QHash>
+
+#include "binds.h"
+
+class QListWidget;
+class QTableWidgetItem;
+class QTableWidget;
+class QBoxLayout;
+class QComboBox;
+
+// USAGE NOTE: Every time the widget comes into view, you must call resetInterface()
+
+class KeyBinder : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ KeyBinder(QWidget * parent = NULL, const QString & helpText = QString(), const QString & defaultText = QString(), const QString & resetButtonText = QString());
+ ~KeyBinder();
+
+ void setBindIndex(int keyIndex, int bindIndex);
+ int bindIndex(int keyIndex);
+ void resetInterface();
+
+ private:
+ QHash<QObject *, QTableWidgetItem *> * bindComboBoxCellMappings;
+ QHash<QTableWidgetItem *, QComboBox *> * bindCellComboBoxMappings;
+ QTableWidget * selectedBindTable;
+ QListWidget * catList;
+ QBoxLayout *bindingsPages;
+ QComboBox * CBBind[BINDS_NUMBER];
+ QString defaultText;
+ bool enableSignal;
+
+ signals:
+ void bindUpdate(int bindID);
+ void resetAllBinds();
+
+ private slots:
+ void changeBindingsPage(int page);
+ void bindChanged(const QString &);
+ void bindCellClicked(QTableWidgetItem * item);
+ void bindSelectionChanged();
+};
+
+#endif // _KEY_BINDER_H
diff --git a/QTfrontend/ui/widget/lineeditcursor.cpp b/QTfrontend/ui/widget/lineeditcursor.cpp
new file mode 100644
index 0000000..63f7715
--- /dev/null
+++ b/QTfrontend/ui/widget/lineeditcursor.cpp
@@ -0,0 +1,35 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QKeyEvent>
+
+#include "lineeditcursor.h"
+
+void LineEditCursor::keyPressEvent(QKeyEvent * event)
+{
+ if (event->key() == Qt::Key_Up)
+ emit moveUp();
+ else if (event->key() == Qt::Key_Down)
+ emit moveDown();
+ else if (event->key() == Qt::Key_Left)
+ emit moveLeft();
+ else if (event->key() == Qt::Key_Right)
+ emit moveRight();
+ else
+ QLineEdit::keyPressEvent(event);
+}
diff --git a/QTfrontend/ui/widget/lineeditcursor.h b/QTfrontend/ui/widget/lineeditcursor.h
new file mode 100644
index 0000000..77cf73f
--- /dev/null
+++ b/QTfrontend/ui/widget/lineeditcursor.h
@@ -0,0 +1,41 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef LINEEDITCURSOR_H
+#define LINEEDITCURSOR_H
+
+#include <QLineEdit>
+
+class LineEditCursor : public QLineEdit
+{
+ Q_OBJECT
+
+ public:
+ LineEditCursor(QWidget* parent = 0) : QLineEdit(parent) {}
+
+ signals:
+ void moveUp();
+ void moveDown();
+ void moveLeft();
+ void moveRight();
+
+ private:
+ void keyPressEvent(QKeyEvent * event);
+};
+
+#endif // LINEEDITCURSOR_H
diff --git a/QTfrontend/ui/widget/mapContainer.cpp b/QTfrontend/ui/widget/mapContainer.cpp
index 96fde84..d5fa6b6 100644
--- a/QTfrontend/ui/widget/mapContainer.cpp
+++ b/QTfrontend/ui/widget/mapContainer.cpp
@@ -30,13 +30,24 @@
#include <QIcon>
#include <QLineEdit>
#include <QStringListModel>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QDebug>
+#include <QFile>
+#include <QFileDialog>
+#include <QInputDialog>
+#include <QMessageBox>
#include "hwconsts.h"
#include "mapContainer.h"
+#include "themeprompt.h"
+#include "seedprompt.h"
#include "igbox.h"
#include "HWApplication.h"
#include "ThemeModel.h"
+
+
HWMapContainer::HWMapContainer(QWidget * parent) :
QWidget(parent),
mainLayout(this),
@@ -47,145 +58,210 @@ HWMapContainer::HWMapContainer(QWidget * parent) :
hhSmall.load(":/res/hh_small.png");
hhLimit = 18;
templateFilter = 0;
+ m_master = true;
linearGrad = QLinearGradient(QPoint(128, 0), QPoint(128, 128));
linearGrad.setColorAt(1, QColor(0, 0, 192));
linearGrad.setColorAt(0, QColor(66, 115, 225));
mainLayout.setContentsMargins(HWApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
- 1,
+ 10,
HWApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin),
HWApplication::style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
- QWidget* mapWidget = new QWidget(this);
- mainLayout.addWidget(mapWidget, 0, 0, Qt::AlignHCenter);
-
- QGridLayout* mapLayout = new QGridLayout(mapWidget);
- mapLayout->setMargin(0);
-
- imageButt = new QPushButton(mapWidget);
- imageButt->setObjectName("imageButt");
- imageButt->setFixedSize(256 + 6, 128 + 6);
- imageButt->setFlat(true);
- imageButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);//QSizePolicy::Minimum, QSizePolicy::Minimum);
- mapLayout->addWidget(imageButt, 0, 0, 1, 2);
- connect(imageButt, SIGNAL(clicked()), this, SLOT(setRandomMap()));
-
- chooseMap = new QComboBox(mapWidget);
- chooseMap->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- m_mapModel = DataManager::instance().mapModel();
- chooseMap->setEditable(false);
- chooseMap->setModel(m_mapModel);
-
- mapLayout->addWidget(chooseMap, 1, 1);
-
- QLabel * lblMap = new QLabel(tr("Map"), mapWidget);
- mapLayout->addWidget(lblMap, 1, 0);
-
- lblFilter = new QLabel(tr("Filter"), mapWidget);
- mapLayout->addWidget(lblFilter, 2, 0);
-
- cbTemplateFilter = new QComboBox(mapWidget);
- cbTemplateFilter->addItem(tr("All"), 0);
- cbTemplateFilter->addItem(tr("Small"), 1);
- cbTemplateFilter->addItem(tr("Medium"), 2);
- cbTemplateFilter->addItem(tr("Large"), 3);
- cbTemplateFilter->addItem(tr("Cavern"), 4);
- cbTemplateFilter->addItem(tr("Wacky"), 5);
- mapLayout->addWidget(cbTemplateFilter, 2, 1);
-
- connect(cbTemplateFilter, SIGNAL(activated(int)), this, SLOT(setTemplateFilter(int)));
-
- maze_size_label = new QLabel(tr("Type"), mapWidget);
- mapLayout->addWidget(maze_size_label, 2, 0);
- maze_size_label->hide();
- cbMazeSize = new QComboBox(mapWidget);
- cbMazeSize->addItem(tr("Small tunnels"), 0);
- cbMazeSize->addItem(tr("Medium tunnels"), 1);
- cbMazeSize->addItem(tr("Large tunnels"), 2);
- cbMazeSize->addItem(tr("Small floating islands"), 3);
- cbMazeSize->addItem(tr("Medium floating islands"), 4);
- cbMazeSize->addItem(tr("Large floating islands"), 5);
- cbMazeSize->setCurrentIndex(1);
-
- mapLayout->addWidget(cbMazeSize, 2, 1);
- cbMazeSize->hide();
- connect(cbMazeSize, SIGNAL(activated(int)), this, SLOT(setMazeSize(int)));
-
- gbThemes = new IconedGroupBox(mapWidget);
- gbThemes->setTitleTextPadding(80);
- gbThemes->setContentTopPadding(15);
- gbThemes->setTitle(tr("Themes"));
-
- //gbThemes->setStyleSheet("padding: 0px"); // doesn't work - stylesheet is set with icon
- mapLayout->addWidget(gbThemes, 0, 2, 3, 1);
- // disallow row to be collapsed (so it can't get ignored when Qt applies rowSpan of gbThemes)
- mapLayout->setRowMinimumHeight(2, 13);
- QVBoxLayout * gbTLayout = new QVBoxLayout(gbThemes);
- gbTLayout->setContentsMargins(0, 0, 0 ,0);
- gbTLayout->setSpacing(0);
- lvThemes = new QListView(mapWidget);
- lvThemes->setMinimumHeight(30);
- lvThemes->setFixedWidth(140);
+ m_staticMapModel = DataManager::instance().staticMapModel();
+ m_missionMapModel = DataManager::instance().missionMapModel();
m_themeModel = DataManager::instance().themeModel();
- lvThemes->setModel(m_themeModel);
- lvThemes->setIconSize(QSize(16, 16));
- lvThemes->setEditTriggers(QListView::NoEditTriggers);
-
- connect(lvThemes->selectionModel(), SIGNAL(currentRowChanged( const QModelIndex &, const QModelIndex &)), this, SLOT(themeSelected( const QModelIndex &, const QModelIndex &)));
-
- // override default style to tighten up theme scroller
- lvThemes->setStyleSheet(QString(
- "QListView{"
- "border: solid;"
- "border-width: 0px;"
- "border-radius: 0px;"
- "border-color: transparent;"
- "background-color: #0d0544;"
- "color: #ffcc00;"
- "font: bold 13px;"
- "}"
- )
- );
-
- gbTLayout->addWidget(lvThemes);
- lvThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
-
- mapLayout->setSizeConstraint(QLayout::SetFixedSize);
-
- QWidget* seedWidget = new QWidget(this);
- mainLayout.addWidget(seedWidget, 1, 0);
-
- QGridLayout* seedLayout = new QGridLayout(seedWidget);
- seedLayout->setMargin(0);
-
- seedLabel = new QLabel(tr("Seed"), seedWidget);
- seedLayout->addWidget(seedLabel, 3, 0);
- seedEdit = new QLineEdit(seedWidget);
- seedEdit->setMaxLength(54);
- connect(seedEdit, SIGNAL(returnPressed()), this, SLOT(seedEdited()));
- seedLayout->addWidget(seedEdit, 3, 1);
- seedLayout->setColumnStretch(1, 5);
- seedSet = new QPushButton(seedWidget);
- seedSet->setText(QPushButton::tr("more"));
- connect(seedSet, SIGNAL(clicked()), this, SLOT(seedEdited()));
- seedLayout->setColumnStretch(2, 1);
- seedLayout->addWidget(seedSet, 3, 2);
-
- seedLabel->setVisible(false);
- seedEdit->setVisible(false);
- setRandomSeed();
- setRandomTheme();
+ /* Layouts */
+
+ QWidget * topWidget = new QWidget();
+ QHBoxLayout * topLayout = new QHBoxLayout(topWidget);
+ topWidget->setContentsMargins(0, 0, 0, 0);
+ topLayout->setContentsMargins(0, 0, 0, 0);
+
+ QHBoxLayout * twoColumnLayout = new QHBoxLayout();
+ QVBoxLayout * leftLayout = new QVBoxLayout();
+ QVBoxLayout * rightLayout = new QVBoxLayout();
+ twoColumnLayout->addLayout(leftLayout, 0);
+ twoColumnLayout->addStretch(1);
+ twoColumnLayout->addLayout(rightLayout, 0);
+ QVBoxLayout * drawnControls = new QVBoxLayout();
+
+ /* Map type combobox */
+
+ topLayout->setSpacing(10);
+ topLayout->addWidget(new QLabel(tr("Map type:")), 0);
+ cType = new QComboBox(this);
+ topLayout->addWidget(cType, 1);
+ cType->insertItem(0, tr("Image map"), MapModel::StaticMap);
+ cType->insertItem(1, tr("Mission map"), MapModel::MissionMap);
+ cType->insertItem(2, tr("Hand-drawn"), MapModel::HandDrawnMap);
+ cType->insertItem(3, tr("Randomly generated"), MapModel::GeneratedMap);
+ cType->insertItem(4, tr("Random maze"), MapModel::GeneratedMaze);
+ connect(cType, SIGNAL(currentIndexChanged(int)), this, SLOT(mapTypeChanged(int)));
+ m_childWidgets << cType;
+
+ /* Randomize button */
+
+ topLayout->addStretch(1);
+ const QIcon& lp = QIcon(":/res/dice.png");
+ QSize sz = lp.actualSize(QSize(65535, 65535));
+ btnRandomize = new QPushButton();
+ btnRandomize->setText(tr("Random"));
+ btnRandomize->setIcon(lp);
+ btnRandomize->setFixedHeight(30);
+ btnRandomize->setIconSize(sz);
+ btnRandomize->setFlat(true);
+ btnRandomize->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ connect(btnRandomize, SIGNAL(clicked()), this, SLOT(setRandomMap()));
+ m_childWidgets << btnRandomize;
+ btnRandomize->setStyleSheet("padding: 5px;");
+ btnRandomize->setFixedHeight(cType->height());
+ topLayout->addWidget(btnRandomize, 1);
+
+ /* Seed button */
+
+ btnSeed = new QPushButton(parentWidget()->parentWidget());
+ btnSeed->setText(tr("Seed"));
+ btnSeed->setStyleSheet("padding: 5px;");
+ btnSeed->setFixedHeight(cType->height());
+ connect(btnSeed, SIGNAL(clicked()), this, SLOT(showSeedPrompt()));
+ topLayout->addWidget(btnSeed, 0);
+
+ /* Map preview label */
+
+ QLabel * lblMapPreviewText = new QLabel(this);
+ lblMapPreviewText->setText(tr("Map preview:"));
+ leftLayout->addWidget(lblMapPreviewText, 0);
+
+ /* Map Preview */
+
+ mapPreview = new QPushButton(this);
+ mapPreview->setObjectName("mapPreview");
+ mapPreview->setFlat(true);
+ mapPreview->setFixedSize(256, 128);
+ mapPreview->setContentsMargins(0, 0, 0, 0);
+ leftLayout->addWidget(mapPreview, 0);
+ connect(mapPreview, SIGNAL(clicked()), this, SLOT(previewClicked()));
+
+ /* Bottom-Left layout */
+
+ QVBoxLayout * bottomLeftLayout = new QVBoxLayout();
+ leftLayout->addLayout(bottomLeftLayout, 1);
+
+ /* Map list label */
+
+ lblMapList = new QLabel();
+ rightLayout->addWidget(lblMapList, 0);
+
+ /* Static maps list */
+
+ staticMapList = new QListView;
+ staticMapList->setModel(m_staticMapModel);
+ rightLayout->addWidget(staticMapList, 1);
+ staticMapList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ m_childWidgets << staticMapList;
+ QItemSelectionModel * staticSelectionModel = staticMapList->selectionModel();
+ connect(staticSelectionModel,
+ SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)),
+ this,
+ SLOT(staticMapChanged(const QModelIndex &, const QModelIndex &)));
+
+ /* Mission maps list */
+
+ missionMapList = new QListView;
+ missionMapList->setModel(m_missionMapModel);
+ missionMapList->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ rightLayout->addWidget(missionMapList, 1);
+ m_childWidgets << missionMapList;
+ QItemSelectionModel * missionSelectionModel = missionMapList->selectionModel();
+ connect(missionSelectionModel,
+ SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)),
+ this,
+ SLOT(missionMapChanged(const QModelIndex &, const QModelIndex &)));
+
+ /* Map load and edit buttons */
+
+ drawnControls->addStretch(1);
+
+ btnLoadMap = new QPushButton(tr("Load map drawing"));
+ btnLoadMap->setStyleSheet("padding: 20px;");
+ drawnControls->addWidget(btnLoadMap, 0);
+ m_childWidgets << btnLoadMap;
+ connect(btnLoadMap, SIGNAL(clicked()), this, SLOT(loadDrawing()));
+
+ btnEditMap = new QPushButton(tr("Edit map drawing"));
+ btnEditMap->setStyleSheet("padding: 20px;");
+ drawnControls->addWidget(btnEditMap, 0);
+ m_childWidgets << btnEditMap;
+ connect(btnEditMap, SIGNAL(clicked()), this, SIGNAL(drawMapRequested()));
+
+ drawnControls->addStretch(1);
+
+ rightLayout->addLayout(drawnControls);
+
+ /* Generator style list */
+
+ generationStyles = new QListWidget();
+ new QListWidgetItem(tr("All"), generationStyles);
+ new QListWidgetItem(tr("Small"), generationStyles);
+ new QListWidgetItem(tr("Medium"), generationStyles);
+ new QListWidgetItem(tr("Large"), generationStyles);
+ new QListWidgetItem(tr("Cavern"), generationStyles);
+ new QListWidgetItem(tr("Wacky"), generationStyles);
+ connect(generationStyles, SIGNAL(currentRowChanged(int)), this, SLOT(setTemplateFilter(int)));
+ m_childWidgets << generationStyles;
+ rightLayout->addWidget(generationStyles, 1);
+
+ /* Maze style list */
+
+ mazeStyles = new QListWidget();
+ new QListWidgetItem(tr("Small tunnels"), mazeStyles);
+ new QListWidgetItem(tr("Medium tunnels"), mazeStyles);
+ new QListWidgetItem(tr("Large tunnels"), mazeStyles);
+ new QListWidgetItem(tr("Small islands"), mazeStyles);
+ new QListWidgetItem(tr("Medium islands"), mazeStyles);
+ new QListWidgetItem(tr("Large islands"), mazeStyles);
+ connect(mazeStyles, SIGNAL(currentRowChanged(int)), this, SLOT(setMazeSize(int)));
+ m_childWidgets << mazeStyles;
+ rightLayout->addWidget(mazeStyles, 1);
+
+ /* Mission description */
+
+ lblDesc = new QLabel();
+ lblDesc->setWordWrap(true);
+ lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ lblDesc->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ lblDesc->setStyleSheet("font: 10px;");
+ bottomLeftLayout->addWidget(lblDesc, 100);
+
+ /* Add stretch above theme button */
+
+ bottomLeftLayout->addStretch(1);
+
+ /* Theme chooser */
+
+ btnTheme = new QPushButton();
+ btnTheme->setFlat(true);
+ connect(btnTheme, SIGNAL(clicked()), this, SLOT(showThemePrompt()));
+ m_childWidgets << btnTheme;
+ bottomLeftLayout->addWidget(btnTheme, 0);
+
+ /* Add everything to main layout */
- chooseMap->setCurrentIndex(0);
- mapChanged(0);
- // use signal "activated" rather than currentIndexChanged
- // because index is somtimes changed a few times in a row programmatically
- connect(chooseMap, SIGNAL(activated(int)), this, SLOT(mapChanged(int)));
+ mainLayout.addWidget(topWidget, 0);
+ mainLayout.addLayout(twoColumnLayout, 1);
+
+ /* Set defaults */
- // update model views after model changes (to e.g. re-adjust separators)
- connect(&DataManager::instance(), SIGNAL(updated()), this, SLOT(updateModelViews()));
+ setRandomSeed();
+ setMazeSize(0);
+ setTemplateFilter(0);
+ staticMapChanged(m_staticMapModel->index(0, 0));
+ missionMapChanged(m_missionMapModel->index(0, 0));
+ changeMapType(MapModel::GeneratedMap);
+ setRandomTheme();
}
void HWMapContainer::setImage(const QImage newImage)
@@ -199,11 +275,12 @@ void HWMapContainer::setImage(const QImage newImage)
px.setMask(bm);
p.fillRect(pxres.rect(), linearGrad);
- p.drawPixmap(QPoint(0, 0), px);
+ p.drawPixmap(0, 0, px);
addInfoToPreview(pxres);
- //chooseMap->setCurrentIndex(mapgen);
pMap = 0;
+
+ cType->setEnabled(isMaster());
}
void HWMapContainer::setHHLimit(int newHHLimit)
@@ -211,70 +288,6 @@ void HWMapContainer::setHHLimit(int newHHLimit)
hhLimit = newHHLimit;
}
-void HWMapContainer::mapChanged(int index)
-{
- if (chooseMap->currentIndex() != index)
- chooseMap->setCurrentIndex(index);
-
- if (index < 0)
- {
- m_mapInfo.type = MapModel::Invalid;
- updatePreview();
- return;
- }
-
- Q_ASSERT(chooseMap->itemData(index, Qt::UserRole + 1).canConvert<MapModel::MapInfo>());
- m_mapInfo = chooseMap->itemData(index, Qt::UserRole + 1).value<MapModel::MapInfo>();
- m_curMap = m_mapInfo.name;
-
- switch(m_mapInfo.type)
- {
- case MapModel::GeneratedMap:
- mapgen = MAPGEN_REGULAR;
- gbThemes->show();
- lblFilter->show();
- cbTemplateFilter->show();
- maze_size_label->hide();
- cbMazeSize->hide();
- break;
- case MapModel::GeneratedMaze:
- mapgen = MAPGEN_MAZE;
- gbThemes->show();
- lblFilter->hide();
- cbTemplateFilter->hide();
- maze_size_label->show();
- cbMazeSize->show();
- break;
- case MapModel::HandDrawnMap:
- mapgen = MAPGEN_DRAWN;
- gbThemes->show();
- lblFilter->hide();
- cbTemplateFilter->hide();
- maze_size_label->hide();
- cbMazeSize->hide();
- break;
- default:
- mapgen = MAPGEN_MAP;
- gbThemes->hide();
- lblFilter->hide();
- cbTemplateFilter->hide();
- maze_size_label->hide();
- cbMazeSize->hide();
- m_theme = m_mapInfo.theme;
- }
-
- // the map has no pre-defined theme, so let's use the selected one
- if (m_mapInfo.theme.isEmpty())
- {
- m_theme = lvThemes->currentIndex().data().toString();
- emit themeChanged(m_theme);
- }
-
- updatePreview();
- emit mapChanged(m_curMap);
- emit mapgenChanged(mapgen);
-}
-
// Should this add text to identify map size?
void HWMapContainer::addInfoToPreview(QPixmap image)
{
@@ -292,13 +305,19 @@ void HWMapContainer::addInfoToPreview(QPixmap image)
p.drawText(image.rect().width() - hhSmall.rect().width() - 14 - (hhLimit > 9 ? 10 : 0), 18, text);
p.drawPixmap(image.rect().width() - hhSmall.rect().width() - 5, 5, hhSmall.rect().width(), hhSmall.rect().height(), hhSmall);
- imageButt->setIcon(finalImage);
- imageButt->setIconSize(image.size());
+ // Shrink, crop, and center preview image
+ QPixmap centered(QSize(m_previewSize.width() - 6, m_previewSize.height() - 6));
+ QPainter pc(¢ered);
+ pc.fillRect(centered.rect(), linearGrad);
+ pc.drawPixmap(-3, -3, finalImage);
+
+ mapPreview->setIcon(QIcon(centered));
+ mapPreview->setIconSize(centered.size());
}
void HWMapContainer::askForGeneratedPreview()
{
- pMap = new HWMap();
+ pMap = new HWMap(this);
connect(pMap, SIGNAL(ImageReceived(const QImage)), this, SLOT(setImage(const QImage)));
connect(pMap, SIGNAL(HHLimitReceived(int)), this, SLOT(setHHLimit(int)));
connect(pMap, SIGNAL(destroyed(QObject *)), this, SLOT(onPreviewMapDestroyed(QObject *)));
@@ -322,14 +341,21 @@ void HWMapContainer::askForGeneratedPreview()
p.drawPixmap(QPoint(x, y), waitIcon);
addInfoToPreview(waitImage);
+
+ cType->setEnabled(false);
}
-void HWMapContainer::themeSelected(const QModelIndex & current, const QModelIndex &)
+void HWMapContainer::previewClicked()
{
- m_theme = current.data().toString();
-
- gbThemes->setIcon(qVariantValue<QIcon>(current.data(Qt::UserRole)));
- emit themeChanged(m_theme);
+ switch (m_mapInfo.type)
+ {
+ case MapModel::HandDrawnMap:
+ emit drawMapRequested();
+ break;
+ default:
+ setRandomMap();
+ break;
+ }
}
QString HWMapContainer::getCurrentSeed() const
@@ -339,8 +365,14 @@ QString HWMapContainer::getCurrentSeed() const
QString HWMapContainer::getCurrentMap() const
{
- if(chooseMap->currentIndex() < MAPGEN_MAP) return QString();
- return(m_curMap);
+ switch (m_mapInfo.type)
+ {
+ case MapModel::StaticMap:
+ case MapModel::MissionMap:
+ return m_curMap;
+ default:
+ return QString();
+ }
}
QString HWMapContainer::getCurrentTheme() const
@@ -370,20 +402,17 @@ QString HWMapContainer::getCurrentWeapons() const
quint32 HWMapContainer::getTemplateFilter() const
{
- return cbTemplateFilter->itemData(cbTemplateFilter->currentIndex()).toInt();
+ return generationStyles->currentRow();
}
void HWMapContainer::resizeEvent ( QResizeEvent * event )
{
Q_UNUSED(event);
- //imageButt->setIconSize(imageButt->size());
}
void HWMapContainer::intSetSeed(const QString & seed)
{
m_seed = seed;
- if (seed != seedEdit->text())
- seedEdit->setText(seed);
}
void HWMapContainer::setSeed(const QString & seed)
@@ -395,11 +424,29 @@ void HWMapContainer::setSeed(const QString & seed)
void HWMapContainer::intSetMap(const QString & map)
{
- m_curMap = map;
-
- int id = m_mapModel->indexOf(map);
-
- mapChanged(id);
+ if (map == "+rnd+")
+ {
+ changeMapType(MapModel::GeneratedMap);
+ }
+ else if (map == "+maze+")
+ {
+ changeMapType(MapModel::GeneratedMaze);
+ }
+ else if (map == "+drawn+")
+ {
+ changeMapType(MapModel::HandDrawnMap);
+ }
+ else if (m_staticMapModel->mapExists(map))
+ {
+ changeMapType(MapModel::StaticMap, m_staticMapModel->index(m_staticMapModel->findMap(map), 0));
+ }
+ else if (m_missionMapModel->mapExists(map))
+ {
+ changeMapType(MapModel::MissionMap, m_missionMapModel->index(m_missionMapModel->findMap(map), 0));
+ } else
+ {
+ qDebug() << "HWMapContainer::intSetMap: Map doesn't exist: " << map;
+ }
}
void HWMapContainer::setMap(const QString & map)
@@ -410,15 +457,17 @@ void HWMapContainer::setMap(const QString & map)
void HWMapContainer::setTheme(const QString & theme)
{
- QModelIndexList mdl = m_themeModel->match(m_themeModel->index(0), Qt::DisplayRole, theme);
+ QModelIndexList mdl = m_themeModel->match(m_themeModel->index(0), ThemeModel::ActualNameRole, theme);
if(mdl.size())
- lvThemes->setCurrentIndex(mdl.at(0));
+ updateTheme(mdl.at(0));
+ else
+ intSetIconlessTheme(theme);
}
void HWMapContainer::setRandomMap()
{
- int idx;
+ if (!m_master) return;
setRandomSeed();
switch(m_mapInfo.type)
@@ -427,21 +476,17 @@ void HWMapContainer::setRandomMap()
case MapModel::GeneratedMaze:
setRandomTheme();
break;
- case MapModel::HandDrawnMap:
- emit drawMapRequested();
- break;
case MapModel::MissionMap:
+ missionMapChanged(m_missionMapModel->index(rand() % m_missionMapModel->rowCount(), 0));
+ break;
case MapModel::StaticMap:
- // get random map of same type
- idx = m_mapModel->randomMap(m_mapInfo.type);
- mapChanged(idx);
+ staticMapChanged(m_staticMapModel->index(rand() % m_staticMapModel->rowCount(), 0));
+ break;
+ default:
break;
- case MapModel::Invalid:
- mapChanged(0);
}
}
-
void HWMapContainer::setRandomSeed()
{
setSeed(QUuid::createUuid().toString());
@@ -452,12 +497,13 @@ void HWMapContainer::setRandomTheme()
{
if(!m_themeModel->rowCount()) return;
quint32 themeNum = rand() % m_themeModel->rowCount();
- lvThemes->setCurrentIndex(m_themeModel->index(themeNum));
+ updateTheme(m_themeModel->index(themeNum));
+ emit themeChanged(m_theme);
}
void HWMapContainer::intSetTemplateFilter(int filter)
{
- cbTemplateFilter->setCurrentIndex(filter);
+ generationStyles->setCurrentRow(filter);
emit newTemplateFilter(filter);
}
@@ -475,12 +521,12 @@ MapGenerator HWMapContainer::get_mapgen(void) const
int HWMapContainer::getMazeSize(void) const
{
- return cbMazeSize->currentIndex();
+ return mazeStyles->currentRow();
}
void HWMapContainer::intSetMazeSize(int size)
{
- cbMazeSize->setCurrentIndex(size);
+ mazeStyles->setCurrentRow(size);
emit mazeSizeChanged(size);
}
@@ -521,9 +567,6 @@ void HWMapContainer::intSetMapgen(MapGenerator m)
break;
}
- if(m != MAPGEN_MAP)
- chooseMap->setCurrentIndex(m);
-
emit mapgenChanged(m);
}
}
@@ -546,23 +589,10 @@ QByteArray HWMapContainer::getDrawnMapData()
return drawMapScene.encode();
}
-void HWMapContainer::seedEdited()
+void HWMapContainer::setNewSeed(const QString & newSeed)
{
- if (seedLabel->isVisible() == false )
- {
- seedLabel->setVisible(true);
- seedEdit->setVisible(true);
- seedSet->setText(tr("Set"));
- return;
- }
-
- if (seedEdit->text().isEmpty())
- seedEdit->setText(m_seed);
- else
- {
- setSeed(seedEdit->text());
- emit seedChanged(seedEdit->text());
- }
+ setSeed(newSeed);
+ emit seedChanged(newSeed);
}
DrawMapScene * HWMapContainer::getDrawMapScene()
@@ -592,8 +622,8 @@ void HWMapContainer::updatePreview()
{
case MapModel::Invalid:
failIcon = QPixmap(":/res/btnDisabled.png");
- imageButt->setIcon(failIcon);
- imageButt->setIconSize(failIcon.size());
+ mapPreview->setIcon(QIcon(failIcon));
+ mapPreview->setIconSize(failIcon.size());
break;
case MapModel::GeneratedMap:
askForGeneratedPreview();
@@ -606,14 +636,11 @@ void HWMapContainer::updatePreview()
break;
default:
QPixmap mapImage;
- bool success = mapImage.load(
- DataManager::instance().findFileForRead(
- "Maps/" + m_mapInfo.name + "/preview.png")
- );
+ bool success = mapImage.load("physfs://Maps/" + m_mapInfo.name + "/preview.png");
if(!success)
{
- imageButt->setIcon(QIcon());
+ mapPreview->setIcon(QIcon());
return;
}
@@ -632,7 +659,6 @@ void HWMapContainer::setAllMapParameters(const QString &map, MapGenerator m, int
intSetMap(map);
}
-
void HWMapContainer::updateModelViews()
{
// restore theme selection
@@ -641,13 +667,13 @@ void HWMapContainer::updateModelViews()
{
QModelIndexList mdl = m_themeModel->match(m_themeModel->index(0), Qt::DisplayRole, m_theme);
if (mdl.size() > 0)
- lvThemes->setCurrentIndex(mdl.at(0));
+ updateTheme(mdl.at(0));
else
setRandomTheme();
}
// restore map selection
- if ((!m_curMap.isEmpty()) && (chooseMap->currentIndex() < 0))
+ if (!m_curMap.isEmpty())
intSetMap(m_curMap);
else
updatePreview();
@@ -659,3 +685,252 @@ void HWMapContainer::onPreviewMapDestroyed(QObject * map)
if (map == pMap)
pMap = 0;
}
+
+void HWMapContainer::mapTypeChanged(int index)
+{
+ changeMapType((MapModel::MapType)cType->itemData(index).toInt());
+}
+
+void HWMapContainer::changeMapType(MapModel::MapType type, const QModelIndex & newMap)
+{
+ staticMapList->hide();
+ missionMapList->hide();
+ lblMapList->hide();
+ generationStyles->hide();
+ mazeStyles->hide();
+ lblDesc->hide();
+ btnLoadMap->hide();
+ btnEditMap->hide();
+
+ switch (type)
+ {
+ case MapModel::GeneratedMap:
+ mapgen = MAPGEN_REGULAR;
+ setMapInfo(MapModel::MapInfoRandom);
+ lblMapList->setText(tr("Map size:"));
+ lblMapList->show();
+ generationStyles->show();
+ break;
+ case MapModel::GeneratedMaze:
+ mapgen = MAPGEN_MAZE;
+ setMapInfo(MapModel::MapInfoMaze);
+ lblMapList->setText(tr("Maze style:"));
+ lblMapList->show();
+ mazeStyles->show();
+ break;
+ case MapModel::HandDrawnMap:
+ mapgen = MAPGEN_DRAWN;
+ setMapInfo(MapModel::MapInfoDrawn);
+ btnLoadMap->show();
+ btnEditMap->show();
+ break;
+ case MapModel::MissionMap:
+ mapgen = MAPGEN_MAP;
+ missionMapChanged(newMap.isValid() ? newMap : missionMapList->currentIndex());
+ lblMapList->setText(tr("Mission:"));
+ lblMapList->show();
+ missionMapList->show();
+ lblDesc->setText(m_mapInfo.desc);
+ lblDesc->show();
+ emit mapChanged(m_curMap);
+ break;
+ case MapModel::StaticMap:
+ mapgen = MAPGEN_MAP;
+ staticMapChanged(newMap.isValid() ? newMap : staticMapList->currentIndex());
+ lblMapList->setText(tr("Map:"));
+ lblMapList->show();
+ staticMapList->show();
+ emit mapChanged(m_curMap);
+ break;
+ default:
+ break;
+ }
+
+ // Update theme button size
+ updateThemeButtonSize();
+
+ // Update cType combobox
+ for (int i = 0; i < cType->count(); i++)
+ {
+ if ((MapModel::MapType)cType->itemData(i).toInt() == type)
+ {
+ cType->setCurrentIndex(i);
+ break;
+ }
+ }
+
+ repaint();
+
+ emit mapgenChanged(mapgen);
+}
+
+void HWMapContainer::updateThemeButtonSize()
+{
+ if (m_mapInfo.type == MapModel::MissionMap)
+ {
+ btnTheme->setIconSize(QSize(30, 30));
+ btnTheme->setFixedHeight(30);
+ }
+ else
+ {
+ QSize iconSize = btnTheme->icon().actualSize(QSize(65535, 65535));
+ btnTheme->setFixedHeight(64);
+ btnTheme->setIconSize(iconSize);
+ }
+
+ repaint();
+}
+
+void HWMapContainer::showThemePrompt()
+{
+ ThemePrompt prompt(m_themeID, this);
+ int theme = prompt.exec() - 1; // Since 0 means canceled, so all indexes are +1'd
+ if (theme < 0) return;
+
+ QModelIndex current = m_themeModel->index(theme, 0);
+ updateTheme(current);
+ emit themeChanged(m_theme);
+}
+
+void HWMapContainer::updateTheme(const QModelIndex & current)
+{
+ m_theme = selectedTheme = current.data(ThemeModel::ActualNameRole).toString();
+ m_themeID = current.row();
+ QIcon icon = qVariantValue<QIcon>(current.data(Qt::DecorationRole));
+ QSize iconSize = icon.actualSize(QSize(65535, 65535));
+ btnTheme->setFixedHeight(64);
+ btnTheme->setIconSize(iconSize);
+ btnTheme->setIcon(icon);
+ btnTheme->setText(tr("Theme: %1").arg(current.data(Qt::DisplayRole).toString()));
+ updateThemeButtonSize();
+}
+
+void HWMapContainer::staticMapChanged(const QModelIndex & map, const QModelIndex & old)
+{
+ mapChanged(map, 0, old);
+}
+
+void HWMapContainer::missionMapChanged(const QModelIndex & map, const QModelIndex & old)
+{
+ mapChanged(map, 1, old);
+}
+
+// Type: 0 = static, 1 = mission
+void HWMapContainer::mapChanged(const QModelIndex & map, int type, const QModelIndex & old)
+{
+ QListView * mapList;
+
+ if (type == 0) mapList = staticMapList;
+ else if (type == 1) mapList = missionMapList;
+ else return;
+
+ // Make sure it is a valid index
+ if (!map.isValid())
+ {
+ if (old.isValid())
+ {
+ mapList->setCurrentIndex(old);
+ mapList->scrollTo(old);
+ }
+ else
+ {
+ m_mapInfo.type = MapModel::Invalid;
+ updatePreview();
+ }
+
+ return;
+ }
+
+ // If map changed, update list selection
+ if (mapList->currentIndex() != map)
+ {
+ mapList->setCurrentIndex(map);
+ mapList->scrollTo(map);
+ }
+
+ if (map.data(Qt::UserRole + 1).canConvert<MapModel::MapInfo>())
+ setMapInfo(map.data(Qt::UserRole + 1).value<MapModel::MapInfo>());
+ else
+ Q_ASSERT(false); // Houston, we have a problem.
+
+}
+
+void HWMapContainer::setMapInfo(MapModel::MapInfo mapInfo)
+{
+ m_mapInfo = mapInfo;
+ m_curMap = m_mapInfo.name;
+
+ // the map has no pre-defined theme, so let's use the selected one
+ if (m_mapInfo.theme.isEmpty())
+ {
+ if (!selectedTheme.isEmpty())
+ {
+ setTheme(selectedTheme);
+ emit themeChanged(selectedTheme);
+ }
+ }
+ else
+ {
+ setTheme(m_mapInfo.theme);
+ emit themeChanged(m_mapInfo.theme);
+ }
+
+ lblDesc->setText(mapInfo.desc);
+
+ updatePreview();
+ emit mapChanged(m_curMap);
+}
+
+void HWMapContainer::loadDrawing()
+{
+ QString fileName = QFileDialog::getOpenFileName(NULL, tr("Load drawn map"), ".", tr("Drawn Maps") + " (*.hwmap);;" + tr("All files") + " (*)");
+
+ if(fileName.isEmpty()) return;
+
+ QFile f(fileName);
+
+ if(!f.open(QIODevice::ReadOnly))
+ {
+ QMessageBox errorMsg(parentWidget());
+ errorMsg.setIcon(QMessageBox::Warning);
+ errorMsg.setWindowTitle(QMessageBox::tr("File error"));
+ errorMsg.setText(QMessageBox::tr("Cannot open '%1' for reading").arg(fileName));
+ errorMsg.setWindowModality(Qt::WindowModal);
+ errorMsg.exec();
+ }
+ else
+ {
+ drawMapScene.decode(qUncompress(QByteArray::fromBase64(f.readAll())));
+ mapDrawingFinished();
+ }
+}
+
+void HWMapContainer::showSeedPrompt()
+{
+ SeedPrompt prompt(parentWidget()->parentWidget(), getCurrentSeed(), isMaster());
+ connect(&prompt, SIGNAL(seedSelected(const QString &)), this, SLOT(setNewSeed(const QString &)));
+ prompt.exec();
+}
+
+bool HWMapContainer::isMaster()
+{
+ return m_master;
+}
+
+void HWMapContainer::setMaster(bool master)
+{
+ if (master == m_master) return;
+ m_master = master;
+
+ foreach (QWidget *widget, m_childWidgets)
+ widget->setEnabled(master);
+}
+
+void HWMapContainer::intSetIconlessTheme(const QString & name)
+{
+ if (name.isEmpty()) return;
+
+ m_theme = name;
+ btnTheme->setIcon(QIcon());
+ btnTheme->setText(tr("Theme: %1").arg(name));
+}
diff --git a/QTfrontend/ui/widget/mapContainer.h b/QTfrontend/ui/widget/mapContainer.h
index 141ff04..680cc88 100644
--- a/QTfrontend/ui/widget/mapContainer.h
+++ b/QTfrontend/ui/widget/mapContainer.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <QWidget>
#include <QGridLayout>
+#include <QVBoxLayout>
#include <QComboBox>
#include <QLabel>
#include <QByteArray>
@@ -37,6 +38,7 @@ class QPushButton;
class IconedGroupBox;
class QListView;
class SeparatorPainter;
+class QListWidget;
class MapFileErrorException
{
@@ -46,6 +48,8 @@ class HWMapContainer : public QWidget
{
Q_OBJECT
+ Q_PROPERTY(bool master READ isMaster WRITE setMaster)
+
public:
HWMapContainer(QWidget * parent=0);
QString getCurrentSeed() const;
@@ -62,6 +66,7 @@ class HWMapContainer : public QWidget
DrawMapScene * getDrawMapScene();
void mapDrawingFinished();
QLineEdit* seedEdit;
+ bool isMaster();
public slots:
void askForGeneratedPreview();
@@ -75,6 +80,7 @@ class HWMapContainer : public QWidget
void setAllMapParameters(const QString & map, MapGenerator m, int mazesize, const QString & seed, int tmpl);
void updateModelViews();
void onPreviewMapDestroyed(QObject * map);
+ void setMaster(bool master);
signals:
void seedChanged(const QString & seed);
@@ -89,22 +95,29 @@ class HWMapContainer : public QWidget
private slots:
void setImage(const QImage newImage);
void setHHLimit(int hhLimit);
- void mapChanged(int index);
void setRandomSeed();
void setRandomTheme();
void setRandomMap();
- void themeSelected(const QModelIndex & current, const QModelIndex &);
void addInfoToPreview(QPixmap image);
- void seedEdited();
+ void setNewSeed(const QString & newSeed);
+ void mapTypeChanged(int);
+ void showThemePrompt();
+ void updateTheme(const QModelIndex & current);
+ void staticMapChanged(const QModelIndex & map, const QModelIndex & old = QModelIndex());
+ void missionMapChanged(const QModelIndex & map, const QModelIndex & old = QModelIndex());
+ void loadDrawing();
+ void showSeedPrompt();
+ void previewClicked();
protected:
virtual void resizeEvent ( QResizeEvent * event );
private:
- QGridLayout mainLayout;
- QPushButton* imageButt;
+ QVBoxLayout mainLayout;
+ QPushButton* mapPreview;
QComboBox* chooseMap;
- MapModel * m_mapModel;
+ MapModel * m_staticMapModel;
+ MapModel * m_missionMapModel;
IconedGroupBox* gbThemes;
QListView* lvThemes;
ThemeModel * m_themeModel;
@@ -121,15 +134,36 @@ class HWMapContainer : public QWidget
QComboBox *cbMazeSize;
MapGenerator mapgen;
DrawMapScene drawMapScene;
+ QComboBox * cType;
+ QListView * staticMapList;
+ QListView * missionMapList;
+ QListWidget * generationStyles;
+ QListWidget * mazeStyles;
+ QLabel * lblMapList;
+ QLabel * lblDesc;
+ QPushButton * btnTheme;
+ QPushButton * btnLoadMap;
+ QPushButton * btnEditMap;
+ QPushButton * btnRandomize;
+ QString selectedTheme;
+ QPushButton * btnSeed;
+ bool m_master;
+ QList<QWidget *> m_childWidgets;
void intSetSeed(const QString & seed);
void intSetMap(const QString & map);
void intSetMapgen(MapGenerator m);
void intSetTemplateFilter(int);
void intSetMazeSize(int size);
+ void intSetIconlessTheme(const QString & name);
+ void mapChanged(const QModelIndex & map, int type, const QModelIndex & old = QModelIndex());
+ void setMapInfo(MapModel::MapInfo mapInfo);
+ void changeMapType(MapModel::MapType type, const QModelIndex & newMap = QModelIndex());
void updatePreview();
+ void updateThemeButtonSize();
MapModel::MapInfo m_mapInfo;
+ int m_themeID;
QString m_theme;
QString m_curMap;
diff --git a/QTfrontend/ui/widget/qpushbuttonwithsound.cpp b/QTfrontend/ui/widget/qpushbuttonwithsound.cpp
index 4f4088f..e77b945 100644
--- a/QTfrontend/ui/widget/qpushbuttonwithsound.cpp
+++ b/QTfrontend/ui/widget/qpushbuttonwithsound.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,11 +33,9 @@ QPushButtonWithSound::QPushButtonWithSound(QWidget *parent) :
void QPushButtonWithSound::buttonClicked()
{
- if ( !isSoundEnabled || !HWForm::config->isFrontendSoundEnabled())
+ if ( !isSoundEnabled )
return;
- DataManager & dataMgr = DataManager::instance();
-
if (this->isEnabled())
- SDLInteraction::instance().playSoundFile(dataMgr.findFileForRead("Sounds/roperelease.ogg"));
+ SDLInteraction::instance().playSoundFile("/Sounds/roperelease.ogg");
}
diff --git a/QTfrontend/ui/widget/qpushbuttonwithsound.h b/QTfrontend/ui/widget/qpushbuttonwithsound.h
index c8352e8..fc01e8a 100644
--- a/QTfrontend/ui/widget/qpushbuttonwithsound.h
+++ b/QTfrontend/ui/widget/qpushbuttonwithsound.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/roomnameprompt.cpp b/QTfrontend/ui/widget/roomnameprompt.cpp
new file mode 100644
index 0000000..200013f
--- /dev/null
+++ b/QTfrontend/ui/widget/roomnameprompt.cpp
@@ -0,0 +1,82 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QLabel>
+#include <QDebug>
+
+#include "roomnameprompt.h"
+
+RoomNamePrompt::RoomNamePrompt(QWidget* parent, const QString & roomName) : QDialog(parent)
+{
+ setModal(true);
+ setWindowFlags(Qt::Sheet);
+ setWindowModality(Qt::WindowModal);
+ setMinimumSize(360, 130);
+ resize(360, 130);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+
+ // Layout
+ QVBoxLayout * dialogLayout = new QVBoxLayout(this);
+
+ // Label
+ label = new QLabel(tr("Enter a name for your room."));
+ label->setWordWrap(true);
+ dialogLayout->addWidget(label, 0);
+
+ // Input box
+ editBox = new QLineEdit();
+ editBox->setText(roomName);
+ editBox->setMaxLength(59); // It didn't like 60 :(
+ editBox->setStyleSheet("QLineEdit { padding: 3px; }");
+ editBox->selectAll();
+ dialogLayout->addWidget(editBox, 1);
+
+ dialogLayout->addStretch(1);
+
+ // Buttons
+ QHBoxLayout * buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch(1);
+ dialogLayout->addLayout(buttonLayout);
+
+ QPushButton * btnCancel = new QPushButton(tr("Cancel"));
+ QPushButton * btnOkay = new QPushButton(tr("Create room"));
+ connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(btnOkay, SIGNAL(clicked()), this, SLOT(accept()));
+#ifdef Q_WS_MAC
+ buttonLayout->addWidget(btnCancel);
+ buttonLayout->addWidget(btnOkay);
+#else
+ buttonLayout->addWidget(btnOkay);
+ buttonLayout->addWidget(btnCancel);
+#endif
+ btnOkay->setDefault(true);
+
+ setStyleSheet("QPushButton { padding: 5px; }");
+
+ connect(btnOkay, SIGNAL(clicked()), this, SLOT(setRoomName()));
+}
+
+void RoomNamePrompt::setRoomName()
+{
+ emit roomNameChosen(editBox->text());
+}
diff --git a/QTfrontend/ui/widget/roomnameprompt.h b/QTfrontend/ui/widget/roomnameprompt.h
new file mode 100644
index 0000000..757f743
--- /dev/null
+++ b/QTfrontend/ui/widget/roomnameprompt.h
@@ -0,0 +1,45 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef ROOMNAMEPROMPT_H
+#define ROOMNAMEPROMPT_H
+
+#include <QDialog>
+
+class QLineEdit;
+class QLabel;
+
+class RoomNamePrompt : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ RoomNamePrompt(QWidget* parent, const QString & roomName);
+
+ signals:
+ void roomNameChosen(const QString & roomName);
+
+ private slots:
+ void setRoomName();
+
+ private:
+ QLineEdit * editBox;
+ QLabel * label;
+};
+
+#endif // ROOMNAMEPROMPT_H
diff --git a/QTfrontend/ui/widget/seedprompt.cpp b/QTfrontend/ui/widget/seedprompt.cpp
new file mode 100644
index 0000000..a871a20
--- /dev/null
+++ b/QTfrontend/ui/widget/seedprompt.cpp
@@ -0,0 +1,90 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QLabel>
+#include <QDebug>
+
+#include "seedprompt.h"
+
+SeedPrompt::SeedPrompt(QWidget* parent, const QString & seed, bool editable) : QDialog(parent)
+{
+ setModal(true);
+ setWindowFlags(Qt::Sheet);
+ setWindowModality(Qt::WindowModal);
+ setMinimumSize(360, 160);
+ resize(360, 160);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ // Layout
+ QVBoxLayout * dialogLayout = new QVBoxLayout(this);
+
+ // Label
+ QLabel * label = new QLabel(tr("The map seed is the basis for all random values generated by the game."));
+ label->setWordWrap(true);
+ dialogLayout->addWidget(label, 0);
+
+ // Input box
+ editBox = new QLineEdit();
+ editBox->setText(seed);
+ editBox->setReadOnly(!editable);
+ editBox->setStyleSheet("QLineEdit { padding: 3px; }");
+ dialogLayout->addWidget(editBox, 1);
+
+ dialogLayout->addStretch(1);
+
+ // Buttons
+ QHBoxLayout * buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch(1);
+ dialogLayout->addLayout(buttonLayout);
+ if (editable)
+ {
+ QPushButton * btnCancel = new QPushButton(tr("Cancel"));
+ QPushButton * btnOkay = new QPushButton(tr("Set seed"));
+ connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(btnOkay, SIGNAL(clicked()), this, SLOT(accept()));
+#ifdef Q_WS_MAC
+ buttonLayout->addWidget(btnCancel);
+ buttonLayout->addWidget(btnOkay);
+#else
+ buttonLayout->addWidget(btnOkay);
+ buttonLayout->addWidget(btnCancel);
+#endif
+ btnOkay->setDefault(true);
+ }
+ else
+ {
+ QPushButton * btnClose = new QPushButton(tr("Close"));
+ connect(btnClose, SIGNAL(clicked()), this, SLOT(reject()));
+ buttonLayout->addWidget(btnClose);
+ btnClose->setDefault(true);
+ }
+
+ setStyleSheet("QPushButton { padding: 5px; }");
+
+ connect(this, SIGNAL(accepted()), this, SLOT(setSeed()));
+}
+
+void SeedPrompt::setSeed()
+{
+ emit seedSelected(editBox->text());
+}
diff --git a/QTfrontend/ui/widget/seedprompt.h b/QTfrontend/ui/widget/seedprompt.h
new file mode 100644
index 0000000..e330123
--- /dev/null
+++ b/QTfrontend/ui/widget/seedprompt.h
@@ -0,0 +1,43 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef SEEDPROMPT_H
+#define SEEDPROMPT_H
+
+#include <QDialog>
+
+class QLineEdit;
+
+class SeedPrompt : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ SeedPrompt(QWidget* parent, const QString & seed, bool editable);
+
+ signals:
+ void seedSelected(const QString & seed);
+
+ private slots:
+ void setSeed();
+
+ private:
+ QLineEdit * editBox;
+};
+
+#endif // SEEDPROMPT_H
diff --git a/QTfrontend/ui/widget/selectWeapon.cpp b/QTfrontend/ui/widget/selectWeapon.cpp
index bd645ff..d4b31d7 100644
--- a/QTfrontend/ui/widget/selectWeapon.cpp
+++ b/QTfrontend/ui/widget/selectWeapon.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/selectWeapon.h b/QTfrontend/ui/widget/selectWeapon.h
index 7718da1..f856d6f 100644
--- a/QTfrontend/ui/widget/selectWeapon.h
+++ b/QTfrontend/ui/widget/selectWeapon.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/teamselect.cpp b/QTfrontend/ui/widget/teamselect.cpp
index 102f961..61bcde7 100644
--- a/QTfrontend/ui/widget/teamselect.cpp
+++ b/QTfrontend/ui/widget/teamselect.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,11 +36,11 @@ void TeamSelWidget::addTeam(HWTeam team)
{
framePlaying->addTeam(team, true);
curPlayingTeams.push_back(team);
- connect(framePlaying->getTeamWidget(team), SIGNAL(teamStatusChanged(HWTeam)),
- this, SLOT(netTeamStatusChanged(const HWTeam&)));
connect(framePlaying->getTeamWidget(team), SIGNAL(hhNmChanged(const HWTeam&)),
this, SLOT(hhNumChanged(const HWTeam&)));
+ blockSignals(true);
dynamic_cast<TeamShowWidget*>(framePlaying->getTeamWidget(team))->hhNumChanged();
+ blockSignals(false);
connect(framePlaying->getTeamWidget(team), SIGNAL(teamColorChanged(const HWTeam&)),
this, SLOT(proxyTeamColorChanged(const HWTeam&)));
}
@@ -59,6 +59,7 @@ void TeamSelWidget::addTeam(HWTeam team)
this, SLOT(changeTeamStatus(HWTeam)));
}
}
+
emit setEnabledGameStart(curPlayingTeams.size()>1);
}
@@ -144,17 +145,6 @@ void TeamSelWidget::removeNetTeam(const HWTeam& team)
emit setEnabledGameStart(curPlayingTeams.size()>1);
}
-void TeamSelWidget::netTeamStatusChanged(const HWTeam& team)
-{
- QList<HWTeam>::iterator itPlay=std::find(curPlayingTeams.begin(), curPlayingTeams.end(), team);
-
-}
-
-//void TeamSelWidget::removeTeam(__attribute__ ((unused)) HWTeam team)
-//{
-//curDontPlayingTeams.erase(std::find(curDontPlayingTeams.begin(), curDontPlayingTeams.end(), team));
-//}
-
void TeamSelWidget::changeTeamStatus(HWTeam team)
{
QList<HWTeam>::iterator itDontPlay=std::find(m_curNotPlayingTeams.begin(), m_curNotPlayingTeams.end(), team);
@@ -168,6 +158,12 @@ void TeamSelWidget::changeTeamStatus(HWTeam team)
m_curNotPlayingTeams.push_back(*itPlay);
emit teamNotPlaying(*itPlay);
curPlayingTeams.erase(itPlay);
+
+ // Show team notice if less than two teams.
+ if (curPlayingTeams.size() < 2)
+ {
+ numTeamNotice->show();
+ }
}
else
{
@@ -179,6 +175,12 @@ void TeamSelWidget::changeTeamStatus(HWTeam team)
curPlayingTeams.push_back(*itDontPlay);
if(!m_acceptOuter) emit teamWillPlay(*itDontPlay);
m_curNotPlayingTeams.erase(itDontPlay);
+
+ // Hide team notice if at least two teams.
+ if (curPlayingTeams.size() >= 2)
+ {
+ numTeamNotice->hide();
+ }
}
FrameTeams* pRemoveTeams;
@@ -210,7 +212,9 @@ void TeamSelWidget::changeTeamStatus(HWTeam team)
{
connect(framePlaying->getTeamWidget(team), SIGNAL(hhNmChanged(const HWTeam&)),
this, SLOT(hhNumChanged(const HWTeam&)));
+ blockSignals(true);
dynamic_cast<TeamShowWidget*>(framePlaying->getTeamWidget(team))->hhNumChanged();
+ blockSignals(false);
connect(framePlaying->getTeamWidget(team), SIGNAL(teamColorChanged(const HWTeam&)),
this, SLOT(proxyTeamColorChanged(const HWTeam&)));
emit teamColorChanged(((TeamShowWidget*)framePlaying->getTeamWidget(team))->getTeam());
@@ -224,6 +228,8 @@ void TeamSelWidget::changeTeamStatus(HWTeam team)
pRemoveTeams->resize(pRemoveTeams->size().width(), szh1.height());
}
+ repaint();
+
emit setEnabledGameStart(curPlayingTeams.size()>1);
}
@@ -254,10 +260,18 @@ TeamSelWidget::TeamSelWidget(QWidget* parent) :
framePlaying = new FrameTeams();
frameDontPlaying = new FrameTeams();
+ // Add notice about number of required teams.
+ numTeamNotice = new QLabel(tr("At least two teams are required to play!"));
+ numTeamNotice->setWordWrap(true);
+ mainLayout.addWidget(numTeamNotice);
+
QPalette p;
p.setColor(QPalette::Window, QColor(0x00, 0x00, 0x00));
- addScrArea(framePlaying, p.color(QPalette::Window).light(105), 250);
+ addScrArea(framePlaying, p.color(QPalette::Window).light(105), 150);
addScrArea(frameDontPlaying, p.color(QPalette::Window).dark(105), 0);
+
+ this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ this->setMinimumWidth(200);
}
void TeamSelWidget::setAcceptOuter(bool acceptOuter)
@@ -280,7 +294,9 @@ void TeamSelWidget::resetPlayingTeams(const QList<HWTeam>& teamslist)
m_curNotPlayingTeams.clear();
foreach(HWTeam team, teamslist)
- addTeam(team);
+ addTeam(team);
+
+ repaint();
}
bool TeamSelWidget::isPlaying(const HWTeam &team) const
@@ -303,3 +319,10 @@ void TeamSelWidget::pre_changeTeamStatus(const HWTeam & team)
//team.setColor(framePlaying->getNextColor());
emit acceptRequested(team);
}
+
+void TeamSelWidget::repaint()
+{
+ QWidget::repaint();
+ framePlaying->repaint();
+ frameDontPlaying->repaint();
+}
diff --git a/QTfrontend/ui/widget/teamselect.h b/QTfrontend/ui/widget/teamselect.h
index 1636d80..a373b42 100644
--- a/QTfrontend/ui/widget/teamselect.h
+++ b/QTfrontend/ui/widget/teamselect.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#ifndef _TEAM_SELECT_INCLUDED
#define _TEAM_SELECT_INCLUDED
+#include <QLabel>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QColor>
@@ -50,7 +51,6 @@ class TeamSelWidget : public QGroupBox
public slots:
void addTeam(HWTeam team);
- void netTeamStatusChanged(const HWTeam& team);
void changeHHNum(const HWTeam&);
void changeTeamColor(const HWTeam&);
void changeTeamStatus(HWTeam team);
@@ -74,7 +74,9 @@ class TeamSelWidget : public QGroupBox
FrameTeams* framePlaying;
QVBoxLayout mainLayout;
+ QLabel *numTeamNotice;
bool m_acceptOuter;
+ void repaint();
QList<HWTeam> curPlayingTeams;
QList<HWTeam> m_curNotPlayingTeams;
diff --git a/QTfrontend/ui/widget/teamselhelper.cpp b/QTfrontend/ui/widget/teamselhelper.cpp
index 3e60eda..a9b5b28 100644
--- a/QTfrontend/ui/widget/teamselhelper.cpp
+++ b/QTfrontend/ui/widget/teamselhelper.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,7 +55,7 @@ TeamShowWidget::TeamShowWidget(const HWTeam & team, bool isPlaying, FrameTeams *
butt = new QPushButton(difficultyIcon, team.name().replace("&","&&"), this);
butt->setFlat(true);
- butt->setToolTip(team.owner());
+ butt->setWhatsThis(tr("%1's team").arg(team.owner()));
mainLayout.addWidget(butt);
butt->setStyleSheet("QPushButton{"
"icon-size: 48px;"
diff --git a/QTfrontend/ui/widget/teamselhelper.h b/QTfrontend/ui/widget/teamselhelper.h
index 5abb445..8a90e61 100644
--- a/QTfrontend/ui/widget/teamselhelper.h
+++ b/QTfrontend/ui/widget/teamselhelper.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2007 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/themeprompt.cpp b/QTfrontend/ui/widget/themeprompt.cpp
new file mode 100644
index 0000000..8a36ec0
--- /dev/null
+++ b/QTfrontend/ui/widget/themeprompt.cpp
@@ -0,0 +1,186 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <QDialog>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QScrollArea>
+#include <QPushButton>
+#include <QToolButton>
+#include <QWidgetItem>
+#include <QModelIndex>
+#include <QListView>
+#include <QLineEdit>
+#include <QLabel>
+#include <QSortFilterProxyModel>
+#include <QDebug>
+
+#include "DataManager.h"
+#include "lineeditcursor.h"
+#include "ThemeModel.h"
+#include "themeprompt.h"
+
+
+void ThemeListView::moveUp()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier));
+}
+
+void ThemeListView::moveDown()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier));
+}
+
+void ThemeListView::moveLeft()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveLeft, Qt::NoModifier));
+}
+
+void ThemeListView::moveRight()
+{
+ setCurrentIndex(moveCursor(QAbstractItemView::MoveRight, Qt::NoModifier));
+}
+
+ThemePrompt::ThemePrompt(int currentIndex, QWidget* parent) : QDialog(parent)
+{
+ setModal(true);
+ setWindowFlags(Qt::Sheet);
+ setWindowModality(Qt::WindowModal);
+ setMinimumSize(550, 430);
+ resize(550, 430);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ setStyleSheet("QPushButton { padding: 5px; margin-top: 10px; }");
+
+ // Theme model, and a model for setting a filter
+ ThemeModel * themeModel = DataManager::instance().themeModel();
+ filterModel = new QSortFilterProxyModel();
+ filterModel->setSourceModel(themeModel);
+ filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
+ // Grid
+ QGridLayout * dialogLayout = new QGridLayout(this);
+ dialogLayout->setSpacing(0);
+ dialogLayout->setColumnStretch(1, 1);
+
+ QHBoxLayout * topLayout = new QHBoxLayout();
+
+ // Help/prompt message at top
+ QLabel * lblDesc = new QLabel(tr("Search for a theme:"));
+ lblDesc->setObjectName("lblDesc");
+ lblDesc->setStyleSheet("#lblDesc { color: #130F2A; background: #F6CB1C; border: solid 4px #F6CB1C; border-top-left-radius: 10px; padding: 4px 10px;}");
+ lblDesc->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ lblDesc->setFixedHeight(24);
+ lblDesc->setMinimumWidth(0);
+
+ // Filter text box
+ QWidget * filterContainer = new QWidget();
+ filterContainer->setFixedHeight(24);
+ filterContainer->setObjectName("filterContainer");
+ filterContainer->setStyleSheet("#filterContainer { background: #F6CB1C; border-top-right-radius: 10px; padding: 3px; }");
+ filterContainer->setFixedWidth(150);
+ txtFilter = new LineEditCursor(filterContainer);
+ txtFilter->setFixedWidth(150);
+ txtFilter->setFocus();
+ txtFilter->setFixedHeight(22);
+ txtFilter->setStyleSheet("LineEditCursor { border-width: 0px; border-radius: 6px; margin-top: 3px; margin-right: 3px; padding-left: 4px; padding-bottom: 2px; background-color: rgb(23, 11, 54); } LineEditCursor:hover, LineEditCursor:focus { background-color: rgb(13, 5, 68); }");
+ connect(txtFilter, SIGNAL(textChanged(const QString &)), this, SLOT(filterChanged(const QString &)));
+ connect(txtFilter, SIGNAL(moveUp()), this, SLOT(moveUp()));
+ connect(txtFilter, SIGNAL(moveDown()), this, SLOT(moveDown()));
+ connect(txtFilter, SIGNAL(moveLeft()), this, SLOT(moveLeft()));
+ connect(txtFilter, SIGNAL(moveRight()), this, SLOT(moveRight()));
+
+ // Corner widget
+ QLabel * corner = new QLabel();
+ corner->setPixmap(QPixmap(QString::fromUtf8(":/res/inverse-corner-bl.png")));
+ corner->setFixedSize(10, 10);
+
+ // Add widgets to top layout
+ topLayout->addWidget(lblDesc);
+ topLayout->addWidget(filterContainer);
+ topLayout->addWidget(corner, 0, Qt::AlignBottom);
+ topLayout->addStretch(1);
+
+ // Cancel button (closes dialog)
+ QPushButton * btnCancel = new QPushButton(tr("Cancel"));
+ connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));
+
+ // Select button
+ QPushButton * btnSelect = new QPushButton(tr("Use selected theme"));
+ btnSelect->setDefault(true);
+ connect(btnSelect, SIGNAL(clicked()), this, SLOT(onAccepted()));
+
+ // Add themes
+ list = new ThemeListView();
+ list->setModel(filterModel);
+ list->setViewMode(QListView::IconMode);
+ list->setResizeMode(QListView::Adjust);
+ list->setMovement(QListView::Static);
+ list->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ list->setSpacing(8);
+ list->setWordWrap(true);
+ list->setSelectionMode(QAbstractItemView::SingleSelection);
+ list->setObjectName("themeList");
+ list->setCurrentIndex(filterModel->index(currentIndex, 0));
+ connect(list, SIGNAL(activated(const QModelIndex &)), this, SLOT(themeChosen(const QModelIndex &)));
+ connect(list, SIGNAL(clicked(const QModelIndex &)), this, SLOT(themeChosen(const QModelIndex &)));
+
+ // Add elements to layouts
+ dialogLayout->addLayout(topLayout, 0, 0, 1, 3);
+ dialogLayout->addWidget(list, 1, 0, 1, 3);
+ dialogLayout->addWidget(btnCancel, 2, 0, 1, 1, Qt::AlignLeft);
+ dialogLayout->addWidget(btnSelect, 2, 2, 1, 1, Qt::AlignRight);
+}
+
+void ThemePrompt::moveUp()
+{
+ list->moveUp();
+}
+
+void ThemePrompt::moveDown()
+{
+ list->moveDown();
+}
+
+void ThemePrompt::moveLeft()
+{
+ list->moveLeft();
+}
+
+void ThemePrompt::moveRight()
+{
+ list->moveRight();
+}
+
+void ThemePrompt::onAccepted()
+{
+ themeChosen(list->currentIndex());
+}
+
+// When a theme is selected
+void ThemePrompt::themeChosen(const QModelIndex & index)
+{
+ done(filterModel->mapToSource(index).row() + 1); // Since returning 0 means canceled
+}
+
+// When the text in the filter text box is changed
+void ThemePrompt::filterChanged(const QString & text)
+{
+ filterModel->setFilterFixedString(text);
+ list->setCurrentIndex(filterModel->index(0, 0));
+}
diff --git a/QTfrontend/ui/widget/themeprompt.h b/QTfrontend/ui/widget/themeprompt.h
new file mode 100644
index 0000000..643a427
--- /dev/null
+++ b/QTfrontend/ui/widget/themeprompt.h
@@ -0,0 +1,65 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef THEMEPROMPT_H
+#define THEMEPROMPT_H
+
+#include <QWidget>
+#include <QDialog>
+#include <QListView>
+
+class QLineEdit;
+class QModelIndex;
+class QSortFilterProxyModel;
+class LineEditCursor;
+
+class ThemeListView : public QListView
+{
+ friend class ThemePrompt;
+
+ public:
+ ThemeListView(QWidget* parent = 0) : QListView(parent){}
+ void moveUp();
+ void moveDown();
+ void moveLeft();
+ void moveRight();
+};
+
+class ThemePrompt : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ ThemePrompt(int currentIndex = 0, QWidget* parent = 0);
+
+ private:
+ LineEditCursor * txtFilter;
+ ThemeListView * list;
+ QSortFilterProxyModel * filterModel;
+
+ private slots:
+ void onAccepted();
+ void themeChosen(const QModelIndex & index);
+ void filterChanged(const QString & text);
+ void moveUp();
+ void moveDown();
+ void moveLeft();
+ void moveRight();
+};
+
+#endif // THEMEPROMPT_H
diff --git a/QTfrontend/ui/widget/togglebutton.cpp b/QTfrontend/ui/widget/togglebutton.cpp
index 8c2801f..6c7bb87 100644
--- a/QTfrontend/ui/widget/togglebutton.cpp
+++ b/QTfrontend/ui/widget/togglebutton.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Kristian Lehmann <email at thexception.net>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/togglebutton.h b/QTfrontend/ui/widget/togglebutton.h
index e256987..90d2380 100644
--- a/QTfrontend/ui/widget/togglebutton.h
+++ b/QTfrontend/ui/widget/togglebutton.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Kristian Lehmann <email at thexception.net>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/vertScrollArea.cpp b/QTfrontend/ui/widget/vertScrollArea.cpp
index c95ab27..018e95b 100644
--- a/QTfrontend/ui/widget/vertScrollArea.cpp
+++ b/QTfrontend/ui/widget/vertScrollArea.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/vertScrollArea.h b/QTfrontend/ui/widget/vertScrollArea.h
index 4b1699a..b29f874 100644
--- a/QTfrontend/ui/widget/vertScrollArea.h
+++ b/QTfrontend/ui/widget/vertScrollArea.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/weaponItem.cpp b/QTfrontend/ui/widget/weaponItem.cpp
index 7e37962..f62d696 100644
--- a/QTfrontend/ui/widget/weaponItem.cpp
+++ b/QTfrontend/ui/widget/weaponItem.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui/widget/weaponItem.h b/QTfrontend/ui/widget/weaponItem.h
index b2d6a70..b50a229 100644
--- a/QTfrontend/ui/widget/weaponItem.h
+++ b/QTfrontend/ui/widget/weaponItem.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2006-2008 Igor Ulyanov <iulyanov at gmail.com>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/ui_hwform.cpp b/QTfrontend/ui_hwform.cpp
index c5eeab6..05cc9b6 100644
--- a/QTfrontend/ui_hwform.cpp
+++ b/QTfrontend/ui_hwform.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,10 +27,8 @@
#include "pagetraining.h"
#include "pagenetserver.h"
#include "pageoptions.h"
-#include "pagefeedback.h"
#include "pageingame.h"
#include "pagescheme.h"
-#include "pagenettype.h"
#include "pageroomslist.h"
#include "pageinfo.h"
#include "pagenetgame.h"
@@ -56,11 +54,15 @@ void Ui_HWForm::setupUi(HWForm *HWForm)
HWForm->setObjectName(QString::fromUtf8("HWForm"));
HWForm->resize(QSize(640, 480).expandedTo(HWForm->minimumSizeHint()));
HWForm->setMinimumSize(QSize(720, 450));
- HWForm->setWindowTitle(QMainWindow::tr("Hedgewars %1").arg(*cVersionString));
+ QString title = QMainWindow::tr("Hedgewars %1").arg(*cVersionString);
+#ifdef DEBUG
+ title += QMainWindow::tr("-r%1 (%2)").arg(*cRevisionString, *cHashString);
+#endif
+ HWForm->setWindowTitle(title);
centralWidget = new QWidget(HWForm);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
- SetupPages(centralWidget, HWForm);
+ SetupPages(centralWidget);
HWForm->setCentralWidget(centralWidget);
@@ -74,7 +76,7 @@ void Ui_HWForm::SetupFonts()
font14 = new QFont("MS Shell Dlg", 14);
}
-void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm)
+void Ui_HWForm::SetupPages(QWidget *Parent)
{
Pages = new QStackedLayout(Parent);
@@ -93,7 +95,7 @@ void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm)
pageNet = new PageNet();
Pages->addWidget(pageNet);
- pageNetGame = new PageNetGame(Parent, HWForm->gameSettings);
+ pageNetGame = new PageNetGame(Parent);
Pages->addWidget(pageNetGame);
pageInfo = new PageInfo();
@@ -120,7 +122,7 @@ void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm)
pageInGame = new PageInGame();
Pages->addWidget(pageInGame);
- pageRoomsList = new PageRoomsList(Parent, HWForm->gameSettings);
+ pageRoomsList = new PageRoomsList(Parent);
Pages->addWidget(pageRoomsList);
pageConnecting = new PageConnecting();
@@ -132,9 +134,6 @@ void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm)
pageAdmin = new PageAdmin();
Pages->addWidget(pageAdmin);
- pageNetType = new PageNetType();
- Pages->addWidget(pageNetType);
-
pageCampaign = new PageCampaign();
Pages->addWidget(pageCampaign);
@@ -144,9 +143,6 @@ void Ui_HWForm::SetupPages(QWidget *Parent, HWForm *HWForm)
pageDataDownload = new PageDataDownload();
Pages->addWidget(pageDataDownload);
- pageFeedback = new PageFeedback();
- Pages->addWidget(pageFeedback);
-
pageVideos = new PageVideos();
Pages->addWidget(pageVideos);
}
diff --git a/QTfrontend/ui_hwform.h b/QTfrontend/ui_hwform.h
index 1b24e39..b950e1b 100644
--- a/QTfrontend/ui_hwform.h
+++ b/QTfrontend/ui_hwform.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@ class PageEditTeam;
class PageMultiplayer;
class PagePlayDemo;
class PageOptions;
-class PageFeedback;
class PageNet;
class PageNetServer;
class PageNetChat;
@@ -41,7 +40,6 @@ class PageRoomsList;
class PageConnecting;
class PageScheme;
class PageAdmin;
-class PageNetType;
class PageDrawMap;
class PageVideos;
class QStackedLayout;
@@ -60,7 +58,6 @@ class Ui_HWForm
PageMultiplayer *pageMultiplayer;
PagePlayDemo *pagePlayDemo;
PageOptions *pageOptions;
- PageFeedback *pageFeedback;
PageNet *pageNet;
PageNetServer * pageNetServer;
PageNetChat *pageNetChat;
@@ -76,7 +73,6 @@ class Ui_HWForm
PageConnecting *pageConnecting;
PageScheme *pageScheme;
PageAdmin *pageAdmin;
- PageNetType *pageNetType;
PageCampaign *pageCampaign;
PageDrawMap *pageDrawMap;
PageVideos *pageVideos;
@@ -86,7 +82,7 @@ class Ui_HWForm
void setupUi(HWForm *HWForm);
void SetupFonts();
- void SetupPages(QWidget *Parent, HWForm *HWForm);
+ void SetupPages(QWidget *Parent);
};
#endif // UI_HWFORM_H
diff --git a/QTfrontend/util/DataManager.cpp b/QTfrontend/util/DataManager.cpp
index 302fc28..b359dc7 100644
--- a/QTfrontend/util/DataManager.cpp
+++ b/QTfrontend/util/DataManager.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,8 @@
#include <QStringList>
#include <QStandardItemModel>
#include <QFileInfo>
+#include <QSettings>
+#include <QColor>
#include "hwconsts.h"
#include "HWApplication.h"
@@ -39,14 +41,9 @@
DataManager::DataManager()
{
- m_userData = new QDir(cfgdir->absolutePath());
- if (!m_userData->cd("Data"))
- m_userData = NULL;
-
- m_defaultData = new QDir(datadir->absolutePath());
-
m_hatModel = NULL;
- m_mapModel = NULL;
+ m_staticMapModel = NULL;
+ m_missionMapModel = NULL;
m_themeModel = NULL;
m_colorsModel = NULL;
m_bindsModel = NULL;
@@ -66,20 +63,8 @@ QStringList DataManager::entryList(
const QStringList & nameFilters
) const
{
- QStringList result;
-
- if (m_userData != NULL)
- {
- QDir tmpDir(*m_userData);
- if (tmpDir.cd(subDirectory))
- result.append(tmpDir.entryList(nameFilters, filters));
- }
-
- QDir tmpDir(*m_defaultData);
- if (tmpDir.cd(subDirectory))
- result.append(tmpDir.entryList(nameFilters, filters));
-
- result.removeDuplicates();
+ QDir tmpDir(QString("physfs://%1").arg(subDirectory));
+ QStringList result = tmpDir.entryList(nameFilters, filters);
// sort case-insensitive
QMap<QString, QString> sortedFileNames;
@@ -92,40 +77,6 @@ QStringList DataManager::entryList(
return result;
}
-
-QString DataManager::findFileForRead(
- const QString & relativeDataFilePath) const
-{
- QString path;
-
- if (m_userData != NULL)
- path = m_userData->absolutePath()+"/"+relativeDataFilePath;
-
- if ((!path.isEmpty()) && (!QFile::exists(path)))
- path = m_defaultData->absolutePath()+"/"+relativeDataFilePath;
-
- return path;
-}
-
-
-QString DataManager::findFileForWrite(
- const QString & relativeDataFilePath) const
-{
- if (m_userData != NULL)
- {
- QString path = m_userData->absolutePath()+"/"+relativeDataFilePath;
-
- // create folders if needed
- QDir tmp;
- tmp.mkpath(QFileInfo(path).absolutePath());
-
- return path;
- }
-
-
- return "";
-}
-
GameStyleModel * DataManager::gameStyleModel()
{
if (m_gameStyleModel == NULL) {
@@ -144,13 +95,22 @@ HatModel * DataManager::hatModel()
return m_hatModel;
}
-MapModel * DataManager::mapModel()
+MapModel * DataManager::staticMapModel()
{
- if (m_mapModel == NULL) {
- m_mapModel = new MapModel();
- m_mapModel->loadMaps();
+ if (m_staticMapModel == NULL) {
+ m_staticMapModel = new MapModel();
+ m_staticMapModel->loadMaps(MapModel::StaticMap);
}
- return m_mapModel;
+ return m_staticMapModel;
+}
+
+MapModel * DataManager::missionMapModel()
+{
+ if (m_missionMapModel == NULL) {
+ m_missionMapModel = new MapModel();
+ m_missionMapModel->loadMaps(MapModel::MissionMap);
+ }
+ return m_missionMapModel;
}
ThemeModel * DataManager::themeModel()
@@ -187,6 +147,11 @@ QStandardItemModel * DataManager::bindsModel()
{
m_bindsModel = new QStandardItemModel();
+ QStandardItem * firstItem = new QStandardItem();
+ firstItem->setData(tr("Use Default"), Qt::DisplayRole);
+ firstItem->setData("default", Qt::UserRole + 1);
+ m_bindsModel->appendRow(firstItem);
+
for(int j = 0; sdlkeys[j][1][0] != '\0'; j++)
{
QStandardItem * item = new QStandardItem();
@@ -199,6 +164,41 @@ QStandardItemModel * DataManager::bindsModel()
return m_bindsModel;
}
+QString DataManager::settingsFileName()
+{
+ if(m_settingsFileName.isEmpty())
+ {
+ QFile settingsFile("physfs://settings.ini");
+
+ if(!settingsFile.exists())
+ {
+ QFile oldSettingsFile("physfs://hedgewars.ini");
+
+ settingsFile.open(QFile::WriteOnly);
+ settingsFile.close();
+
+ if(oldSettingsFile.exists())
+ {
+ QSettings sOld(oldSettingsFile.fileName(), QSettings::IniFormat);
+ QSettings sNew(settingsFile.fileName(), QSettings::IniFormat);
+ sNew.setIniCodec("UTF-8");
+
+ foreach(const QString & key, sOld.allKeys())
+ {
+ if(key.startsWith("colors/color"))
+ sNew.setValue(key, sOld.value(key).value<QColor>().name());
+ else
+ sNew.setValue(key, sOld.value(key));
+ }
+ }
+ }
+
+ m_settingsFileName = settingsFile.fileName();
+ }
+
+ return m_settingsFileName;
+}
+
void DataManager::reload()
{
// removed for now (also code was a bit unclean, could lead to segfault if
@@ -213,3 +213,12 @@ void DataManager::resetColors()
m_colorsModel->item(i)->setData(QColor(colors[i]));
}
}
+
+bool DataManager::ensureFileExists(const QString &fileName)
+{
+ QFile tmpfile(fileName);
+ if (!tmpfile.exists())
+ return tmpfile.open(QFile::WriteOnly);
+ else
+ return true;
+}
diff --git a/QTfrontend/util/DataManager.h b/QTfrontend/util/DataManager.h
index b50bddd..90fa6fb 100644
--- a/QTfrontend/util/DataManager.h
+++ b/QTfrontend/util/DataManager.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -70,28 +70,6 @@ class DataManager: public QObject
) const;
/**
- * @brief Returns the path for the desires data file.
- *
- * Use this method if you want to read an existing data file.
- *
- * @param relativeDataFilePath relative path of the data file.
- * @return real path to the file.
- */
- QString findFileForRead(const QString & relativeDataFilePath) const;
-
-
- /**
- * @brief Returns the path for the data file that is to be written.
- *
- * Use this method if you want to create or write into a data file.
- *
- * @param relativeDataFilePath relative path of data file write path.
- * @return destination of path data file.
- */
- QString findFileForWrite(const QString & relativeDataFilePath) const;
-
-
- /**
* @brief Returns pointer to a model of available game styles.
*
* The model is updated automatically on data reload.
@@ -110,13 +88,22 @@ class DataManager: public QObject
HatModel * hatModel();
/**
- * @brief Returns pointer to a model of available maps.
+ * @brief Returns pointer to a model of available static maps.
*
* The model is updated automatically on data reload.
*
* @return map model pointer.
*/
- MapModel * mapModel();
+ MapModel * staticMapModel();
+
+ /**
+ * @brief Returns pointer to a model of available mission maps.
+ *
+ * The model is updated automatically on data reload.
+ *
+ * @return map model pointer.
+ */
+ MapModel * missionMapModel();
/**
* @brief Returns pointer to a model of available themes.
@@ -130,6 +117,10 @@ class DataManager: public QObject
QStandardItemModel * colorsModel();
QStandardItemModel * bindsModel();
+ QString settingsFileName();
+
+ static bool ensureFileExists(const QString & fileName);
+
public slots:
/// Reloads data from storage.
void reload();
@@ -152,15 +143,14 @@ class DataManager: public QObject
*/
DataManager();
- QDir * m_defaultData; ///< directory of the installed data
- QDir * m_userData; ///< directory of custom data in the user's directory
-
GameStyleModel * m_gameStyleModel; ///< game style model instance
HatModel * m_hatModel; ///< hat model instance
- MapModel * m_mapModel; ///< map model instance
+ MapModel * m_staticMapModel; ///< static map model instance
+ MapModel * m_missionMapModel; ///< mission map model instance
ThemeModel * m_themeModel; ///< theme model instance
QStandardItemModel * m_colorsModel;
QStandardItemModel * m_bindsModel;
+ QString m_settingsFileName;
};
#endif // HEDGEWARS_DATAMANAGER_H
diff --git a/QTfrontend/util/FileEngine.cpp b/QTfrontend/util/FileEngine.cpp
new file mode 100644
index 0000000..337ec55
--- /dev/null
+++ b/QTfrontend/util/FileEngine.cpp
@@ -0,0 +1,380 @@
+/* borrowed from https://github.com/skhaz/qt-physfs-wrapper
+ * TODO: add copyright header, determine license
+ */
+
+#include "hwpacksmounter.h"
+#include "FileEngine.h"
+
+
+const QString FileEngineHandler::scheme = "physfs:/";
+
+FileEngine::FileEngine(const QString& filename)
+ : m_handle(NULL)
+ , m_size(0)
+ , m_flags(0)
+ , m_bufferSet(false)
+ , m_readWrite(false)
+{
+ setFileName(filename);
+}
+
+FileEngine::~FileEngine()
+{
+ close();
+}
+
+bool FileEngine::open(QIODevice::OpenMode openMode)
+{
+ close();
+
+ if ((openMode & QIODevice::ReadWrite) == QIODevice::ReadWrite) {
+ m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
+ if(m_handle)
+ {
+ m_readWrite = true;
+ seek(0);
+ }
+ }
+
+ else if (openMode & QIODevice::WriteOnly) {
+ m_handle = PHYSFS_openWrite(m_fileName.toUtf8().constData());
+ m_flags = QAbstractFileEngine::WriteOwnerPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::FileType;
+ }
+
+ else if (openMode & QIODevice::ReadOnly) {
+ m_handle = PHYSFS_openRead(m_fileName.toUtf8().constData());
+ }
+
+ else if (openMode & QIODevice::Append) {
+ m_handle = PHYSFS_openAppend(m_fileName.toUtf8().constData());
+ }
+
+ else {
+ qWarning("[PHYSFS] Bad file open mode: %d", (int)openMode);
+ }
+
+ if (!m_handle) {
+ qWarning("[PHYSFS] Failed to open %s, reason: %s", m_fileName.toUtf8().constData(), PHYSFS_getLastError());
+ return false;
+ }
+
+ return true;
+}
+
+bool FileEngine::close()
+{
+ if (isOpened()) {
+ int result = PHYSFS_close(m_handle);
+ m_handle = NULL;
+ return result != 0;
+ }
+
+ return true;
+}
+
+bool FileEngine::flush()
+{
+ return PHYSFS_flush(m_handle) != 0;
+}
+
+qint64 FileEngine::size() const
+{
+ return m_size;
+}
+
+qint64 FileEngine::pos() const
+{
+ return PHYSFS_tell(m_handle);
+}
+
+bool FileEngine::setSize(qint64 size)
+{
+ if(size == 0)
+ {
+ m_size = 0;
+ return open(QIODevice::WriteOnly);
+ }
+ else
+ return false;
+}
+
+bool FileEngine::seek(qint64 pos)
+{
+ bool ok = PHYSFS_seek(m_handle, pos) != 0;
+
+ return ok;
+}
+
+bool FileEngine::isSequential() const
+{
+ return false;
+}
+
+bool FileEngine::remove()
+{
+ return PHYSFS_delete(m_fileName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::mkdir(const QString &dirName, bool createParentDirectories) const
+{
+ Q_UNUSED(createParentDirectories);
+
+ return PHYSFS_mkdir(dirName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const
+{
+ Q_UNUSED(recurseParentDirectories);
+
+ return PHYSFS_delete(dirName.toUtf8().constData()) != 0;
+}
+
+bool FileEngine::caseSensitive() const
+{
+ return true;
+}
+
+bool FileEngine::isRelativePath() const
+{
+ return false;
+}
+
+QAbstractFileEngineIterator * FileEngine::beginEntryList(QDir::Filters filters, const QStringList &filterNames)
+{
+ return new FileEngineIterator(filters, filterNames, entryList(filters, filterNames));
+}
+
+QStringList FileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
+{
+ Q_UNUSED(filters);
+
+ QString file;
+ QStringList result;
+ char **files = PHYSFS_enumerateFiles(m_fileName.toUtf8().constData());
+
+ for (char **i = files; *i != NULL; i++) {
+ file = QString::fromUtf8(*i);
+
+ if (filterNames.isEmpty() || QDir::match(filterNames, file)) {
+ result << file;
+ }
+ }
+
+ PHYSFS_freeList(files);
+
+ return result;
+}
+
+QAbstractFileEngine::FileFlags FileEngine::fileFlags(FileFlags type) const
+{
+ return type & m_flags;
+}
+
+QString FileEngine::fileName(FileName file) const
+{
+ switch(file)
+ {
+ case QAbstractFileEngine::AbsolutePathName:
+ {
+ QString s(PHYSFS_getWriteDir());
+ return s;
+ }
+ case QAbstractFileEngine::BaseName:
+ {
+ int l = m_fileName.lastIndexOf('/');
+ QString s = m_fileName.mid(l + 1);
+ return s;
+ }
+ case QAbstractFileEngine::DefaultName:
+ case QAbstractFileEngine::AbsoluteName:
+ default:
+ {
+ QString s = "physfs:/" + m_fileName;
+ return s;
+ }
+ }
+}
+
+QDateTime FileEngine::fileTime(FileTime time) const
+{
+ switch (time)
+ {
+ case QAbstractFileEngine::ModificationTime:
+ default:
+ return m_date;
+ break;
+ };
+}
+
+void FileEngine::setFileName(const QString &file)
+{
+ if(file.startsWith(FileEngineHandler::scheme))
+ m_fileName = file.mid(FileEngineHandler::scheme.size());
+ else
+ m_fileName = file;
+ PHYSFS_Stat stat;
+ if (PHYSFS_stat(m_fileName.toUtf8().constData(), &stat) != 0) {
+ m_size = stat.filesize;
+ m_date = QDateTime::fromTime_t(stat.modtime);
+// m_flags |= QAbstractFileEngine::WriteOwnerPerm;
+ m_flags |= QAbstractFileEngine::ReadOwnerPerm;
+ m_flags |= QAbstractFileEngine::ReadUserPerm;
+ m_flags |= QAbstractFileEngine::ExistsFlag;
+ m_flags |= QAbstractFileEngine::LocalDiskFlag;
+
+ switch (stat.filetype)
+ {
+ case PHYSFS_FILETYPE_REGULAR:
+ m_flags |= QAbstractFileEngine::FileType;
+ break;
+ case PHYSFS_FILETYPE_DIRECTORY:
+ m_flags |= QAbstractFileEngine::DirectoryType;
+ break;
+ case PHYSFS_FILETYPE_SYMLINK:
+ m_flags |= QAbstractFileEngine::LinkType;
+ break;
+ default: ;
+ }
+ }
+}
+
+bool FileEngine::atEnd() const
+{
+ return PHYSFS_eof(m_handle) != 0;
+}
+
+qint64 FileEngine::read(char *data, qint64 maxlen)
+{
+ if(m_readWrite)
+ {
+ if(pos() == 0)
+ open(QIODevice::ReadOnly);
+ else
+ return -1;
+ }
+
+ qint64 len = PHYSFS_readBytes(m_handle, data, maxlen);
+ return len;
+}
+
+qint64 FileEngine::readLine(char *data, qint64 maxlen)
+{
+ if(!m_bufferSet)
+ {
+ PHYSFS_setBuffer(m_handle, 4096);
+ m_bufferSet = true;
+ }
+
+ qint64 bytesRead = 0;
+ while(PHYSFS_readBytes(m_handle, data, 1)
+ && maxlen
+ && (*data == '\n'))
+ {
+ ++data;
+ --maxlen;
+ ++bytesRead;
+ }
+
+ return bytesRead;
+}
+
+qint64 FileEngine::write(const char *data, qint64 len)
+{
+ return PHYSFS_writeBytes(m_handle, data, len);
+}
+
+bool FileEngine::isOpened() const
+{
+ return m_handle != NULL;
+}
+
+QFile::FileError FileEngine::error() const
+{
+ return QFile::UnspecifiedError;
+}
+
+QString FileEngine::errorString() const
+{
+ return PHYSFS_getLastError();
+}
+
+bool FileEngine::supportsExtension(Extension extension) const
+{
+ return
+ (extension == QAbstractFileEngine::AtEndExtension)
+ || (extension == QAbstractFileEngine::FastReadLineExtension)
+ ;
+}
+
+
+FileEngineHandler::FileEngineHandler(char *argv0)
+{
+ PHYSFS_init(argv0);
+}
+
+FileEngineHandler::~FileEngineHandler()
+{
+ PHYSFS_deinit();
+}
+
+QAbstractFileEngine* FileEngineHandler::create(const QString &filename) const
+{
+ if (filename.startsWith(scheme))
+ return new FileEngine(filename);
+ else
+ return NULL;
+}
+
+void FileEngineHandler::mount(const QString &path)
+{
+ PHYSFS_mount(path.toUtf8().constData(), NULL, 0);
+}
+
+void FileEngineHandler::mount(const QString & path, const QString & mountPoint)
+{
+ PHYSFS_mount(path.toUtf8().constData(), mountPoint.toUtf8().constData(), 0);
+}
+
+void FileEngineHandler::setWriteDir(const QString &path)
+{
+ PHYSFS_setWriteDir(path.toUtf8().constData());
+}
+
+void FileEngineHandler::mountPacks()
+{
+ hedgewarsMountPackages();
+}
+
+
+FileEngineIterator::FileEngineIterator(QDir::Filters filters, const QStringList &nameFilters, const QStringList &entries)
+ : QAbstractFileEngineIterator(filters, nameFilters)
+{
+ m_entries = entries;
+
+ /* heck.. docs are unclear on this
+ * QDirIterator puts iterator before first entry
+ * but QAbstractFileEngineIterator example puts iterator on first entry
+ * though QDirIterator approach seems to be the right one
+ */
+
+ m_index = -1;
+}
+
+bool FileEngineIterator::hasNext() const
+{
+ return m_index < m_entries.size() - 1;
+}
+
+QString FileEngineIterator::next()
+{
+ if (!hasNext())
+ return QString();
+
+ ++m_index;
+ return currentFilePath();
+}
+
+QString FileEngineIterator::currentFileName() const
+{
+ return m_entries.at(m_index);
+}
diff --git a/QTfrontend/util/FileEngine.h b/QTfrontend/util/FileEngine.h
new file mode 100644
index 0000000..001a13f
--- /dev/null
+++ b/QTfrontend/util/FileEngine.h
@@ -0,0 +1,92 @@
+#ifndef _FileEngine_h
+#define _FileEngine_h
+
+#include <QAbstractFileEngine>
+#include <QAbstractFileEngineHandler>
+#include <QAbstractFileEngineIterator>
+#include <QDateTime>
+
+#include "physfs.h"
+
+
+
+class FileEngine : public QAbstractFileEngine
+{
+ public:
+ FileEngine(const QString& filename);
+
+ virtual ~FileEngine();
+
+ virtual bool open(QIODevice::OpenMode openMode);
+ virtual bool close();
+ virtual bool flush();
+ virtual qint64 size() const;
+ virtual qint64 pos() const;
+ virtual bool setSize(qint64 size);
+ virtual bool seek(qint64 pos);
+ virtual bool isSequential() const;
+ virtual bool remove();
+ virtual bool mkdir(const QString &dirName, bool createParentDirectories) const;
+ virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const;
+ virtual bool caseSensitive() const;
+ virtual bool isRelativePath() const;
+ QAbstractFileEngineIterator *beginEntryList(QDir::Filters filters, const QStringList & filterNames);
+ virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const;
+ virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const;
+ virtual QString fileName(FileName file=DefaultName) const;
+ virtual QDateTime fileTime(FileTime time) const;
+ virtual void setFileName(const QString &file);
+ bool atEnd() const;
+
+ virtual qint64 read(char *data, qint64 maxlen);
+ virtual qint64 readLine(char *data, qint64 maxlen);
+ virtual qint64 write(const char *data, qint64 len);
+
+ bool isOpened() const;
+
+ QFile::FileError error() const;
+ QString errorString() const;
+
+ virtual bool supportsExtension(Extension extension) const;
+
+ private:
+ PHYSFS_file *m_handle;
+ qint64 m_size;
+ FileFlags m_flags;
+ QString m_fileName;
+ QDateTime m_date;
+ bool m_bufferSet;
+ bool m_readWrite;
+};
+
+class FileEngineHandler : public QAbstractFileEngineHandler
+{
+ public:
+ FileEngineHandler(char * argv0);
+ ~FileEngineHandler();
+
+ QAbstractFileEngine *create(const QString &filename) const;
+
+ static void mount(const QString & path);
+ static void mount(const QString & path, const QString & mountPoint);
+ static void setWriteDir(const QString & path);
+ static void mountPacks();
+
+// private:
+ static const QString scheme;
+};
+
+class FileEngineIterator : public QAbstractFileEngineIterator
+{
+public:
+ FileEngineIterator(QDir::Filters filters, const QStringList & nameFilters, const QStringList & entries);
+
+ bool hasNext() const;
+ QString next();
+ QString currentFileName() const;
+private:
+ QStringList m_entries;
+ int m_index;
+};
+
+#endif
diff --git a/QTfrontend/util/LibavInteraction.cpp b/QTfrontend/util/LibavInteraction.cpp
index 4dbdea0..410d399 100644
--- a/QTfrontend/util/LibavInteraction.cpp
+++ b/QTfrontend/util/LibavInteraction.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ LibavInteraction::LibavInteraction() : QObject()
// get list of all codecs
AVCodec* pCodec = NULL;
- while (pCodec = av_codec_next(pCodec))
+ while ((pCodec = av_codec_next(pCodec)))
{
#if LIBAVCODEC_VERSION_MAJOR >= 54
if (!av_codec_is_encoder(pCodec))
@@ -162,7 +162,7 @@ LibavInteraction::LibavInteraction() : QObject()
// get list of all formats
AVOutputFormat* pFormat = NULL;
- while (pFormat = av_oformat_next(pFormat))
+ while ((pFormat = av_oformat_next(pFormat)))
{
if (!pFormat->extensions)
continue;
@@ -270,7 +270,7 @@ QString LibavInteraction::getFileInfo(const QString & filepath)
QByteArray utf8path = filepath.toUtf8();
if (avformat_open_input(&pContext, utf8path.data(), NULL, NULL) < 0)
return "";
-#if LIBAVFORMAT_VERSION_MAJOR < 54
+#if LIBAVFORMAT_VERSION_MAJOR < 53
if (av_find_stream_info(pContext) < 0)
#else
if (avformat_find_stream_info(pContext, NULL) < 0)
@@ -302,13 +302,13 @@ QString LibavInteraction::getFileInfo(const QString & filepath)
else
continue;
AVCodec* pDecoder = avcodec_find_decoder(pCodec->codec_id);
- desc += pDecoder? pDecoder->name : "unknown";
+ desc += pDecoder? pDecoder->name : tr("unknown");
desc += "\n";
}
AVDictionaryEntry* pComment = av_dict_get(pContext->metadata, "comment", NULL, 0);
if (pComment)
desc += QString("\n") + pComment->value;
-#if LIBAVFORMAT_VERSION_MAJOR < 54
+#if LIBAVFORMAT_VERSION_MAJOR < 53
av_close_input_file(pContext);
#else
avformat_close_input(&pContext);
diff --git a/QTfrontend/util/LibavInteraction.h b/QTfrontend/util/LibavInteraction.h
index 8010f8d..639cbcf 100644
--- a/QTfrontend/util/LibavInteraction.h
+++ b/QTfrontend/util/LibavInteraction.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/util/MessageDialog.cpp b/QTfrontend/util/MessageDialog.cpp
new file mode 100644
index 0000000..06e3b15
--- /dev/null
+++ b/QTfrontend/util/MessageDialog.cpp
@@ -0,0 +1,55 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "MessageDialog.h"
+#include "HWApplication.h"
+
+int MessageDialog::ShowFatalMessage(const QString & msg, QWidget * parent)
+{
+ return ShowMessage(QMessageBox::tr("Hedgewars - Error"),
+ msg,
+ QMessageBox::Critical,
+ parent);
+}
+
+int MessageDialog::ShowErrorMessage(const QString & msg, QWidget * parent)
+{
+ return ShowMessage(QMessageBox::tr("Hedgewars - Warning"),
+ msg,
+ QMessageBox::Warning,
+ parent);
+}
+
+int MessageDialog::ShowInfoMessage(const QString & msg, QWidget * parent)
+{
+ return ShowMessage(QMessageBox::tr("Hedgewars - Information"),
+ msg,
+ QMessageBox::Information,
+ parent);
+}
+
+int MessageDialog::ShowMessage(const QString & title, const QString & msg, QMessageBox::Icon icon, QWidget * parent)
+{
+ QMessageBox msgMsg(parent ? parent : HWApplication::activeWindow());
+ msgMsg.setWindowTitle(title != NULL ? title : "Hedgewars");
+ msgMsg.setText(msg);
+ msgMsg.setIcon(icon);
+ msgMsg.setWindowModality(Qt::WindowModal);
+
+ return msgMsg.exec();
+}
diff --git a/QTfrontend/util/MessageDialog.h b/QTfrontend/util/MessageDialog.h
new file mode 100644
index 0000000..b9c6cec
--- /dev/null
+++ b/QTfrontend/util/MessageDialog.h
@@ -0,0 +1,43 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef MESSAGEDIALOG_H
+#define MESSAGEDIALOG_H
+
+#include <QMessageBox>
+
+class QWidget;
+
+class MessageDialog
+{
+ public:
+ static int ShowFatalMessage(const QString & msg, QWidget * parent = 0);
+ static int ShowErrorMessage(const QString & msg, QWidget * parent = 0);
+ static int ShowInfoMessage(const QString & msg, QWidget * parent = 0);
+ /**
+ * @brief Displays a message.
+ * @param title message title or <code>NULL</code> if no/default title
+ * @param msg message to display
+ * @param icon (optional) icon to be displayed next to the message
+ * @param parent parent Widget
+ * @return a QMessageBox::StandardButton value indicating which button was clicked
+ */
+ static int ShowMessage(const QString & title, const QString & msg, QMessageBox::Icon icon = QMessageBox::NoIcon, QWidget * parent = 0);
+};
+
+#endif
diff --git a/QTfrontend/util/SDLInteraction.cpp b/QTfrontend/util/SDLInteraction.cpp
index f008ee6..d7b3ec1 100644
--- a/QTfrontend/util/SDLInteraction.cpp
+++ b/QTfrontend/util/SDLInteraction.cpp
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,9 +25,13 @@
#include "SDL_mixer.h"
#include "HWApplication.h"
+#include "hwform.h" /* you know, we could just put a config singleton lookup function in gameuiconfig or something... */
+#include "gameuiconfig.h"
#include "SDLInteraction.h"
+#include "physfsrwops.h"
+
extern char sdlkeys[1024][2][128];
extern char xb360buttons[][128];
extern char xb360dpad[128];
@@ -184,16 +188,18 @@ void SDLInteraction::SDLAudioInit()
return;
SDL_Init(SDL_INIT_AUDIO);
- Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024);
- m_audioInitialized = true;
+ if(!Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)) /* should we keep trying, or just turn off permanently? */
+ m_audioInitialized = true;
}
void SDLInteraction::playSoundFile(const QString & soundFile)
{
+ if (!HWForm::config || !HWForm::config->isFrontendSoundEnabled()) return;
SDLAudioInit();
+ if (!m_audioInitialized) return;
if (!m_soundMap->contains(soundFile))
- m_soundMap->insert(soundFile, Mix_LoadWAV(soundFile.toLocal8Bit().constData()));
+ m_soundMap->insert(soundFile, Mix_LoadWAV_RW(PHYSFSRWOPS_openRead(soundFile.toLocal8Bit().constData()), 1));
//FIXME: this is a hack, but works as long as we have few concurrent playing sounds
if (Mix_Playing(lastchannel) == false)
@@ -230,9 +236,10 @@ void SDLInteraction::startMusic()
return;
SDLAudioInit();
+ if (!m_audioInitialized) return;
if (m_music == NULL)
- m_music = Mix_LoadMUS(m_musicTrack.toLocal8Bit().constData());
+ m_music = Mix_LoadMUS_RW(PHYSFSRWOPS_openRead(m_musicTrack.toLocal8Bit().constData()));
Mix_VolumeMusic(MIX_MAX_VOLUME - 28);
Mix_FadeInMusic(m_music, -1, 1750);
diff --git a/QTfrontend/util/SDLInteraction.h b/QTfrontend/util/SDLInteraction.h
index 0df8624..766e38e 100644
--- a/QTfrontend/util/SDLInteraction.h
+++ b/QTfrontend/util/SDLInteraction.h
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/util/namegen.cpp b/QTfrontend/util/namegen.cpp
index d945ea0..d879ffe 100644
--- a/QTfrontend/util/namegen.cpp
+++ b/QTfrontend/util/namegen.cpp
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Martin Minarik <ttsmj at pokec.sk>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -125,23 +125,21 @@ QStringList HWNamegen::dictContents(const QString filename)
QStringList list;
// find .txt to load the names from
- QFile * file = new QFile(DataManager::instance().findFileForRead(QString(
- "Names/%1.txt").arg(filename)));
+ QFile file(QString("physfs://Names/%1.txt").arg(filename));
- if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text))
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
- QTextStream in(file);
- while (!in.atEnd())
+ QTextStream in(&file);
+ QString line;
+ do
{
- QString line = in.readLine();
+ line = in.readLine();
+
if(!line.isEmpty())
list.append(line);
- }
+ } while (!line.isNull());
}
- // this QFile isn't needed any further
- delete file;
-
if (list.size() == 0)
list.append(filename);
@@ -154,23 +152,21 @@ QStringList HWNamegen::dictsForHat(const QString hatname)
QStringList list;
// find .cfg to load the dicts from
- QFile * file = new QFile(DataManager::instance().findFileForRead(QString(
- "Names/%1.cfg").arg(hatname)));
+ QFile file(QString("physfs://Names/%1.cfg").arg(hatname));
- if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text))
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
- QTextStream in(file);
- while (!in.atEnd())
+ QTextStream in(&file);
+ QString line;
+ do
{
- QString line = in.readLine();
+ line = in.readLine();
+
if(!line.isEmpty())
list.append(line);
- }
+ } while (!line.isNull());
}
- // this QFile isn't needed any further
- delete file;
-
if (list.size() == 0)
list.append(QString("generic"));
@@ -183,8 +179,7 @@ bool HWNamegen::loadTypes()
typesAvailable = false;
// find .ini to load the names from
- QFile * file = new QFile(
- DataManager::instance().findFileForRead(QString("Names/types.ini")));
+ QFile * file = new QFile(QString("physfs://Names/types.ini"));
if (file->exists() && file->open(QIODevice::ReadOnly | QIODevice::Text))
diff --git a/QTfrontend/util/namegen.h b/QTfrontend/util/namegen.h
index 009d8ad..6a33448 100644
--- a/QTfrontend/util/namegen.h
+++ b/QTfrontend/util/namegen.h
@@ -1,7 +1,7 @@
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2009 Martin Minarik <ttsmj at pokec.sk>
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/QTfrontend/AutoUpdater.cpp b/QTfrontend/util/platform/AutoUpdater.cpp
similarity index 100%
rename from QTfrontend/AutoUpdater.cpp
rename to QTfrontend/util/platform/AutoUpdater.cpp
diff --git a/QTfrontend/util/platform/AutoUpdater.h b/QTfrontend/util/platform/AutoUpdater.h
new file mode 100644
index 0000000..cfe517a
--- /dev/null
+++ b/QTfrontend/util/platform/AutoUpdater.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008 Remko Troncon
+ */
+
+#ifndef AUTOUPDATER_H
+#define AUTOUPDATER_H
+
+class AutoUpdater
+{
+ public:
+ virtual ~AutoUpdater();
+
+ virtual void checkForUpdates() = 0;
+ virtual void checkForUpdatesNow() = 0;
+};
+
+#endif
diff --git a/QTfrontend/util/platform/CocoaInitializer.h b/QTfrontend/util/platform/CocoaInitializer.h
new file mode 100644
index 0000000..282c40c
--- /dev/null
+++ b/QTfrontend/util/platform/CocoaInitializer.h
@@ -0,0 +1,35 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
+
+#ifndef COCOAINITIALIZER_H
+#define COCOAINITIALIZER_H
+
+class CocoaInitializer
+{
+ public:
+ CocoaInitializer();
+ ~CocoaInitializer();
+
+ private:
+ class Private;
+ Private* c;
+};
+
+#endif
diff --git a/QTfrontend/util/platform/CocoaInitializer.mm b/QTfrontend/util/platform/CocoaInitializer.mm
new file mode 100644
index 0000000..adb25ba
--- /dev/null
+++ b/QTfrontend/util/platform/CocoaInitializer.mm
@@ -0,0 +1,44 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
+
+#include "CocoaInitializer.h"
+
+#include <AppKit/AppKit.h>
+#include <Cocoa/Cocoa.h>
+#include <QtDebug>
+
+class CocoaInitializer::Private
+{
+ public:
+ NSAutoreleasePool* pool;
+};
+
+CocoaInitializer::CocoaInitializer()
+{
+ c = new CocoaInitializer::Private();
+ c->pool = [[NSAutoreleasePool alloc] init];
+ NSApplicationLoad();
+}
+
+CocoaInitializer::~CocoaInitializer()
+{
+ [c->pool release];
+ delete c;
+}
diff --git a/QTfrontend/util/platform/InstallController.cpp b/QTfrontend/util/platform/InstallController.cpp
new file mode 100644
index 0000000..d35df86
--- /dev/null
+++ b/QTfrontend/util/platform/InstallController.cpp
@@ -0,0 +1,23 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "InstallController.h"
+
+InstallController::~InstallController()
+{
+}
diff --git a/QTfrontend/util/platform/InstallController.h b/QTfrontend/util/platform/InstallController.h
new file mode 100644
index 0000000..d493eda
--- /dev/null
+++ b/QTfrontend/util/platform/InstallController.h
@@ -0,0 +1,30 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef INSTALLCONTROLLER_H
+#define INSTALLCONTROLLER_H
+
+class InstallController
+{
+ public:
+ virtual ~InstallController();
+
+ virtual void showInstallController() = 0;
+};
+
+#endif
diff --git a/QTfrontend/M3InstallController.h b/QTfrontend/util/platform/M3InstallController.h
similarity index 100%
rename from QTfrontend/M3InstallController.h
rename to QTfrontend/util/platform/M3InstallController.h
diff --git a/QTfrontend/util/platform/M3InstallController.m b/QTfrontend/util/platform/M3InstallController.m
new file mode 100644
index 0000000..e67c1d3
--- /dev/null
+++ b/QTfrontend/util/platform/M3InstallController.m
@@ -0,0 +1,140 @@
+/*****************************************************************
+ M3InstallController.m
+
+ Created by Martin Pilkington on 02/06/2007.
+
+ Copyright (c) 2006-2009 M Cubed Software
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ *****************************************************************/
+
+#import "M3InstallController.h"
+#import "NSWorkspace_RBAdditions.h"
+
+#import <Foundation/Foundation.h>
+
+ at implementation M3InstallController
+
+-(id) init {
+ if ((self = [super init])) {
+ NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
+ NSString *title = [NSString stringWithFormat:NSLocalizedString(@"%@ is currently running from a disk image", @"AppName is currently running from a disk image"), appName];
+ NSString *body = [NSString stringWithFormat:NSLocalizedString(@"Would you like to install %@ in your applications folder before quitting?", @"Would you like to install App Name in your applications folder before quitting?"), appName];
+ alert = [[NSAlert alertWithMessageText:title
+ defaultButton:NSLocalizedString(@"Install", @"Install")
+ alternateButton:NSLocalizedString(@"Don't Install", @"Don't Install")
+ otherButton:nil
+ informativeTextWithFormat:body] retain];
+ //[alert setShowsSuppressionButton:YES];
+ }
+ return self;
+}
+
+-(void) displayInstaller {
+ NSString *imageFilePath = [[[NSWorkspace sharedWorkspace] propertiesForPath:[[NSBundle mainBundle] bundlePath]] objectForKey:NSWorkspace_RBimagefilepath];
+ if (imageFilePath && ![imageFilePath isEqualToString:[NSString stringWithFormat:@"/Users/.%@/%@.sparseimage", NSUserName(), NSUserName()]] && ![[NSUserDefaults standardUserDefaults] boolForKey:@"M3DontAskInstallAgain"]) {
+ NSInteger returnValue = [alert runModal];
+ if (returnValue == NSAlertDefaultReturn) {
+ [self installApp];
+ }
+ if ([NSAlert instancesRespondToSelector:@selector(suppressionButton)])
+ if ([[alert performSelector:@selector(suppressionButton)] state] == NSOnState)
+ [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"M3DontAskInstallAgain"];
+ }
+}
+
+-(void) installApp {
+ NSString *appsPath = [[NSString stringWithString:@"/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]];
+ NSString *userAppsPath = [[[NSString stringWithString:@"~/Applications"] stringByAppendingPathComponent:[[[NSBundle mainBundle] bundlePath] lastPathComponent]] stringByExpandingTildeInPath];
+ NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
+ NSString *currentPath = [[NSBundle mainBundle] bundlePath];
+ NSString *finalPath;
+ NSError *error = nil;
+ BOOL success;
+
+ // Prepare the remove invocation
+ SEL removeSelector;
+ if ([NSFileManager instancesRespondToSelector:@selector(removeItemAtPath:error:)])
+ removeSelector = @selector(removeItemAtPath:error:);
+ else
+ removeSelector = @selector(removeFileAtPath:handler:);
+
+ NSMethodSignature *removeSignature = [NSFileManager instanceMethodSignatureForSelector:removeSelector];
+ NSInvocation *removeInvocation = [NSInvocation invocationWithMethodSignature:removeSignature];
+ [removeInvocation setTarget:[NSFileManager defaultManager]];
+ [removeInvocation setSelector:removeSelector];
+
+ // Delete the app if already installed
+ if ([[NSFileManager defaultManager] fileExistsAtPath:appsPath]) {
+ [removeInvocation setArgument:&appsPath atIndex:2];
+ [removeInvocation setArgument:&error atIndex:3];
+ [removeInvocation invoke];
+ }
+
+ // Prepare the copy invocation
+ SEL copySelector;
+ if ([NSFileManager instancesRespondToSelector:@selector(copyItemAtPath:toPath:error:)])
+ copySelector = @selector(copyItemAtPath:toPath:error:);
+ else
+ copySelector = @selector(copyPath:toPath:handler:);
+
+ NSMethodSignature *copySignature = [NSFileManager instanceMethodSignatureForSelector:copySelector];
+ NSInvocation *copyInvocation = [NSInvocation invocationWithMethodSignature:copySignature];
+
+ [copyInvocation setTarget:[NSFileManager defaultManager]];
+ [copyInvocation setSelector:copySelector];
+
+ // Copy the app in /Applications
+ [copyInvocation setArgument:¤tPath atIndex:2];
+ [copyInvocation setArgument:&appsPath atIndex:3];
+ [copyInvocation setArgument:&error atIndex:4];
+ [copyInvocation invoke];
+ [copyInvocation getReturnValue:&success];
+ finalPath = @"/Applications";
+
+ // In case something went wrong, let's try again somewhere else
+ if (success == NO) {
+ // Delete the app if already installed
+ if ([[NSFileManager defaultManager] fileExistsAtPath:userAppsPath]) {
+ [removeInvocation setArgument:&userAppsPath atIndex:2];
+ [removeInvocation invoke];
+ }
+
+ // Copy the app in ~/Applications
+ [copyInvocation setArgument:&userAppsPath atIndex:3];
+ [copyInvocation invoke];
+ [copyInvocation getReturnValue:&success];
+ finalPath = [[NSString stringWithString:@"~/Applications"] stringByExpandingTildeInPath];
+ }
+
+ if (success)
+ NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"%@ installed successfully", @"successful installation title"), appName],
+ [NSString stringWithFormat:NSLocalizedString(@"%@ was installed in %@", @"successfull installation text"), appName, finalPath],
+ NSLocalizedString(@"Ok", @"ok message"), nil, nil);
+ else
+ NSRunAlertPanel([NSString stringWithFormat:NSLocalizedString(@"Could not install %@", @"installation failure title"), appName],
+ NSLocalizedString(@"An error occurred when installing", @"installation failure text"),
+ NSLocalizedString(@"Quit", @"exit message"), nil, nil);
+}
+
+ at end
diff --git a/QTfrontend/util/platform/M3Panel.h b/QTfrontend/util/platform/M3Panel.h
new file mode 100644
index 0000000..4cc5001
--- /dev/null
+++ b/QTfrontend/util/platform/M3Panel.h
@@ -0,0 +1,37 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef M3PANEL_H
+#define M3PANEL_H
+
+#include "InstallController.h"
+
+class M3Panel : public InstallController
+{
+ public:
+ M3Panel(void);
+ ~M3Panel();
+
+ void showInstallController();
+
+ private:
+ class Private;
+ Private* m;
+};
+
+#endif
diff --git a/QTfrontend/util/platform/M3Panel.mm b/QTfrontend/util/platform/M3Panel.mm
new file mode 100644
index 0000000..4a689ca
--- /dev/null
+++ b/QTfrontend/util/platform/M3Panel.mm
@@ -0,0 +1,47 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "M3Panel.h"
+#include "M3InstallController.h"
+
+#include <Cocoa/Cocoa.h>
+
+class M3Panel::Private
+{
+ public:
+ M3InstallController *install;
+};
+
+M3Panel::M3Panel(void)
+{
+ m = new M3Panel::Private();
+
+ m->install = [[M3InstallController alloc] init];
+ [m->install retain];
+}
+
+M3Panel::~M3Panel()
+{
+ [m->install release];
+ delete m;
+}
+
+void M3Panel::showInstallController()
+{
+ [m->install displayInstaller];
+}
diff --git a/QTfrontend/NSWorkspace_RBAdditions.h b/QTfrontend/util/platform/NSWorkspace_RBAdditions.h
similarity index 100%
rename from QTfrontend/NSWorkspace_RBAdditions.h
rename to QTfrontend/util/platform/NSWorkspace_RBAdditions.h
diff --git a/QTfrontend/util/platform/NSWorkspace_RBAdditions.m b/QTfrontend/util/platform/NSWorkspace_RBAdditions.m
new file mode 100644
index 0000000..204bae6
--- /dev/null
+++ b/QTfrontend/util/platform/NSWorkspace_RBAdditions.m
@@ -0,0 +1,263 @@
+//
+// NSWorkspace_RBAdditions.m
+// PathProps
+//
+// Created by Rainer Brockerhoff on 10/04/2007.
+// Copyright 2007 Rainer Brockerhoff. All rights reserved.
+//
+
+#import "NSWorkspace_RBAdditions.h"
+#include <IOKit/IOKitLib.h>
+#include <sys/mount.h>
+#include <mach/mach.h>
+
+NSString* NSWorkspace_RBfstypename = @"NSWorkspace_RBfstypename";
+NSString* NSWorkspace_RBmntonname = @"NSWorkspace_RBmntonname";
+NSString* NSWorkspace_RBmntfromname = @"NSWorkspace_RBmntfromname";
+NSString* NSWorkspace_RBdeviceinfo = @"NSWorkspace_RBdeviceinfo";
+NSString* NSWorkspace_RBimagefilepath = @"NSWorkspace_RBimagefilepath";
+NSString* NSWorkspace_RBconnectiontype = @"NSWorkspace_RBconnectiontype";
+NSString* NSWorkspace_RBpartitionscheme = @"NSWorkspace_RBpartitionscheme";
+NSString* NSWorkspace_RBserverURL = @"NSWorkspace_RBserverURL";
+
+// This static funtion concatenates two strings, but first checks several possibilities...
+// like one or the other nil, or one containing the other already.
+
+static NSString* AddPart(NSString* first,NSString* second) {
+ if (!second) {
+ return first;
+ }
+ second = [second stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+ if (first) {
+ if ([first rangeOfString:second options:NSCaseInsensitiveSearch].location==NSNotFound) {
+ if ([second rangeOfString:first options:NSCaseInsensitiveSearch].location==NSNotFound) {
+ return [NSString stringWithFormat:@"%@; %@",first,second];
+ }
+ return second;
+ }
+ return first;
+ }
+ return second;
+}
+
+// This static functions recurses "upwards" over the IO registry. Returns strings that are concatenated
+// and ultimately end up under the NSWorkspace_RBdeviceinfo key.
+// This isn't too robust in that it assumes that objects returned by the objectForKey methods are
+// either strings or dictionaries. A "standard" implementations would use either only CoreFoundation and
+// IOKit calls for this, or do more robust type checking on the returned objects.
+//
+// Also notice that this works as determined experimentally in 10.4.9, there's no official docs I could find.
+// YMMV, and it may stop working in any new version of Mac OS X.
+
+static NSString* CheckParents(io_object_t thing,NSString* part,NSMutableDictionary* dict) {
+ NSString* result = part;
+ io_iterator_t parentsIterator = 0;
+ kern_return_t kernResult = IORegistryEntryGetParentIterator(thing,kIOServicePlane,&parentsIterator);
+ if ((kernResult==KERN_SUCCESS)&&parentsIterator) {
+ io_object_t nextParent = 0;
+ while ((nextParent = IOIteratorNext(parentsIterator))) {
+ NSDictionary* props = nil;
+ NSString* image = nil;
+ NSString* partition = nil;
+ NSString* connection = nil;
+ kernResult = IORegistryEntryCreateCFProperties(nextParent,(CFMutableDictionaryRef*)&props,kCFAllocatorDefault,0);
+ if (IOObjectConformsTo(nextParent,"IOApplePartitionScheme")) {
+ partition = [props objectForKey:@"Content Mask"];
+ } else if (IOObjectConformsTo(nextParent,"IOMedia")) {
+ partition = [props objectForKey:@"Content"];
+ } else if (IOObjectConformsTo(nextParent,"IODiskImageBlockStorageDeviceOutKernel")) {
+ NSData* data = nil;
+ if ((data = [[props objectForKey:@"Protocol Characteristics"] objectForKey:@"Virtual Interface Location Path"])) {
+ image = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding] autorelease];
+ }
+ } else if (IOObjectConformsTo(nextParent,"IOHDIXHDDriveInKernel")) {
+ image = [props objectForKey:@"KDIURLPath"];
+ }
+ NSDictionary* subdict;
+ if ((subdict = [props objectForKey:@"Protocol Characteristics"])) {
+ connection = [subdict objectForKey:@"Physical Interconnect"];
+ } else {
+ connection = [props objectForKey:@"Physical Interconnect"];
+ }
+ if (connection) {
+ [dict setObject:AddPart([dict objectForKey:NSWorkspace_RBconnectiontype],connection) forKey:NSWorkspace_RBconnectiontype];
+ }
+ if (partition) {
+ [dict setObject:partition forKey:NSWorkspace_RBpartitionscheme];
+ }
+ if (image) {
+ [dict setObject:image forKey:NSWorkspace_RBimagefilepath];
+ }
+ NSString* value;
+ if ((subdict = [props objectForKey:@"Device Characteristics"])) {
+ if ((value = [subdict objectForKey:@"Product Name"])) {
+ result = AddPart(result,value);
+ }
+ if ((value = [subdict objectForKey:@"Product Revision Level"])) {
+ result = AddPart(result,value);
+ }
+ if ((value = [subdict objectForKey:@"Vendor Name"])) {
+ result = AddPart(result,value);
+ }
+ }
+ if ((value = [props objectForKey:@"USB Serial Number"])) {
+ result = AddPart(result,value);
+ }
+ if ((value = [props objectForKey:@"USB Vendor Name"])) {
+ result = AddPart(result,value);
+ }
+ NSString* cls = [(NSString*)IOObjectCopyClass(nextParent) autorelease];
+ if (![cls isEqualToString:@"IOPCIDevice"]) {
+
+// Uncomment the following line to have the device tree dumped to the console.
+// NSLog(@"=================================> %@:%@\n",cls,props);
+
+ result = CheckParents(nextParent,result,dict);
+ }
+ IOObjectRelease(nextParent);
+ }
+ }
+ if (parentsIterator) {
+ IOObjectRelease(parentsIterator);
+ }
+ return result;
+}
+
+// This formats the (partially undocumented) AFPXMountInfo info into a string.
+
+/*
+static NSString* FormatAFPURL(AFPXVolMountInfoPtr mountInfo,NSString** devdesc) {
+ UInt8* work = ((UInt8*)mountInfo)+mountInfo->serverNameOffset;
+ if (devdesc) {
+ *devdesc = [[[NSString alloc] initWithBytes:&work[1] length:work[0] encoding:NSUTF8StringEncoding] autorelease];
+ }
+ work = ((UInt8*)mountInfo)+mountInfo->volNameOffset;
+ NSString* volname = [[[NSString alloc] initWithBytes:&work[1] length:work[0] encoding:NSUTF8StringEncoding] autorelease];
+ work = ((UInt8*)mountInfo)+mountInfo->alternateAddressOffset;
+ AFPAlternateAddress* afpa = (AFPAlternateAddress*)work;
+ AFPTagData* afpta = (AFPTagData*)(&afpa->fAddressList);
+ NSString* ip = nil;
+ NSString* dns = nil;
+ int i = afpa->fAddressCount;
+ while ((i-->0)) {
+ switch (afpta->fType) {
+ case kAFPTagTypeIP:
+ if (!ip) {
+ ip = [[[NSString alloc] initWithBytes:&afpta->fData[0] length:afpta->fLength-2 encoding:NSUTF8StringEncoding] autorelease];
+ }
+ break;
+ case kAFPTagTypeIPPort:
+ ip = [NSString stringWithFormat:@"%u.%u.%u.%u:%u",afpta->fData[0],afpta->fData[1],afpta->fData[2],afpta->fData[3],OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[4])];
+ break;
+ case kAFPTagTypeDNS:
+ dns = [[[NSString alloc] initWithBytes:&afpta->fData[0] length:afpta->fLength-2 encoding:NSUTF8StringEncoding] autorelease];
+ break;
+ case 0x07:
+ ip = [NSString stringWithFormat:@"[%x:%x:%x:%x:%x:%x:%x:%x]",OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[0]),
+ OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[2]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[4]),
+ OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[6]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[8]),
+ OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[10]),OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[12]),
+ OSSwapBigToHostInt16(*(UInt16*)&afpta->fData[14])];
+ break;
+ }
+ afpta = (AFPTagData*)((char*)afpta+afpta->fLength);
+ }
+ return [NSString stringWithFormat:@"afp://%@/%@",dns?:(ip?:@""),volname];
+}
+*/
+
+ at implementation NSWorkspace (NSWorkspace_RBAdditions)
+
+// Returns a NSDictionary with properties for the path. See details in the .h file.
+// This assumes that the length of path is less than PATH_MAX (currently 1024 characters).
+
+- (NSDictionary*)propertiesForPath:(NSString*)path {
+ const char* ccpath = (const char*)[path fileSystemRepresentation];
+ NSMutableDictionary* result = nil;
+ struct statfs fs;
+ if (!statfs(ccpath,&fs)) {
+ NSString* from = [NSString stringWithUTF8String:fs.f_mntfromname];
+ result = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithUTF8String:fs.f_fstypename],NSWorkspace_RBfstypename,
+ [NSString stringWithUTF8String:fs.f_mntonname],NSWorkspace_RBmntonname,
+ nil];
+ if (strncmp(fs.f_mntfromname,"/dev/",5)==0) {
+// For a local volume,get the IO registry tree and search it for further info.
+ mach_port_t masterPort = 0;
+ io_iterator_t mediaIterator = 0;
+ kern_return_t kernResult = IOMasterPort(bootstrap_port,&masterPort);
+ if (kernResult==KERN_SUCCESS) {
+ CFMutableDictionaryRef classesToMatch = IOBSDNameMatching(masterPort,0,&fs.f_mntfromname[5]);
+ if (classesToMatch) {
+ kernResult = IOServiceGetMatchingServices(masterPort,classesToMatch,&mediaIterator);
+ if ((kernResult==KERN_SUCCESS)&&mediaIterator) {
+ io_object_t firstMedia = 0;
+ while ((firstMedia = IOIteratorNext(mediaIterator))) {
+ NSString* stuff = CheckParents(firstMedia,nil,result);
+ if (stuff) {
+ [result setObject:stuff forKey:NSWorkspace_RBdeviceinfo];
+ }
+ IOObjectRelease(firstMedia);
+ }
+ }
+ }
+ }
+ if (mediaIterator) {
+ IOObjectRelease(mediaIterator);
+ }
+ if (masterPort) {
+ mach_port_deallocate(mach_task_self(),masterPort);
+ }
+ }
+ //Don't need this for disk images, gets around warnings for some deprecated functions
+
+ /* else {
+// For a network volume, get the volume reference number and use to get the server URL.
+ FSRef ref;
+ if (FSPathMakeRef((const UInt8*)ccpath,&ref,NULL)==noErr) {
+ FSCatalogInfo info;
+ if (FSGetCatalogInfo(&ref,kFSCatInfoVolume,&info,NULL,NULL,NULL)==noErr) {
+ ParamBlockRec pb;
+ UInt16 vmisize = 0;
+ VolumeMountInfoHeaderPtr mountInfo = NULL;
+ pb.ioParam.ioCompletion = NULL;
+ pb.ioParam.ioNamePtr = NULL;
+ pb.ioParam.ioVRefNum = info.volume;
+ pb.ioParam.ioBuffer = (Ptr)&vmisize;
+ pb.ioParam.ioReqCount = sizeof(vmisize);
+ if ((PBGetVolMountInfoSize(&pb)==noErr)&&vmisize) {
+ mountInfo = (VolumeMountInfoHeaderPtr)malloc(vmisize);
+ if (mountInfo) {
+ pb.ioParam.ioBuffer = (Ptr)mountInfo;
+ pb.ioParam.ioReqCount = vmisize;
+ if (PBGetVolMountInfo(&pb)==noErr) {
+ NSString* url = nil;
+ switch (mountInfo->media) {
+ case AppleShareMediaType:
+ url = FormatAFPURL((AFPXVolMountInfoPtr)mountInfo,&from);
+ break;
+ case 'http':
+ url = from;
+ break;
+ case 'crbm':
+ case 'nfs_':
+ case 'cifs':
+ url = [NSString stringWithUTF8String:(char*)mountInfo+sizeof(VolumeMountInfoHeader)+sizeof(OSType)];
+ break;
+ }
+ if (url) {
+ [result setObject:url forKey:NSWorkspace_RBserverURL];
+ }
+ }
+ }
+ free(mountInfo);
+ }
+ }
+ }
+ }*/
+ [result setObject:from forKey:NSWorkspace_RBmntfromname];
+ }
+ return result;
+}
+
+ at end
diff --git a/QTfrontend/SparkleAutoUpdater.h b/QTfrontend/util/platform/SparkleAutoUpdater.h
similarity index 100%
rename from QTfrontend/SparkleAutoUpdater.h
rename to QTfrontend/util/platform/SparkleAutoUpdater.h
diff --git a/QTfrontend/util/platform/SparkleAutoUpdater.mm b/QTfrontend/util/platform/SparkleAutoUpdater.mm
new file mode 100644
index 0000000..effac0b
--- /dev/null
+++ b/QTfrontend/util/platform/SparkleAutoUpdater.mm
@@ -0,0 +1,54 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+// see original example here http://el-tramo.be/blog/mixing-cocoa-and-qt
+
+#include "SparkleAutoUpdater.h"
+
+#include <Cocoa/Cocoa.h>
+#include <Sparkle/Sparkle.h>
+
+class SparkleAutoUpdater::Private
+{
+ public:
+ SUUpdater* updater;
+};
+
+SparkleAutoUpdater::SparkleAutoUpdater()
+{
+ d = new SparkleAutoUpdater::Private();
+
+ d->updater = [SUUpdater sharedUpdater];
+ [d->updater retain];
+}
+
+SparkleAutoUpdater::~SparkleAutoUpdater()
+{
+ [d->updater release];
+ delete d;
+}
+
+void SparkleAutoUpdater::checkForUpdates()
+{
+ [d->updater checkForUpdatesInBackground];
+}
+
+void SparkleAutoUpdater::checkForUpdatesNow()
+{
+ [d->updater checkForUpdates:NULL];
+}
diff --git a/misc/xfire/Xfire Game SDK.url b/QTfrontend/util/platform/Xfire Game SDK.url
similarity index 100%
rename from misc/xfire/Xfire Game SDK.url
rename to QTfrontend/util/platform/Xfire Game SDK.url
diff --git a/QTfrontend/util/platform/xfire.cpp b/QTfrontend/util/platform/xfire.cpp
new file mode 100644
index 0000000..9be4d11
--- /dev/null
+++ b/QTfrontend/util/platform/xfire.cpp
@@ -0,0 +1,85 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <string>
+#include <cstring>
+#include <stdio.h>
+
+#include "xfire.h"
+#include "xfiregameclient.h"
+
+#ifdef USE_XFIRE
+// use_xfire: stores if xfire is loaded and functions should do something at all
+bool use_xfire = false;
+char *keys[XFIRE_KEY_COUNT];
+char *values[XFIRE_KEY_COUNT];
+
+// xfire_init(): used to initialize all variables and set their default values
+void xfire_init(void)
+{
+ if(use_xfire)
+ return;
+ use_xfire = XfireIsLoaded() == 1;
+
+ if(!use_xfire)
+ return;
+
+ for(int i = 0; i < XFIRE_KEY_COUNT; i++)
+ {
+ keys[i] = new char[256];
+ values[i] = new char[256];
+ strcpy(keys[i], "");
+ strcpy(values[i], "");
+ }
+
+ strcpy(keys[XFIRE_NICKNAME], "Nickname");
+ strcpy(keys[XFIRE_ROOM], "Room");
+ strcpy(keys[XFIRE_SERVER], "Server");
+ strcpy(keys[XFIRE_STATUS], "Status");
+ xfire_update();
+}
+
+// xfire_free(): used to free up ressources used etc.
+void xfire_free(void)
+{
+ if(!use_xfire)
+ return;
+
+ for(int i = 0; i < XFIRE_KEY_COUNT; i++)
+ {
+ delete [] keys[i];
+ delete [] values[i];
+ }
+}
+
+// xfire_setvalue(): set a specific value
+void xfire_setvalue(const XFIRE_KEYS status, const char *value)
+{
+ if(!use_xfire || strlen(value) > 255)
+ return;
+ strcpy(values[status], value);
+}
+
+// xfire_update(): submits current values to the xfire app
+void xfire_update(void)
+{
+ if(!use_xfire)
+ return;
+ XfireSetCustomGameDataA(XFIRE_KEY_COUNT, (const char**)keys, (const char**)values);
+}
+#endif // USE_XFIRE
diff --git a/QTfrontend/util/platform/xfire.h b/QTfrontend/util/platform/xfire.h
new file mode 100644
index 0000000..6d54c87
--- /dev/null
+++ b/QTfrontend/util/platform/xfire.h
@@ -0,0 +1,39 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef XFIRE_H
+#define XFIRE_H
+
+
+#ifdef USE_XFIRE
+enum XFIRE_KEYS
+{
+ XFIRE_STATUS = 0,
+ XFIRE_NICKNAME,
+ XFIRE_SERVER,
+ XFIRE_ROOM,
+ XFIRE_KEY_COUNT,
+};
+
+void xfire_init(void);
+void xfire_free(void);
+void xfire_setvalue(const XFIRE_KEYS status, const char *value);
+void xfire_update(void);
+#endif
+
+#endif // XFIRE_H
diff --git a/QTfrontend/util/platform/xfire_license.txt b/QTfrontend/util/platform/xfire_license.txt
new file mode 100644
index 0000000..b4b77b7
--- /dev/null
+++ b/QTfrontend/util/platform/xfire_license.txt
@@ -0,0 +1,103 @@
+Terms and Conditions
+AGREEMENT BETWEEN USER AND XFIRE INC.
+This is a legal agreement between you and Xfire Inc. ("Xfire") with respect to your access and use of the Xfire Service, which may also include Xfire software, content and related documentation and information (collectively, the "Service"). You must accept without modification all of the terms, conditions, and notices contained in these Terms of Use in order to access and/or use the Service (collectively, the "Terms of Use" or "Agreement"). If you do not accept these Terms of Use in their entirety, you may not access or use the Service.
+
+Portions of the Service may be governed by posted guidelines, rules, or other terms and conditions. All such guidelines, rules, terms and conditions are hereby incorporated by reference into these Terms of Use. In the event of a conflict between such other guidelines, rules, terms and conditions and these Terms of Use, the Terms of Use shall control, except that the Xfire Service Privacy Policy, referenced below, supersedes any conflicting language in these Terms of Use and/or any other guidelines, rules, terms and conditions published in connection with the Service with respect to the subject matter covered by such privacy policy.
+
+MODIFICATION OF THESE TERMS OF USE; UPDATES
+Xfire may change the Terms of Use at any time and such changes shall be effective immediately. You are responsible for regularly reviewing the Terms of Use. The most recent version of the Terms of Use can be found at http://www.xfire.com/xf/terms.php. Your continued use of the Service affirms your agreement to the Terms of Use and any changes.
+
+Xfire is not obligated to provide updates or improvements to the Service. However, if Xfire, in its sole discretion, updates or improves the Service, these Terms of Use shall apply to such updates and improvements unless expressly noted otherwise.
+
+CLIENT SOFTWARE USE LIMITATION
+YOU MAY ONLY USE XFIRE CLIENT SOFTWARE OR AUTHORIZED THIRD-PARTY SOFTWARE TO ACCESS AND/OR USE THE SERVICE. You may not use any software or services in conjunction with the Xfire software or authorized third-party software which modifies or reroutes, or attempts to modify or reroute, the Service. You may not authorize any third party to access and/or use the Service on your behalf using any automated process such as a BOT, a spider or periodic caching of information stored by the Xfire Service on your behalf without a separate written agreement with Xfire. You may not use any software or hardware that reduces the number of users directly accessing or using the Service (sometimes called 'multiplexing' or 'pooling' software or hardware).
+
+You may not modify, copy, distribute, transmit, display, perform, reproduce, publish, license, create derivative works from, transfer, or sell any information, software, products or services that are part of the Service except as expressly provided in these Terms of Use.
+
+NO UNLAWFUL OR PROHIBITED USE; RESPONSIBILITY FOR YOUR ACCOUNT
+As a condition of your use of the Service, you will not use the Service for any purpose that is unlawful or prohibited by these Terms of Use. You may not use the Service in any manner that could damage, disable, overburden, or impair the Service or interfere with any other party's use and enjoyment of it. You may not attempt to gain unauthorized access to any account, computer systems or networks associated with the Service or to otherwise interfere with or disrupt any accounts, computer systems or networks connected to the Service. You may not obtain or attempt to obtain any materials or information through any means not intentionally made available or provided for through the Service. You may not use access to the Service to obtain information necessary for you to design, develop or update unauthorized software that you use or provide to others to use to access the Service. You may not charge others to use the Service either directly or indirectly without the express written agreement of Xfire.
+Subject to these Terms of Use, you may use the Service within your commercial organization, but you may not use the Service to advertise or offer to buy or sell any goods or services, or to run a business or commercial entity without the express written agreement of Xfire.
+You agree to use the Service only to send, receive, and transfer appropriate messages and material. By way of example, and not as a limitation, you agree that when using the Service, you will not:
+
+
+ Use the Service in connection with surveys, contests, pyramid schemes, chain letters, junk email, spamming or any duplicative, bulk or unsolicited messages (commercial or otherwise).
+
+ Defame, abuse, harass, stalk, threaten or otherwise violate the legal rights (such as rights of privacy and publicity) of others.
+
+ Create a false identity for the purpose of misleading others.
+
+ Publish, transfer, distribute or disseminate any inappropriate, profane, defamatory, obscene, indecent or unlawful topic, name, material or information.
+
+ Transfer, stream, or otherwise make available, files or other material that contain images, photographs, software or other material protected by intellectual property laws, including, by way of example, and not as limitation, copyright or trademark laws (or by rights of privacy or publicity) unless you own or control the rights thereto or have received all necessary consents to do the same.
+
+ Use any material or information, including images or photographs, which is made available through the Service in any manner that infringes any copyright, trademark, patent, trade secret, or other proprietary right of any party.
+
+ Transfer, stream or otherwise make available, files or other material that contain viruses, Trojan horses, worms, time bombs, cancelbots, corrupted files, or any other similar software or programs that may damage the operation of another's computer or property of another.
+
+ Download any file or other material transferred by another user of the Service that you know, or reasonably should know, cannot be legally distributed in such manner.
+
+ Use, download or otherwise copy, or provide (whether or not for a fee) to a person or entity any directory of users of the Service or other user or usage information or any portion thereof.
+
+ Falsify or delete any author attributions, legal or other proper notices or proprietary designations or labels of the origin or source of software or other material contained in a file that is transferred.
+
+ Violate any code of conduct or other guidelines which may be applicable to the Service.
+
+ Use any portion of the Service to harvest or otherwise collect information about others, including e-mail addresses.
+
+Xfire reserves the right at all times to monitor communications on the Service and disclose any information Xfire deems necessary to (i) ensure your compliance with this Agreement; (ii) satisfy any applicable law, regulation or legal process; or (iii) protect the rights, property, and interests of Xfire, its employees or the public. Xfire also reserves the right to edit, refuse to transfer or to remove any information or materials, in whole or in part, in Xfire's sole discretion.
+
+Always use caution when giving out any personally identifiable information about yourself or your children in the Service. Xfire does not control or endorse the content, messages or information exchanged by means of the Service and, therefore, Xfire specifically disclaims any liability with regard to the Service and any actions resulting from your participation in the Service.
+
+You are responsible for all activities that occur in your Service account. You agree to notify Xfire immediately of any unauthorized use of your account or breach in security known to you related to the Service.
+
+
+PRIVACY
+See the Xfire Service Privacy Statement at http://www.xfire.com/xf/privacy.php for disclosures relating to the collection and use of your information.
+
+
+INTERACTION WITH THIRD PARTY SITES AND SERVICES
+The Service may allow you to interact with third-party Web sites and Web services ("Link(s)"). The Links are not under the control of Xfire and Xfire is not responsible for the contents of any Links, including without limitation any link contained in a Link, or any changes or updates to a Link. Xfire is not responsible for any form of transmission received from any Link, nor is Xfire responsible if the Link is not working appropriately. Xfire is providing these Links to you only as a convenience, and the inclusion of any Link does not imply endorsement by Xfire of the Link or any association with its operators. You are responsible for viewing and abiding by any privacy statements and terms of use posted in connection with the Links.
+
+You are solely responsible for any dealings with third parties (including advertisers) who support the Service, including the delivery of and payment for goods and services.
+
+TERMS OF USE FOR SERVICE-ENABLED PROPERTIES
+For the terms and conditions governing your use of any Xfire or authorized third party Web site or service that enables you to use the Service other than the Service itself ("Service-Enabled Properties"), please refer to the applicable Terms of Use for such Service-Enabled Properties.
+
+SOFTWARE AND CONTENT AVAILABLE ON THE SERVICE
+All Xfire content and software (if any) that is made available to view and/or download in connection with the Service ("Software") is owned by and is the copyrighted work of Xfire and/or its suppliers and is licensed, not sold. Your use of the Software is governed by the terms of the license agreement, if any, which accompanies or is included with the Software ("License Agreement"). You may not install or use any Software that is accompanied by or includes a License Agreement unless you first agree to the License Agreement terms. For any Software not accompanied by a license agreement, Xfire hereby grants to you, the user, a non-exclusive, revocable, personal, non-transferable license to use the Software solely in connection with the Service in accordance with these Terms of Use. You may not lend, lease, rent or sublicense the Software or any aspect of the Service.
+
+You will not disassemble, decompile, or reverse engineer the Software. All Software is protected by copyright laws and international treaty provisions. Any unauthorized reproduction or redistribution of the Software is expressly prohibited by law, and may result in severe civil and criminal penalties. WITHOUT LIMITING THE FOREGOING, COPYING OR REPRODUCTION OF THE SOFTWARE TO ANY OTHER SERVER OR LOCATION FOR FURTHER REPRODUCTION OR REDISTRIBUTION IS EXPRESSLY PROHIBITED. THE SOFTWARE IS WARRANTED, IF AT ALL, ONLY ACCORDING TO THE TERMS OF THE LICENSE AGREEMENT. You acknowledge that the Software, and any accompanying documentation and/or technical information, is subject to applicable export control laws and regulations of the U.S.A. You agree not to export or re-export the Software, directly or indirectly, to any countries that are subject to U.S.A. export restrictions.
+
+Your license to use the Software with the Service terminates when you terminate your use of the Service. Your license to use the Software with the Service may also terminate if Xfire, in its sole discretion, modifies the Service to no longer support such Software.
+
+NO WARRANTIES; LIABILITY DISCLAIMER; EXCLUSIVE REMEDY
+XFIRE PROVIDES THE SERVICE AND THE SOFTWARE "AS IS," "WITH ALL FAULTS" AND "AS AVAILABLE," AND THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH YOU. XFIRE, ITS AFFILIATES, ITS RESELLERS, DISTRIBUTORS, SERVICE PROVIDERS AND/OR SUPPLIERS (COLLECTIVELY, THE "XFIRE PARTIES") MAKE NO WARRANTIES. THE XFIRE PARTIES DISCLAIM ANY AND ALL WARRANTIES, EXPRESS, STATUTORY AND IMPLIED, INCLUDING WITHOUT LIMITATION (1) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE EFFORT, ACCURACY, TITLE, QUIET ENJOYMENT, NO ENCUMBRANCES, NO LIENS AND NON-INFRINGEMENT, (2) WARRANTIES ARISING THROUGH COURSE OF DEALING OR USAGE OF TRADE, AND (3) WARRANTIES THAT ACCESS TO OR USE OF THE SERVICE WILL BE UNINTERRUPTED OR ERROR-FREE. THERE ARE NO WARRANTIES THAT EXTEND BEYOND THE FACE OF THIS AGREEMENT. XFIRE MAY CHANGE THE SERVICE OR THE FEATURES IN ANY WAY, AND AT ANY TIME AND FOR ANY REASON.
+
+IN NO EVENT SHALL ANY OF THE XFIRE PARTIES BE LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, SPECIAL, INCIDENTAL, OR PUNITIVE DAMAGES ARISING OUT OF, BASED ON, OR RESULTING FROM THIS AGREEMENT OR YOUR USE OF THE SERVICE, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, WITH THE DELAY OR INABILITY TO USE THE SERVICE, THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, OR FOR ANY INFORMATION, SOFTWARE, PRODUCTS, OR SERVICES OBTAINED THROUGH THE SERVICE, OR OTHERWISE ARISING OUT OF THE USE OF THE SERVICE, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF XFIREOR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
+
+IF YOU ARE DISSATISFIED WITH ANY PORTION OF THE SERVICE, OR WITH ANY OF THESE TERMS OF USE, YOUR SOLE AND EXCLUSIVE REMEDY IS TO DISCONTINUE USING THE SERVICE.
+
+INDEMNITY
+You agree to indemnify and hold Xfire, its officers, and employees, harmless from any claim or demand, including reasonable attorneys' fees, made by any third party due to or arising out of your use of the Services, the violation of these Terms of Use by you, or the infringement by you, or other user of the Services using your computer or identity, of any intellectual property or other right of any person or entity.
+
+CUSTOMER SUPPORT
+Xfire may, but is not required to, provide you with customer support ("Support"). Unless you have entered into a separate written support agreement with Xfire with respect to the Service, Xfire may terminate any Support it provides at any time in its sole discretion.
+
+Authorized third-party software that uses the Service is not supported by Xfire and you should contact the provider of such software for support, if any.
+
+TERMINATION/ACCESS RESTRICTION
+Unless you, or a third party on your behalf, have entered into a separate written agreement with Xfire that modifies these Terms of Use, Xfire reserves the right, in its sole discretion, to terminate your access to and use of the Service or any portion thereof at any time, without notice. Also, unless you or a third party on your behalf have entered into a separate agreement with Xfire, Xfire may terminate or suspend your access to the Service for inactivity, which is defined as failing to log onto the Service for an extended period of time, as determined by Xfire.
+ELECTRONIC NOTICES
+You consent to Xfire providing you any information regarding the Service in electronic form. Xfire may provide such information to you via e-mail at the e-mail address you specified when you registered for the Service, by instant message to your account, or by access to a Xfire web site. As long as you access and use the Service, you will have the necessary software and hardware to receive such notices. If you do not consent to receive any notices electronically, you must discontinue your use of the Service.
+
+GENERAL
+If you reside in the United States, claims for enforcement, breach or violation of duties or rights under these Terms of Use are governed by the laws of the State of California, without reference to conflict of laws principles. All other claims, including, without limitation, claims under or for violation of state consumer protection laws, unfair competition laws, and in tort, are governed by the laws of your state of residence in the United States. If you reside outside of the United States, these Terms of Use are governed by the laws of the State of California, without reference to conflict of laws principles. You hereby irrevocably consent to the exclusive jurisdiction and venue of courts in San Mateo County, California, U.S.A. in all disputes arising out of or relating to the use of the Service.
+
+YOU AND XFIRE AGREE THAT ANY CAUSE OF ACTION ARISING OUT OF OR RELATED TO THE SERVICE MUST COMMENCE WITHIN ONE (1) YEAR AFTER THE CAUSE OF ACTION ACCRUES. OTHERWISE, SUCH CAUSE OF ACTION IS PERMANENTLY BARRED.
+
+Xfire may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in any Web pages that are part of the Service. Except as expressly provided in these Terms of Use, the furnishing of such Web pages to you does not give you any license to these patents, trademarks, copyrights, or other intellectual property. Any rights not expressly granted herein are reserved.
+
+June 2004
+
+
+
diff --git a/QTfrontend/util/platform/xfiregameclient.cpp b/QTfrontend/util/platform/xfiregameclient.cpp
new file mode 100644
index 0000000..a7a6b0c
--- /dev/null
+++ b/QTfrontend/util/platform/xfiregameclient.cpp
@@ -0,0 +1,121 @@
+/* This file is NOT open source. See "license.txt" to read the full license provided with the Xfire SDK. */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tlhelp32.h>
+
+#include "xfiregameclient.h"
+
+static HMODULE g_toucan_dll = NULL;
+static void HelperInit();
+static HMODULE HelperGetToucanDLL();
+
+typedef int (*XfireSetCustomGameDataAFunction)(int , const char **, const char **);
+typedef int (*XfireSetCustomGameDataWFunction)(int , const wchar_t **, const wchar_t **);
+typedef int (*XfireSetCustomGameDataUTF8Function)(int , const char **, const char **);
+
+static XfireSetCustomGameDataAFunction ptr_XfireSetCustomGameDataA = NULL;
+static XfireSetCustomGameDataWFunction ptr_XfireSetCustomGameDataW = NULL;
+static XfireSetCustomGameDataUTF8Function ptr_XfireSetCustomGameDataUTF8 = NULL;
+
+/* make sure we are going to call the ANSI version */
+#ifdef MODULEENTRY32
+#undef MODULEENTRY32
+#endif
+
+#ifdef Module32First
+#undef Module32First
+#endif
+
+#ifdef Module32Next
+#undef Module32Next
+#endif
+
+
+int XfireIsLoaded()
+{
+ HelperInit();
+ if (ptr_XfireSetCustomGameDataA &&
+ ptr_XfireSetCustomGameDataW &&
+ ptr_XfireSetCustomGameDataUTF8)
+ return 1;
+ return 0;
+}
+
+int XfireSetCustomGameDataA(int num_keys, const char **keys, const char **values)
+{
+ HelperInit();
+ if (ptr_XfireSetCustomGameDataA)
+ return ptr_XfireSetCustomGameDataA(num_keys, keys, values);
+ return 1;
+}
+
+int XfireSetCustomGameDataW(int num_keys, const wchar_t **keys, const wchar_t **values)
+{
+ HelperInit();
+ if (ptr_XfireSetCustomGameDataW)
+ return ptr_XfireSetCustomGameDataW(num_keys, keys, values);
+ return 1;
+}
+
+int XfireSetCustomGameDataUTF8(int num_keys, const char **keys, const char **values)
+{
+ HelperInit();
+ if (ptr_XfireSetCustomGameDataUTF8)
+ return ptr_XfireSetCustomGameDataUTF8(num_keys, keys, values);
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+static void HelperInit()
+{
+ if (!ptr_XfireSetCustomGameDataA ||
+ !ptr_XfireSetCustomGameDataW ||
+ !ptr_XfireSetCustomGameDataUTF8)
+ {
+ HMODULE toucan_dll = HelperGetToucanDLL();
+ if (toucan_dll)
+ {
+ ptr_XfireSetCustomGameDataA = (XfireSetCustomGameDataAFunction)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataA_V1");
+ ptr_XfireSetCustomGameDataW = (XfireSetCustomGameDataWFunction)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataW_V1");
+ ptr_XfireSetCustomGameDataUTF8 = (XfireSetCustomGameDataUTF8Function)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataUTF8_V1");
+ }
+ }
+}
+
+
+static HMODULE HelperGetToucanDLL()
+{
+ if (g_toucan_dll)
+ return g_toucan_dll;
+
+ /*
+ ** We need to enumerate the DLLs loaded to find toucan dll.
+ ** This is done because the toucan dll changes with each update.
+ ** The toucan dll has the following format. "xfire_toucan_{BUILD_NUMBER}.dll"
+ ** We simply try to find a dll w/ the prefix "xfire_toucan"
+ */
+ HANDLE snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
+ if (snapshot_handle != INVALID_HANDLE_VALUE)
+ {
+ MODULEENTRY32 module_entry;
+ module_entry.dwSize = sizeof(MODULEENTRY32);
+
+ BOOL result = Module32First(snapshot_handle, &module_entry);
+ char module_name[] = "xfire_toucan";
+ DWORD module_name_len = sizeof(module_name)-1;
+ while (result)
+ {
+ if (CompareStringA(LOCALE_USER_DEFAULT, NORM_IGNORECASE, module_entry.szModule, module_name_len, module_name, module_name_len) == CSTR_EQUAL)
+ {
+ g_toucan_dll = module_entry.hModule;
+ break;
+ }
+ result = Module32Next(snapshot_handle, &module_entry);
+ }
+
+ CloseHandle(snapshot_handle);
+ }
+
+ return g_toucan_dll;
+}
diff --git a/misc/xfire/xfiregameclient.h b/QTfrontend/util/platform/xfiregameclient.h
similarity index 100%
rename from misc/xfire/xfiregameclient.h
rename to QTfrontend/util/platform/xfiregameclient.h
diff --git a/QTfrontend/weapons.h b/QTfrontend/weapons.h
new file mode 100644
index 0000000..c6c81fb
--- /dev/null
+++ b/QTfrontend/weapons.h
@@ -0,0 +1,66 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+// TODO: keep on documenting all the weapons
+//skip---------------------------------|
+//structure------------------------------------------------------------------|
+
+#define AMMOLINE_DEFAULT_QT "9391929422199121032235111001201000000211110101011111121"
+#define AMMOLINE_DEFAULT_PROB "0405040541600655546554464776576666666155510101115411121"
+#define AMMOLINE_DEFAULT_DELAY "0000000000000205500000040007004000000000220000000600020"
+#define AMMOLINE_DEFAULT_CRATE "1311110312111111123114111111111111111211111101111111121"
+
+#define AMMOLINE_CRAZY_QT "9999999999999999992999999999999999299999999909999992999"
+#define AMMOLINE_CRAZY_PROB "1111110111111111111111111111111111111111111101111111111"
+#define AMMOLINE_CRAZY_DELAY "0000000000000000000000000000000000000000000000000000000"
+#define AMMOLINE_CRAZY_CRATE "1311110312111111123114111111111111111211110101111111121"
+
+#define AMMOLINE_PROMODE_QT "9090009000000000000009000000000000000000000000000000000"
+#define AMMOLINE_PROMODE_PROB "0000000000000000000000000000000000000000000000000000000"
+#define AMMOLINE_PROMODE_DELAY "0000000000000205500000040007004000000000200000000000020"
+#define AMMOLINE_PROMODE_CRATE "1111110111111111111111111111111111111111100101111111121"
+
+#define AMMOLINE_SHOPPA_QT "0000009900000000000000000000000000000000000000000000000"
+#define AMMOLINE_SHOPPA_PROB "4444410044244402210112121222422000000002000400010011001"
+#define AMMOLINE_SHOPPA_DELAY "0000000000000000000000000000000000000000000000000000000"
+#define AMMOLINE_SHOPPA_CRATE "1111110111111111111111111111111111111111101101111111121"
+
+#define AMMOLINE_CLEAN_QT "1010009000010000011000000000000000000000000000001000000"
+#define AMMOLINE_CLEAN_PROB "0405040541600655546554464776576666666155510101115411121"
+#define AMMOLINE_CLEAN_DELAY "0000000000000000000000000000000000000000000000000000020"
+#define AMMOLINE_CLEAN_CRATE "1311110312111111123114111111111111111211111101111111121"
+
+#define AMMOLINE_MINES_QT "0000009900090000000300000000000000000000000000000000000"
+#define AMMOLINE_MINES_PROB "0000000000000000000000000000000000000000000000000000000"
+#define AMMOLINE_MINES_DELAY "0000000000000205500000040007004000000000200000000600020"
+#define AMMOLINE_MINES_CRATE "1111110111111111111111111111111111111111111101111111121"
+
+#define AMMOLINE_PORTALS_QT "9000009002000000002100000000000000110000090000000000000"
+#define AMMOLINE_PORTALS_PROB "0405040541600655546554464776576666666155510101115411121"
+#define AMMOLINE_PORTALS_DELAY "0000000000000205500000040007004000000000200000000600020"
+#define AMMOLINE_PORTALS_CRATE "1311110312111111123114111111111111111211111101111111121"
+
+#define AMMOLINE_ONEEVERY_QT "1111119111111111111111111111111111111111111111111111111"
+#define AMMOLINE_ONEEVERY_PROB "1111110111111111111111111111111111111111111111111111111"
+#define AMMOLINE_ONEEVERY_DELAY "0000000000000000000000000000000000000000000000000000000"
+#define AMMOLINE_ONEEVERY_CRATE "1111110111111111111111111111111111111111111111111111111"
+
+//When adding new weapons also insert one element in cDefaultAmmos list (hwconsts.cpp.in)
+
+
diff --git a/QTfrontend/xfire.cpp b/QTfrontend/xfire.cpp
deleted file mode 100644
index 1840bbc..0000000
--- a/QTfrontend/xfire.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#include <string>
-#include <cstring>
-#include <stdio.h>
-
-#include "xfire.h"
-#include "../misc/xfire/xfiregameclient.h"
-
-#ifdef USE_XFIRE
-// use_xfire: stores if xfire is loaded and functions should do something at all
-bool use_xfire = false;
-char *keys[XFIRE_KEY_COUNT];
-char *values[XFIRE_KEY_COUNT];
-
-// xfire_init(): used to initialize all variables and set their default values
-void xfire_init(void)
-{
- if(use_xfire)
- return;
- use_xfire = XfireIsLoaded() == 1;
-
- if(!use_xfire)
- return;
-
- for(int i = 0; i < XFIRE_KEY_COUNT; i++)
- {
- keys[i] = new char[256];
- values[i] = new char[256];
- strcpy(keys[i], "");
- strcpy(values[i], "");
- }
-
- strcpy(keys[XFIRE_NICKNAME], "Nickname");
- strcpy(keys[XFIRE_ROOM], "Room");
- strcpy(keys[XFIRE_SERVER], "Server");
- strcpy(keys[XFIRE_STATUS], "Status");
- xfire_update();
-}
-
-// xfire_free(): used to free up ressources used etc.
-void xfire_free(void)
-{
- if(!use_xfire)
- return;
-
- for(int i = 0; i < XFIRE_KEY_COUNT; i++)
- {
- delete [] keys[i];
- delete [] values[i];
- }
-}
-
-// xfire_setvalue(): set a specific value
-void xfire_setvalue(const XFIRE_KEYS status, const char *value)
-{
- if(!use_xfire || strlen(value) > 255)
- return;
- strcpy(values[status], value);
-}
-
-// xfire_update(): submits current values to the xfire app
-void xfire_update(void)
-{
- if(!use_xfire)
- return;
- XfireSetCustomGameDataA(XFIRE_KEY_COUNT, (const char**)keys, (const char**)values);
-}
-#endif // USE_XFIRE
diff --git a/QTfrontend/xfire.h b/QTfrontend/xfire.h
deleted file mode 100644
index 70d233d..0000000
--- a/QTfrontend/xfire.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef XFIRE_H
-#define XFIRE_H
-
-
-#ifdef USE_XFIRE
-enum XFIRE_KEYS
-{
- XFIRE_STATUS = 0,
- XFIRE_NICKNAME,
- XFIRE_SERVER,
- XFIRE_ROOM,
- XFIRE_KEY_COUNT,
-};
-
-void xfire_init(void);
-void xfire_free(void);
-void xfire_setvalue(const XFIRE_KEYS status, const char *value);
-void xfire_update(void);
-#endif
-
-#endif // XFIRE_H
diff --git a/README b/README
index 71513ab..b36fb01 100644
--- a/README
+++ b/README
@@ -3,5 +3,15 @@ Distributed under the terms of the GNU GPL licence.
Images and sounds are distributed under the terms of the GNU FDL licence.
Source:
-Copyright 2004-2011 Andrey Korotaev <unC0Rr at gmail.com>
+Copyright 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
Portions copyright 2006-2008 Igor Ulyanov aka Displacer <iulyanov at gmail.com>
+
+Instructions:
+depending on your system, consult our wiki at:
+- http://code.google.com/p/hedgewars/wiki/BuildingOnLinux
+- http://code.google.com/p/hedgewars/wiki/BuildingOnWindows
+- http://code.google.com/p/hedgewars/wiki/BuildingOnMac
+
+Dependencies:
+you can find an outline of the necessary dependencies in the INSTALL file.
+
diff --git a/README_WINDOWS b/README_WINDOWS
deleted file mode 100644
index 4239dd6..0000000
--- a/README_WINDOWS
+++ /dev/null
@@ -1 +0,0 @@
-For instructions, please visit: http://code.google.com/p/hedgewars/wiki/BuildingOnWindows
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt
index aff962a..ec3afc2 100644
--- a/bin/CMakeLists.txt
+++ b/bin/CMakeLists.txt
@@ -1,9 +1,9 @@
if(WIN32 AND NOT UNIX)
- file(GLOB DLLs *.dll)
- file(GLOB ICOs *.ico)
-
- install(FILES
- ${DLLs}
- ${ICOs}
- DESTINATION bin)
+ file(GLOB DLLs *.dll)
+ file(GLOB ICOs *.ico)
+
+ install(FILES
+ ${DLLs}
+ ${ICOs}
+ DESTINATION ${target_library_install_dir})
endif(WIN32 AND NOT UNIX)
diff --git a/bin/hwdfile.ico b/bin/hwdfile.ico
new file mode 100644
index 0000000..73549a1
Binary files /dev/null and b/bin/hwdfile.ico differ
diff --git a/bin/hwsfile.ico b/bin/hwsfile.ico
new file mode 100644
index 0000000..73549a1
Binary files /dev/null and b/bin/hwsfile.ico differ
diff --git a/cmake_modules/CPackConfig.cmake b/cmake_modules/CPackConfig.cmake
new file mode 100644
index 0000000..c1aa7b2
--- /dev/null
+++ b/cmake_modules/CPackConfig.cmake
@@ -0,0 +1,98 @@
+
+# revision information in cpack-generated names
+if(CMAKE_BUILD_TYPE MATCHES DEBUG)
+ set(full_suffix "${HEDGEWARS_VERSION}-r${HEDGEWARS_REVISION}")
+else()
+ set(full_suffix "${HEDGEWARS_VERSION}")
+endif()
+
+# CPack variables
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hedgewars, a free turn-based strategy game")
+set(CPACK_PACKAGE_VENDOR "Hedgewars Project")
+set(CPACK_PACKAGE_FILE_NAME "Hedgewars-${full_suffix}")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "hedgewars-src-${full_suffix}")
+set(CPACK_SOURCE_GENERATOR "TBZ2")
+set(CPACK_PACKAGE_EXECUTABLES "hedgewars" "Hedgewars")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Hedgewars ${full_suffix}")
+set(CPACK_STRIP_FILES true)
+
+if(WIN32 AND NOT UNIX)
+ set(CPACK_NSIS_DISPLAY_NAME "Hedgewars")
+ set(CPACK_NSIS_HELP_LINK "http://www.hedgewars.org/")
+ set(CPACK_NSIS_URL_INFO_ABOUT "http://www.hedgewars.org/")
+ set(CPACK_NSIS_CONTACT "unC0Rr at gmail.com")
+ set(CPACK_NSIS_MODIFY_PATH OFF)
+ set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
+ set(CPACK_NSIS_MUI_FINISHPAGE_RUN "hedgewars${CMAKE_EXECUTABLE_SUFFIX}")
+ set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Hedgewars.lnk' '$INSTDIR\\\\hedgewars.exe'")
+ set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "hedgewars")
+endif(WIN32 AND NOT UNIX)
+
+set(CPACK_SOURCE_IGNORE_FILES
+ #temporary files
+ "~"
+ ".swp"
+ #version control
+ "\\\\.hg"
+ #output binary/library
+ "\\\\.exe$"
+ "\\\\.a$"
+ "\\\\.so$"
+ "\\\\.dylib$"
+ "\\\\.dll$"
+ "\\\\.ppu$"
+ "\\\\.o$"
+ "\\\\.cxx$"
+ #graphics
+ "\\\\.xcf$"
+ "\\\\.svg$"
+ "\\\\.svgz$"
+ "\\\\.psd$"
+ "\\\\.sifz$"
+ #misc
+ "\\\\.core$"
+ "\\\\.sh$"
+ "\\\\.orig$"
+ "\\\\.layout$"
+ "\\\\.db$"
+ "\\\\.dof$"
+ #archives
+ "\\\\.zip$"
+ "\\\\.gz$"
+ "\\\\.bz2$"
+ "\\\\.tmp$"
+ #cmake-configured files
+ "hwconsts\\\\.cpp$"
+ "config\\\\.inc$"
+ "hwengine\\\\.desktop$"
+ "Info\\\\.plist$"
+ #other cmake generated files
+ "Makefile"
+ "Doxyfile"
+ "CMakeFiles"
+ "[dD]ebug$"
+ "[rR]elease$"
+ "CPack"
+ "cmake_install\\\\.cmake$"
+ "CMakeCache\\\\.txt$"
+# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libtremor"
+# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libfreetype"
+# "^${CMAKE_CURRENT_SOURCE_DIR}/misc/liblua"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/misc/libopenalbridge"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/frontlib"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/promotional_art"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/project_files/cmdlineClient"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/tools/templates"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/bin/checkstack*"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/doc"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/templates"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/tmp"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/utils"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/share/hedgewars/Data/Maps/test"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/install_manifest.txt"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt"
+ "^${CMAKE_CURRENT_SOURCE_DIR}/hedgewars\\\\."
+)
+
+include(CPack)
diff --git a/cmake_modules/FindFFMPEG.cmake b/cmake_modules/FindFFMPEG.cmake
index b42d6ce..1f674f5 100644
--- a/cmake_modules/FindFFMPEG.cmake
+++ b/cmake_modules/FindFFMPEG.cmake
@@ -1,94 +1,83 @@
-# - Try to find ffmpeg libraries (libavcodec, libavformat and libavutil)
+# Find ffmpeg/libav libraries (libavcodec, libavformat and libavutil)
# Once done this will define
#
-# FFMPEG_FOUND - system has ffmpeg or libav
-# FFMPEG_INCLUDE_DIR - the ffmpeg include directory
-# FFMPEG_LIBRARIES - Link these to use ffmpeg
-# FFMPEG_LIBAVCODEC
-# FFMPEG_LIBAVFORMAT
-# FFMPEG_LIBAVUTIL
+# FFMPEG_FOUND - system has libavcodec, libavformat, libavutil
+# FFMPEG_INCLUDE_DIR - the libav include directories
+# FFMPEG_LIBRARIES - the libav libraries
+#
+# LIBAVCODEC_LIBRARY - the libavcodec library
+# LIBAVCODEC_INCLUDE_DIR - the libavcodec include directory
+# LIBAVFORMAT_LIBRARY - the libavformat library
+# LIBAVUTIL_LIBRARY - the libavutil library
#
# Copyright (c) 2008 Andreas Schneider <mail at cynapses.org>
# Modified for other libraries by Lasse Kärkkäinen <tronic>
# Modified for Hedgewars by Stepik777
+# Copyright (c) 2013 Vittorio Giovara <vittorio.giovara at gmail.com>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
#
-if (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
- # in cache already
- set(FFMPEG_FOUND TRUE)
-else (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
- # use pkg-config to get the directories and then use these values
- # in the FIND_PATH() and FIND_LIBRARY() calls
- find_package(PkgConfig)
- if (PKG_CONFIG_FOUND)
- pkg_check_modules(_FFMPEG_AVCODEC libavcodec)
- pkg_check_modules(_FFMPEG_AVFORMAT libavformat)
- pkg_check_modules(_FFMPEG_AVUTIL libavutil)
- endif (PKG_CONFIG_FOUND)
+include(FindPackageHandleStandardArgs)
+
- find_path(FFMPEG_AVCODEC_INCLUDE_DIR
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig)
+if (PKG_CONFIG_FOUND)
+ pkg_check_modules(_FFMPEG_AVCODEC libavcodec ${VERBOSITY})
+ pkg_check_modules(_FFMPEG_AVFORMAT libavformat ${VERBOSITY})
+ pkg_check_modules(_FFMPEG_AVUTIL libavutil ${VERBOSITY})
+endif (PKG_CONFIG_FOUND)
+
+find_path(LIBAVCODEC_INCLUDE_DIR
NAMES libavcodec/avcodec.h
- PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS}
+ PATHS ${_AVCODEC_INCLUDE_DIRS}
/usr/include /usr/local/include #system level
/opt/local/include #macports
/sw/include #fink
- PATH_SUFFIXES ffmpeg libav
- )
+ PATH_SUFFIXES libav ffmpeg
+)
+
+#TODO: add other include paths
- find_library(FFMPEG_LIBAVCODEC
+find_library(LIBAVCODEC_LIBRARY
NAMES avcodec
- PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS}
+ PATHS ${_AVCODEC_LIBRARY_DIRS}
/usr/lib /usr/local/lib #system level
/opt/local/lib #macports
/sw/lib #fink
- )
+)
- find_library(FFMPEG_LIBAVFORMAT
+find_library(LIBAVFORMAT_LIBRARY
NAMES avformat
- PATHS ${_FFMPEG_AVFORMAT_LIBRARY_DIRS}
+ PATHS ${_AVFORMAT_LIBRARY_DIRS}
/usr/lib /usr/local/lib #system level
/opt/local/lib #macports
/sw/lib #fink
- )
+)
- find_library(FFMPEG_LIBAVUTIL
+find_library(LIBAVUTIL_LIBRARY
NAMES avutil
- PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS}
+ PATHS ${_AVUTIL_LIBRARY_DIRS}
/usr/lib /usr/local/lib #system level
/opt/local/lib #macports
/sw/lib #fink
- )
-
- if (FFMPEG_LIBAVCODEC AND FFMPEG_LIBAVFORMAT)
- set(FFMPEG_FOUND TRUE)
- endif()
-
- if (FFMPEG_FOUND)
- set(FFMPEG_INCLUDE_DIR ${FFMPEG_AVCODEC_INCLUDE_DIR})
-
- set(FFMPEG_LIBRARIES
- ${FFMPEG_LIBAVCODEC}
- ${FFMPEG_LIBAVFORMAT}
- ${FFMPEG_LIBAVUTIL}
- )
- if (APPLE)
- set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} "bz2" "-framework CoreVideo" "-framework VideoDecodeAcceleration")
- endif(APPLE)
+)
- endif (FFMPEG_FOUND)
+find_package_handle_standard_args(FFMPEG DEFAULT_MSG LIBAVCODEC_LIBRARY LIBAVCODEC_INCLUDE_DIR
+ LIBAVFORMAT_LIBRARY
+ LIBAVUTIL_LIBRARY
+ )
+set(FFMPEG_INCLUDE_DIR ${LIBAVCODEC_INCLUDE_DIR}
+ #TODO: add other include paths
+ )
+set(FFMPEG_LIBRARIES ${LIBAVCODEC_LIBRARY}
+ ${LIBAVFORMAT_LIBRARY}
+ ${LIBAVUTIL_LIBRARY}
+ )
- if (FFMPEG_FOUND)
- if (NOT FFMPEG_FIND_QUIETLY)
- message(STATUS "Found FFMPEG/LibAV: ${FFMPEG_LIBRARIES}, ${FFMPEG_INCLUDE_DIR}")
- endif (NOT FFMPEG_FIND_QUIETLY)
- else (FFMPEG_FOUND)
- if (FFMPEG_FIND_REQUIRED)
- message(FATAL_ERROR "Could NOT find libavcodec or libavformat or libavutil")
- endif (FFMPEG_FIND_REQUIRED)
- endif (FFMPEG_FOUND)
+mark_as_advanced(FFMPEG_INCLUDE_DIR FFMPEG_LIBRARIES LIBAVCODEC_LIBRARY LIBAVCODEC_INCLUDE_DIR LIBAVFORMAT_LIBRARY LIBAVUTIL_LIBRARY)
-endif (FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
diff --git a/cmake_modules/FindFreePascal.cmake b/cmake_modules/FindFreePascal.cmake
new file mode 100644
index 0000000..78c777e
--- /dev/null
+++ b/cmake_modules/FindFreePascal.cmake
@@ -0,0 +1,37 @@
+# - 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 at gmail.com>
+# Copyright (c) 2013, Vittorio Giovara <vittorio.giovara at 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)
+
diff --git a/cmake_modules/FindGHC.cmake b/cmake_modules/FindGHC.cmake
new file mode 100644
index 0000000..026e002
--- /dev/null
+++ b/cmake_modules/FindGHC.cmake
@@ -0,0 +1,38 @@
+# - Try to find the Glasgow Haskell Compiler executable
+# Once done this will define
+#
+# GHC_FOUND - system has GHC
+# GHC_VERSION - GHC version
+# GHC_EXECUTABLE - GHC executable
+#
+# Copyright (c) 2013, Vittorio Giovara <vittorio.giovara at 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(GHC_EXECUTABLE
+ NAMES ghc
+ PATHS /opt/local/bin /usr/local/bin /usr/bin
+ )
+
+if (GHC_EXECUTABLE)
+ # check Freepascal version
+ execute_process(COMMAND ${GHC_EXECUTABLE} -V
+ OUTPUT_VARIABLE GHC_VERSION_OUTPUT
+ ERROR_VARIABLE GHC_VERSION_ERROR
+ RESULT_VARIABLE GHC_VERSION_RESULT
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ if(${GHC_VERSION_RESULT} EQUAL 0)
+ string(REGEX MATCH "([0-9]+)" GHC_VERSION ${GHC_VERSION_OUTPUT})
+ else()
+ message(SEND_ERROR "Command \"${GHC_EXECUTABLE} -V\" failed with output: ${GHC_VERSION_ERROR}")
+ endif()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GHC DEFAULT_MSG GHC_EXECUTABLE GHC_VERSION)
+mark_as_advanced(GHC_VERSION)
+
diff --git a/cmake_modules/FindLibraryWithDebug.cmake b/cmake_modules/FindLibraryWithDebug.cmake
index 58cd730..20c2b74 100644
--- a/cmake_modules/FindLibraryWithDebug.cmake
+++ b/cmake_modules/FindLibraryWithDebug.cmake
@@ -100,7 +100,7 @@ MACRO(FIND_LIBRARY_WITH_DEBUG var_name win32_dbg_postfix_name dgb_postfix libnam
SET(${var_name} ${${var_name}_DEBUG})
ENDIF(${var_name}_RELEASE)
-
+
ENDIF(${var_name}_RELEASE AND ${var_name}_DEBUG)
MARK_AS_ADVANCED(${var_name}_RELEASE)
diff --git a/cmake_modules/FindLua.cmake b/cmake_modules/FindLua.cmake
index 0824b49..f69f086 100644
--- a/cmake_modules/FindLua.cmake
+++ b/cmake_modules/FindLua.cmake
@@ -6,6 +6,7 @@
# the bundled one when nothing is found
set(LUA_FOUND false)
+set(LUA_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/misc/liblua)
if (ANDROID)
SET(LUA_DEFAULT "liblua5.1.so")
@@ -19,10 +20,11 @@ else (ANDROID)
#locate the system's lua library
FIND_LIBRARY(LUA_DEFAULT NAMES lua51 lua5.1 lua-5.1 lua PATHS /lib /usr/lib /usr/local/lib /usr/pkg/lib)
IF(${LUA_DEFAULT} MATCHES "LUA_DEFAULT-NOTFOUND")
- set(LUA_DEFAULT lua)
+ set(LUA_DEFAULT lua)
ELSE()
set(LUA_FOUND true)
message(STATUS "LibLua 5.1 found at ${LUA_DEFAULT}")
+ find_path(LUA_INCLUDE_DIR lua.h)
#remove the path (fpc doesn't like it - why?)
GET_FILENAME_COMPONENT(LUA_DEFAULT ${LUA_DEFAULT} NAME)
ENDIF()
@@ -32,3 +34,4 @@ ENDIF(ANDROID)
SET(LUA_LIBRARY ${LUA_DEFAULT} CACHE STRING "Lua library to link to; file name without path only!")
+
diff --git a/cmake_modules/FindOggVorbis.cmake b/cmake_modules/FindOggVorbis.cmake
index e818d6b..c3e6af4 100644
--- a/cmake_modules/FindOggVorbis.cmake
+++ b/cmake_modules/FindOggVorbis.cmake
@@ -1,61 +1,68 @@
-### SuperTux - Removed unused vorbisenc library
-
# - Try to find the OggVorbis libraries
# Once done this will define
#
-# OGGVORBIS_FOUND - system has OggVorbis
-# OGGVORBIS_VERSION - set either to 1 or 2
+# OGGVORBIS_FOUND - system has both Ogg and Vorbis
+# OGGVORBIS_VERSION - set either to 1 or 2
# OGGVORBIS_INCLUDE_DIR - the OggVorbis include directory
-# OGGVORBIS_LIBRARIES - The libraries needed to use OggVorbis
-# OGG_LIBRARY - The Ogg library
-# VORBIS_LIBRARY - The Vorbis library
-# VORBISFILE_LIBRARY - The VorbisFile library
-# Copyright (c) 2006, Richard Laerkaeng, <richard at goteborg.utfors.se>
+# OGGVORBIS_LIBRARIES - the libraries needed to use OggVorbis
+#
+# OGG_LIBRARY - the Ogg library
+# OGG_INCLUDE_DIR - the Ogg include directory
+# VORBIS_LIBRARY - the Vorbis library
+# VORBIS_INCLUDE_DIR - the Vorbis include directory
+# VORBISFILE_LIBRARY - the VorbisFile library
+#
+# Copyright (c) 2006, Richard Laerkaeng <richard at goteborg.utfors.se>
+# Copyright (c) 2013, Vittorio Giovara <vittorio.giovara at gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+### sommer [SuperTux]
+## - Removed unused vorbisenc library
+## - reversed order of libraries, so that cmake 2.4.5 for Windows generates an MSYS Makefile that will link correctly
+
+### koda [Hedgewars]
+## - split ogg and vorbis lookup
+## - special case for framework handling
+## - standard variables handling
+
include (CheckLibraryExists)
-find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h)
+include (FindPackageHandleStandardArgs)
+
+find_path(OGG_INCLUDE_DIR ogg.h PATH_SUFFIXES ogg)
+find_path(VORBIS_INCLUDE_DIR vorbisfile.h PATH_SUFFIXES vorbis)
-find_library(OGG_LIBRARY NAMES ogg)
-find_library(VORBIS_LIBRARY NAMES vorbis)
+find_library(OGG_LIBRARY NAMES Ogg ogg)
+find_library(VORBIS_LIBRARY NAMES Vorbis vorbis)
find_library(VORBISFILE_LIBRARY NAMES vorbisfile)
-if(APPLE AND NOT VORBISFILE_LIBRARY)
-# [koda] (for Hedgewars) frameworks don't come with libvorbisfile
- set(VORBISFILE_LIBRARY "${VORBIS_LIBRARY}")
+
+set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES})
+set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OGGVORBIS_LIBRARIES})
+check_library_exists(${VORBIS_LIBRARY} vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2)
+set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP})
+
+if(HAVE_LIBVORBISENC2)
+ set(OGGVORBIS_VERSION 2)
+else(HAVE_LIBVORBISENC2)
+ set(OGGVORBIS_VERSION 1)
+endif(HAVE_LIBVORBISENC2)
+
+if(${OGG_LIBRARY} MATCHES ".framework" AND ${VORBIS_LIBRARY} MATCHES ".framework")
+ set(VORBISFILE_LIBRARY "") #vorbisfile will appear as NOTFOUND and discarded
+ set(fphsa_vorbis_list VORBIS_LIBRARY)
+else()
+ set(fphsa_vorbis_list VORBISFILE_LIBRARY VORBIS_LIBRARY)
endif()
-if (OGG_LIBRARY AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY)
- set(OGGVORBIS_FOUND TRUE)
-# [sommer] (for SuperTux) reversed order of libraries, so that cmake 2.4.5 for Windows generates an MSYS Makefile that will link correctly
-# set(OGGVORBIS_LIBRARIES ${OGG_LIBRARY} ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY})
- set(OGGVORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY})
- set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES})
- set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OGGVORBIS_LIBRARIES})
- check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2)
- set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP})
- if (HAVE_LIBVORBISENC2)
- set (OGGVORBIS_VERSION 2)
- else (HAVE_LIBVORBISENC2)
- set (OGGVORBIS_VERSION 1)
- endif (HAVE_LIBVORBISENC2)
-else ()
- set(OGGVORBIS_VERSION)
- set(OGGVORBIS_FOUND FALSE)
-endif ()
-if (OGGVORBIS_FOUND)
- if (NOT OggVorbis_FIND_QUIETLY)
- message(STATUS "Found OggVorbis: ${OGGVORBIS_LIBRARIES}")
- endif (NOT OggVorbis_FIND_QUIETLY)
-else (OGGVORBIS_FOUND)
- if (OggVorbis_FIND_REQUIRED)
- message(FATAL_ERROR "Could NOT find OggVorbis libraries")
- else (OggVorbis_FIND_REQUIRED)
- if (NOT OggVorbis_FIND_QUIETLY)
- message(STATUS "Could NOT find OggVorbis libraries")
- endif (NOT OggVorbis_FIND_QUIETLY)
- endif(OggVorbis_FIND_REQUIRED)
-endif (OGGVORBIS_FOUND)
+find_package_handle_standard_args(OggVorbis DEFAULT_MSG ${fphsa_vorbis_list} OGG_LIBRARY
+ OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR)
+unset(fphsa_vorbis_list)
+
+set(OGGVORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY})
+set(OGGVORBIS_INCLUDE_DIR ${VORBIS_INCLUDE_DIR} ${OGG_INCLUDE_DIR})
+
+mark_as_advanced(OGGVORBIS_VERSION OGGVORBIS_INCLUDE_DIR OGGVORBIS_LIBRARIES
+ OGG_LIBRARY OGG_INCLUDE_DIR VORBIS_LIBRARY VORBIS_INCLUDE_DIR VORBISFILE_LIBRARY)
diff --git a/cmake_modules/FindSDL_Extras.cmake b/cmake_modules/FindSDL_Extras.cmake
deleted file mode 100644
index f24d79d..0000000
--- a/cmake_modules/FindSDL_Extras.cmake
+++ /dev/null
@@ -1,36 +0,0 @@
-#if the headers are not installed, the newer apis won't be activated
-
-#find which version of SDL_mixer we have (for Mix_Init)
-find_file(sdlmixer_h SDL_mixer.h ${SDLMIXER_INCLUDE_DIR})
-if(sdlmixer_h)
- file(STRINGS ${sdlmixer_h} sdlmixer_majorversion_tmp REGEX "SDL_MIXER_MAJOR_VERSION[\t' ']+[0-9]+")
- file(STRINGS ${sdlmixer_h} sdlmixer_minorversion_tmp REGEX "SDL_MIXER_MINOR_VERSION[\t' ']+[0-9]+")
- file(STRINGS ${sdlmixer_h} sdlmixer_patchversion_tmp REGEX "SDL_MIXER_PATCHLEVEL[\t' ']+[0-9]+")
- string(REGEX MATCH ".([0-9]+)" sdlmixer_majorversion "${sdlmixer_majorversion_tmp}")
- string(REGEX MATCH ".([0-9]+)" sdlmixer_minorversion "${sdlmixer_minorversion_tmp}")
- string(REGEX MATCH ".([0-9]+)" sdlmixer_patchversion "${sdlmixer_patchversion_tmp}")
- math(EXPR sdlmixer_version "${sdlmixer_majorversion}*10000 + ${sdlmixer_minorversion}*100 + ${sdlmixer_patchversion}")
-
- if(sdlmixer_version GREATER "10209")
- message(STATUS "Mix_Init() is present")
- set(pascal_flags "-dSDL_MIXER_NEWER" ${pascal_flags})
- endif()
-endif()
-
-#find which version of SDL_image we have (for IMG_Init)
-find_file(sdlimage_h SDL_image.h ${SDLIMAGE_INCLUDE_DIR})
-if(sdlimage_h)
- file(STRINGS ${sdlimage_h} sdlimage_majorversion_tmp REGEX "SDL_IMAGE_MAJOR_VERSION[\t' ']+[0-9]+")
- file(STRINGS ${sdlimage_h} sdlimage_minorversion_tmp REGEX "SDL_IMAGE_MINOR_VERSION[\t' ']+[0-9]+")
- file(STRINGS ${sdlimage_h} sdlimage_patchversion_tmp REGEX "SDL_IMAGE_PATCHLEVEL[\t' ']+[0-9]+")
- string(REGEX MATCH ".([0-9]+)" sdlimage_majorversion "${sdlimage_majorversion_tmp}")
- string(REGEX MATCH ".([0-9]+)" sdlimage_minorversion "${sdlimage_minorversion_tmp}")
- string(REGEX MATCH ".([0-9]+)" sdlimage_patchversion "${sdlimage_patchversion_tmp}")
- math(EXPR sdlimage_version "${sdlimage_majorversion}*10000 + ${sdlimage_minorversion}*100 + ${sdlimage_patchversion}")
-
- if(sdlimage_version GREATER "010207")
- message(STATUS "IMG_Init() is present")
- set(pascal_flags "-dSDL_IMAGE_NEWER" ${pascal_flags})
- endif()
-endif()
-
diff --git a/cmake_modules/FindSparkle.cmake b/cmake_modules/FindSparkle.cmake
index f79eabe..2c1e194 100644
--- a/cmake_modules/FindSparkle.cmake
+++ b/cmake_modules/FindSparkle.cmake
@@ -1,39 +1,23 @@
-### Hedgewars
-
-# - Try to find the Sparkle framework
-# Once done this will define
+# Find Sparkle.framework
#
+# Once done this will define
# SPARKLE_FOUND - system has Sparkle
# SPARKLE_INCLUDE_DIR - the Sparkle include directory
# SPARKLE_LIBRARY - The library needed to use Sparkle
-# Copyright (c) 2009, Vittorio Giovara, <vittorio.giovara at gmail.com>
+# Copyright (c) 2009, Vittorio Giovara <vittorio.giovara at gmail.com>
#
-# Redistribution and use is allowed according to the terms of a Creative Commons license.
-# For details see http://creativecommons.org/licenses/by-sa/3.0/
-# original version of this module was derived from Richard Laerkaeng, <richard at goteborg.utfors.se>
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+include(FindPackageHandleStandardArgs)
-include (CheckLibraryExists)
find_path(SPARKLE_INCLUDE_DIR Sparkle.h)
find_library(SPARKLE_LIBRARY NAMES Sparkle)
-if (SPARKLE_INCLUDE_DIR AND SPARKLE_LIBRARY)
- set(SPARKLE_FOUND TRUE)
-else ()
- set(SPARKLE_FOUND FALSE)
-endif ()
-
-if (SPARKLE_FOUND)
- if (NOT SPARKLE_FIND_QUIETLY)
- message(STATUS "Found Sparkle: ${SPARKLE_LIBRARY}")
- endif ()
-else ()
- if (SPARKLE_FIND_REQUIRED)
- message(FATAL_ERROR "Could NOT find Sparkle framework")
- else ()
- if (NOT SPARKLE_FIND_QUIETLY)
- message(STATUS "Could NOT find Sparkle framework, autoupdate feature will be disabled")
- endif()
- endif ()
-endif ()
+find_package_handle_standard_args(Sparkle DEFAULT_MSG SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY)
+mark_as_advanced(SPARKLE_INCLUDE_DIR SPARKLE_LIBRARY)
diff --git a/cmake_modules/utils.cmake b/cmake_modules/utils.cmake
new file mode 100644
index 0000000..819efd7
--- /dev/null
+++ b/cmake_modules/utils.cmake
@@ -0,0 +1,30 @@
+
+macro(find_package_or_fail _PKG_NAME)
+ find_package(${_PKG_NAME})
+ string(TOUPPER ${_PKG_NAME} _PKG_NAME_UP)
+ if(NOT ${_PKG_NAME_UP}_FOUND)
+ message(SEND_ERROR "Missing ${_PKG_NAME}! Please install it and rerun cmake.")
+ endif(NOT ${_PKG_NAME_UP}_FOUND)
+endmacro(find_package_or_fail _PKG_NAME)
+
+macro(find_package_or_disable _PKG_NAME _VAR_NAME)
+ find_package(${_PKG_NAME})
+ string(TOUPPER ${_PKG_NAME} _PKG_NAME_UP)
+ if(NOT ${_PKG_NAME_UP}_FOUND)
+ message(SEND_ERROR "Missing ${_PKG_NAME}! Rerun cmake with -D${_VAR_NAME}=1 to build without it.")
+ endif(NOT ${_PKG_NAME_UP}_FOUND)
+endmacro(find_package_or_disable _PKG_NAME _VAR_NAME)
+
+macro(find_package_or_disable_msg _PKG_NAME _VAR_NAME _MSG)
+ if(NOT ${_VAR_NAME})
+ find_package_or_disable(${_PKG_NAME} ${_VAR_NAME})
+ else(NOT ${_VAR_NAME})
+ message(STATUS "${_PKG_NAME} disabled. ${_MSG}")
+ string(TOUPPER ${_PKG_NAME} _PKG_NAME_UP)
+ set(${_PKG_NAME_UP}_FOUND false)
+ endif(NOT ${_VAR_NAME})
+endmacro(find_package_or_disable_msg _PKG_NAME _VAR_NAME _MSG)
+
+
+#TODO: find_package_or_bundle
+
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index ca93144..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,595 +0,0 @@
-hedgewars (0.9.18-1) unstable; urgency=low
-
- [ Gianfranco Costamagna ]
- * Added myself and unera to uploaders, with unera's permission.
- * Added Debian Games Team to Maintainer and removed from uploaders.
- * Bumped compat version to 9.
- * Added some deps and build-deps on control file.
- * Removed some check in control file (higher versions
- already in oldstable)
- * Enabled hardening flags.
- * Fixed armhf and powerpc build failure with libc 2.17
- with Felix Geyer's help. (LP: #1179850)
-
- [ Felix Geyer ]
- * Drop build-dependency on libghc-binary-dev and libghc-deepseq-dev as
- they are just virtual packages provided by ghc.
-
- -- Gianfranco Costamagna <costamagnagianfranco at yahoo.it> Fri, 03 May 2013 10:31:44 +0200
-
-hedgewars (0.9.18-0.3) experimental; urgency=low
-
- * Non-maintainer upload.
-
- [ Felix Geyer ]
- * Add missing dependency on freeglut3. (LP: #1171825)
-
- [ Colin Watson ]
- * Build-depend on ghc and libghc-* rather than the transitional ghc6 and
- libghc6-*. (Closes: #705125)
-
- [ Gianfranco Costamagna ]
- * Updated debian/rules file, the SERVER disable string has changed.
-
- -- Felix Geyer <fgeyer at debian.org> Thu, 02 May 2013 17:55:31 +0200
-
-hedgewars (0.9.18-0.2) experimental; urgency=low
-
- * Non-maintainer upload
- * Added patch from upstream to fix a FTBFS with haskell 7.6
-
- -- Gianfranco Costamagna <costamagnagianfranco at yahoo.it> Thu, 21 Feb 2013 17:26:19 +0100
-
-hedgewars (0.9.18-0.1) experimental; urgency=low
-
- * Non-maintainer upload
- * New upstream version (Closes: #691986 LP: #1073730)
- + Built using the -3 upstream tarball hedgewars-src-0.9.18-3.tar.bz2
- * Bumped standards version to 3.9.4
- * Added some external build-dependencies
-
- -- Gianfranco Costamagna <costamagnagianfranco at yahoo.it> Mon, 28 Jan 2013 15:45:14 +0100
-
-hedgewars (0.9.17-1) unstable; urgency=low
-
- * [Paul Wise]
- * Mention the homing bee in the package description (Closes: #577092)
- * Also install the hwengine desktop file (LP: #811770)
- * Depend on ttf-dejavu-core since it is smaller
- * Depend on ttf-wqy-zenhei instead of embedding a copy of it
- * [Dmitry E. Oboukhov]
- * New upstream version.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Sun, 20 Nov 2011 18:31:17 +0400
-
-hedgewars (0.9.16-1) unstable; urgency=low
-
- * New upstream version.
- + Downloadable content! Simply click to install any content.
- New voices, hats, maps, themes, translations, music, scripts...
- Hedgewars is now more customisable than ever before! As time goes
- by we will be soliciting community content to feature on this page,
- so remember to check it from time to time. If you decide you want
- to go back to standard Hedgewars, just remove the Data directory
- from your Hedgewars config directory.
- + 3-D rendering! Diorama-like rendering of the game in a variety
- of 3D modes. Let us know which ones work best for you, we didn't
- really have the equipment to test them all.
- + Resizable game window.
- + New utilities! The Time Box will remove one of your hedgehogs
- from the game for a while, protecting from attack until it returns,
- somewhere else on the map. Land spray will allow you to build bridges,
- seal up holes, or just make life unpleasant for your enemies.
- + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
- the Tree and multi-player: The Specialists, Space Invaders,
- Racer - scripts! And a ton more script hooks for scripters
- + New twists on old weapons. Drill strike, seduction and fire have
- been adjusted. Defective mines have been added, rope can attach to
- hogs/crates/barrels again, grenades now have variable bounce (use
- precise key + 1-5). Portal gun is now more usable in flight and
- all game actions are a lot faster.
- + New theme - Golf, dozens of new community hats and a new
- localised Default voice, Ukranian.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Fri, 23 Sep 2011 10:16:55 +0400
-
-hedgewars (0.9.15-4) unstable; urgency=low
-
- * Exclude buggy icnsutils from B-D.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Thu, 07 Jul 2011 17:23:34 +0400
-
-hedgewars (0.9.15-3) unstable; urgency=low
-
- * Fixed hicolor icons path.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Wed, 06 Jul 2011 11:25:45 +0400
-
-hedgewars (0.9.15-2) unstable; urgency=low
-
- * Fixed depends (FTBFS, closes: #629778), closed fake bug (closes: #631152).
- * Bump Standards-Version to 3.9.2.
- * Install hicolor icons, closes: #621792,
- thanks to Kees Cook <kees at debian.org>.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 05 Jul 2011 17:35:56 +0400
-
-hedgewars (0.9.15-1) unstable; urgency=low
-
- * New upstream version.
- + Ability to create, save and load hand drawn maps
- + New maps: Capture the Flag (Blizzard) Map
- + New themes: Christmas
- + Snowflakes on Christmas/Snow themes accumulates on the ground
- + New game modifiers: No wind, More wind
- + New missions: Dangerous ducklings, Diver, Spooky tree, Teamwork
- + New weapons: Mudball, Drill strike
- + Many more Lua hooks
- + Readytimer
- + Ability to edit seed
- + Ability to select gameplay scripts
- + New gameplay scripts: Capture the Flag, No jumping, Random weapon
- + New Lua unified translation framework
- + Code refactoring
- + Max teams upped to 8
- + Cosmetic enhancements to Napalm strike
- + Selecting a game scheme selects the corresponding weapon set
- + Dust when drills dig
- + New hats: beaver, porkey, sheep
- + Add density property to Gears
- + Reworked management of schemes and weapon sets
- + Will ask before deleting teams, schemes and weapon sets
- + Explosions detach rope from land
- + Allow hog speech when not your turn
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 28 Dec 2010 23:29:54 +0300
-
-hedgewars (0.9.14.1-1) unstable; urgency=low
-
- * New upstream version.
- + New audio tracks
- + New forts: EvilChicken, Tank
- + New game modes: AI Survival Mode, Per Hedgehog Ammo,
- Reset Health, Reset Weapons, Unlimited Attacks
- + New grave: ring
- + Over 30 new hats
- + New themes: Art, Brick, Jungle, Stage
- + New maps: ShoppaKing, Sticks, TrophyRace (Mission)
- + New utilities: Portal Gun, Resurrector
- + New weapons: Flamethrower, Hammer, Old Limburger,
- Piano Strike, Sticky Mines
- + Weapons' projectiles will how be launched from their
- barrels instead of the hog's center
- + Flying Saucers may be used for moving below the water surface
- + New default game schemes: Clean Slate, Fort Mode, Timeless,
- Thinking with Portals, King Mode
- + New default weapon set: Clean Slate, Thinking with Portals
- + Bomb clusters/Melon parts inherit some of the original bomb's speed
- + Extended game statistics
- + Improved health bar updating
- + Hogs that blow themselves up will use triggers in they team color
- + Settings allow better control over the level of details/effects
- + Improved Lua support
- + On empty ammo switch to no weapon rather than the first available
- one (to avoid shooting by accident)
- + Display of hints in the frontend
- + Some improvements of existing Themes of Maps
- + Land destruction effects added
- + Improved fire effects
- + Improved Melon explosion effects
- + Online game lobby now features game filters
- + Other Frontend enhancements
- + Additional sounds
- + Show special game rules in Esc screen
- + Updated translation
- + Speed optimizations
- + Hedgewars will now use a sub directory of "My Documents"
- like other games instead of "%userprofile%/.hedgewars" under Windows
- + Added support for graphics cards/drivers that have a 512x512
- pixel textures limit
- + Team colors are more distinguishable from each other now
- * Fixed bug that allowed charging a weapon while on rope,
- leading to frozen timer
- * Various bug fixes
- * Switched to 3.0 source format.
- * Switched to cdbs build system.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Sun, 14 Nov 2010 22:45:48 +0300
-
-hedgewars (0.9.13-1) unstable; urgency=low
-
- * New upstream version, closes: #576370
- * many bug fixes
- * speed optimisations
- * many new hats, hats visible while using rope and blowtorch
- * Exploding barrels
- * AI uses new weapons, aware of fire, can fight in artillery mode
- * New options in ammo editing - crate probability, delays
- * option of semi-opaque hog name tags to avoid fail when
- land is hidden by name
- * new British voicepack
- * notification sound when people join your room
- * translation updates
- * contextual help when using weapons menu
- * 3d effect for waves
- * fade effect when starting/stopping game
- * new game modes - place hedgehog, king mode, randomise starts,
- allies share ammo, disable girders
- * shift + direction to turn without moving
- * view ammo menu when not your turn
- * new font for CJK text and better CJK detection
- * dud mines
- * hat reservation for donators (hats should be released to public
- in 6 months or so)
- * team flags
- * visual effects: dust on fall impact, smoke, shotgun shells,
- blink team name on start of turn, hogs pulling weapons out,
- falling flakes kicked by explosion and more
- * hogs react to throwing grenades / dynamite and when near them
- * graphic of crate contents when picking up weapon/utility
- * walk sound for hedgehogs
- * UFO changed to homing bee
- * splashes/droplets when things fall in the water
- * 45 degree bounce when throwing grenades
- * new bounce sounds
- * information on game rules when starting game
- * knockball map (scripted map)
- * Birdy weapon and poisoning effect
- * maze generator for new random maps
- * new crazy map template
- * new Olympics, Desert themes, visual updates to many other themes
- * Background texture for land for a 3d effect on explosions
- * frontend able to delete teams
- * ignore/friends lists in frontend
- * alt weapon preview on rope, parachute
- * updated options in frontend: independent toggles for
- frontend/game sound/music, select locale
- * More
- * lua scripting
- Lua scripting allows the easy creation of missions and special maps.
- Examples of this can be seen in the Knockball and Basketball maps,
- that are now scripted
-
- -- Dmitry E. Oboukhov <unera at debian.org> Mon, 05 Apr 2010 10:39:04 +0400
-
-hedgewars (0.9.12-2) unstable; urgency=low
-
- * fixes 'FTBFS: Error: Illegal parameter: -Nu', closes: #573694,
- thanks for Lucas Nussbaum <lucas at lucas-nussbaum.net>.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Mon, 15 Mar 2010 11:03:16 +0300
-
-hedgewars (0.9.12-1) unstable; urgency=low
-
- * New upstream version.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Sun, 18 Oct 2009 22:39:07 +0400
-
-hedgewars (0.9.11-5) unstable; urgency=low
-
- * Icon for .desktop file has been installed, too, closes: #540235,
- thanks for Andrew SB <a.starr.b at gmail.com>.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Thu, 06 Aug 2009 22:38:40 +0400
-
-hedgewars (0.9.11-4) unstable; urgency=low
-
- * Fixed FTBFS: added absent build-depends.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Wed, 05 Aug 2009 12:02:26 +0400
-
-hedgewars (0.9.11-3) unstable; urgency=low
-
- * Turned on network/server features (server was patched for buildling by
- new haskell-compiler).
-
- -- Dmitry E. Oboukhov <unera at debian.org> Wed, 05 Aug 2009 10:44:23 +0400
-
-hedgewars (0.9.11-2) unstable; urgency=low
-
- * Added Debian Games Team <pkg-games-devel at lists.alioth.debian.org>
- to uploaders list.
- * debian/copyright has been updated (added section about fonts).
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 07 Jul 2009 15:38:33 +0400
-
-hedgewars (0.9.11-1) unstable; urgency=low
-
- * New upstream version, closes: #526975, #532851.
- * Now upstream contains .desktop entry, closes: #512842.
- * Debian hasn't haskell libraries it need, so we temporary turned off
- the network features.
- * Fixed all the warnings of dpkg-shlibdeps.
- * Standards-Version bumped to 3.8.2.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 07 Jul 2009 12:52:36 +0400
-
-hedgewars (0.9.9-2) unstable; urgency=low
-
- * Added VCS-* records to debian/control.
- * GIT-repo has been created in git.debian.org.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Sun, 01 Feb 2009 23:25:04 +0300
-
-hedgewars (0.9.9-1) unstable; urgency=low
-
- * New upstream (and bugfix) release, closes: #511558
- * Voicepacks, customize your teams voice!
- * Nice new visual statistics page after the match
- * Precise aiming, hold shift to aim more accurately
- * Improved lobby chat
- * Remote Control Plane weapon
- * A couple of additions to customization content,
- (i.e. grave / fort / hat content)
- * Additional sound effects
- * Various tweaks and bug fixes
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 20 Jan 2009 20:19:13 +0300
-
-hedgewars (0.9.8-1) unstable; urgency=low
-
- * New upstream release, upstream changes:
- * Massive number of network play bugfixes
- * Now spectating works for those who joined after game start
- * New Drill rocket weapon
- * New Napalm strike weapon
- * New Super awesome super weapon
- * Land can now be set to be indestructable
- * Six brand new maps using new themes
- * Lots of new forts
- * Hellish hand grenade reworked
- * Brand new server lobby
- * Lobby chat
- * Spread of Melon Bomb fragments improved
- * Blowtorch bug fixes and improvements
- * Fixed a crash bug that occured when the engine had no room to
- place all Hedgehogs
- * More delay after jump, less delay after small fall for hedgehog
- * Limit max chat message length to 300 characters
- * Ammo menu no longer closes when user clicks on not yet available weapon
- * Ammo scheme bug fixes
- * Fire effect improved
-
- -- Dmitry E. Oboukhov <unera at debian.org> Fri, 09 Jan 2009 22:40:13 +0300
-
-hedgewars (0.9.7-3) unstable; urgency=low
-
- * Recompiled with enable server options.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 04 Nov 2008 21:31:43 +0300
-
-hedgewars (0.9.7-2) unstable; urgency=low
-
- * DejaVuSans-Bold.ttf has been replaced by symlink.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 04 Nov 2008 21:31:40 +0300
-
-hedgewars (0.9.7-1) unstable; urgency=low
-
- * New upstream release, upstream changes:
- * A completely redesigned, redrawn frontend, built to be both
- prettier and easier to use.
- * Completely reworked netplay, supports players joining and
- leaving games in progress
- * Admin controls for network play
- * A new, official central dedicated server, allowing mutiple
- "rooms" per server, a multiplayer lobby for matchmaking
- * The ability to customize your team in exciting new ways,
- including the ability to customize the visual look of your
- hedgehogs
- * New maps, themes, and graphics, a huge addition to content
- * New weapons, gameplay mechanics and game options. New super
- weapons that you will find only in crates
- * New working flames that damage hedgehogs and corrode the
- terrain
- * New sounds, music and media
- * Atmostrophic's chat border
-
- -- Dmitry E. Oboukhov <unera at debian.org> Mon, 03 Nov 2008 13:18:28 +0300
-
-hedgewars (0.9.6-1) unstable; urgency=low
-
- * New upstream release, closes: #492953.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Wed, 30 Jul 2008 11:03:46 +0400
-
-hedgewars (0.9.5-2) unstable; urgency=low
-
- * Fix typo in german translation,
- thanks for Michael Vogt, closes: #492859.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Tue, 29 Jul 2008 17:04:59 +0400
-
-hedgewars (0.9.5-1) unstable; urgency=low
-
- * New upstream release.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Thu, 10 Jul 2008 21:18:26 +0400
-
-hedgewars (0.9.4-2) unstable; urgency=low
-
- * Switching between fullscreen and window mode has been restored,
- closes: #489011.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Fri, 04 Jul 2008 22:40:37 +0400
-
-hedgewars (0.9.4-1) unstable; urgency=low
-
- * New upstream release, closes: #483813.
- * Standards-Version bumped to 3.8.0.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Thu, 19 Jun 2008 16:10:12 +0400
-
-hedgewars (0.9.3-3~bpo40+1) etch-backports; urgency=low
-
- * Rebuilt for etch.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Wed, 11 Jun 2008 18:01:53 +0400
-
-hedgewars (0.9.3-3) unstable; urgency=low
-
- * My email address has been changed.
-
- -- Dmitry E. Oboukhov <unera at debian.org> Fri, 30 May 2008 08:00:33 +0400
-
-hedgewars (0.9.3-2) unstable; urgency=low
-
- * Fix depends on hedgewars-data (0.9.3).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 18 May 2008 19:49:13 +0400
-
-hedgewars (0.9.3-1) unstable; urgency=low
-
- * New upstream release, closes: #476190 (To easy win).
- * Removed unnecessary build-depends.
- * Added fp-units-gfx to build-depends.
- * Upload sponsored by Al Nikolov <clown at debian.org>.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Tue, 29 Apr 2008 16:26:09 +0400
-
-hedgewars (0.9.2-2) unstable; urgency=low
-
- * Fix FTBFS make configure-stamp (added libxrandr-dev, libfontconfig1-dev,
- libxi-dev, libsm-dev, libice-dev to build-depends), closes: #477012.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 20 Apr 2008 20:01:42 +0400
-
-hedgewars (0.9.2-1) unstable; urgency=low
-
- * New upstream version (closes: #420431, #420418).
- * Standards-Version bumped to 3.7.3.
- * Move menu item to Games/Action (closes lintian warning).
- * Added debian/watch file.
- * Updated packaging, now using tar-in-tar approach.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Tue, 22 Jan 2008 17:34:31 +0300
-
-hedgewars (0.9.0-7) unstable; urgency=low
-
- * Apply patch for gcc4.3, thanks Martin Michlmayr <tbm at cyrius.com>
- (closes: #421216).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Fri, 27 Apr 2007 22:50:36 +0400
-
-hedgewars (0.9.0-6) unstable; urgency=low
-
- * Disable debug mode (closes: #415606).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Fri, 16 Mar 2007 19:13:05 +0300
-
-hedgewars (0.9.0-5) unstable; urgency=low
-
- * Apply new_team_warnings_cmake.patch (closes: #415004):
- - new team in multiplayer and net game fix - new team is now
- correctly added to widgets;
- - Fix most of the warnings in hwengine;
- - Use right way of finding and using Qt4 in CMake.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Thu, 15 Mar 2007 15:18:19 +0300
-
-hedgewars (0.9.0-4) unstable; urgency=low
-
- * Add dpatch mechanizm.
- * Apply 'http://hedgewars.org/download/new_team_readme_angle.patch'
- pacth.
- * Remove one 'make install' from debian/rules.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 25 Feb 2007 19:54:29 +0300
-
-hedgewars (0.9.0-3) unstable; urgency=low
-
- * Add "Recommends" record into debian/control (for hedgewars-data package).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sat, 24 Feb 2007 23:31:56 +0300
-
-hedgewars (0.9.0-2) unstable; urgency=low
-
- * Fix 'Messes with the mouse in other desktops' bug (closes: #405875).
- * Record about tools/runhelper.dpr is removed from debian/copyright.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sat, 24 Feb 2007 12:55:19 +0300
-
-hedgewars (0.9.0-1) UNRELEASE; urgency=low
-
- * New upstream version.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sat, 24 Feb 2007 12:21:08 +0300
-
-hedgewars (0.8.2+trunk20070223) UNRELEASE; urgency=low
-
- * Trunk version.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Fri, 23 Feb 2007 16:18:53 +0300
-
-hedgewars (0.8.1-11) unstable; urgency=low
-
- * Split into two packages: hedgewars and hedgewars-data (closes: #406129).
- * Remove build-depend libsdl-net1.2 (>= 1.2.5-4).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Wed, 21 Feb 2007 23:09:19 +0300
-
-hedgewars (0.8.1-10) unstable; urgency=low
-
- * Set build depends for libsdl-net1.2 to >= 1.2.5-4,
- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=217221.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Mon, 19 Feb 2007 22:17:46 +0300
-
-hedgewars (0.8.1-9) unstable; urgency=low
-
- * Fixed debian/copyright (added copyright from tools/runhelper.dpr file).
- * Removed file 'Fonts_LICENSE.txt' from orig.tar.gz (font was removed in
- revision 0.8.1-5).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Thu, 28 Dec 2006 18:03:25 +0300
-
-hedgewars (0.8.1-8) unstable; urgency=low
-
- * Removed lintian and linda overrides.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 17 Dec 2006 20:52:10 +0300
-
-hedgewars (0.8.1-7) unstable; urgency=low
-
- * Add 'debian/README.Debian-sources' file (diff -ur hedgewars-0.8.1.orig
- hedgewars-0.8.1).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 17 Dec 2006 12:07:59 +0300
-
-hedgewars (0.8.1-6) unstable; urgency=low
-
- * For upload (Closes: #401790).
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Wed, 6 Dec 2006 01:14:08 +0300
-
-hedgewars (0.8.1-5) unstable; urgency=low
-
- * Remove DejaVuSans.ttf from orig.tar.gz.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Mon, 4 Dec 2006 00:10:10 +0300
-
-hedgewars (0.8.1-4) unstable; urgency=low
-
- * Move exec-files into /usr/games.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 3 Dec 2006 21:25:32 +0300
-
-hedgewars (0.8.1-3) unstable; urgency=low
-
- * Fix (or overrides) all linda/lintianwarnings.
- * Add depends: 'ttf-dejavu'.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Sun, 3 Dec 2006 16:41:32 +0300
-
-hedgewars (0.8.1-2) unstable; urgency=low
-
- * Add menu item.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Tue, 28 Nov 2006 20:57:06 +0300
-
-hedgewars (0.8.1-1) unstable; urgency=low
-
- * Initial release.
-
- -- Dmitry E. Oboukhov <dimka at avanto.org> Mon, 27 Nov 2006 13:58:41 +0300
-
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index eae2f74..0000000
--- a/debian/control
+++ /dev/null
@@ -1,83 +0,0 @@
-Source: hedgewars
-Section: games
-Priority: extra
-Maintainer: Debian Games Team <pkg-games-devel at lists.alioth.debian.org>
-Uploaders: Dmitry E. Oboukhov <unera at debian.org>,
- Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
-Build-Depends: debhelper (>= 9), cmake, cdbs,
- libqt4-dev (>= 4.2),
- fp-compiler,
- libsdl1.2-dev,
- libsdl-ttf2.0-dev,
- libsdl-mixer1.2-dev,
- libsdl-image1.2-dev,
- libsdl-net1.2-dev,
- bzip2,
- fp-units-gfx,
- ghc,
- libghc-stm-dev,
- libghc-network-dev,
- libghc-dataenc-dev,
- libghc-hslogger-dev,
- libghc-utf8-string-dev,
- liblua5.1-dev,
- imagemagick,
- libghc-bytestring-show-dev,
- fpc,
- libpng12-dev,
- libavcodec-dev,
- libavformat-dev,
- freeglut3-dev,
- libghc-mtl-dev,
- libghc-parsec3-dev,
- libghc-vector-dev,
- qt4-qmake,
- dpkg-dev (>= 1.16.1~),
- fp-units-misc
-Standards-Version: 3.9.4
-Homepage: http://hedgewars.org
-VCS-Browser: http://git.debian.org/?p=collab-maint/hedgewars.git;a=summary
-VCS-Git: git://git.debian.org/collab-maint/hedgewars.git
-
-Package: hedgewars
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends},
- ttf-dejavu-core,
- ttf-wqy-zenhei,
- freeglut3,
- hedgewars-data (>= ${source:Upstream-Version})
-Description: Worms style game
- Each player controls a team of several hedgehogs. During the
- course of the game, players take turns with one of their
- hedgehogs. They then use whatever tools and weapons are
- available to attack and kill the opponents' hedgehogs, thereby
- winning the game. Hedgehogs may move around the terrain in a
- variety of ways, normally by walking and jumping but also by
- using particular tools such as the "Rope" or "Parachute", to
- move to otherwise inaccessible areas. Each turn is time-limited
- to ensure that players do not hold up the game with excessive
- thinking or moving.
- .
- A large variety of tools and weapons are available for players
- during the game: Grenade, Cluster Bomb, Bazooka, UFO, Homing Bee,
- Shotgun, Desert Eagle, Fire Punch, Baseball Bat, Dynamite, Mine,
- Rope, Pneumatic pick, Parachute. Most weapons, when used, cause
- explosions that deform the terrain, removing circular chunks.
- The landscape is an island floating on a body of water, or a
- restricted cave with water at the bottom. A hedgehog dies when
- it enters the water (either by falling off the island, or
- through a hole in the bottom of it), it is thrown off either
- side of the arena or when its health is reduced, typically from
- contact with explosions, to zero (the damage dealt to the
- attacked hedgehog or hedgehogs after a player's or CPU turn is
- shown only when all movement on the battlefield has ceased).
-
-Package: hedgewars-data
-Conflicts: hedgewars (<= 0.8.1-10)
-Replaces: hedgewars (<= 0.8.1-10)
-Architecture: all
-Depends: ${misc:Depends}
-Recommends: hedgewars
-Description: Data files for hedgewars
- This package contains data files (images, sounds, levels data)
- for the hedgewars package.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 687f05d..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,63 +0,0 @@
-This package was debianized by Dmitry E. Oboukhov <dimka at avanto.org> on
-Mon, 27 Nov 2006 13:58:41 +0300.
-
-It was downloaded from:
- http://hedgewars.org/
-
-Upstream Author:
- Andrey Korotaev <unC0Rr at gmail.com>
- Igor Ulyanov aka Displacer <iulyanov at gmail.com>
-
-
-Copyright:
- 2004-2008 Andrey Korotaev <unC0Rr at gmail.com>
- 2006-2008 Igor Ulyanov aka Displacer <iulyanov at gmail.com>
-
-
- Images in Data/Front, Data/Graphics/Graves,
- themes "ethereal", "norsk", "wood", "xtheme":
- Copyright 2005 Alexey Andreev <grayfox at inbox.ru>
-
- images in Data/Graphics,
- sounds in Data/Sounds,
- themes "avematan", "bubbles", "tibet"
- Copyright 2004, 2005, 2006 Andrey Korotaev <unC0Rr at gmail.com>
-
- Map and theme "cheese":
- based on Wormux map "cheese" by Anthony Carré <yeknan AT yahoo DOT fr>
-
- Map and theme "Volcano":
- by Damion Brookes <nintendo_wii33 at hotmail.co.uk>
-
-License:
- This package 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 package 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 package; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
- Images and sounds are distributed under the terms of the
- GNU FDL licence.
-
-
-On Debian systems, the complete text of the GNU General
-Public License can be found in `/usr/share/common-licenses/GPL-2'.
-
-Data/Fonts/DroidSansFallback.ttf:
- Google Droid are (c) The Android Open Source Project under the
- terms of the Apache license (2.0). Google Droid changes are in
- public domain.
-On Debian systems, the complete text of the Apache License version 2.0
-can be found in `/usr/share/common-licenses/Apache-2.0'.
-
-The Debian packaging is (C) 2006, Dmitry E. Oboukhov <dimka at avanto.org> and
-is licensed under the GPL, see `/usr/share/common-licenses/GPL-2'.
-
diff --git a/debian/hedgewars-data.install b/debian/hedgewars-data.install
deleted file mode 100644
index a97eda2..0000000
--- a/debian/hedgewars-data.install
+++ /dev/null
@@ -1 +0,0 @@
-debian/tmp/usr/share/games/hedgewars /usr/share/games/
diff --git a/debian/hedgewars-data.links b/debian/hedgewars-data.links
deleted file mode 100644
index f973342..0000000
--- a/debian/hedgewars-data.links
+++ /dev/null
@@ -1,3 +0,0 @@
-/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf /usr/share/games/hedgewars/Data/Fonts/DejaVuSans.ttf
-/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf /usr/share/games/hedgewars/Data/Fonts/DejaVuSans-Bold.ttf
-/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc /usr/share/games/hedgewars/Data/Fonts/wqy-zenhei.ttc
diff --git a/debian/hedgewars.install b/debian/hedgewars.install
deleted file mode 100644
index 86c67d0..0000000
--- a/debian/hedgewars.install
+++ /dev/null
@@ -1,4 +0,0 @@
-debian/tmp/usr/lib/* /usr/lib/
-obj-*/share/hedgewars/Data/misc/hwengine.desktop /usr/share/games/hedgewars/Data/misc
-misc/hedgewars.desktop /usr/share/applications/
-tmp-icon/* /usr/share/icons/hicolor/
diff --git a/debian/hedgewars.links b/debian/hedgewars.links
deleted file mode 100644
index 41547b1..0000000
--- a/debian/hedgewars.links
+++ /dev/null
@@ -1 +0,0 @@
-/usr/lib/hedgewars/bin/hedgewars /usr/games/hedgewars
diff --git a/debian/hedgewars.manpages b/debian/hedgewars.manpages
deleted file mode 100644
index 7da6ccd..0000000
--- a/debian/hedgewars.manpages
+++ /dev/null
@@ -1 +0,0 @@
-man/hedgewars.6
diff --git a/debian/hicolor-icons/128x128/hedgewars.xpm b/debian/hicolor-icons/128x128/hedgewars.xpm
deleted file mode 100644
index 6524c94..0000000
--- a/debian/hicolor-icons/128x128/hedgewars.xpm
+++ /dev/null
@@ -1,387 +0,0 @@
-/* XPM */
-static char *Icon____x___x__[] = {
-/* columns rows colors chars-per-pixel */
-"128 128 253 2",
-" c #010101",
-". c #0A0A0A",
-"X c #121212",
-"o c #181718",
-"O c #191819",
-"+ c #222121",
-"@ c #555655",
-"# c #585758",
-"$ c #656465",
-"% c #686768",
-"& c #696869",
-"* c #706F70",
-"= c #747374",
-"- c #797778",
-"; c #7F7E7F",
-": c #93005C",
-"> c #9A0066",
-", c #9D046A",
-"< c #9F096E",
-"1 c #9E0B71",
-"2 c #8E1A7E",
-"3 c #971277",
-"4 c #9A1176",
-"5 c #93157A",
-"6 c #9B1579",
-"7 c #92197D",
-"8 c #99197C",
-"9 c #A50065",
-"0 c #A90067",
-"q c #A4046B",
-"w c #A80168",
-"e c #A0096F",
-"r c #A10B71",
-"t c #A51176",
-"y c #A71479",
-"u c #A8167B",
-"i c #AA1B7E",
-"p c #7E2A8D",
-"a c #7A2F91",
-"s c #6C3C9C",
-"d c #753394",
-"f c #783192",
-"g c #723698",
-"h c #703899",
-"j c #5F48A7",
-"k c #5B4DAB",
-"l c #5751AF",
-"z c #4D59B6",
-"x c #4B5CB9",
-"c c #5354B2",
-"v c #515DBB",
-"b c #6443A3",
-"n c #6648A8",
-"m c #6E4AAA",
-"M c #6952B1",
-"N c #6559B7",
-"B c #7F55B1",
-"V c #7D59B5",
-"C c #7B5DBA",
-"Z c #4562BE",
-"A c #6161BF",
-"S c #7765BE",
-"D c #3D69C5",
-"F c #376FCA",
-"G c #396DC9",
-"H c #3373CE",
-"J c #3C73CF",
-"K c #2E77D1",
-"L c #277CD6",
-"P c #2B7BD5",
-"I c #277FD9",
-"U c #2B7ED8",
-"Y c #3076D0",
-"T c #307BD5",
-"R c #3F7CD7",
-"E c #307FD9",
-"W c #4264C1",
-"Q c #4B65C2",
-"! c #4E68C5",
-"~ c #496CC8",
-"^ c #5D69C6",
-"/ c #5971CD",
-"( c #5B76D2",
-") c #5C7AD4",
-"_ c #7667C1",
-"` c #7569C3",
-"' c #736EC8",
-"] c #6E78CF",
-"[ c #7173CC",
-"{ c #627AD4",
-"} c #6C7DD5",
-"| c #8B1E81",
-" . c #971D81",
-".. c #AD1D82",
-"X. c #852487",
-"o. c #892084",
-"O. c #822689",
-"+. c #84298C",
-"@. c #8E2B8D",
-"#. c #952284",
-"$. c #932588",
-"%. c #922A8B",
-"&. c #812F92",
-"*. c #8F2F91",
-"=. c #8D3394",
-"-. c #8A3B9B",
-";. c #AE2284",
-":. c #B02687",
-">. c #B12589",
-",. c #B42B8C",
-"<. c #B6318E",
-"1. c #B72E92",
-"2. c #B82F94",
-"3. c #B63290",
-"4. c #B93395",
-"5. c #BC3B97",
-"6. c #BC359A",
-"7. c #BD3B9B",
-"8. c #C03B9F",
-"9. c #C13EA2",
-"0. c #BF419C",
-"q. c #8644A2",
-"w. c #8449A6",
-"e. c #824DAA",
-"r. c #C0429E",
-"t. c #C342A4",
-"y. c #C54BA4",
-"u. c #C646A9",
-"i. c #C748AC",
-"p. c #C94AAE",
-"a. c #CA53AC",
-"s. c #CB58AE",
-"d. c #CB4EB1",
-"f. c #CE52B5",
-"g. c #CF5CB3",
-"h. c #D055B7",
-"j. c #D05EB5",
-"k. c #D157BA",
-"l. c #D35BBD",
-"z. c #C465A5",
-"x. c #D161B6",
-"c. c #D465BB",
-"v. c #D66ABE",
-"b. c #D86BBF",
-"n. c #D55EC0",
-"m. c #D760C3",
-"M. c #D863C5",
-"N. c #D76CC0",
-"B. c #D96DC2",
-"V. c #DA66C9",
-"C. c #DE6CCE",
-"Z. c #DB73C5",
-"A. c #DE75CA",
-"S. c #DF78C9",
-"D. c #DF6ED0",
-"F. c #E076CE",
-"G. c #E17CCD",
-"H. c #E06FD1",
-"J. c #E273D4",
-"K. c #E479D6",
-"L. c #E576D8",
-"P. c #E67CD9",
-"I. c #E87EDD",
-"U. c #EA7EE0",
-"Y. c #1F87DF",
-"T. c #2482DB",
-"R. c #2983DC",
-"E. c #3382DC",
-"W. c #1E87E0",
-"Q. c #1E89E1",
-"!. c #2F8AE3",
-"~. c #3786E0",
-"^. c #3689E2",
-"/. c #3B8AE3",
-"(. c #3C94ED",
-"). c #3B9CF4",
-"_. c #6A81D6",
-"`. c #6983DB",
-"'. c #408DE6",
-"]. c #4B8EE6",
-"[. c #418FE8",
-"{. c #4593EC",
-"}. c #4A94ED",
-"|. c #5496EE",
-" X c #4997F0",
-".X c #4C9BF4",
-"XX c #519EF6",
-"oX c #5E9CF2",
-"OX c #519FF8",
-"+X c #648CE2",
-"@X c #6293E6",
-"#X c #6293EA",
-"$X c #6098ED",
-"%X c #4AA4FC",
-"&X c #4DACFF",
-"*X c #5CA1F5",
-"=X c #54A3FB",
-"-X c #59A7FF",
-";X c #56ACFF",
-":X c #5AA8FF",
-">X c #54B2FF",
-",X c #838283",
-"<X c #888787",
-"1X c #898889",
-"2X c #908F90",
-"3X c #929192",
-"4X c #9D9C9D",
-"5X c #A09FA0",
-"6X c #A5A4A5",
-"7X c #ABAAAB",
-"8X c #B5B3B5",
-"9X c #BAB9B9",
-"0X c #E584D4",
-"qX c #E788D7",
-"wX c #E888D7",
-"eX c #E781DA",
-"rX c #E985DC",
-"tX c #EA8CDC",
-"yX c #ED91DE",
-"uX c #EC87E1",
-"iX c #ED8EE1",
-"pX c #EE92E2",
-"aX c #F196E5",
-"sX c #F39BE7",
-"dX c #F397E8",
-"fX c #F49EE9",
-"gX c #F6A1EB",
-"hX c #F8A5EF",
-"jX c #F5AAEC",
-"kX c #F7B4EE",
-"lX c #F7BAEF",
-"zX c #F9A6F0",
-"xX c #FAA9F2",
-"cX c #F7BCF0",
-"vX c #F9BDF2",
-"bX c #CBCACB",
-"nX c #D0CFD0",
-"mX c #DBDADB",
-"MX c #F8C5F2",
-"NX c #F9CAF3",
-"BX c #FECBF9",
-"VX c #FAD4F5",
-"CX c #FBDCF7",
-"ZX c #FED3FA",
-"AX c #FBDEF8",
-"SX c #E5E4E5",
-"DX c #ECEBEC",
-"FX c #FCE3F9",
-"GX c #FDECFB",
-"HX c #F4F3F4",
-"JX c #FEF4FD",
-"KX c #FFFFFF",
-"LX c None",
-/* pixels */
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 w e 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < e d 5 w < 1 r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 0 Z K p w e 1 < e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r w z T.T.c 1 0 1 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 e x T.K T.H a w q 1 < < LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e w x T.P P I T.z 3 w 1 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 e Z T.K P P K T.H d 0 e 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e W I P P P P P P T.z 3 0 1 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e D I P P {./.P K P T.Y d w q 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < D I K U .X-X{.E P P P T.z 5 0 e 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 G I P U .X:X:XXX^.P P P T.K g q q r e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 F U P E XX:X-X:X-X{.E.P K U T.x 5 0 1 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 3 H U P U .X:X;X-X-X:X=X/.P P P T.K h q q 1 < e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 H P P E.=X:X-X-X-X-X;X-X{.E P P U T.x 7 0 < 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 3 Y I P P =X-X-X-X-X-X-X-X:XOX/.P P P T.P s e q 1 e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe q 3 K P P R.=X-X-X-X-X-X-X-X-X:X-X{.E.P P P T.Z | 0 e 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX1 q 5 K P L E =X-X-X;X-X-X-X-X-X-X:X:X=X/.P P K T.P b e w 1 e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX1 q 7 K P P E.=X-X-X-X-X-X-X:X-X-X-X-X:X-X{.E.L P P T.W o.w e 1 e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 q 2 P P L E.=X:X-X-X-X-X-X-X-X-X-X-X:X-X:XOX/.P P K T.I b e w 1 e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r q 2 P P P E.=X:X-X-X-X-X-X-X-X-X-X-X-X-X-X:X:X.XE.P K K T.W o.0 e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXe e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXr 1 w | P K K E.-X:X-X-X-X-X:X*X-X-X-X-X-X-X-X-X-X-X=X(.R.T.I Q.T.k 3 q e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe e e r r e e e e e e e e e < 1 e e LXLXLXLXLXLXLXLXLXLXLX< 1 w X.Q.T.T.!.=X;X:X:X:X-X-X-X-X-X-X-X-X:X>X>X>X:X*X at X( v c c l x n 3 e e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe e q q e q e e 1 1 1 1 1 1 1 1 e r 1 < e e e e e e e e e e < e 5 k c z ! `.oX*X*X:X;X;X>X>X>X>X>X;XoX} C -.$.6 e q q q w w w , 1 e e e e e e r LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXe e e 3 | 5 3 < e e w 0 0 0 0 w w w q q e e e 1 1 1 1 1 1 1 1 1 < e w w w q e 1 4 8 #. at .=.q.e._ _.V %.4 w 9 w q q r r < < < 1 1 1 e e r r r r e < e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXe e e 3 H P H F D Z x c k b s d p X.| 5 3 1 r q w w 0 w w w w w e e e , 1 1 r r , e q 9 9 w 9 9 w 9 q e < < , > > > , 1 1 r t t < , , > > , , e r r e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe 1 0 s T.P U I R.T.T.T.T.T.T.T.T.P P H F D W x c k b s d p X.| 7 3 1 r q q w 0 e < 1 1 1 1 4 e < , > < u <.y.g.B.0XqXtXwXyXwXqXK.Z.x.y.3.i e > , , e r e e r LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe e e 1 F I P P P P K P P P P P P P P U U I T.T.T.T.T.T.T.T.I P P H H G W z x l | e < 1 r < > > t 4.j.0XsXhXxXxXxXhXgXhXhXgXgXgXjXhXxXxXzXsXwXc.5.u > > < r e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXe 1 0 g T.K P P P P P P P P P P P P P P K P P K P P K P P P P P U P P T.Q.D +.< < r < > e 5.b.pXjXxXgXgXsXsXsXsXsXsXsXfXfXfXfXfXsXfXsXfXfXhXxXxXsXZ.0.t > , r r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXe e e < D I P P P P P P P P P P R.P P P P P P P P P P P L P P P P P T.H g w q r q > y a.wXxXxXgXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXsXfXxXxXyXg.i > , r e < e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 0 f T.K L P P P P P P P P P P P P P P P P P P P P P P P P P T.z 3 w r 1 > y g.sXxXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXsXjXzXgXc.;.> , r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 e ~ (./././.E.E.E.R.E P P P P P P P L P P L P P P P K L R.s w q 1 , e y.pXxXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXfXfXfXfXfXfXsXsXfXzXfXg.t > r r < e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 w &.%X:X-X-X-X-X=X=XXX.X.X.X{.{.{./././.^.E.E.R.E.P R.H o.0 r e > ,.0XxXjXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXxXyX5., , r r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r q / ;X-X-X-X-X:X:X:X:X:X:X:X:X:X-X-X-X-X=X=X=XXX%X) 4 w 4 , e g.hXjXaXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXxXN.t > r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 9 +.%X-X-X-X-X-X-X-X-X:X-X-X-X:X-X-X-X-X-X-X*X>X] e q r , i 0XxXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXsXgXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXsXxXyX,.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < 9 ^ ;X-X-X-X:X-X:X-X-X-X-X-X-X-X-X-X-X-X-X>X[ q e r > 3.sXjXaXgXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXgXsXfXgXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXgXy.> e r < LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX< 1 q X..X:X-X-X-X-X-X-X:X-X-X-X-X-X-X-X-X-X>X[ q e r > r.hXgXsXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXfXfXfXfXfXfXfXsXgXfXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXxXg., e r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r 9 ^ ;X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X>X_.q e r , t.fXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXxXv., e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 w 2 .X:X-X-X-X-X-X-X-X-X-X-X-X-X-X;X at X1 e e , 9.aXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXxXb., e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 0 N &X:X-X-X-X:X-X-X-X-X-X-X-X-X*X .q r > 7.eXaXfXfXfXfXfXfXfXfXgXfXfXgXfXfXfXfXfXfXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXsXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXxXc.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < e 5 }.-X-X-X-X-X-X-X-X-X-X:X>X>X-.9 r , 1.J.rXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXgXsXsXsXdXsXfXgXfXfXfXfXfXfXgXfXsXsXfXfXfXxXa.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r 9 M &X-X:X:X-X-X-X-X;X>XoX` $.q 1 , ..J.J.aXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXaXsXjXkXcXlXjXgXsXdXfXfXfXfXsXdXfXhXjXjXfXaXsXxX5.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e 3 }.:X-X-X-X:X>X;X`.w.6 9 q 1 < r V.H.eXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXMXFXKXKXKXKXKXJXCXkXfXsXfXsXjXVXJXKXKXKXGXNXfXsXgX;., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < 9 m &X-X;X>XoXS $.q 9 e 1 < r , f.J.H.iXgXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXgXfXfXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXdXkXJXKXKXKXKXKXKXKXKXKXKXFXkXaXkXJXKXKXKXKXKXKXKXJXlXfX0X, e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < e 1 ].;X_.q.3 9 q 1 e e e r , 1.L.D.J.sXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXfXfXfXfXfXgXfXfXdXcXKXKXKXKXKXKXKXKXKXKXKXKXKXKXVXKXKXKXKXKXKXKXKXKXKXKXVXzXg.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 q +. at .w 9 1 1 e 0 1 r e < t V.J.D.eXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXgXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXsXlXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXVXsX:., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 q q 1 1 w q | l s q r , u.L.D.H.tXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXfXfXfXsXfXfXgXfXgXsXgXsXfXfXsXjXJXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXZXA., e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < 1 1 q w 1 d x I P 3 q , ..J.J.D.J.aXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXsXgXfXgXaXAXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXvX6.> r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e e 1 e w q o.k H Y.T.T.b 0 1 , f.J.C.C.L.sXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXkXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXGXwXe < e e LXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r 1 e w w 3 g Z I T.P P P Y 5 e , ..J.D.H.D.eXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXCXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXHXKXKXKXKXKXKXBX7., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXe e r < e e 0 e X.l H T.R.P K P K T.c w 1 , d.L.H.H.D.rXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXgXJXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXJX0X, e e e LXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXe e e 1 1 e w w 5 s W I T.P P P P P P P T.O.w < u H.H.H.H.H.tXgXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXkXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKX8X$ $ 9XKXKXKXKXMX,., r < LXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXe e e < e e 0 r O.c Y T.T.P P P P P P P P T.D e e , 9.L.D.H.H.H.yXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXdXNXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKX@ $ KXKXKXFXm.> r e LXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXe e e 1 1 e w q 7 s D T.T.P P P P P P P P P U P T.j w 1 r n.J.D.D.H.J.aXgXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXCXKXKXKXKXKXKXKXKXKXKXKXKXKXbX; ,XbXKXKXKXKXKXKXKXKX= 1XKXKXJXpXu , r e LXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXe e e 1 r q 0 1 p c P T.T.K K P P P P U P P P P P P I O.q , ;.J.H.D.D.H.J.aXsXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXFXKXKXKXKXKXKXKXKXKXKXKXKX- = KXKXKXKXKXKXmX. O DXKXKXvXr.> r e LXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXe r e e w w 2 b F I T.P P P P U P P P P P P P P L P U R 3 e , t.L.H.D.J.J.J.sXgXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXsXFXKXKXKXKXKXKXKXKXKXKXKX1X 3XKXKXKXKXKX1X 7XKXKXNXB., r r LXLXLXLXLXLXLXLXLXLXLXLX",
-"LXe e 1 e 1 a x P T.I P P P P P P P P P P P P P P P E./.%X} 9 1 e l.J.D.D.J.D.J.aXsXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXsXfXfXfXfXfXfXfXfXfXsXFXKXKXKXKXKXKXKXKXKXKXDXO O DXKXKXKXKX$ ; KXKXNXtXt , r LXLXLXLXLXLXLXLXLXLXLXLX",
-"LXe 1 q | Y T.T.P K P P P P P P P P P P P P P U ^.{.=X-X>Xe.9 < y H.H.H.H.H.H.J.sXsXfXfXfXsXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXsXAXKXKXKXKXKXKXKXKXKXKX7X 7XKXKXKXKX@ * KXKXNXfX1., e e LXLXLXLXLXLXLXLXLXLXLX",
-"LXe < r e f H T.P P P P P P P P P P P P P E.[..X-X:X-X-X>X-.w , 1.J.H.H.H.H.H.J.sXgXgXsXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXVXKXKXKXKXKXKXKXKXHXKX= = KXHXKXKX% ; KXKXVXzXa.> r e LXLXLXLXLXLXLXLXLXLXLX",
-"LXLXe e e 0 5 W T.P P P P P P P L L P /.{.=X:X:X-X:X-X:X*X8 q , 9.L.H.H.H.H.H.J.aXgXsXgXfXsXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXdXNXKXKXKXKXKXKXKXKXKXKX$ $ KXKXKXKX4X 8XKXKXVXgXZ., e e LXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXe e 1 q q n T.L P P P L P E.{..X-X:X:X:X:X-X-X-X;X at Xe r , d.J.H.H.H.H.H.J.aXsXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXfXfXfXfXfXfXfXfXfXsXkXKXKXKXKXKXKXKXKXKXKX= = KXHXKXKXSXX + HXKXKXNXfX0Xe e e LXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXe e 1 e 0 p Y T.K P E. X=X:X;X-X-X-X-X-X-X-X-X>XB 9 1 1 n.J.D.H.H.H.D.J.yXgXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXJXKXKXKXKXKXKXKXKXKX4X 6XKXKXKXKXKX,X 4XKXKXKXcXdXsXy , r LXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXe e e < 9 3 ! ).=X:X:X:X-X:X-X-X-X-X-X-X-X>X_.q r e r V.J.H.H.H.H.H.H.tXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXsXAXKXKXKXKXKXKXKXKXKXSXX X SXKXKXKXKXKXKX= <XKXKXKXKXjXsXfX;., r e LXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXe < 1 q q C >X-X-X:X-X-X-X-X-X-X:X-X:XoX8 e r q u H.H.H.H.H.H.H.D.tXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXcXKXKXKXKXKXKXKXKXKXKX,X . ; KXKXKXKXKXKXKXKXbX,X,XbXKXKXKXKXGXsXfXhX3., r e LXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXe < e < 0 =.oX>X-X-X-X-X-X-X-X-X-X>X-.9 1 e , ..J.H.H.H.H.H.H.D.eXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXfXGXKXKXKXKXKXKXKXKXKXKX$ $ KXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXNXaXfXzX7.> r e e LXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXe e e 1 9 8 _.>X-X-X-X:X-X-X-X>XS w 1 e e , >.J.D.H.H.H.H.H.D.P.fXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXdXNXKXKXKXKXKXKXKXKXKXKXKX8X% $ 8XKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXJXgXfXfXhX0.> r < < e LXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXe r 1 q q V ;X-X-X:X:X-X;X`.< < < e r , >.J.H.H.H.H.H.H.H.J.sXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXGXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXlXsXgXsXxXy.> r < e r e e LXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe e 1 r 9 =.oX>X=X:X:X;X#.w 4 e 3 r , >.L.D.H.H.H.H.H.H.H.pXgXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXkXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXNXsXfXfXsXxXy.> r t , , r e e LXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < 9 4 } >X*X>Xw.9 r 0 b g q , >.J.D.H.H.H.H.H.H.D.rXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXNXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXHXGXKXKXKXKXKXKXJXMXsXfXfXfXfXxXy.> , :.b.< , r e LXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < 1 e w B >X[ 9 1 q | Y.d 9 , :.J.H.H.H.H.D.D.H.C.L.fXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXAXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXVXaXlXVXFXFXFXNXjXaXfXfXfXfXsXxXr.> , :.xXG.e e r e LXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < 1 r 9 *.6 , e 1 D !.g w , ..J.H.H.H.H.J.H.H.D.J.pXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXFXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXKXFXfXfXsXaXsXsXdXaXsXfXfXfXfXfXsXhX5., , <.gXxXZ., e e t LXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < q e 1 0 l T.T.b 0 , u D.D.H.D.H.H.H.H.H.D.rXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXCXKXKXKXKXKXKXKXKXKXKXKXKXKXKXGXgXsXfXfXgXfXfXfXgXgXgXfXfXfXfXsXhX<., , 5.xXaXxXy.> e r LXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < r < w d T.Y T.l 0 1 r V.J.H.H.H.H.H.H.H.D.L.sXgXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXdXcXJXKXKXKXKXKXKXKXKXKXKXKXAXgXfXfXfXfXfXfXfXfXxXa.A.hXsXfXfXfXgX;., , y.xXsXgXpXt , t > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < q 7 K P P T.x q < q n.J.D.H.H.D.H.H.H.H.H.pXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXgXaXgXNXJXKXKXKXKXKXKXKXGXcXsXfXfXfXfXfXfXfXfXxXx.: s.xXfXfXfXgXyXy < > x.xXsXfXxXy.> r > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e e Z T.P P U F 1 < , d.L.D.H.J.D.H.H.H.H.D.L.fXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXaXfXkXNXVXAXVXNXkXfXsXfXgXfXfXfXfXfXfXxXx., , G.hXfXfXfXhX0X< e , A.hXsXfXhXS., t > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e < 0 n Y.P P P P K 7 e , 8.L.C.D.H.H.H.H.H.H.H.A.tXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXdXdXsXsXdXsXfXgXfXfXfXfXfXsXhXhXa., > 5.hXsXfXfXfXxXb.> e r tXjXfXfXsXyXt e > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < w p T.P P P P P T.p q , ,.J.D.J.H.H.H.H.H.H.H.C.P.fXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXfXfXfXsXsXsXsXsXsXfXgXxXgX0X,.> , :.fXgXfXfXfXsXxXy.> , :.fXfXsXgXsXfX;.< > z.LX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 e 1 Y U P P P P P T.n w < y D.H.H.H.H.H.H.H.H.H.H.H.tXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXhXzXxXxXxXxXhXfXwXj.<., > > ,.aXgXfXgXsXgXsXhX,., > 0.xXfXfXfXfXfX;., > z.LX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe < 1 w x T.P P P P P P !.{ q 1 , k.J.D.H.H.H.H.H.H.H.H.H.L.sXgXfXfXfXfXfXfXfXfXfXfXfXgXfXfXgXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXG.a.a.a.s.y.5.;.e , , , , y.gXgXsXgXsXsXfXgXyXr e > c.xXsXfXfXfXfX..e > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 1 w s T.P P P U P P P .XoX6 e , 9.L.H.H.H.H.H.H.H.H.H.D.C.rXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXjXyXe > , , > > , , r , > ,.S.xXsXgXgXsXgXsXfXzXb.> r < 0XhXfXsXfXgXyXr e > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 q | P P P P P P P P /.-X>X-.9 , ..H.H.H.H.H.H.D.C.H.H.J.J.J.pXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXpXt , e e e , > , r 3.Z.jXzXaXfXfXsXgXsXgXfXxX5.> , ;.gXfXfXgXfXhXN.> t > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXe 1 < 1 D T.P P P P P P ^.=X-X>X_ 9 1 , n.J.D.D.H.J.L.L.J.D.V.C.C.L.gXxXhXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXjXb.u r r t ;.r.v.tXzXhXfXfXfXfXfXfXfXfXsXgXpXy < > y.xXfXsXsXiXuX3., t > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXe e 1 w k T.P P P P P P E..X:X-X:X$X1 r , 6.L.C.L.J.V.d.7.;.u y t u ..5.v.wXgXzXfXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXhXfXtXqXyXgXxXzXgXsXfXfXfXfXfXfXfXfXsXfXxXx.> r e B.aXtXI.J.J.n.r e < > LXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe e 1 w d T.P P U P P P P {.:X-X-X-X;X-.w 1 t D.J.i.>.r , , , e e e < , , > < :.g.sXxXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXaXgXjXgXgXfXsXfXsXgXfXfXfXfXgXsXfXfXsXfXjX,., < i J.H.D.D.H.L.,.> r r LXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXe < q 7 K U P P P P P P /.:X:X:X:X-X>X] 9 1 , 6.;., , r r , > > > > > , , e e , > u b.zXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXsXfXsXgXfXfXgXsXfXfXfXfXfXfXsXhXG., r > t.J.D.H.D.L.t., e < t LXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXe e e e Z T.K P P P P P E.=X:X:X-X-X-X:X:X#.q r , , e e > , ;.5.a.j.g.a.t.:.r > , t , > 5.sXhXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXgXfXfXsXgXfXfXfXsXfXfXfXfXfXfXfXhX4.> r r V.J.D.H.L.u., e e e LXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXe e 1 0 n T.P P P P P P U .X:X-X-X-X-X-X-X>XS w r r e > y s.0XfXzXxXxXxXxXxXhXwXx.;.> e r > ..yXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXsXgXfXgXfXfXfXfXfXfXhXG., r , 4.J.H.J.J.7., e r r LXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXe r w O.I P P P P P P P {.:X-X-X-X-X-X-X=X;X-.q r , e a.aXxXzXfXfXsXaXfXfXfXfXgXjXgXc.t > t > i pXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXfXsXsXsXfXfXfXfXgXfXfXfXfXfXgX,., < e V.L.H.h..., e e , LXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXe 1 e 3 H L P P P P P P /.-X:X-X-X-X-X-X-X;XB 9 < , t G.xXfXsXfXfXfXfXgXfXfXfXfXfXsXfXxXyX:.> t > <.gXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXgXfXfXfXfXfXfXfXfXfXhXl., r , 2.n.9..., , r e e LXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXe e e w x T.P P P P P P E.=X-X-X-X-X-X-X-X>X} 9 < < y A.jXaXsXgXfXfXfXfXfXfXfXfXfXfXfXfXaXjXgX,.> t > s.xXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXL.y , r e t < , , r e e e LXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXe e 1 0 b T.K P P P P P R. X:X-X-X-X-X-X-X-X-X#.q < e l.iXsXfXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXsXgXaXu , e r tXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXiXI.4., r e e e e r e e r LXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXe 1 w o.P K K P P K K L {.-X-X-X-X-X-X-X-X>X[ 9 1 > 9.L.tXgXsXfXfXfXfXgXfXfXfXfXfXfXfXgXfXfXfXaXzXS., r > a.zXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXsXgXsXfXfXsXgXgXsXeXL.f., r , e e r r e e LXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXe e e 3 Y Y.T.T.T.T.T.L E.=X:X-X*X-X-X-X-X-X>X-.w < y C.J.iXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXhX<.> < ;.gXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXfXfXsXfXfXgXfXfXfXfXgXsXpXJ.J.V.t , r r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXe e q | s b k l x Z D J XX*X;X;X>X>X>X>X>X>X;X8 e , 6.L.D.tXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXxXb.> r e F.sXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXsXaXeXJ.C.J..., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXe e r q 0 w 0 0 w q e 1 6 .$.*.-.w.B C _ } ' e e , h.J.D.tXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXtXr r , p.P.rXpXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXfXaXI.J.C.H.J.1., r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXe e 1 1 1 1 1 < 1 e e e q q 9 9 9 9 9 9 9 w e e e m.J.D.P.fXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfX;., , 7.L.C.J.rXpXfXgXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXgXsXiXP.J.C.H.D.L.7.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXe < r e e e e e e e r 1 1 1 r 1 1 1 1 r < e e r V.J.D.J.dXfXfXfXfXfXfXfXfXfXfXfXfXgXfXfXfXfXfXfXfXgX;., , 6.L.D.H.D.J.P.rXpXsXfXgXgXfXgXfXfXfXfXfXfXfXfXfXfXfXfXfXgXgXfXaXpXeXJ.J.C.D.F.D.L.8., r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e e e e e e e < e e r V.J.D.D.eXfXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfX.., , 7.L.H.H.H.H.D.D.J.K.eXtXpXaXsXfXgXfXgXgXfXfXfXgXfXfXsXaXpXtXI.J.J.D.D.H.H.C.H.L.7., e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , k.J.D.H.J.tXgXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgXsXfXyXt < , u.L.C.H.H.H.H.H.H.D.D.H.J.J.K.L.I.rXrXtXtXtXuXrXP.P.K.J.H.D.C.H.H.H.H.H.H.H.J.2., r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r > 9.L.D.D.H.J.aXgXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXsXzXS., e e l.J.H.H.H.H.H.H.H.H.H.H.H.D.D.D.D.D.D.D.D.D.D.D.D.D.D.H.H.H.H.H.H.H.H.D.J.C.>.> r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , i J.D.D.J.H.J.iXfXgXfXfXfXfXfXfXfXfXfXfXfXfXgXsXhX6., e y H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.D.H.H.H.H.H.H.H.H.H.H.H.H.L.l.y , r e r LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , d.L.H.H.H.D.J.rXfXgXfXfXfXfXfXfXsXfXgXfXfXfXfXV., r , 2.L.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.D.H.H.H.H.H.H.H.C.J.J.9., , r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r e r V.J.D.H.H.H.H.J.tXaXfXfXfXgXgXgXgXsXsXaXeXL.>., r , n.J.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.J.D.H.H.H.H.H.C.H.L.n..., r r r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , ..H.J.H.H.H.H.H.H.J.P.rXiXiXiXiXtXrXL.J.J.4., r > 4.J.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.D.D.J.L.V.4., , r r e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r r , ;.V.L.D.C.H.H.H.H.H.H.H.H.J.H.H.C.J.H.4., r , y C.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.D.D.H.J.L.V.7.r , r r , , e r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r , y f.L.J.H.D.C.D.H.H.H.D.C.H.J.L.n.>.> r e e k.I.J.H.H.D.D.H.D.D.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.H.J.L.J.l.6.r , e r > , p.S.< < e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r , , >.h.D.L.L.L.J.J.J.L.J.J.k.1.q , r r e r ..8.n.H.L.J.J.H.D.D.H.D.H.H.H.H.H.D.H.H.H.H.H.J.J.J.J.m.t..., , r r , , <.0XhXxXg.> r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r r , , u 1.u.f.l.l.h.u.6...e , < e < , e e e , e u 6.d.m.D.J.L.L.L.J.L.J.L.J.J.J.L.J.J.H.V.d.7...r , , r e > , <.S.hXhXfXfXgX;., e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r r r , , > , , , , , , , e e e , >.7.r , , e r e , , 1 u >.4.9.i.f.f.k.k.k.f.d.9.6.>.u r , , < r r , > t 5.G.hXhXsXfXfXsXxXx.> r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e r r e r r 1 e r r e e e r , t.U.V.p.,.t , > , r r , , , , , > , , e , , , , > , , r r , > > r <.x.yXzXhXfXfXfXfXfXfXgXwXr e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e e e e e e e r e < r , u.J.H.J.uXtXN.t.;.r , > , , < e e e e e r 1 e e r e e , e ;.5.v.wXgXxXgXsXfXfXfXfXfXfXfXgXsXi , r LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXr r , 9.L.D.D.D.aXxXxXgXtXZ.a.7.,.u t r , q , , < t t e < r m.wXfXxXxXgXfXsXfXfXfXfXfXfXfXfXfXfXgX;., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX< e , 6.L.D.H.A.L.sXfXfXgXxXxXhXgXfXyXwX0X0X0X0X0XsXy., , ..fXzXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXgX;., r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXr e , ;.H.D.H.H.H.rXfXfXfXfXsXfXfXfXgXgXhXhXhXhXgXzX<., , ,.uXsXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXaXu , e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r V.H.H.H.H.H.tXfXfXfXfXfXfXfXfXfXfXfXsXfXgXyXr e , t.L.uXfXfXfXfXfXfXfXfXfXfXfXfXfXfXfXhXG., e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , 9.L.H.H.H.H.H.rXsXgXfXfXfXfXfXfXsXfXfXgXhXa.> e , n.J.H.tXfXfXfXfXfXfXfXfXfXfXfXfXfXfXxXt.> r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r e r C.H.H.H.H.H.H.L.iXsXfXgXfXfXgXgXfXsXaXJ.y e , ..H.H.H.J.eXsXfXfXfXfXfXfXfXfXfXgXfXfXJ.e < r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r , ,.L.H.H.H.H.H.H.F.L.rXiXiXaXpXiXrXJ.P.2., r , d.L.D.H.H.D.J.rXaXsXfXgXfXgXgXsXpXqXP.>., e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r , 9.L.H.H.H.H.H.H.D.D.H.J.J.J.H.A.L.9., e r , 1.J.H.D.H.H.H.C.J.L.eXrXrXrXeXJ.J.L.6., r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e , 8.J.J.H.H.H.H.H.H.H.C.C.D.J.L.9., r e e e , ,.D.L.H.H.H.H.H.F.H.D.D.C.C.J.J.6., e r e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX< e e , >.n.L.J.J.H.H.D.H.J.J.L.m.>., 1 , e e e e , u f.J.L.J.H.H.C.H.J.J.L.J.l..., r , r LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r , e 1.h.V.H.H.J.J.C.f.2.e , r e e LXLXe e r , , ..i.n.H.J.J.J.H.M.i.>., , r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e r e , , r ..>.>...t , , e e e e LXLXLXLXe e r r , , r u ..>.;.u r , , r r e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe r e r e e , , , , , r r e e e LXLXLXLXLXLXLXe e r r e , , , q e e r r e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX",
-"LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXe e e r e r e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXe e e r e e e e e e LXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLXLX"
-};
diff --git a/debian/hicolor-icons/16x16/hedgewars.xpm b/debian/hicolor-icons/16x16/hedgewars.xpm
deleted file mode 100644
index 2d6f9a3..0000000
--- a/debian/hicolor-icons/16x16/hedgewars.xpm
+++ /dev/null
@@ -1,166 +0,0 @@
-/* XPM */
-static char *Icon___x__x__[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 144 2",
-" c #393839",
-". c #7C147E",
-"X c #667169",
-"o c #717F75",
-"O c #9F0068",
-"+ c #99096E",
-"@ c #A91C7D",
-"# c #5D359B",
-"$ c #6A238C",
-"% c #7C3192",
-"& c #763898",
-"* c #733E9D",
-"= c #773E9D",
-"- c #793A9B",
-"; c #395FBB",
-": c #5E47A9",
-"> c #5850AD",
-", c #4A5DB9",
-"< c #3C6ECA",
-"1 c #2F71CB",
-"2 c #5C67C4",
-"3 c #4175D0",
-"4 c #5779D4",
-"5 c #7165C1",
-"6 c #AB1B80",
-"7 c #AC1E83",
-"8 c #9C2E8F",
-"9 c #803090",
-"0 c #833696",
-"q c #B82B8F",
-"w c #B73193",
-"e c #BC379B",
-"r c #BD379C",
-"t c #BD399C",
-"y c #BE3C9D",
-"u c #A34293",
-"i c #B74192",
-"p c #9044A7",
-"a c #8D53AE",
-"s c #825AB8",
-"d c #BE43A7",
-"f c #A751B2",
-"g c #B651B0",
-"h c #BF61A3",
-"j c #C242A3",
-"k c #C549A7",
-"l c #CC4DA6",
-"z c #C143A8",
-"x c #D14CA9",
-"c c #C950AC",
-"v c #C951AC",
-"b c #CA50AE",
-"n c #CF5BB6",
-"m c #CC5CB4",
-"M c #CF5FB4",
-"N c #D05DB5",
-"B c #D35FBA",
-"V c #D258BE",
-"C c #E05EB9",
-"Z c #D162B8",
-"A c #D365BA",
-"S c #D464BB",
-"D c #D568BD",
-"F c #D66BBF",
-"G c #D864C6",
-"H c #DB6FC6",
-"J c #DD76C8",
-"K c #DE79C9",
-"L c #E367CA",
-"P c #E079CD",
-"I c #E17FCD",
-"U c #E77DCD",
-"Y c #E376D5",
-"T c #E376D7",
-"R c #3584DE",
-"E c #3AA4F7",
-"W c #31B0FF",
-"Q c #408FE4",
-"! c #5F8EE8",
-"~ c #4A98ED",
-"^ c #5790E6",
-"/ c #6293E8",
-"( c #52AFFF",
-") c #A2A1A1",
-"_ c #A7A9A7",
-"` c #D489C1",
-"' c #E483D3",
-"] c #E880D0",
-"[ c #E88AD7",
-"{ c #E887D9",
-"} c #EA87DF",
-"| c #E88BDB",
-" . c #EB8CD9",
-".. c #F489DE",
-"X. c #ED87E0",
-"o. c #EB88E0",
-"O. c #EE8DE2",
-"+. c #ED91E0",
-"@. c #EE9FE1",
-"#. c #F09AE5",
-"$. c #F298E7",
-"%. c #F299E7",
-"&. c #F29AE7",
-"*. c #F29BE7",
-"=. c #F29CE6",
-"-. c #F29CE7",
-";. c #F29DE7",
-":. c #F39AE9",
-">. c #F499EB",
-",. c #F39DE8",
-"<. c #F29EE8",
-"1. c #F39EE8",
-"2. c #F39FE8",
-"3. c #F39EE9",
-"4. c #F49DE9",
-"5. c #F59FEB",
-"6. c #F2A0E9",
-"7. c #F4A0EA",
-"8. c #F5A0EB",
-"9. c #F5A2EB",
-"0. c #F5A1EC",
-"q. c #F6A2EC",
-"w. c #F6A3EC",
-"e. c #F5A4EE",
-"r. c #F7A5EE",
-"t. c #F7A7EF",
-"y. c #FBA5EE",
-"u. c #F4B0EC",
-"i. c #F5B6EE",
-"p. c #F8A2F0",
-"a. c #F9AAF2",
-"s. c #FAADF3",
-"d. c #FBABF4",
-"f. c #C5C4C4",
-"g. c #FAD5F5",
-"h. c #F7DAF0",
-"j. c #FFD6FE",
-"k. c #FAE1F6",
-"l. c #FDEDFC",
-"z. c #FAFFFA",
-"x. c #FEFBFE",
-"c. c #FFFCFF",
-"v. c #FFFFFF",
-"b. c None",
-/* pixels */
-"b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.",
-"b.b.b.b.b.b.# b.b.b.b.b.b.b.b.b.",
-"b.b.b.b.b.b.Q ~ & b.b.b.b.b.b.b.",
-"b.b.b.b.b.+ 2 ! 4 9 O b.b.b.b.b.",
-"b.b.* R 3 < % l U .' M i b.b.b.",
-"b.b.b./ ( s ] d.e.9.9.t.{ @ b.b.",
-"b.b.b.0 - C a.#.#.3.k.c.c.h.b.b.",
-"b.. > 1 p ..6.<.:.i.c._ f.X h b.",
-"b.$ E ^ z O.9.<.#.u.c. ) o ` b.",
-"b.b.8 = j } 9.=.3.:.g.z.l.j.] @ ",
-"b.b.b.; f L | e.=.#.3.#.Z H J Z ",
-"b.b., W a x m F q.3.9.+.[ 9.k w ",
-"b.u : 5 g y.s.A P 5.#.q.p.c b.b.",
-"b.b.b.b.q o.:.c V T T G r b.b.b.",
-"b.b.b.b.b.7 7 r N b j D K b.b.b.",
-"b.b.b.b.b.b.b.r o.N y :.S b.b.b."
-};
diff --git a/debian/hicolor-icons/256x256/hedgewars.xpm b/debian/hicolor-icons/256x256/hedgewars.xpm
deleted file mode 100644
index eb99a04..0000000
--- a/debian/hicolor-icons/256x256/hedgewars.xpm
+++ /dev/null
@@ -1,518 +0,0 @@
-/* XPM */
-static char *Icon____x___x__[] = {
-/* columns rows colors chars-per-pixel */
-"256 256 256 2",
-" c #000000",
-". c #0D0D0D",
-"X c #181717",
-"o c #201F20",
-"O c #2D2B2C",
-"+ c #262425",
-"@ c #3A3939",
-"# c #312F31",
-"$ c #3F403F",
-"% c #4A494A",
-"& c #545254",
-"* c #5B595B",
-"= c #656365",
-"- c #696769",
-"; c #6B6A6B",
-": c #716F71",
-"> c #7D7C7D",
-", c #7A7679",
-"< c #706F6F",
-"1 c #9A0066",
-"2 c #9D046A",
-"3 c #9F096E",
-"4 c #970063",
-"5 c #9E0B71",
-"6 c #8E1A7F",
-"7 c #971277",
-"8 c #9B1075",
-"9 c #94157A",
-"0 c #9B157A",
-"q c #91197D",
-"w c #99197D",
-"e c #A50065",
-"r c #A90067",
-"t c #A4046B",
-"y c #A80168",
-"u c #A0096F",
-"i c #A10B71",
-"p c #A51176",
-"a c #A71579",
-"s c #A8167B",
-"d c #AA1A7E",
-"f c #7D2C8E",
-"g c #7A2E91",
-"h c #6D3C9C",
-"j c #743495",
-"k c #793193",
-"l c #713798",
-"z c #72399A",
-"x c #6C3FA0",
-"c c #5C4CAB",
-"v c #574FAE",
-"b c #5750AF",
-"n c #4E5AB6",
-"m c #4B5CBA",
-"M c #4B5BB8",
-"N c #5254B3",
-"B c #5D59B7",
-"V c #6444A4",
-"C c #6A42A2",
-"Z c #654AAA",
-"A c #7E55B2",
-"S c #7C5AB6",
-"D c #7A5EBB",
-"F c #704EAD",
-"G c #4561BE",
-"H c #5762BF",
-"J c #7961BD",
-"K c #3D6AC6",
-"L c #376FCB",
-"P c #396DC9",
-"I c #3F67C4",
-"U c #3472CD",
-"Y c #2B7BD5",
-"T c #277FD9",
-"R c #2C7ED8",
-"E c #2F77D2",
-"W c #3176D0",
-"Q c #317FD9",
-"! c #307CD6",
-"~ c #4265C1",
-"^ c #476CC8",
-"/ c #477AD5",
-"( c #5273CF",
-") c #746CC5",
-"_ c #746BC6",
-"` c #6E77CE",
-"' c #7173CB",
-"] c #6C7CD3",
-"[ c #6E77D0",
-"{ c #8B1E81",
-"} c #971E82",
-"| c #AC1D82",
-" . c #862386",
-".. c #832689",
-"X. c #82288B",
-"o. c #892084",
-"O. c #952285",
-"+. c #912B8D",
-"@. c #932689",
-"#. c #8C2F91",
-"$. c #8C3495",
-"%. c #8A3B9B",
-"&. c #8C3798",
-"*. c #AE2285",
-"=. c #AF2288",
-"-. c #B02686",
-";. c #B2268A",
-":. c #B42B8C",
-">. c #B12887",
-",. c #B6318E",
-"<. c #B62D91",
-"1. c #B82F93",
-"2. c #B73391",
-"3. c #B93394",
-"4. c #BB3996",
-"5. c #BC3599",
-"6. c #BE3C9B",
-"7. c #C03C9F",
-"8. c #C13DA1",
-"9. c #88429E",
-"0. c #B84693",
-"q. c #BF419C",
-"w. c #817F80",
-"e. c #8644A3",
-"r. c #824DAB",
-"t. c #834BA7",
-"y. c #8051AE",
-"u. c #C1449E",
-"i. c #C343A4",
-"p. c #C54BA4",
-"a. c #C646A9",
-"s. c #C74CAA",
-"d. c #C94AAD",
-"f. c #C847AB",
-"g. c #CA53AC",
-"h. c #CC58AF",
-"j. c #C750A8",
-"k. c #CB4EB1",
-"l. c #CE52B5",
-"z. c #CE5BB2",
-"x. c #D05EB5",
-"c. c #D156B9",
-"v. c #D35ABD",
-"b. c #D054B7",
-"n. c #D364BA",
-"m. c #D66ABE",
-"M. c #D160B7",
-"N. c #D55EC1",
-"B. c #D761C3",
-"V. c #D963C6",
-"C. c #D96EC1",
-"Z. c #DB66C9",
-"A. c #DE6CCE",
-"S. c #D76BC0",
-"D. c #DB72C5",
-"F. c #DE77C9",
-"G. c #DF79CA",
-"H. c #DF6ED0",
-"J. c #E17CCD",
-"K. c #E177CF",
-"L. c #E06FD1",
-"P. c #E273D4",
-"I. c #E47AD6",
-"U. c #E577D8",
-"Y. c #E67BD9",
-"T. c #E87EDE",
-"R. c #2383DC",
-"E. c #2A83DD",
-"W. c #3382DC",
-"Q. c #3A86DF",
-"!. c #1C8AE2",
-"~. c #2A8BE4",
-"^. c #3786E0",
-"/. c #3887E1",
-"(. c #3C8BE4",
-"). c #3A8CE5",
-"_. c #3993EC",
-"`. c #3D9CF5",
-"'. c #3C9BF4",
-"]. c #3DA1F9",
-"[. c #4483DD",
-"{. c #6984DA",
-"}. c #6689DE",
-"|. c #6984D9",
-" X c #408FE8",
-".X c #428AE3",
-"XX c #4493EC",
-"oX c #4896EF",
-"OX c #5E9BEE",
-"+X c #4997F0",
-"@X c #4C9BF3",
-"#X c #519EF6",
-"$X c #5E9DF2",
-"%X c #519FF8",
-"&X c #658DE2",
-"*X c #6293E7",
-"=X c #6195EA",
-"-X c #6098EB",
-";X c #42A2FA",
-":X c #4DA3FB",
-">X c #4AA7FC",
-",X c #5BA2F5",
-"<X c #55A3FB",
-"1X c #59A7FF",
-"2X c #56ADFF",
-"3X c #58A9FE",
-"4X c #54B2FF",
-"5X c #51B8FF",
-"6X c #4FB2FF",
-"7X c #848283",
-"8X c #8C8A8C",
-"9X c #9B999B",
-"0X c #908E8F",
-"qX c #A6A4A6",
-"wX c #BCBABB",
-"eX c #B5B3B5",
-"rX c #E583D3",
-"tX c #E780DA",
-"yX c #E984DC",
-"uX c #EB8ADD",
-"iX c #E788D7",
-"pX c #ED91DE",
-"aX c #ED8DE1",
-"sX c #EC87E2",
-"dX c #EF92E2",
-"fX c #F196E5",
-"gX c #F39BE7",
-"hX c #F397E8",
-"jX c #F49EE9",
-"kX c #F6A2EB",
-"lX c #F8A5EF",
-"zX c #F6ABEC",
-"xX c #F6B2ED",
-"cX c #F7BBEF",
-"vX c #F9A6F0",
-"bX c #FBA9F2",
-"nX c #F8BEF0",
-"mX c #FAB8F4",
-"MX c #C7C5C7",
-"NX c #D6D5D6",
-"BX c #DBDADB",
-"VX c #F8C4F2",
-"CX c #F9CBF3",
-"ZX c #F7C3F0",
-"AX c #FAD4F5",
-"SX c #FBDAF6",
-"DX c #FCDEF8",
-"FX c #EBEAEB",
-"GX c #E4E3E4",
-"HX c #FCE4F9",
-"JX c #FDEBFB",
-"KX c #F8E7F5",
-"LX c #F6F5F5",
-"PX c #FEF4FC",
-"IX c #FFFFFF",
-"UX c None",
-/* pixels */
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX0.UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX1 1 2 1 1 2 1 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i i u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 3 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 3 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 t t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu 3 u u u u 5 c { r u 5 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i u u u u t U T z t t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u t 5 K R.R.G 6 r u i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 u 5 P T Y R.Y h t t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 t 5 U T Y W Y R.G { r u 3 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 t 7 U T Y Y Y Y R.Y x u t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 2 7 U T Y T Y Y Y Y R.~ { r u 3 3 5 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX3 u u u 5 t 7 U T Y Y Y Y Y Y Y R.T V 3 y 5 3 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u 5 5 t 9 E T Y Y Y Y Y Y Y Y Y R.I .r u 3 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u t 5 t 9 E T E Y Y Y Y Y Y Y Y Y R.Y V 3 y 3 3 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu 5 3 i 3 t q Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.K .r t 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu 5 t 3 5 y { Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.T c 5 r 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu 3 i 3 5 y { T Y Y Y T Y Y Y Y Y Y Y Y Y Y Y Y R.P .r t 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu 3 5 3 3 t { R.Y Y Y Y Y Y W.^.W.Y Y Y Y Y Y Y E E.E.c i r 5 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 y .E.Y Y Y Y Y Y ^.oXXXW.E.Y Y Y Y Y Y Y Y R.P ..e t 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 5 y ..T Y Y Y Y Y Y ^. at X<X at X(.W.Y Y Y Y Y Y Y Y T E.c 5 e i i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 y ..T Y Y Y Y Y Y /.:X1X3X<XoX/.Q Y Y Y Y Y Y Y Y R.P X.r u 5 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 e f E.Y Y Y Y Y Y (.%X1X1X1X<X at X(.W.Y Y Y Y Y Y Y Y T E.v 5 e 3 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 r g R.Y Y Y Y Y Y ^. at X1X1X1X1X1X<XXX(.R Y Y Y Y Y Y Y Y R.L f e t 5 5 3 3 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 5 5 e k R.Y Y Y Y Y Y (.#X1X1X1X1X1X1X<X at X(.W.Y Y Y Y Y Y Y E E.T v 7 r 5 5 u 3 u 5 u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 r k R.Y Y Y Y Y Y (.#X1X1X1X1X1X1X1X1X<XXX(.R R Y Y Y Y Y Y Y R.U f e 3 5 u u 5 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 5 e l R.Y Y Y Y Y R (.<X1X1X1X1X1X1X1X1X1X<X at X X! Y Y Y Y Y Y Y Y Y E.N 5 r 5 5 t u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 r h R.Y Y Y Y Y Y (.<X1X1X1X1X1X1X1X1X1X1X1X<XXXQ.R Y Y Y Y Y Y Y Y R.U k y t 3 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i 3 u 5 e h R.Y Y Y Y Y Y (.<X1X1X1X1X3X1X1X3X1X1X1X3X1X at X(.W.Y Y Y Y Y Y Y Y Y R.n 7 r 5 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 r h R.E R Y Y Y Y (.<X1X1X1X1X1X1X1X1X1X3X1X1X1X1X<XoX(.R Y Y Y Y Y Y Y Y R.E j r t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 5 5 r V R.Y Y Y Y Y R (.<X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X at X XW.R Y Y Y Y Y Y Y Y R.M 9 r u 5 u u 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 r V R.Y Y Y Y Y R (.<X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X<XoX/.R Y Y Y Y Y Y Y Y R.W h y t 5 3 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 5 r c R.Y Y Y Y Y ! XX<X1X3X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X3X1X at XXXW.R Y Y Y Y Y Y Y Y R.m 6 r 3 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u 5 u 5 y c !.Y Y Y Y Y E X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<XoX(.R Y Y Y Y Y Y Y Y E.Y h t t 5 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u 5 t 5 e c R.Y Y Y Y Y ! _.<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X#XXXW.R Y Y Y Y Y Y Y Y R.G 6 r u 5 u u u u u u 3 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 y b R.Y Y Y Y Y E.XX<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X<X+X).W.Y Y Y Y Y Y Y E E.Y C t t 3 3 3 3 u u u u t 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i u u 5 y N R.Y Y Y Y Y Q X1X1X1X1X1X1X1X3X1X1X3X1X1X1X1X1X1X1X1X1X3X1X1X1X1X3X at XXXW.Y Y Y Y Y Y Y Y Y R.~ { r u 3 u u 3 5 i 3 i 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 y N R.Y Y Y Y Y R XX<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X<X+X(.W.Y Y Y Y Y Y Y Y R.Y c u t 5 u t 5 u 5 t 3 u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 y n R.E Y Y Y Y Q XX<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<XXX^.Y Y Y Y Y Y Y Y Y R.~ .r u 5 u u 3 5 5 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 u y M R.E Y Y Y Y R XX1X1X1X1X1X1X1X1X3X1X1X1X1X3X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X at X).W.R Y Y Y Y Y Y Y E.Y c 3 y 5 5 5 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 3 t G R.Y Y Y Y Y R XX1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X<X:XXXW.R Y Y Y Y Y Y Y Y R.I .r t 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u t G R.Y Y Y Y Y Q XX3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X at X(.W.Y Y Y Y Y Y Y Y R.E.c 5 y 5 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u t G E.Y Y Y Y Y W.XX1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X<XXXW.R Y Y Y Y Y Y Y Y R.P ..r t 5 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 5 t I R.E Y Y Y Y R oX1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X at X(.W.Y Y Y Y Y Y E E T Y c 3 e 3 u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u i u u u u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u t u K T Y Y Y Y Y W.XX1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X%XXX/.E.E.Y E.E.R.R.E.R.!.U f t u 3 u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u u u u u u u u 3 u u u u u 5 3 i 3 i t 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 5 5 I T E E Y Y Y W.oX<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X4X3X4X4X2X1X at X.XP ~ ~ ~ m m G ~ G P U V p u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u u u u u u u u u 5 5 u u u u 5 t 3 5 3 i 5 3 u u u u i 3 i u u u u u u u UXUXUXUXUXUXUXUXu u u u 5 t 5 U !.T R.R.T T E.+X1X1X1X1X1X1X,X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X4X4X4X3XOX|.' D t.&. at .w 0 8 u t u t t e t t t 3 q 8 u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX3 u u u u u 3 u u u u u u 5 i 3 u u u u u 3 t 5 t u u u u u u t 5 u u u u u u u u u u u u 3 i t 3 u u u u u u u u i t 5 5 u u u t 5 V N N m I P U ! oX3X2X4X4X4X4X4X4X4X4X1X3X3X1X1X1X1X1X<X1X1X1X1X1X4X4X4X3X-X|.J 9. at .0 u r e e e y t t t u u u u 5 i u 5 u t t u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i u u u u u u u u 5 5 5 5 5 5 5 5 5 5 3 u 5 3 5 5 u u u 5 3 u i 5 u u u u u u u u u 3 u u t 5 5 3 u u u u u u u u 3 i i 3 u u u u 5 y e y t 5 5 7 0 O.+.&.9.r.S J ) ` ] }.*X$X,X3X1X4X4X4X4X2X3X2X4X3X-X` y.+.0 t e e e t u i 3 3 5 i 5 3 i u u u u u u u u u 5 5 u u u u u u u u u u u 3 u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 5 5 t t r r r r r r y y t t t i 5 5 5 3 5 5 5 5 5 5 5 5 5 3 u u u u u u 5 3 5 t 5 5 5 5 u u u u u u u u 3 i 3 t i 3 u 3 5 5 5 5 3 t t t t t e e e e e e e e e u 5 0 w @.+.%.9.y.' =X,X|.S +.8 e e e u u 5 5 5 5 u u u u u u u u u u u u u u u u u i u u u u u u u u u u u u u i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 t 5 m ~ M N c V h k g ..{ q 7 5 3 t y e e r r r r y y t t t u u 3 5 5 5 5 5 5 5 5 5 5 5 5 u u u u u u u u u 3 5 5 u u u 3 5 t 3 i 5 5 5 5 u 3 5 5 5 5 u 5 5 5 u u u t t e e e e e e i w t e e u u i i u u u u u u u u u u u i i i i i i u i i i i i i i i u u u u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 r V !.R.R.R.R.R.R.R.T Y E W P K G M N c c h j f f 6 q 7 5 5 3 y y r r r r r e t t t 3 t 5 5 5 5 5 5 5 5 5 5 5 3 5 5 5 5 3 i 3 3 u u 5 5 5 t 5 5 u u u u i u u i 3 i 5 5 5 5 i 5 5 u t 3 i 5 u u u u u u u u i i i i i u u 2 2 2 1 1 1 4 1 4 4 1 1 1 1 1 2 2 3 u u i i u i u t 5 u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 t 5 P Y Y Y E Y Y Y Y Y T Y T T R.R.R.R.T R.R.R.Y Y Y E U K G M N v V h l g ..{ q 7 5 5 t y e r y e y e y y t t t t t 5 5 5 5 5 5 5 5 5 5 5 5 5 u u u u u u u u u u u u u u u u u u i u i u u u u u i i i u 2 2 4 4 2 2 u a d *.:.4.u.6.u.p.u.6.q.4.,.:.d a i 2 1 4 2 1 2 3 5 i i i u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 r h R.E Y Y Y Y Y Y Y Y Y Y Y E Y E Y E Y Y Y Y Y Y R.T E.E.R.R.R.R.R.R.T T T Y W L I ~ M N v V h l g ..{ q 7 5 3 t t y e y e r r y y y t u t u u i 5 u i u u u u u u u u u u u u u u 3 u u i i u 2 4 4 3 a *.q.g.m.J.iXpXjXkXkXlXbXvXbXbXbXbXvXvXlXkXkXfXuXrXm.M.u.:.d i 1 1 1 2 u i i i u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 3 3 K T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E Y Y Y Y Y Y Y Y T Y T T E.R.R.R.R.R.!.R.T T T Y E U P ~ m N c c h l g X.{ 6 9 5 i t t e r t 5 u u u u u u u u u u u u u i i u 2 4 1 p >.u.n.rXdXkXbXbXvXvXlXkXkXjXjXjXjXgXjXjXjXjXgXjXjXjXjXkXlXvXbXbXbXkXgXiXC.j.,.a 2 4 1 u i i u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 5 r k E.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E Y E Y E Y Y Y Y Y Y T T E.R.R.R.R.R.R.R.T T Y E U K K M M n g u u u u u u u u u u u u i u 1 1 2 d q.m.pXkXvXbXvXkXjXjXjXfXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXgXgXgXgXgXgXkXjXlXbXbXvXdXG.j.:.u 4 1 3 i i u u u u u u u u u 2 1 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 5 t u I R.Y Y Y Y Y Y Y Y Y T T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E Y Y Y E Y Y Y Y Y T E.Y R.!.W z 5 u u u u u u u u i i i 2 4 3 *.h.rXkXbXvXkXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXkXjXjXjXgXgXgXjXlXvXbXkXuXn.,.p 1 4 3 i i u u u u u u i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u t 5 5 y f T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.W h u r u 5 u u u u u i i u 1 1 *.j.rXkXbXzXkXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXfXkXkXbXlXuXn.,.u 1 3 u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u 5 3 3 3 3 m R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E T R.v 7 r u 5 u u u u u i i 2 1 i 4.D.jXbXlXjXjXfXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXvXkXrXj.s 4 2 u i u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y f T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.P X.r t 5 5 u u t 5 i i 2 4 a g.uXvXvXkXgXgXkXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXkXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXgXkXlXbXgXn.*.2 1 u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y M E.E Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y Y Y Y Y Y T T c 5 e 5 5 i 3 u u i i 2 1 d x.fXbXkXgXgXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXgXgXkXvXkXD.,.2 4 i i u 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y .T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.P .r t 5 u u u u u i 2 1 d M.jXbXjXkXjXjXjXkXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXgXfXkXvXzXF.:.1 2 u i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 5 y N R.R R R R Y Y Y Y Y Y Y Y Y Y Y T Y Y Y R Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E.R.N 5 e 5 5 u 5 u u i u 1 p z.gXbXgXjXjXjXjXjXjXgXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXkXjXjXjXjXvXkXD.>.1 3 i u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u i 3 u 5 y { W.(.XX(.(.(.(.W./.W.W.W.W.R ! R T R Y R Y Y R R Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E R.Y j r t 5 5 5 5 5 5 5 1 3 p.pXbXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXgXjXvXkXM.a 1 3 u i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 5 y B `.<X<X<X<X<X at X<X at X@X+XoXoXoXXXXX(.(.(.^.(.W.W.^.W.! R Q Q R R T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.I 6 e 5 5 5 t 3 t i 3 4 2.rXbXkXgXgXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXdXp.2 1 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 i 5 t q .X:X1X1X1X1X1X1X1X1X1X1X1X1X<X<X<X<X<X<X at X@X at X@X+XoXoXXXXXXX(.(.(.)./.(.W.W.W.W.! W.Q E.Q Y Y Y Y Y Y R.N 5 y 5 u 3 3 3 i 5 1 p n.lXlXjXjXjXjXjXjXjXjXgXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXbXrX>.4 u i i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u i i 5 5 y Z @X<X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X<X<X<X<X<X#X:X at X@X at X@XoXoXXXXX_. X X(.(.Q././.h r t 5 u 3 i 3 i 3 1 4.dXbXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXlXkXh.u 1 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 5 t 9 .X:X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X<X1X<X%X%X#X:X at X$.r 5 u u u u u i 1 p n.bXkXgXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXvXrX*.4 u i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 u 5 r Z @X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X4XOX+.e 5 u u u u i u 1 :.uXbXgXgXkXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXvXkXp.1 3 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 7 [.<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X<X4X&X0 e 5 u u u u i 3 1 j.lXkXgXjXgXkXgXkXjXkXjXjXjXjXgXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXvXD.i 1 i u u u u u i u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 5 r C +X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X4X}.p e 5 u u u u i 2 i C.bXkXgXjXjXkXgXkXgXjXjXjXgXkXjXkXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXvXuX>.1 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 i u 5 / >X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X|.p t 5 3 u u 5 i 1 d iXbXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXfXlXjX6.1 i i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 5 r z ].<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X3X1X1X1X1X1X3X|.3 t 5 u u u u i 1 :.fXvXfXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXgXjXjXkXjXjXjXjXjXjXjXjXjXjXkXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXbXj.1 3 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 u 3 ( :X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X}.8 t 5 u u u u i 1 4.gXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXkXkXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXn.2 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 3 r k '.<X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X3X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X&X8 t 5 3 u u i u 1 8.gXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXF.3 3 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u t ^ >X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3XOXw e p 3 3 3 i u 2 8.fXgXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXfXbXrXu 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y f '.<X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X+.y i u u 3 i 5 2 8.sXdXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXzXrXp 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i i t ^ :X1X1X1X1X1X1X1X3X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X2X&.e 5 u u u u 5 1 i.tXsXgXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXkXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXrXu 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i r ._.<X1X1X1X1X1X1X1X1X3X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4XA e 5 u u u u u 1 7.Y.Y.fXgXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXbXJ.u 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y ^ @X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X4X) y 5 5 3 u u i 1 5.U.P.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXbXF.2 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y { _.<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X<X3X*Xu t i 3 3 u i 1 :.U.P.U.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXm.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 r B ;X<X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X4X3X at .e 5 u u u i 2 *.P.P.P.uXgXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXgXbXg.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i t { (.1X1X1X1X1X3X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X3X2X4X-X%.e u u u u u 2 s A.P.H.U.dXgXjXjXjXkXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXgXjXfXgXjXfXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXkXjXjXjXjXjXjXkXjXjXjXjXkXgXbXq.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i r B ;X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X4X,X] %.5 t 5 u u u 3 3 i N.U.H.P.yXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXhXhXjXkXzXxXxXzXkXkXgXfXhXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXfXfXgXjXgXgXhXgXhXjXjXjXjXgXkXkX>.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 9 (.<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X,X1X4X4X*XS O.e e t 5 u u u u i 2 k.U.A.H.P.aXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXkXjXjXhXgXzXZXSXJXPXPXPXIXPXPXJXSXCXxXgXhXgXjXjXjXjXjXjXjXjXjXkXjXfXzXcXAXDXHXHXHXAXVXbXjXhXgXkXjXjXlXpXp 2 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX3 i u u u 5 e Z ].<X1X1X1X1X1X1X1X1X1X1X1X1X2X4X,X` %.u e e u 8 u u u u u i 1 5.U.H.P.H.Y.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXfXjXcXDXIXIXIXIXIXIXIXIXIXIXIXIXIXIXHXCXvXfXgXkXkXjXjXjXkXgXfXzXSXPXIXIXIXIXIXIXIXIXIXJXCXkXhXjXkXgXbXF.2 3 u i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i t 7 .X<X1X1X1X1X1X1X1X1X1X1X4X2X*XA O.r e u p u u u u u u 3 i 2 | L.P.H.H.P.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXhXxXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXvXfXjXjXjXjXgXjXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXCXjXfXjXjXbXj.1 i 5 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 r C `.1X1X1X1X1X<X1X2X4X,X' &.u e t u 5 u 3 u u u u u u i t i B.P.A.H.L.P.dXgXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXSXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXCXjXgXjXgXkXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXJXxXgXjXjXkX:.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 5 [.:X1X1X1X1X4X4X&XA w e e t 5 3 u u u 3 3 u u u u u i 1 a.U.A.H.P.P.tXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXzXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXJXxXfXvXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXCXgXgXlXiXi t i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i e C `.<X4X4X,X) $.t e t 5 5 i 3 3 u u u u u u u u u i 1 ;.U.H.P.H.H.P.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXkXfXzXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXCXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXgXgXbXx.1 i i u 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i [.>X{.r.w r e u 3 5 u u u 3 u 5 5 u u u u u u i 5 5 B.P.H.L.L.P.U.aXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXxXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXHXgXgXkX:.1 i u i u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 y X.#.t e t 5 5 t 5 5 i 3 i 5 5 t y u u u u u u i 1 8.U.L.L.L.P.H.Y.dXkXgXjXjXkXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXkXjXjXjXjXkXgXzXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXDXgXkXrX3 5 5 t u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 5 t y 3 5 5 5 3 5 i 3 5 5 3 y y 7 j 8 u u u u u 2 | L.L.L.L.L.H.P.uXgXgXkXjXgXgXjXjXjXkXjXjXjXjXjXkXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXSXfXbXp.1 i 5 u u u 3 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 i 5 5 5 u u t 5 5 5 5 t e 3 ..v E.Z e i u u u i 2 l.U.A.L.L.L.P.P.aXgXgXkXgXkXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXjXjXjXkXfXSXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXCXhXgXa 2 i u u 5 5 u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 5 5 3 5 u 5 5 t y r 7 l I Y R.U 3 u u u u i 1 :.U.L.L.L.L.L.H.T.dXkXkXgXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXgXjXjXjXfXcXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXxXvXn.1 i u u t 3 u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 3 u t 5 5 3 t r t f v E R.T Y R.h r 5 u u u u i N.P.L.L.L.L.L.P.Y.gXgXjXjXgXkXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXkXgXjXgXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXjXjX;.2 i t 5 i u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 3 i 3 5 5 5 3 y e 9 h K T R.T E Y T U 8 u 5 u u i 2 5.U.A.L.L.L.L.L.P.uXgXgXjXjXjXjXjXjXkXjXjXjXjXgXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXgXjXjXjXjXkXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXgXkXfXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXkXF.1 i u 5 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u 5 u 5 5 5 y r 3 f n E R.E.Y Y Y Y E R.V e 5 i u u 3 i V.P.L.L.L.L.L.L.P.aXjXjXjXjXgXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXkXjXkXkXkXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXzXjX2.1 i 3 5 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u 3 i u u u 5 5 t y y 6 V K T R.Y Y Y Y Y Y Y Y Y 9 t 3 3 u i 1 5.U.A.L.L.L.L.L.L.U.dXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXfXZXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXHXvXF.2 i u 5 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u 5 5 i 3 5 t 3 5 u u 5 5 5 y e 5 g M E R.T Y Y Y Y Y Y Y Y Y R.v y 5 u u i t i V.P.L.L.L.L.L.L.L.U.dXkXgXkXgXgXkXjXjXjXjXjXjXjXgXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXgXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXcXjX:.2 i t u 3 u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 t 3 5 5 i 3 3 5 5 t y t { V P R.R.Y Y Y Y Y Y Y Y Y Y Y Y T o.t 3 u u i 2 1.U.A.L.L.L.L.L.L.L.tXgXkXgXgXkXkXgXjXjXjXjXjXjXjXkXjXkXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXgXzXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXHXvXD.1 i i u i u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u t 5 t 5 3 5 5 5 y r 5 k m Y R.E.Y Y Y Y Y Y Y Y Y Y Y Y Y E.G t u u u u u 3 v.P.L.L.L.L.L.L.L.P.sXgXjXgXkXgXkXkXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXhXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXIXIXIXPXIXIXIXIXIXIXIXIXcXgX;.2 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u t 5 5 5 5 t e t { c U R.R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.l r 5 u u i 2 ;.P.L.L.L.L.L.L.L.L.P.aXgXjXkXgXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXvXn.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u 5 5 5 t e 7 l m Y R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T U 7 t i u u u 2 k.U.L.L.L.L.L.L.L.L.U.aXgXkXgXgXkXgXkXjXjXgXkXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXNX7X& $ & 0XGXIXIXIXIXIXIXIXIXPXzXfXa 2 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u i 5 t y t .c L R.T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E R.v r 5 u u i 2 d L.L.L.L.L.L.L.L.L.A.I.dXgXgXkXkXgXkXgXkXgXgXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXgXjXjXjXgXcXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXFX= . . > LXIXIXIXIXIXIXIXZXkXp.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u 5 5 u e e 7 l ~ Y R.T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.f y 5 u u i 1 8.U.L.L.L.L.L.L.L.L.L.U.dXkXkXgXgXgXjXgXkXgXkXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXhXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXIXLXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXBX# % LXIXIXIXIXIXIXHXkXrX3 u i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u 5 5 t r u .v W R.T Y Y Y Y Y Y Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y Y Y T U 5 3 5 u u u i V.L.F.L.L.L.L.L.L.L.L.Y.dXkXgXkXgXkXkXgXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXAXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXFX@ & IXIXIXIXIXIXIXzXjX,.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXi u u u t 5 5 3 5 t 5 5 5 5 u e y 9 h ~ R.R.T E Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E ~.c e 5 t u i 2 ;.P.H.L.L.L.L.L.L.L.L.P.Y.fXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXIXLXwX7X: 7XwXLXIXLXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX= 8XIXIXIXIXIXIXcXvXn.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUX5 5 3 u 3 i 3 i u u 5 5 5 5 t r 3 ..N W R.E.Y E Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R.f y 5 u u i 1 f.U.H.L.L.L.L.L.L.L.L.P.tXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX9X# O qXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXwX X GXIXIXIXIXIXAXgXuXi 3 i 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXu u u 3 t 5 t t 3 i 3 u 5 5 t y y q x I R.R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E.U 7 t 5 u i 3 i V.P.L.L.L.L.L.L.L.L.L.P.tXfXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX; - IXIXIXIXIXIXIXIXIXIXIXIXIXIX& 7XIXPXIXIXIXJXgXvX2.1 i i u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXu u u u i 3 5 5 5 5 3 5 5 t r 5 g N Y R.R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T T Y Y Y Y E R.n y 3 5 3 i 2 ;.U.H.L.L.L.L.L.L.L.L.L.P.yXgXkXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXlXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX- . = IXIXIXIXIXIXIXIXIXIXIXIXBXX O LXIXIXIXIXPXkXvXn.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi u u u u i 3 t 5 5 5 t y t 6 V P R.R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y ! ~.C r 5 u u i 1 f.U.H.L.L.L.H.H.L.L.H.H.P.yXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX9X 9XIXIXIXIXIXIXIXIXIXIXIX9X MXIXIXIXIXIXxXjXiX5 3 3 u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX1 i u u u u 5 5 5 5 t y 5 g M Y R.T Y E Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R E.^. X:X+.e 5 u u 3 i N.P.H.L.L.L.P.H.L.L.H.P.P.yXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXzXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXGXX X GXIXIXIXIXIXIXIXIXPXIX: 9XIXIXIXIXIXnXgXlX:.2 3 u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX1 i u u u u 3 t y t { c P R.R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y Y Y Y Y Y Y R W.(.+X%X3XOX5 t 5 u i 2 | H.L.L.L.L.L.H.H.H.H.P.H.P.uXgXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXkXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXw. 7XIXLXIXIXIXIXIXIXIXIX% . , IXIXIXIXIXZXfXbXg.4 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX1 i i u u u u 7 k m Y R.T Y Y Y Y Y Y Y Y Y R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R W.(.XX at X<X1X<X4X] y 5 5 5 i 2 5.U.H.L.L.L.L.P.H.H.P.H.H.P.yXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXLX+ O LXIXIXIXIXIXIXIXIXLX@ ; IXPXIXIXIXAXdXvXG.2 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX2 i u u 5 t ..Y R.E.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Q W. X+X<X1X1X1X1X<X4XA e 5 u u 5 2 k.U.H.L.L.L.L.L.L.L.L.H.P.P.uXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXMX MXIXIXIXIXIXIXIXIXLX@ * IXIXIXIXIXSXfXkXpXa 2 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX1 i u u u u 5 h Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R W.(.XX at X<X1X1X1X1X1X1X1X2X$.e 5 u u t i V.P.H.L.L.L.L.L.L.L.L.H.H.P.yXgXjXjXjXkXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIX8X 8XIXPXIXIXIXIXIXIXIX@ ; IXPXIXIXIXSXgXkXzX,.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX1 i u u i u 3 r { K R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y E.^.(.oX:X1X1X1X1X1X1X1X1X1X3X,X0 t 5 u i 2 | L.H.L.L.L.L.L.L.L.L.L.H.P.P.uXjXjXjXjXjXjXjXjXjXjXgXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX= ; IXIXIXIXIXIXIXIXIX& 7XIXPXIXIXIXDXhXjXbXj.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUX2 i u u 3 u 3 5 y 5 b R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R W.(.oX at X<X1X1X1X1X1X1X1X1X1X1X1X4X{.t u u i i 1 1.U.H.L.L.L.L.L.L.L.L.L.H.H.P.yXfXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXgXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX& * IXIXIXIXIXIXIXIXIX> . qXIXIXIXIXIXSXhXjXlXm.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi u u u u u u 5 t r l Y R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Q /. X+X%X1X1X1X1X1X1X1X1X1X1X1X1X1X<X4X) e 5 3 3 i 1 i.U.H.L.L.L.L.L.L.L.L.L.L.L.P.yXgXjXgXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXhXZXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX% % IXIXIXIXIXIXIXPXIXeX . NXIXIXIXIXIXSXhXjXlXiXu 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXu u u u u u u 5 3 r q K R.Y Y Y Y Y Y Y Y T Y Y Y Y Y Y Y Y ! W.(.oX at X<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X4Xt.e 5 u u i 2 b.U.L.L.L.L.L.L.L.L.L.L.L.L.P.tXfXkXgXkXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXxXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX& & IXIXIXIXIXIXIXIXIXGXX @ IXIXIXIXIXIXAXfXjXkXgXd 2 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXu u u u u u u u 5 t u v R.Y Y Y Y Y Y Y Y Y Y Y Y Y R R /._. at X%X<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X2X$.e 5 u u 3 i N.P.L.L.L.L.L.L.L.L.L.L.L.L.L.tXfXgXkXgXgXkXgXkXjXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX* = IXPXIXIXIXIXIXIXIXIX; 9XIXIXIXIXIXIXCXfXjXjXkX:.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXu u u u u u u u i t r k Y R.Y Y Y Y Y Y Y Y Y Y E.).XX at X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X,Xw t 3 u i 2 s L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.T.fXkXgXkXkXgXkXgXjXkXjXjXgXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX7X 7XIXIXIXIXIXIXIXIXIXIXNXX O LXIXIXIXIXIXIXcXfXjXjXvXp.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXu u u u u u u 5 5 r 9 ~ !.Y Y Y Y R Y W./. XoX<X1X1X1X1X1X1X1X1X1X1X3X1X3X1X1X1X1X1X1X1X1X1X1X4XA e 5 u 5 i 2 =.P.L.L.L.L.L.L.L.L.L.L.L.H.P.P.Y.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXeX wXIXIXIXIXIXIXIXIXIXIXIX8X eXIXPXIXIXIXIXIXxXgXjXgXbXz.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXu u u u u u u u 3 t u c R.Y E R W.(.XX at X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X|.t u u u u i 1 1.U.H.L.L.L.L.L.L.L.L.L.L.H.H.H.I.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXxXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXFXo + FXIXIXIXIXIXIXIXIXIXIXIXIX* 7XIXIXIXIXIXIXIXPXkXjXjXgXvXD.1 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 u e f Q _..X at X<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X3X,Xw t 5 u u u i 1 7.U.H.L.L.L.L.L.L.L.L.L.L.H.P.H.U.dXgXjXjXjXjXjXjXjXkXjXjXjXjXjXjXgXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIX; < IXPXIXIXIXIXIXIXIXIXIXIXIXLX= 7XIXIXIXIXIXIXIXIXHXgXkXjXgXvXrX2 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u 3 3 e 6 ] 4X1X1X1X1X1X1X1X1X3X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X%.e 5 3 u u u i 2 a.U.H.L.L.L.L.L.L.L.L.L.H.H.H.P.P.dXgXjXjXjXjXjXjXjXjXjXgXkXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXkXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXNX. . NXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXqXO @ eXIXIXIXIXIXIXIXIXIXCXfXkXjXjXlXiXp 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 t u D 4X2X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X1X3X1X1X4XJ e 5 u u u u u u 2 k.P.H.L.L.L.L.L.L.P.L.L.L.L.L.L.P.aXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXbXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIX> > IXIXIXIXIXIXIXIXIXIXIXIXIXIXIXLXIXLXeX7X> 8XwXLXIXIXIXIXIXIXIXIXIXIXzXgXgXjXjXlXdXa 2 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 u e &.OX4X1X1X1X1X1X1X1X1X1X3X1X1X3X1X1X1X1X1X1X1X1X1X1X2X}.u 3 3 u u u u u u 2 N.U.H.L.L.L.L.L.L.H.H.L.L.L.L.L.P.yXhXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXLX% % PXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXJXgXkXgXjXjXkXgXd 2 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 3 i i e w |.4X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X3X,XO.y 5 u u u u u u 3 i N.P.H.L.L.L.L.L.L.L.L.L.L.L.L.H.P.tXgXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXkXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXcXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXFX% . % FXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXPXIXIXIXIXIXIXIXIXIXIXIXVXhXkXkXjXjXjXkX:.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 5 e t S 4X2X1X1X1X1X3X1X1X1X1X1X3X1X1X1X1X1X1X1X1X4Xe.e 5 u u u u u u u u p N.P.H.L.L.L.L.L.L.L.L.L.L.L.L.H.L.Y.dXkXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXgXjXjXjXkXjXjXjXjXjXjXjXjXjXkXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXLX> X . > LXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXkXgXgXgXjXjXjXkX,.1 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 u e &.OX4X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X' e u u u u u u u u u 2 p Z.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.I.aXkXgXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXnXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXIXNX8X& @ & 8XNXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXVXfXkXjXjXjXjXjXlX4.4 i u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 3 e 0 ] 4X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X*X8 t u u u u u u u u u 3 p Z.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.aXgXgXgXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXJXjXjXjXjXjXjXjXjXlX6.1 i u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 t t S 2X2X1X1X1X3X1X1X1X1X1X1X1X1X1X,X+.e 8 u u u u u u u u u 3 a A.L.L.L.L.L.L.L.L.H.H.H.P.L.L.L.L.P.iXfXkXjXjXjXkXkXgXjXjXkXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXxXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXxXfXjXjXjXjXkXgXgXbXq.1 i u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u 5 u e $.-X4X1X1X1X1X1X1X1X1X1X1X1X4XA e i u u u u u u u u u i 2 a A.P.L.L.L.L.L.L.L.P.H.H.H.L.L.L.L.P.Y.gXgXjXjXjXgXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXAXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXZXgXjXjXjXjXjXgXgXgXbXu.1 i u u u u i u u u u i u u u UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 u u u u 5 e 0 ] 4X1X1X1X1X1X1X1X3X3X4X|.t u u u u u u 8 7 3 3 u u 2 p L.L.L.L.L.L.L.L.L.H.H.P.H.L.L.L.L.H.I.dXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXlXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXCXgXjXjXjXjXjXjXkXgXgXbXp.4 i i u u u 1 u u 3 u 3 u u u u UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u i u u u u u 5 t t A 3X3X<X1X1X1X1X1X3XOXw u i u u u u y v { t 3 3 u 2 s L.P.L.L.L.L.L.L.L.H.P.H.H.H.L.L.L.H.P.aXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXhXnXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXCXgXjXjXjXjXjXjXjXgXkXgXbXq.4 i u u u u q.p 2 p u u u u u u u UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 5 e +.=X4X1X1X1X1X1X2X&.e i u u u u e k R.} y u u i u p A.L.L.L.L.L.L.L.L.H.H.H.H.P.H.P.L.H.P.yXgXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXhXAXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXnXhXjXjXjXjXjXjXjXjXkXkXgXbXq.4 i i u u 2 iXiXa 1 u u u u u u u UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u i e 0 ` 4X1X1X,X4XJ e 3 u u u 5 y q E R.{ t i u u 2 p H.L.L.L.L.L.L.L.L.H.H.P.H.P.H.H.H.P.H.Y.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXgXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXxXzXSXIXIXIXIXIXIXIXIXIXIXIXPXCXkXgXkXjXjXjXjXjXjXjXjXgXgXgXbX6.1 i i u u 3 rXbXpX-.1 i u u u u u u UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 5 u t y.3X2X2X}.u t 5 t 5 5 i t ~ R.Y .y 5 5 u 3 i Z.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.aXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXkXgXkXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXfXgXgXkXCXAXJXPXIXPXPXPXDXZXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXlX3.1 i u u 3 u iXkXkXgX>.1 i i u u u u u UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u e +.-X,X} y 5 3 3 5 5 r c R.Y T ..y 5 5 u 3 i N.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.P.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXzXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXJXkXjXjXjXgXgXgXjXkXkXzXkXjXgXfXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkX,.2 i u u 2 p uXkXgXkXgX*.1 i u u u u u UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 3 e w $.e 5 3 5 3 5 y f T Y Y R.g r 5 3 u u u N.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.P.tXfXkXgXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXfXzXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXzXgXkXjXjXjXkXjXjXjXgXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjX-.1 u u u 2 p fXkXjXgXvXiXi 3 u u u u u u UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u 3 5 u t 5 u u u 5 t 9 E T Y E R.l r 5 5 u u 2 c.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.P.A.P.aXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXlXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXcXfXjXjXjXjXjXjXjXjXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXd 2 u u u 2 d jXkXjXgXgXbXC.1 i u u u u u u UXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 5 i 5 i u i u 5 y m R.E Y Y R.V r 5 5 3 i 2 k.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.yXgXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXHXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXZXhXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXpXa 3 u u i 2 >.kXjXjXjXjXgXbX6.1 i 3 u u u u UXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 t 3 i 3 u 3 5 e x R.Y Y Y Y R.v r 5 5 3 i 1 i.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.Y.fXjXjXgXkXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXCXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXnXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXjXjXjXjXjXjXjXjXjXjXjXlXrXu u u u i 1 3.lXjXjXjXjXgXlXpXp 3 i u u u i UXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 3 5 5 5 y ..T Y Y Y Y Y R.n r 5 t t i 1 6.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.H.P.aXgXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXhXzXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXPXbXhXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXg.d fXjXjXjXjXjXjXjXjXjXkXgXvXJ.2 u u u i 1 u.bXgXjXjXjXkXgXbXj.1 i u u u 3 i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 5 t 5 5 t 5 L T Y Y Y Y Y T ~ i u i 5 i 1 <.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.H.H.P.P.tXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXhXgXCXPXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXAXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXM.2 4 n.vXjXjXjXjXjXjXjXjXjXjXvXm.1 i u u i 1 h.bXjXjXjXjXgXgXvXdXp 2 u u u u i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 y N R.E Y Y Y Y Y T W 5 t 5 u i 2 | L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.dXgXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXfXkXCXJXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXIXHXxXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXm.1 i 1 z.bXjXjXjXjXjXjXjXjXjXgXvXg.4 i u u i 1 C.vXgXjXjXjXjXjXjXbX6.1 5 t u u i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u 5 5 5 r l ~.Y Y Y Y Y Y Y Y T { t 5 u u 3 p A.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.tXgXjXgXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXfXjXcXSXJXIXIXIXIXIXIXIXIXIXIXIXJXAXxXgXhXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXD.2 3 i 1 C.vXjXjXjXjXjXjXjXjXkXgXlXq.4 i u u 5 t rXvXgXjXjXjXjXjXgXvXF.2 5 3 u u i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 6 Y T Y Y Y T Y Y Y Y R.g r 5 u u i 5 N.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.U.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXfXgXkXxXCXAXDXHXHXHXSXAXZXxXjXfXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXD.2 3 u 2 d gXkXjXjXjXjXjXjXjXjXgXkXkX>.2 i u i 2 p dXkXgXjXjXjXjXjXjXkXdXs 3 i u u i 2 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 3 K T Y Y Y Y Y Y Y Y Y R.x r 5 u u i 1 k.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXgXfXfXgXgXjXgXgXhXhXgXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXbXm.2 3 i i 4 z.bXgXjXjXjXjXjXjXjXjXgXkXpXp t u u i 1 >.kXjXkXjXjXjXjXjXjXjXbX,.2 i u u i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 3 5 e c R.Y Y Y Y Y Y Y Y Y Y R.N y 5 t 5 i 1 7.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.F.U.dXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXkXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXvXg.1 3 u i 1 :.kXgXgXjXjXjXjXjXjXjXjXjXlXJ.2 u u u i 1 u.bXgXjXjXjXjXjXjXjXjXbXp.1 i u u i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 5 y g T Y Y Y Y Y Y Y Y Y Y E R.K 5 5 5 u i 1 ;.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.sXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXkXbXpX2.4 u i i 2 i iXlXjXjXjXjXjXjXjXjXjXjXjXbXn.1 i u u i 4 x.bXjXjXkXjXjXjXjXkXfXbXn.1 i u i i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 3 5 t 9 E T Y Y Y Y Y Y Y Y Y Y Y T E q y 5 u 5 3 s A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.U.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXgXgXlXbXjXn.p 1 u u i 2 2 G.bXgXjXjXjXjXjXjXjXjXjXjXgXlXu.4 i u u u 2 J.zXgXjXjXjXjXjXjXjXgXbXF.2 i u u i 2 0.UXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 3 t m R.Y Y Y Y Y Y Y Y Y Y Y Y Y R.g y 5 3 3 t 3 N.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.P.P.yXgXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXkXbXlXuXx.d 1 3 u u i 2 3 D.bXgXjXjXjXjXjXjXjXjXjXjXjXjXkX-.2 i u i 2 a dXkXgXjXjXjXjXjXjXjXgXvXJ.2 u u u i 1 0.UXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 i 5 5 u 5 5 y V R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y E.Z r i i u i 1 f.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXfXgXgXjXgXgXjXjXjXjXjXkXkXbXbXvXpXm.4.i 1 2 i i 5 5 1 i G.bXgXjXjXkXjXjXjXjXjXjXjXgXkXlXiXp 2 u u i 1 :.lXjXjXjXjXjXjXjXjXjXjXlXJ.3 t 5 3 i 1 0.UXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 t 3 t u u 5 y ..T Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y ~.( i t i u i 1 <.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.P.tXgXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXlXbXbXbXbXbXbXbXbXbXvXlXjXpXJ.h.2.p 1 1 3 i i u i i 4 | iXbXgXjXjXjXjXjXkXjXjXjXjXgXkXgXbXm.1 i u u i 1 j.bXjXjXjXjXjXjXjXjXjXjXlXJ.3 3 t 5 i 2 0.UXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 5 5 t u 5 t 5 U T Y Y Y Y Y Y Y Y Y T Y Y Y Y ! XX$Xw t 5 5 i 3 s A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.uXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXzXpXn.g.j.p.h.g.z.h.h.p.4.>.p 3 4 2 2 u p u u u i 3 1 6.gXlXgXjXjXjXjXjXjXgXjXjXjXjXkXjXgXbXu.1 i u u 3 2 F.bXjXgXjXjXjXjXjXjXjXgXbXC.2 i 5 5 5 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu t 5 5 3 u 5 y N R.E Y Y Y Y Y Y Y Y Y Y Y Y Y T (. at X4X&.e 5 3 u 3 2 c.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.Y.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXgXjXjXjXjXjXlXrXp 4 4 1 1 1 1 1 1 1 4 1 1 t u u u u u u i i 3 4 s m.bXlXgXjXjXjXjXjXjXjXjXjXjXjXjXgXgXjXgXd 2 u u u 2 p pXkXjXkXjXjXjXjXjXjXjXgXbXx.1 i 5 t i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 5 e l R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y ^. at X<X4XD e 5 u u i 1 8.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.tXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXvXu.4 p i i u u u p u u i i u i u u u u u u 3 4 u p.fXbXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXrX3 u u u i 1 :.lXgXkXgXgXkXjXjXjXjXgXgXbXi.1 i 3 i i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 y 6 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y W.XX<X1X4X{.u u u u i 2 | L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.uXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXgXvX6.1 i u u u u u u u u u u u u u i u u 2 4 u p.iXbXkXgXkXgXjXjXjXjXgXkXjXjXjXjXjXjXgXkXgXbXj.1 i u u i 1 g.bXgXgXkXjXjXjXgXjXjXkXgXkX*.1 i i i i 2 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 u 3 ~ R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R ).<X1X1X2X,XO.e 5 u t 5 2 N.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.tXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXjXjXjXjXgXjXjXjXjXbXg.1 i u u u u u u u u u u i i u 2 4 2 d g.uXvXlXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXkX-.1 u u u u 2 rXvXjXjXjXjXjXgXkXjXjXjXkXrXi 3 i 3 t i 1 UXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 i 5 r c R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R /. at X3X1X1X1X4Xe.e 5 3 5 i 2 8.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.L.L.A.A.H.F.L.yXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXkXkXuXp 1 i i u p u u i i u t 1 4 2 d u.F.kXbXlXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXkXgXlXrX3 u u u u 2 s gXkXjXjXjXjXjXkXgXjXgXdXdXg.1 i 3 5 5 i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 5 y f R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y T W.+X1X1X1X3X<X4X` t 3 3 u i 2 | L.L.L.L.L.L.L.L.L.L.L.L.L.A.L.L.U.U.U.U.U.U.T.U.U.U.U.aXgXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXlXJ.d 2 4 1 1 1 4 4 4 3 s 3.g.J.fXvXvXkXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXj.4 u u u 5 1 i.bXjXgXjXjXkXjXjXgXdXaXY.U.| 2 i u 5 t i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t 7 U Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y W.XX1X1X1X1X1X1X3X,Xw t 3 u u u 2 c.U.L.L.L.L.L.L.L.L.L.L.P.U.U.L.V.v.d.f.i.8.8.i.d.c.V.U.gXbXvXkXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXkXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXlXjXm.p.4.4.4.q.g.n.rXfXlXbXlXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXkXgX| 2 u u u t 2 D.bXgXgXgXgXgXdXuXtXI.P.U.c.3 5 t u 5 5 i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 y M R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R (. at X1X1X1X1X1X1X1X4Xe.e 5 3 5 i 2 5.U.H.L.L.L.H.H.L.U.U.H.N.f.3.| i u 2 2 2 2 1 2 2 u u s <.g.F.fXvXbXvXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXgXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXvXvXvXzXkXvXbXbXkXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXkXgXgXbXC.1 i u u u 3 s uXdXaXaXuXyXY.U.P.P.H.H.U.;.1 i u u t 3 i UXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 5 e h R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R ^. at X1X1X1X1X1X1X1X<X4X] t 3 3 t 3 3 i Z.L.L.H.L.U.U.Z.k.<.s t 2 1 2 u u i i i i i u u u u 2 1 1 2 i :.z.rXvXbXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXgXjXjXkXjXjXjXjXjXjXjXjXgXjXjXjXgXjXjXjXjXgXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXgXbX4.1 i u u i 1 5.yXP.P.P.P.P.L.L.H.L.H.U.l.2 i i u u 5 5 UXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 y .Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y W.oX1X1X1X1X1X1X1X1X1X1X3XO.e 5 u u i 1 f.U.H.P.U.v.1.i t 1 3 3 i u i u u u u u u u u u u u u i i i 3 1 1 t :.m.jXbXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXkXgXkXgXlXiXi t u u u u 2 v.U.A.P.P.P.H.H.L.L.L.P.H.s 3 i u u u i i UXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 u 5 P R.Y Y Y Y Y Y Y Y Y Y R Y Y Y Q XX<X1X1X1X1X1X1X1X1X1X1X4XS e 5 u u i 2 | P.U.N.:.2 2 3 5 u i 5 u u u u u u u u u u u u u u u u u 3 i i 5 3 2 1 d n.kXvXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXgXbXg.1 i u u u 2 *.P.L.L.P.A.L.L.L.L.L.L.U.3.1 5 3 i u u 3 UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u r b R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R (.#X1X1X1X1X1X1X1X1X1X1X1X3X*Xu t 5 5 u u 2 f.6.2 2 u u i 5 5 3 u u u i i i i u i i i i i u u u u u u u i u u i i 2 1 >.J.bXjXgXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXgXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXgXkXgXa 2 i u u i 1 a.U.A.L.A.A.H.L.L.L.A.Y.a.2 i 3 u u u u u UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i r l R.Y Y Y Y Y Y Y Y Y Y T Y Y Y Y W. at X<X1X1X1X1X1X1X1X1X1X1X1X1X4X&.y 5 3 3 u u i 2 u u u u 5 t u i i i u 2 1 1 1 1 1 1 4 4 2 1 1 2 3 i i i u u u u u u u 2 2 p.kXbXgXjXjXjXjXjXjXjXjXkXjXjXkXgXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXbXz.4 i u u i u p Z.P.L.L.H.P.P.A.L.A.U.l.3 3 i u u u u u UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 t q Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y W.XX3X1X1X1X1X1X1X1X1X1X1X1X1X1X4X] t 5 u u u u u i u u u u u u u u 2 1 2 a :.u.g.M.n.m.m.M.h.u.3.d u 1 1 2 u u u u u u u i u 1 -.iXbXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgX| 2 u u u i 1 5.U.H.L.L.L.L.L.L.A.Y.l.3 3 u u u 5 3 i u UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 u u G R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R (.<X1X1X1X1X1X1X3X1X1X1X1X1X1X1X1X2X+.e 5 u u u u u u u u u i t 1 i :.z.rXdXkXvXlXvXbXvXvXbXbXbXzXkXiXm.q.a 2 1 u i u u u u u i 1 i C.bXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXn.1 i u u u 3 5 N.U.H.L.L.L.L.A.L.U.d.2 3 u u u u 5 t 3 UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 r Z R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y (. at X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X2X' t u u u u u u u u u 2 4 d g.iXkXlXlXkXjXgXfXjXjXgXgXgXjXgXjXjXkXvXvXfXD.3.2 4 i u u u u u i u 1 x.bXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgX| 2 i u u i 1 <.P.H.L.L.L.L.A.P.P.5.2 u i u u u u 3 i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 r f R.Y Y Y Y Y Y Y Y Y T Y Y Y Y Y W. at X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X}.t u u u u u i u u 4 d n.kXbXlXjXjXgXjXjXjXkXjXjXjXkXjXjXjXjXjXjXgXjXjXlXzXJ.3.2 2 i u u u u i u 1 h.bXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXz.1 i u u u u 3 c.U.H.L.H.L.P.U.v.| 2 i u u u u u u i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 t 7 E Y Y Y Y Y Y Y Y Y Y Y Y Y Y R W.XX<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X*X0 t 5 5 u u u i 2 u g.fXbXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXzXkXF.d 1 u u u u u i u 1 x.bXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXuXp 3 i 3 3 i 2 ;.U.H.H.L.P.U.Z.1.3 2 i i 3 u u u i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 5 3 t m R.E Y Y Y Y Y Y Y Y Y Y Y Y Y ! (.<X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X,X at .e 5 3 3 u u i 1 *.rXvXkXgXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXvXjXp.1 u u u u u i t t F.bXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXi.1 i t 5 i 5 2 c.U.L.U.P.N.5.i 2 t i u u u u t i i UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 r V R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y E.^. at X1X1X1X1X3X1X1X1X1X1X1X1X1X1X1X1X1X4Xe.e 5 u 3 3 u u 1 3.pXlXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXm.u 2 i u u u 5 3 p pXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXkXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXgXZ.3 u 3 5 u i 1 5.T.H.N.i.| 5 1 3 i 5 5 u u u u 5 3 UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 y .R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y E.oX1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X) e 5 i u u u u 1 6.fXkXgXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXJ.p 2 i u u u i 1 ,.lXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXdXyX:.1 i i 5 u t 5 <.<.a u 1 2 i 5 t u u u u u u i 1 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 3 t 7 P R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R XX<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X3X-X8 t 5 u u i i 1 7.T.aXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXrXp 2 u u u u i 1 z.bXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXkXgXkXgXgXaXsXa.1 i u u u u 3 i 2 2 t 5 i i u u u u u u u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 3 e n R.E Y Y Y Y Y Y Y Y Y Y Y Y Y R (.<X3X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4X%.e 5 u u u i 1 3.U.Y.hXkXjXjXjXjXjXjXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXvXG.3 3 i u u i 3 p uXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXgXuXU.A.i 3 i u u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 5 r h R.Y Y Y Y Y Y Y Y Y Y Y Y Y Y R W. at X<X1X1X1X1X1X3X1X1X1X1X1X1X1X1X1X<X4X] t i u u u i 1 =.P.P.yXgXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXfXbXn.1 i u u u i 1 q.bXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXgXdXtXP.U.<.2 i u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u t o.Y Y E Y Y Y Y Y Y Y Y Y Y Y Y Y W.oX1X1X1X1X3X1X1X1X1X1X3X1X1X1X1X1X1X1X4X&.e i u u i 3 i V.P.P.aXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXvX4.1 i u u 3 3 3 iXlXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXaXY.P.U.d.1 i u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u 3 u 3 K R.E Y Y Y Y Y Y Y Y Y Y Y Y Y ! X<X1X1X1X1X1X1X1X1X1X1X1X1X3X1X1X1X1X2X}.3 t i u i u 2 i.U.H.P.dXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXpXp u u u u i 1 p.bXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXkXgXkXgXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXpXsXP.P.P.V.i 3 i u u u u u u u u 3 5 i 3 u i 3 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX1 i u u u u u r b R.E Y Y Y Y Y Y Y Y Y Y Y Y Y R ^.#X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X4XA e 5 u u i 2 | L.L.H.I.dXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXfXbXh.4 i u u u 2 d jXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXgXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXkXjXfXuXtXP.L.H.P.| 2 i u u u i u u u u u i 5 t i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX1 i u u u 5 r k R.Y Y E Y Y E Y Y Y Y Y Y R Y Y Q.+X<X1X1X1X1X1X1X3X1X1X3X1X1X1X1X1X1X1X1X3X at .t 5 5 5 i 2 a.U.H.P.U.dXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXa 2 i u u u 2 J.vXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXfXfXiXU.P.L.H.U.6.2 i u u u u t 5 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX2 i u u 5 t { Y R.R.R.R.R.R.R.R.Y R.Y Y Y Y E ! XX<X1X<X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X2X*X5 t i 5 i t i A.L.L.F.U.dXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXlXp.1 i u u i 1 s.vXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXfXyXU.P.L.L.H.U.k.2 t i u u u u 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX1 i u u 5 t 6 g k h V v N M ~ K U U Y Y E.R.~._.2X4X4X2X4X2X3X1X1X1X1X1X1X1X<X1X1X1X1X,X4X' y 5 3 3 i 1 3.U.H.L.L.U.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXlXJ.2 3 3 u i 2 :.aXfXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXgXkXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXfXuXtXP.P.L.L.L.U.N.i 3 i t t 5 5 3 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX2 i u u i 3 t r r e r r r r t u 5 7 q { ..g z F D _ ' |.&X*XOX,X1X2X2X4X4X4X4X4X4X4X1X3X5Xr.e 5 3 i i 2 l.U.H.L.L.P.uXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXgX*.2 i u i 2 a A.U.iXdXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXgXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXkXjXfXuXtXU.L.L.F.L.L.L.A.p 2 i 5 5 5 5 3 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUX1 i u u u u 5 5 5 5 5 5 u u u u u t t t e r r e e e y t u i 0 q O.+.&.e.r.S J ' ] }.*X-X,X+.y 5 u i 3 i V.P.H.L.L.P.yXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXgXbXq.1 i u u 3 3 v.U.L.U.yXfXfXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXgXjXjXjXkXgXjXjXjXjXjXjXgXkXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXfXfXuXtXU.L.L.L.L.L.L.L.L.*.2 i u 3 t 5 t i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u i 5 t 5 u u u u i u u 5 5 5 5 5 5 5 5 3 3 t t y e e e e e e e r e e u 8 0 i 3 3 u u 2 | P.L.L.L.L.P.tXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXz.4 i u u u 2 f.U.A.L.P.U.yXpXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXkXjXkXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXfXiXtXP.A.L.L.L.L.L.L.L.U.<.1 i u u i 3 5 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXi i u u u u u u u u u u u u u u u u u u u 5 t 3 u u u u i 5 5 5 5 5 5 u i 5 u i u u t t t u u u i 1 <.P.L.L.L.A.P.U.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXgXlXD.1 i u u u 1 6.U.L.L.L.L.P.I.tXuXfXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXkXgXgXkXjXjXjXjXgXjXjXjXjXjXjXjXjXjXgXfXpXyXY.I.A.L.L.L.L.L.L.H.L.U.5.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u u u u u 3 5 3 3 i u u u u u u u u i u u u u u u u u i 5 u u u u i 1 1.U.L.L.L.P.A.P.sXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXgXjXjXjXgXlXJ.2 i u u i 1 3.U.L.L.L.L.A.P.P.P.Y.yXpXfXgXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXkXgXjXjXjXjXkXgXjXjXjXjXkXgXgXdXuXT.U.P.L.L.L.L.L.L.L.L.H.L.U.5.2 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u u u u 3 i i u u 3 u u u u u u u u u u u u 3 u u u 5 3 u u i i 1 5.U.A.L.L.A.P.L.yXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXgXjXjXlXrX2 u u u i 1 1.U.H.L.L.L.P.H.P.A.L.P.U.Y.uXdXfXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXgXkXjXjXjXjXjXjXjXjXjXjXkXgXkXgXjXjXjXjXgXkXjXgXgXfXdXsXyXU.P.L.A.P.A.L.L.L.L.L.L.H.L.U.8.1 u i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u 5 5 t u u u u u u u u u u u u u u u u u u u 3 3 3 i i i 1 3.U.L.L.L.L.A.L.U.aXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXlXrX2 u u u i 2 1.U.H.L.L.L.A.A.P.H.L.L.L.L.P.U.Y.yXsXdXgXjXgXjXjXjXjXjXjXjXjXgXkXjXjXjXgXjXjXjXjXjXgXkXjXjXjXjXjXjXgXkXgXkXkXgXkXgXgXgXfXaXaXiXY.P.P.P.L.L.P.A.P.A.L.L.L.L.H.L.U.8.1 u i u u u u i u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u u u u u u u u 3 5 i 3 u u u u u i 1 <.P.L.L.L.L.L.L.L.T.fXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXjXjXgXlXF.1 u u u i 2 5.U.A.L.L.L.L.L.L.L.L.P.H.H.L.L.P.P.P.Y.Y.iXaXdXgXgXgXgXgXkXkXjXjXjXjXjXgXjXjXjXkXgXkXjXjXjXjXjXjXkXgXjXgXgXgXfXdXdXuXtXY.I.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.U.7.1 i i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi 5 t i u u u u u i 2 =.U.L.L.L.L.L.L.L.P.aXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXkXjXjXkXfXvXm.1 u u u u 2 8.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.A.P.P.P.P.U.I.Y.yXuXaXdXdXfXfXgXgXgXgXgXgXjXgXgXgXgXgXgXgXgXfXdXdXdXuXyXyXY.Y.P.P.P.P.A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.U.3.1 i i 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi 3 u u i 2 p Z.L.L.L.L.L.L.L.P.I.dXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXbXs.4 i u u i 2 l.U.A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.A.H.H.P.H.H.P.P.P.P.I.U.tXT.yXtXiXyXuXaXaXuXyXuXsXaXtXiXY.tXY.U.P.P.P.P.P.H.L.H.P.A.P.L.L.L.L.L.L.L.L.L.L.L.L.L.H.U.L.:.1 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u i 3 N.P.L.L.L.L.L.L.H.P.tXdXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXlX,.1 i u i t i V.L.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.A.P.P.H.P.H.H.P.H.H.H.P.H.P.H.P.P.P.P.P.P.P.P.P.P.P.P.P.P.A.P.L.L.L.P.P.H.H.H.L.H.H.H.H.L.L.L.L.L.L.L.L.L.L.L.H.H.U.Z.| 1 i i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 1 i.U.L.L.H.P.H.H.H.H.P.tXdXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXjXjXjXjXjXjXjXkXaXi 3 i u u 3 | L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.H.P.H.L.L.L.L.L.L.L.L.L.L.L.L.H.H.P.H.L.L.L.L.L.L.L.L.L.L.H.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.U.v.p 1 i u i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 2 | P.L.L.H.H.H.P.P.H.P.P.yXhXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXjXjXjXjXjXjXjXjXjXgXbXn.1 u u u i 1 3.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.H.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.H.L.L.L.L.L.L.L.L.L.L.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.U.a.3 3 5 u u 3 u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u 3 v.P.H.H.P.H.H.A.P.A.P.P.tXdXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXkXgXjXjXgXgX;.2 i u u i 2 k.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.H.P.L.L.L.L.L.L.L.L.L.L.H.H.H.P.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.L.1.1 t i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 2 <.U.H.H.H.H.P.H.A.P.A.L.P.tXaXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXgXkXgXgXjXB.1 i u u 3 3 i Z.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.H.L.L.L.L.L.L.L.L.L.L.P.H.H.H.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.U.v.d 2 i 3 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 3 v.U.H.H.L.L.L.L.L.L.L.L.P.U.uXdXjXkXjXjXjXjXjXjXjXgXjXjXjXgXjXjXjXjXjXkXgXjXjXjXjXjXjXjXgXuXtX*.1 i i i i 1 ;.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.P.8.t 2 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 1 | P.L.L.L.H.L.L.L.L.L.L.H.L.P.Y.uXdXgXjXjXjXjXjXjXkXjXjXjXkXjXjXjXgXjXjXjXjXjXjXjXjXgXaXtXT.a.2 5 t i 5 i 2 k.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.U.N.;.1 5 i u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u t 5 1 8.U.H.H.P.L.L.L.L.L.L.L.L.P.P.P.tXaXfXgXjXjXkXkXgXjXjXkXgXjXjXjXkXkXgXjXjXjXgXfXaXyXU.U.V.i t 5 3 u u 2 d L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.U.L.8.u 2 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 i 3 3 b.U.H.H.L.L.L.L.L.L.L.L.H.H.P.P.P.U.yXaXdXgXgXgXjXjXgXkXjXjXjXgXgXgXgXfXaXuXY.U.L.P.A.| 2 i 5 i u u 2 k.U.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.P.U.l.| 1 3 u i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 3 i N.U.H.L.L.L.L.L.L.L.L.H.H.H.P.L.L.P.P.U.tXyXuXaXaXfXdXdXdXdXdXaXuXtXY.U.P.L.L.L.U.;.2 i u u u i 2 ;.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.U.N.;.2 2 i u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u t 5 3 p B.U.H.L.L.L.L.L.L.L.P.H.H.H.H.H.H.L.P.H.P.P.P.U.U.U.U.I.I.P.P.P.P.P.L.L.A.L.P.1.2 i u u u i t 5 V.P.H.L.L.L.L.L.L.L.L.L.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.P.U.V.3.u 2 i i u u u u i i 5 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i 2 i v.U.H.H.L.L.L.L.L.L.L.L.L.L.P.L.L.L.L.P.H.L.L.L.L.P.H.L.L.A.P.A.A.L.L.P.L.;.2 i u u u i i 1 d.U.H.L.L.L.L.L.L.L.L.L.L.L.P.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.P.U.V.5.i 2 u u u u u u u i 2 2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 i 2 3 i.U.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.L.L.L.L.L.L.L.L.H.H.P.A.L.U.N.| 2 i u u u u i 1 1.U.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.U.U.N.3.i 1 3 u u u u u u i i 1 | :.1 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i u 2 ;.V.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.U.P.i.i 3 i u u u u u 2 ;.P.H.H.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.U.L.b.:.3 2 3 i i u u u u i i 2 1 q.gXjX*.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u i 2 i 8.L.U.L.L.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.A.L.U.P.c.| 1 3 i u u u u u i 2 <.N.H.U.P.L.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.L.P.U.P.V.8.d 2 2 3 u 3 u u u u u u 3 1 >.F.vXjXlXuXp 2 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i i u 2 a 8.V.U.U.P.A.H.H.L.L.L.L.L.L.L.L.H.H.L.A.L.P.U.L.k.;.3 2 u u u u u u u u u i 2 3 | 8.N.L.U.U.L.H.H.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.H.H.P.U.P.Z.f.;.i 2 2 i i u u u u u u i 3 4 s n.kXlXjXjXgXbXm.1 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u u u 3 2 i <.l.Z.P.U.U.P.P.L.L.L.L.L.P.U.P.U.P.P.v.8.d 2 1 5 i u u u u u u u u 3 3 i t 2 2 u | 7.c.H.U.U.P.L.L.A.H.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.H.H.L.L.L.U.U.L.N.a.;.i 2 2 3 i i u u u u u u i u 2 a g.fXvXkXgXjXkXgXkXbX2.1 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u i i 3 2 2 p ;.5.k.v.V.Z.H.L.H.Z.V.N.b.i.<.d 3 1 2 i i t u u u u u u u u u u u u u u i u 3 1 3 p <.f.N.H.P.U.L.U.L.L.L.A.A.L.L.L.H.H.L.L.L.L.L.L.L.L.H.H.L.H.H.H.H.L.L.P.U.U.U.L.V.k.3.| u 1 2 3 u i 3 u u u u u u u 2 1 p j.fXbXkXfXjXjXjXjXjXgXlXJ.3 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u i u u u u u u 3 i 5 t 2 2 2 2 i a p d s a i 3 3 1 1 3 u i i u u u u u u u 3 2 2 u i i u u u u u u i i u 2 2 1 u s :.7.d.N.A.P.U.U.U.U.P.P.P.P.L.P.L.L.L.P.L.P.P.P.P.U.U.U.U.P.H.N.k.8.<.| i 2 2 2 u i u u t 5 u u 3 u i u 2 1 d h.pXbXkXjXjXjXjXjXjXjXjXjXjXvX,.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u u u 3 i i i u 3 u 3 3 2 2 2 i i i i i i u u u u u u u u i 2 | b.:.u 1 2 3 u i u u u 3 u u i i i u 2 2 1 2 t i | :.5.i.k.l.v.V.Z.Z.Z.H.H.H.A.Z.Z.B.N.c.k.a.5.<.| p 5 2 2 2 2 3 u i i u u u u u u i i i 3 1 t >.n.gXbXkXgXjXjXjXjXjXjXjXjXjXjXjXbXm.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u 3 u u u u i u i i i 5 i u u u u u u u u u u u u u i 2 5.T.U.N.8.| 2 2 2 i i i i 3 u u 3 3 u i i i u 3 2 2 2 1 1 2 2 3 i i p p p p p p i p 5 t 2 2 2 2 1 2 3 3 t i i u u u u u u u u i i i 3 1 1 a u.J.lXbXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXkXdXa 2 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u u u u u u u u u u u u 3 i 5 t u u i 2 8.P.H.P.U.H.b.4.s 1 1 2 3 i u 3 u 3 i 3 3 u u u i i i i i u i u t 3 3 2 3 2 3 2 t 3 3 u u i i i i 5 i 5 u u u u u u 3 i i i i 3 1 1 p 3.m.pXvXlXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXjXlX4.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 i u u u u u u u u i u u u u u u u u 3 5 5 u u i 2 k.U.H.H.H.H.U.U.tXD.i.*.u 1 1 3 u i i i u u u 3 3 u u u u u u u 3 5 3 i u u u i i i 3 3 u u 5 5 5 t u u u 3 u i i i 5 3 1 1 2 s 4.n.pXbXbXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXg.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u 3 u u u u u u UXUXi t 5 3 u i 1 k.P.H.L.L.L.A.H.U.gXbXjXrXx.3.s 3 1 1 2 3 i i i u u i 3 u u 5 i 3 u u i u u u u u u u u u i 3 t u u u u u i 3 2 1 1 1 p :.s.F.fXlXbXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXbXC.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u UXUXUXUXUXUX3 5 5 u u i 1 k.U.H.L.L.L.H.P.P.yXgXjXlXbXvXfXrXz.6.| i 1 1 2 2 3 3 i i i i 5 i i i i i i i i i i i i i i i 3 u u u u i 2 2 d 3.g.F.dXlXbXvXkXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXbXJ.2 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i 5 u u i 2 a.P.H.L.L.L.L.L.A.Y.dXjXjXjXjXkXvXbXbXjXiXD.z.6.;.p i 2 1 1 1 1 1 1 3 1 2 2 2 2 2 1 1 1 1 1 2 5 u 5 5 i 2 6.iXgXlXbXbXlXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXrX3 u i 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX3 t u u u 2 8.U.H.L.L.L.L.L.P.P.iXgXjXjXjXjXgXgXgXkXlXbXbXbXjXdXyXG.n.z.p.q.4.:.=.;.| | | ;.>.:.2.7.u.z.4.2 i t t i 1 n.bXkXgXgXjXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXlXrX2 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 1 1.U.H.L.L.L.L.L.L.L.Y.uXgXjXjXjXjXjXjXjXgXgXgXgXkXlXlXbXbXbXbXbXvXkXkXkXjXjXjXkXjXkXvXvXbXmXj.4 i 5 5 5 1 S.kXgXgXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXvXJ.2 3 u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 2 | P.L.L.L.H.H.P.L.L.P.tXfXgXjXjXjXjXjXjXkXgXkXgXgXgXgXgXgXgXgXgXjXgXjXjXjXjXkXjXjXjXjXgXgXkX<.1 i t 5 3 i A.hXgXkXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXD.1 i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 3 i V.P.H.L.L.L.L.L.L.L.P.uXfXjXjXjXjXjXjXgXkXgXgXjXjXjXjXjXkXgXjXjXjXjXjXjXjXjXjXjXjXkXgXkXfXs 2 i u i 2 | P.Y.fXgXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXh.1 i 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 i 2 k.U.H.L.L.L.L.L.L.L.L.P.uXgXjXjXjXjXjXkXgXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXvXF.1 u u u i 1 1.U.P.uXgXgXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXvX6.1 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u 3 i 2 1.U.H.L.L.L.L.L.L.L.L.P.P.uXgXjXjXjXjXjXgXkXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXbXp.1 i u u i 2 f.U.H.U.aXgXgXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXfXd 2 i i u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i t i Z.P.L.L.L.L.L.L.L.L.L.P.P.uXgXgXjXjXkXkXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXkXdXs 2 u u u u u N.P.H.L.U.dXgXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXzXD.1 i u 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 1 i.U.A.L.L.L.L.L.L.L.L.L.P.P.yXfXgXjXgXjXkXgXkXgXjXjXjXkXjXkXgXjXjXjXjXjXjXjXjXjXgXkXz.1 i u u u 2 d L.L.L.L.F.U.uXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXgXgXkX4.1 i 3 u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u i 3 s H.L.L.L.L.L.L.L.L.L.L.A.H.P.Y.aXfXjXjXgXkXgXkXjXjXjXgXjXjXjXjXjXjXjXjXjXjXjXgXdXyXd 2 i u u u 1 7.U.L.L.L.L.P.U.uXfXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXI.3 3 i u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 5 i 1 8.U.L.P.H.L.L.L.L.L.L.H.P.H.P.U.yXdXgXgXgXkXjXjXjXjXjXjXjXjXgXjXjXjXjXjXgXdXuXyXa.1 i u u 3 3 t N.P.L.L.L.L.L.P.P.tXdXgXjXjXjXjXjXjXjXjXkXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXaXsX3.1 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 i t i N.U.A.L.L.L.L.L.L.L.L.H.H.H.L.L.U.yXaXdXgXgXjXjXjXjXjXjXjXkXkXgXgXfXaXsXU.U.Z.i 3 i u u i 2 =.P.L.L.L.L.L.L.A.P.P.U.yXfXgXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXjXgXdXtXyXv.2 u 3 u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u i 2 =.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.F.P.Y.yXuXdXfXfXgXfXfXfXfXfXsXuXY.I.P.L.U.;.2 i u u u 3 u c.U.H.L.L.L.L.L.L.L.L.L.P.U.yXdXgXgXjXgXjXjXjXjXkXjXjXjXjXjXjXgXfXaXyXU.P.F.d 2 u u u u 3 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i 2 5.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.P.L.P.P.P.U.Y.Y.tXY.Y.U.U.P.P.P.H.A.U.5.1 i u u u i 3 i Z.P.H.L.L.L.L.L.L.L.L.L.H.P.P.U.Y.uXdXfXfXhXgXgXjXjXgXgXgXfXaXuXtXU.P.P.P.<.1 i u u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u 3 u i 2 8.U.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.A.P.A.L.L.P.L.L.L.F.L.L.L.L.H.A.Y.f.2 u u u u u u i 1 =.L.P.L.L.L.L.L.L.L.L.L.H.L.L.L.L.P.P.Y.Y.yXyXyXyXyXyXtXY.Y.U.P.L.L.L.Y.5.2 i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u 3 i.U.L.L.L.L.L.L.L.L.L.L.L.L.L.A.P.A.P.L.L.L.L.L.L.L.L.L.L.L.H.Y.f.2 u u u u u u u i t 2 =.L.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.H.P.F.P.P.P.P.P.P.P.L.L.L.L.L.L.U.5.1 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i u 2 7.U.P.H.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.U.8.2 u u u u u u u u i u i 1 | V.U.H.H.L.L.L.L.L.L.L.L.L.L.L.H.H.L.L.L.L.L.L.A.A.P.A.L.L.U.L.<.2 i 3 u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u i u 2 :.Z.U.L.A.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.L.P.A.<.2 u i u u u u u u u 3 u i i 2 i k.U.P.H.L.L.L.L.L.L.L.L.L.L.P.H.L.L.L.L.L.L.A.P.L.A.P.U.N.| 1 i u u u u u 3 u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u 1 p k.P.U.L.L.L.L.L.L.L.L.L.L.P.L.L.L.P.A.A.A.L.U.U.k.a 2 u u u u u u u 3 u u u u u u u t 2 <.V.U.P.L.H.L.L.L.L.L.L.L.L.L.L.L.P.L.L.A.L.L.P.U.H.8.3 2 i u u u u u u i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 3 1 ;.b.L.U.P.L.L.H.H.H.L.L.A.L.A.A.A.P.P.U.U.c.:.2 2 i u u u u u u i UXu u u u u u u i u 2 i 5.N.U.U.P.L.H.A.L.H.H.L.L.H.H.A.A.A.P.U.U.Z.a.p 1 3 i i u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i i 2 2 | a.Z.U.U.U.P.P.P.L.P.P.P.U.U.P.Z.f.;.2 2 u i u u u u u u u UXUXUXi 3 u u i 5 3 i 5 5 1 i :.k.Z.P.U.U.P.P.P.P.P.L.P.U.U.U.H.c.3.p 1 3 i u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX3 i u u u u u u i 3 3 2 i | 7.d.N.N.V.H.Z.Z.N.k.8.-.i 2 2 u i u u u u u u u u UXUXUXUXUXu u 5 t 5 t 3 t i i 3 2 2 p ;.7.k.N.V.Z.A.Z.V.N.b.i.<.s 2 2 t 5 5 i u i u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u i u 3 3 2 2 t i p p p i 3 2 2 2 3 i i u u u u u u u u u UXUXUXUXUXUXUXUX5 3 i 3 u u u u u i i 3 2 2 2 2 i i i p i u 2 2 2 2 u i i u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u i 3 3 3 i i 3 3 3 2 3 3 3 3 i i u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXi u u u 3 u u u u u 3 u i i u 3 3 3 t 5 5 u u i u 3 i 3 u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu i u 5 u u u u u u u u u u 3 i i u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i u u u u u u u u u u u i i i u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u 3 u u u u u u u i u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u 5 u u u u u u u u 3 u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi u u u u u u u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u 3 u u u u u 3 u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXu u u u u u u u u u u u u u u UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
-};
diff --git a/debian/hicolor-icons/32x32/hedgewars.xpm b/debian/hicolor-icons/32x32/hedgewars.xpm
deleted file mode 100644
index c32d5f3..0000000
--- a/debian/hicolor-icons/32x32/hedgewars.xpm
+++ /dev/null
@@ -1,239 +0,0 @@
-/* XPM */
-static char *Icon___x__x__[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 201 2",
-" c #010101",
-". c #0A0709",
-"X c #1A1A1A",
-"o c #454545",
-"O c #94005E",
-"+ c #AE005D",
-"@ c #970063",
-"# c #9B0064",
-"$ c #94066D",
-"% c #9D036A",
-"& c #9E086E",
-"* c #880873",
-"= c #960E74",
-"- c #980D73",
-"; c #8C1578",
-": c #8C1A7D",
-"> c #9D1075",
-", c #9D177C",
-"< c #91187D",
-"1 c #9B1C7D",
-"2 c #A20065",
-"3 c #AA0067",
-"4 c #A3046B",
-"5 c #A0096F",
-"6 c #A20C73",
-"7 c #AD0B72",
-"8 c #A41276",
-"9 c #AD1074",
-"0 c #A61479",
-"q c #A81C7B",
-"w c #7B2083",
-"e c #772E8F",
-"r c #7D2C8E",
-"t c #732F91",
-"y c #6B3596",
-"u c #653B9B",
-"i c #6D3A9B",
-"p c #743294",
-"a c #783092",
-"s c #713899",
-"d c #5641A1",
-"f c #504BA9",
-"g c #5A4EAD",
-"h c #4D5AB6",
-"j c #5652B0",
-"k c #5058B5",
-"l c #6444A3",
-"z c #7C4CA8",
-"x c #7654B2",
-"c c #4363BF",
-"v c #3D67C3",
-"b c #3A69C5",
-"n c #3C73CE",
-"m c #2C77D1",
-"M c #237CD6",
-"N c #2C78D2",
-"B c #2F7ED8",
-"V c #3E7BD5",
-"C c #5F71CC",
-"Z c #6F6ECA",
-"A c #627FD6",
-"S c #6C7ED6",
-"D c #617ED9",
-"F c #6F7ED9",
-"G c #881F82",
-"H c #A11F83",
-"J c #AC1D82",
-"K c #872386",
-"L c #8A2387",
-"P c #8D2689",
-"I c #8A2C8F",
-"U c #952388",
-"Y c #812F91",
-"T c #873595",
-"R c #8D3192",
-"E c #8A3799",
-"W c #84399A",
-"Q c #AE2285",
-"! c #A32488",
-"~ c #A92D8D",
-"^ c #B1258A",
-"/ c #B32C8C",
-"( c #BD298E",
-") c #B5308E",
-"_ c #B72E91",
-"` c #BE2C91",
-"' c #BA3495",
-"] c #BA3895",
-"[ c #BC3C9A",
-"{ c #BF3BA0",
-"} c #C32E93",
-"| c #C23391",
-" . c #CF3D9D",
-".. c #C13DA2",
-"X. c #CA3BA0",
-"o. c #BE419C",
-"O. c #8148A4",
-"+. c #8152B0",
-"@. c #C0439E",
-"#. c #C345A3",
-"$. c #C54EA5",
-"%. c #CE4AA3",
-"&. c #C645AA",
-"*. c #C74EA9",
-"=. c #C94AAE",
-"-. c #D045AA",
-";. c #D04BAF",
-":. c #C750A8",
-">. c #CC59AB",
-",. c #CB4DB1",
-"<. c #CC51B4",
-"1. c #CD5AB0",
-"2. c #D45CBF",
-"3. c #D363BA",
-"4. c #D65FC3",
-"5. c #D769C0",
-"6. c #DB6CC3",
-"7. c #DE66C9",
-"8. c #DE6BCE",
-"9. c #DB74C5",
-"0. c #DE76CB",
-"q. c #DF6DD0",
-"w. c #E068CC",
-"e. c #EA7FCF",
-"r. c #E06FD1",
-"t. c #E274D5",
-"y. c #E47BD6",
-"u. c #E376D8",
-"i. c #E479D9",
-"p. c #E87FDE",
-"a. c #1E83DC",
-"s. c #2482DB",
-"d. c #2B80DA",
-"f. c #3682DC",
-"g. c #1B8BE3",
-"h. c #3187E0",
-"j. c #3D8BE4",
-"k. c #2790E8",
-"l. c #3594EC",
-"z. c #3D94EC",
-"x. c #4C90EA",
-"c. c #5494EB",
-"v. c #469CF4",
-"b. c #4C98F1",
-"n. c #5A97F1",
-"m. c #529AF2",
-"M. c #5A9FF8",
-"N. c #6B87E1",
-"B. c #49A1F9",
-"V. c #59A3F6",
-"C. c #52A6FE",
-"Z. c #5DA7FE",
-"A. c #56AFFF",
-"S. c #5CABFF",
-"D. c #56B4FF",
-"F. c #58B5FF",
-"G. c #54BBFF",
-"H. c #898989",
-"J. c #8A918D",
-"K. c #949394",
-"L. c #9C9B9C",
-"P. c #B5B4B5",
-"I. c #E483D2",
-"U. c #E789D6",
-"Y. c #E781DA",
-"T. c #E985DC",
-"R. c #EA89DC",
-"E. c #EC91DE",
-"W. c #EE9BDA",
-"Q. c #EC87E2",
-"!. c #EC8CE2",
-"~. c #EE93E1",
-"^. c #F195E6",
-"/. c #F29BE7",
-"(. c #F49EE9",
-"). c #F4A6E5",
-"_. c #F5A2EB",
-"`. c #F9A6EF",
-"'. c #F6AAED",
-"]. c #F5B2EC",
-"[. c #F6A2F0",
-"{. c #FAA6F1",
-"}. c #FAAAF3",
-"|. c #FBB7F5",
-" X c #FEB1F8",
-".X c #C8C7C8",
-"XX c #CBCBCC",
-"oX c #CDD1CF",
-"OX c #F3D2EB",
-"+X c #F7C6F0",
-"@X c #F8C1F1",
-"#X c #F8CAF2",
-"$X c #FFD1FC",
-"%X c #FDDBFB",
-"&X c #F9E6F7",
-"*X c #FDE5FA",
-"=X c #FDEDFB",
-"-X c #F3FCF5",
-";X c #FCF3FA",
-":X c #FEFEFE",
-">X c None",
-/* pixels */
-">X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>X= & >X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>Xp v : >X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>Xr k.f.u 4 >X>X>X>X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>Xt z.Z.l.c : 3 >X>X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>Xy l.Z.Z.B.h.l > >X>X>X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X>X4 >X>X>X>X>X>Xt j.Z.A.S.n.C f * % >X>X>X>X>X>X>X>X>X>X>X",
-">X>X>X4 l g l i p r K : T P L R ~ ] [ ] ^ 8 O >X>X>X>X>X>X>X>X>X",
-">X>X>X>Xs g.s.s.s.M M s.d 8 %.I.(._.{.`._.E.3.Q # >X>X>X>X>X>X>X",
-">X>X>X>X4 D C.m.m.b.v.p ' E.}._.(././.(./._.`._.1.& >X>X>X>X>X>X",
-">X>X>X>X>XT A.Z.D.D.W .}._././.(._.(.(././.^./.}.6.6 >X>X>X>X>X",
-">X>X>X>X>X2 A D.N.W ( _._./.(.(.(.(.(./.'.+X at X_.].$X9.# >X>X>X>X",
-">X>X>X>X>X>X1 E ; 7 i._.(.(.(.(.(._./.].:X:X:X;X:X:X:X$.>X>X>X>X",
-">X>X>X>X4 < i b y -.!.(.(.(._.(.(.(./.*X:X:X:X:X:X:X-XOX6 >X>X>X",
-">X>X6 r k m a.m ! 7.!._.(.(.(.(.(./._.:X:X:XL.P.:XH. XX>.>X>X>X",
-">X* n a.M B z.C ( t.R._.(.(.(.(.(./.'.;X:X.X X :Xo J.W.# >X>X",
-">X# a V v.V.G.z X.t.R._./._.(./.(.(.(.=X:X.X X :XK.. oX).% >X>X",
-">X>X>X0 F G.S 2 ,.t.Y._./.(.(._.(._.^.#X:X:XK.P.:X:X-X=X~.8 >X>X",
-">X>X>X>X4 x I w ,.u.y.(.(._.(.(._.(.(./.&X:X:X:X=X+X%X'.U.) ] >X",
-">X>X>X>X>X+ h f .t.7.~.(./.(.(./.(.(.(._.#X&X*X|.{.3.U.U.] ^.q ",
-">X>X>X>X>Xp g.h ` i.t.Q.}._./.(.(.(.(.(./.(.~.6.3. at .$.}.3.#. X) ",
-">X>X>X>X: m d.c.! 7.,...3.E.`./.(._.(.(./._./.| @.r._.}.' 3.U.q ",
-">X>X>X4 c M x.F.O.7 [ :.o.Q 3.{./.(.(._.(./._.{. X_._.R.^ r.J >X",
-">X>X4 j g.z.F.V.U 6.}.}.}.E.Q 9.`./.(./.(.(.(././.).[.] 8 6 >X>X",
-">X>X- l g Z N.x } [.(././.}.9._ (.(.(._._.(.(.(.^.^.,.% >X>X>X>X",
-">X>X>X>X>X4 4 2 &.Q.(.(./._.T.Q t.y.R.~.~.~.Q.Q.Y.=.- >X>X>X>X>X",
-">X>X>X>X>X>X>X>X^ u.R./.(.{.*.[ i.q.8.8.q.r.i.q.' & >X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X% _ 4.r.8.#.& ,.q.t.t.t.q.4.| J | 0 >X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X6 0 6 - &.' Q ^ ^ ^ Q / *.U. X[ >X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>X>X>X6 q.!.~.I.U.*.] }.}._.}. at .>X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>X>X>X>X' u.Q.^.~.Q &.Q.~.(.r.8 >X>X>X>X>X>X",
-">X>X>X>X>X>X>X>X>X>X>X>X>X>X% ^ ,.&.J % 0 ..,...6 >X>X>X>X>X>X>X"
-};
diff --git a/debian/hicolor-icons/512x512/hedgewars.xpm b/debian/hicolor-icons/512x512/hedgewars.xpm
deleted file mode 100644
index 81db1dd..0000000
--- a/debian/hicolor-icons/512x512/hedgewars.xpm
+++ /dev/null
@@ -1,774 +0,0 @@
-/* XPM */
-static char *Icon____x___x__[] = {
-/* columns rows colors chars-per-pixel */
-"512 512 256 2",
-" c #000000",
-". c #0C0B0C",
-"X c #080708",
-"o c #141314",
-"O c #1B1A1B",
-"+ c #100F10",
-"@ c #282728",
-"# c #383637",
-"$ c #312E31",
-"% c #221E21",
-"& c #423E41",
-"* c #494648",
-"= c #585557",
-"- c #514E50",
-"; c #696669",
-": c #797679",
-"> c #736D72",
-", c #625C61",
-"< c #413E3F",
-"1 c #A8005E",
-"2 c #970062",
-"3 c #9A0066",
-"4 c #9D056B",
-"5 c #9F086E",
-"6 c #9E0B71",
-"7 c #8E1A7E",
-"8 c #971277",
-"9 c #9A1176",
-"0 c #94157A",
-"q c #9B157A",
-"w c #91197D",
-"e c #99197E",
-"r c #A50064",
-"t c #AA0066",
-"y c #A4056B",
-"u c #A80168",
-"i c #A0096F",
-"p c #A10B71",
-"a c #A51176",
-"s c #A71479",
-"d c #A8167B",
-"f c #AA1A7E",
-"g c #95005F",
-"h c #7D2B8E",
-"j c #792E90",
-"k c #6C3C9D",
-"l c #743495",
-"z c #793193",
-"x c #723798",
-"c c #743A9B",
-"v c #683FA0",
-"b c #5B4CAB",
-"n c #5F47A6",
-"m c #5751AF",
-"M c #4E59B6",
-"N c #4A5CBA",
-"B c #485EBB",
-"V c #5354B2",
-"C c #5958B6",
-"Z c #6444A3",
-"A c #6646A6",
-"S c #7A5DBB",
-"D c #7D56B5",
-"F c #6F4BAB",
-"G c #4561BE",
-"H c #4A62BE",
-"J c #5362BF",
-"K c #7861BE",
-"L c #68409F",
-"P c #3D6AC6",
-"I c #396DC9",
-"U c #386EC9",
-"Y c #3472CD",
-"T c #2F77D1",
-"R c #2B7BD5",
-"E c #277FD9",
-"W c #2C7ED8",
-"Q c #277FD7",
-"! c #3176D1",
-"~ c #307FD9",
-"^ c #3A7CD7",
-"/ c #4265C1",
-"( c #4D6AC7",
-") c #4C71CD",
-"_ c #7569C6",
-"` c #7172CD",
-"' c #6C7BD6",
-"] c #6E71CD",
-"[ c #8B1D81",
-"{ c #971D82",
-"} c #AC1D81",
-"| c #862386",
-" . c #892184",
-".. c #832589",
-"X. c #81298B",
-"o. c #8D278A",
-"O. c #91298D",
-"+. c #942387",
-"@. c #8E3294",
-"#. c #8A3A9C",
-"$. c #8B3699",
-"%. c #8F2E91",
-"&. c #AE2184",
-"*. c #B02586",
-"=. c #B2258A",
-"-. c #B42B8C",
-";. c #B22887",
-":. c #B6308F",
-">. c #B62D91",
-",. c #B82E93",
-"<. c #B73291",
-"1. c #B93394",
-"2. c #BB3996",
-"3. c #BC359A",
-"4. c #BE3B9B",
-"5. c #883DA0",
-"6. c #BF3BA0",
-"7. c #C03C9F",
-"8. c #C13EA2",
-"9. c #BF409C",
-"0. c #8643A4",
-"q. c #824BAC",
-"w. c #8644A5",
-"e. c #8051B0",
-"r. c #827E81",
-"t. c #C0429E",
-"y. c #C343A4",
-"u. c #C54BA5",
-"i. c #C646A9",
-"p. c #C94BAD",
-"a. c #C74AAA",
-"s. c #CA53AC",
-"d. c #CB56AD",
-"f. c #CB4EB1",
-"g. c #CD52B5",
-"h. c #CE5BB2",
-"j. c #CF55B8",
-"k. c #D15FB5",
-"l. c #D156B9",
-"z. c #D35ABD",
-"x. c #D054B7",
-"c. c #D161B7",
-"v. c #D464BA",
-"b. c #D669BE",
-"n. c #D86CBF",
-"m. c #D55EC1",
-"M. c #D761C3",
-"N. c #D963C6",
-"B. c #D96EC2",
-"V. c #DA66C9",
-"C. c #DD6BCD",
-"Z. c #D76BC0",
-"A. c #DB72C5",
-"S. c #DE76C9",
-"D. c #DF79CA",
-"F. c #DF6ED0",
-"G. c #E17CCD",
-"H. c #E077CF",
-"J. c #E06FD1",
-"K. c #E272D3",
-"L. c #E47AD6",
-"P. c #E576D8",
-"I. c #E67CD9",
-"U. c #E87DDD",
-"Y. c #E06DCF",
-"T. c #1F86DF",
-"R. c #2382DC",
-"E. c #2B81DB",
-"W. c #3382DC",
-"Q. c #3B84DE",
-"!. c #1E87E0",
-"~. c #1D89E1",
-"^. c #3786E0",
-"/. c #3887E1",
-"(. c #3C8BE4",
-"). c #368CE6",
-"_. c #3794ED",
-"`. c #389AF2",
-"'. c #2A8AE3",
-"]. c #6984DC",
-"[. c #6788DE",
-"{. c #408FE8",
-"}. c #428EE7",
-"|. c #4493EC",
-" X c #4896EF",
-".X c #5F9AED",
-"XX c #4997F0",
-"oX c #4C9BF3",
-"OX c #4498F1",
-"+X c #509EF7",
-"@X c #5D9DF2",
-"#X c #519FF8",
-"$X c #578FE9",
-"%X c #658BE3",
-"&X c #6887E1",
-"*X c #6293EA",
-"=X c #6294E8",
-"-X c #5BA2F5",
-";X c #55A3FB",
-":X c #59A7FF",
-">X c #56ADFF",
-",X c #58A9FE",
-"<X c #59A8F7",
-"1X c #54B2FF",
-"2X c #52B8FF",
-"3X c #4BA9FD",
-"4X c #5285DF",
-"5X c #888587",
-"6X c #979496",
-"7X c #908D8F",
-"8X c #A8A5A8",
-"9X c #B9B7B9",
-"0X c #B3AEB2",
-"qX c #A39DA2",
-"wX c #E584D4",
-"eX c #E781DA",
-"rX c #E984DC",
-"tX c #EB8ADD",
-"yX c #E888D7",
-"uX c #ED91DE",
-"iX c #ED8DE1",
-"pX c #EB85E0",
-"aX c #EF92E2",
-"sX c #EF98E3",
-"dX c #F195E5",
-"fX c #F29AE6",
-"gX c #F396E8",
-"hX c #F49EE9",
-"jX c #F6A2EC",
-"kX c #F8A5EF",
-"lX c #F6ACEC",
-"zX c #F7B3EE",
-"xX c #F7BAEF",
-"cX c #F9A7F0",
-"vX c #FBAAF3",
-"bX c #FAB9F3",
-"nX c #C0BCC0",
-"mX c #C9C7C9",
-"MX c #D7D6D7",
-"NX c #D0CCCF",
-"BX c #F8C3F1",
-"VX c #F9CBF3",
-"CX c #F7C0F0",
-"ZX c #FAD3F5",
-"AX c #FBDBF7",
-"SX c #FBDEF8",
-"DX c #E1DFE1",
-"FX c #E8E7E8",
-"GX c #FCE3F9",
-"HX c #FDECFB",
-"JX c #F6E8F4",
-"KX c #F4F3F4",
-"LX c #FEF4FD",
-"PX c #FFFFFF",
-"IX c #F8F6F7",
-"UX c None",
-/* pixels */
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i 5 i i i i p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi p i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p 5 i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i p i i i i i i i i i y i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i 5 i i i i i i i y 8 0 i y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 5 u h / x p y y 6 6 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 t h R.T.b 0 y u i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u h ! T.!.I l p y y i i i i i i i i p 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i t z T R.R R.R.b [ y y i i 5 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i t z T R.R T Q !.I x 6 y i p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u l R E R R R R R.R.V [ y y i i i i i i i i i 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 y u x R Q R R R R R Q !.U c 6 u y p 6 i i i i i p i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 5 u x R R.R R R R R R R R.R.V .y y y i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p 5 i i i i 5 i u x R R.R R R R R R R R Q T.U k 6 u y p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y k R E.R R R R R R R R R T T.R.M | y y y i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y y k R E R R R R R R R R R R R E ~.Y k 6 u y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y y Z R.Q R R R R R R R R R R R R R R.R.N ..i u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i p y y Z Q Q R R R R R R R R R R R R R T E !.Y k 8 u 5 5 5 6 y 6 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 y y Z Q Q R R R R R R R R R R R R R R T R T.R.M h y u y 6 y p i i i i i i i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p 5 i i i i y y 5 n E E R R R R R R R R R R R R R R R R R E !.Y v 0 y y 6 5 i i i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i p y 4 b E Q R R R R R R R R R R R R R R R R R R R R.R.B X.y y y i i i i i i i i i i i i i i i i i i 5 p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 y i n Q Q R R R R R R R R R R R R R R R R R R R T R.R.! Z 0 u y 6 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i y y 6 b Q Q R R R R R R R R R R R R R R R R R R R R R R R.R.N h y u i i i i i i i i i i i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 u 6 b Q Q R R R R R R R R R R R R R R R R R R R R R R R R !.! A 0 u y 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 u p V T.R R R R R R R R R R R R R R R R R R R R R R R R R R R.R.G j i u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i u 6 V R.R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R.! A w u y 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 u 6 V T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.R./ j i u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 u 6 N T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.T n w u y 6 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 u 6 N T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E R./ l y u y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i 5 i i i i 6 u 6 N T.T R R R R R R R R R R R R R W R R R R R R R R R R R R R R R R R R Q R.! n w t y p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p i i i i 5 u 8 N !.R R R R R R R R R R R R R ~ ~ W W W R R R R R R R R R R R R R R R R R R.R./ l i u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i p 5 6 u 8 H T.R R R R R R R R R R R R R ~ W./.Q.W.W R R R R R R R R R R R R R R R R R R R.! m 0 u y 6 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 5 5 5 u 8 G T.R R R R R R R R R R R R ~ W.(.(.}./.W.~ R R R R R R R R R R R R R R R R R R R.W / l i t i 5 i i 5 p i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i u 0 G T.E.R R R R R R R R R R R ~ W.{.XXoX|.(.Q.E.W R R R R R R R R R R R R R R R R R R R.! m 7 t y p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u 0 G T.R R R R R R R R R R R R ~ /.|.oX;X+XXX|./.Q.W W R R W R R R R R R R R R R R R R R R.E / x y t i 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u 7 / R.R R R R R R R R R R R R ~ Q.|.oX;X:X+XoX|.(.Q.W.~ T R R R R R R R R R R R R R R R R R R.T m 7 t y 5 i i i i i i i i i i i i i p i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y 7 / R.R R R R R R R R R R R R ~ ^.|.+X:X:X:X:XoXoX{./.W.W.R T R R R R R R R R R R R R R R R R R.R.P x y t i 5 i i i i i i i i i i i 5 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y 7 P R.T R R R R R R R R R R R ~ /.|.+X;X:X:X:X;X;XoX X(.Q.W.~ W R T R R R R R R R R R R R R R R R R.T V 7 t t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u .P T.R R R R R R R R R R R R ~ /.|.;X:X:X:X:X:X;X;XoX X|./.W.E.W W R R R R R R R R R R R R R R R R R.E.P k i t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u ..P R.R R R R R R R R R R R R ~ /.OX+X;X:X:X:X:X:X:X:X;X+X|.}.Q.W.W W R R R R R R R R R R R R R R R R R R.T V .t u 6 i 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p 5 p i i i i i i 4 u ..P R.R R R R R R R R R R R W ~ ^. X+X:X:X:X:X:X:X:X:X;X;X;XOX|./.Q.E.R T R R R R R R R R R R R R R R R W Q R.P k i t i 6 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u ..P R.R R R R R R R R R R R R ~ /. X#X;X:X:X:X:X:X:X:X:X:X;X;XoX X(.).W.W T R R R R R R R R R R R R R R R R R R.R M [ u u 5 i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u ..Y R.R R R R R R R R R R R R W./. X;X;X:X:X:X:X:X:X:X:X:X:X;X;XoXoX|./.W.~ W R R R R R R R R R R R T R R R R R E E U k 5 t i 6 i i i i 5 p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u h Y R.R R R R R R R R R R R R W./.XX#X;X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoX|.(.Q.W.W W T R R R R R R R R R R R R R R R R R.R M | t u i i i i i i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y u h Y R.R R R R R R R R R R R R W./. X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X;XOX|./.Q.E.W R R R R R R R R R R R R R R R R R Q E Y Z i t i 5 i i 5 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y u h ! Q R R R R R R R R R R R W ~ /.oX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+XoX X(./.W.W R R R R R R R R R R R R R R R R R R E W N | t u 5 5 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u z ! Q R R R R R R R R R R R R W.(. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X;X+XoX|.(.^.~ R R R R R R R R R R R R R R R R R R R E.Y Z 6 t 5 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi p i i i i i i i i i 5 u j R E R R R R R R R R R R R R W./. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoXXX{./.~ W R R R R R R R R R R R R R R R R R R E.R G ..u y 6 i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi 5 i i i i i i i i i 5 r l R E R R R R R R R R R R R R W.(.XX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X;X+XXX|.(.^.W.W R R R R R R R R R R R R R R R R Q Q E.Y Z 5 t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i 5 i i i i i y u x R E R R R R R R R R R R R R W.(.XX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX X(.^.W.W R R R R R R R R R R R R R R R R R R E R / h u t i 5 p 5 p i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p i i i i i i u x R E R R R R R R R R R R R R W.(.oX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX|.(.Q.W.R R R R R R R R R R R R R R R R R R R E ! n 6 t y 5 i 5 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u x Q Q R R R R R R R R R R R R W.(.XX;X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X<X;XoX X(.(.W.~ W R R R R R R R R R R R R R R R R R Q Q / h u u 6 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y u k R.R R R R R R R R R R R R R W.}.XX;X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:XoXXX|.(.Q.E.R ~ R R R R R R R R R R R R R R R R Q R.T b 8 t y i i i i i i p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y y k R.E R R R R R R R R R R R R W.}.XX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX X}./.Q.~ ~ R T R R R R R R R R R R R R R R W Q E P h y t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y k R.R R R R R R R R R R R R W W.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoXoX|.(.W.~ W W R R R R R R R R R R R R R R R R R Q T b 0 t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y u v R.R R R R R R R R R R R R R W.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoX X{./.W.W R R R R R R R R R R R R R R R R R R Q E P h y t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u Z !.R R R R R R R R R R R R W W.{.oX;X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+XoX|.(.Q.~ W W R R R R R R R R R R R R R R R R R R.R m 0 t i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i y y Z T.R R R R R R R R R R R R R W.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoX X(./.W.W W R R R R R R R R R R R R R R R R R R R.I z y u 5 5 5 p i i i i i i i i i i i i i i i 5 i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i p 5 i i i y A R.R R R R R R R R R R R R W W.}.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX X(.Q.W.W R R R R R R R R R R R R R R R R R T R.Q m w r i 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i n R.R R R R R R R R R R R R ~ W.{.oX;X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoXOX{./.W.W.R R R R R R R R R R R R R R R R R R Q R.U l y y i i i i i i i i i i i i i i p i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y i b R.R R R R R R R R R R R R ~ W.{.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X+XoX|.(.^.W.W R R R R R R R R R R R R R R R R R R E.R.V w y y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 b T.R R R R R R R R R R R R W W.|.+X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoXXX|.(.W.~ R R R R R R R R R R R R R R R R R R R R.Y x 5 u p i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 6 b R.R R R R R R R R R R R R W W.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX|.(./.W.~ R R R R R R R R R R R R R R R R R R E.E M 7 y y i i i i i i i p 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 6 m T.R R R R R R R R R R R R R W.(.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+XXX{.(.W.~ ~ T R R R R R R R R R R R R R R R R R R.Y k 5 y i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 3 6 m E R R R R R R R R R R R R W Q.{.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X#XoX|.{./.~ W ~ R R R R R R R R R R R R R R R R R R.E M .u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 9 V R.R R R R R R R R R R R R W Q.(.oX;X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X X}.(.W.W.W R R R R R R R R R R R R R R R R R R R.! k 6 i i i i i i i i i i i i i i i i i i i i p y 6 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 9 M R.Q R R R R R R R R R R R ~ Q.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X;X;X;X+X X{.Q.W.W W R R R R R R R R R R R R R R R R R Q R.N .y i 5 i i i i i i i i i i i i i i i i 5 i 5 6 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i u 8 M T.R R R R R R R R R R R R W ).|.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X,X;X;X+XOX|./.Q.E.~ R R R R R R R R R R R R R R R R R R R.T L 6 i i 5 i i i i i i i i i i i 5 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p i i i i i u 0 M R.R R R R R R R R R R R R W W.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X;X;XoX X(.Q.W.E.R R R R R R R R R R R R R R R R R R E.R.N .i y i i i i i i i i i i i p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i u 0 B R.R R R R R R R R R R R R W Q.|.oX;X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X+XoX|./.Q.~ ~ R R R R R R R R R R R R R R R R R R R.T k 8 y i i i i i i i i i i i p 6 6 y i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 0 B R.R R R R R R R R R R R R E.Q.|.+X:X,X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X;X#XoX X}./.W.~ R R R R R R R R R R R R R R R R R R E T.G ..i y i i i i i i i i i 5 y 6 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u 0 G R.R R R R R R R R R R R R W W.|.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X#XXX|.}.W.~ ~ R R R R R R R R R R R R R R R R R R T.R Z 8 y i i i i y 6 5 p y 6 6 p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u 7 G T.R R R R R R R R R R R R W Q.|.;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X:X;XoXXX{./.~ ~ R R R R R R R R R R R R R R R R R R Q R.G ..i y i i 6 6 y 6 y 6 y 6 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u 7 P R.R R R R R R R R R R R R E.Q.|.+X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+XoX|.(.Q.W W R R R R R R R R R R R R R R R R R R R.R Z 9 y y p y 6 6 p 5 y 6 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i p i i i i 5 t 7 / R.R R R R R R R R R R R R ~ Q.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoXOX}./.W.~ R R R R R R R R R R R R R R R R R R Q T./ X.p y p 6 y 6 y 5 p i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i 5 i i i i 5 u 7 P R.R R R R R R R R R R R R ~ Q.|.+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX X(.^.W.W R R R R R R R R R R R R R R R R R R R.R A 0 y y p 6 y 6 6 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 u .P R.R R R R R R R R R R R R W ). X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoXXX|./.W.~ R R R R R R R R R R R R R R R R R R E T./ X.6 y y 6 6 y i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 t [ U R.R R R R R R R R R R R R ~ /. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoXoX|.(./.~ W R R R R R R R R R R R R R R R R R R R.R n 0 i y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 t | Y R.R R R R R R R R R R R R ~ Q.|.;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+X X{.(.^.~ R R R R R R R R R R R R R R R R R R R.R.P h i u i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p t | Y R.R R R R R R R R R R R R W./.|.;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X+XoX|.{./.~ ~ R R R R R R R R R R R R R R R R R R R.W n 0 y y p i i i i i i i p i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 t | Y R.T R R R R R R R R R R R W./.|.+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X+XXX{.(.W.R R R R R R R R R R R R R R R R R R T R.R.P h 6 y y i i i i i i 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u X.! R.R R R R R R R R R R R R W Q. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoX|.(.^.W.W R R R R R R R R R R R R R R R R R R R.Q b w y y 5 5 6 5 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i t X.! R.R R R R R R R R R R R R W.(.|.;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X+XXX{.(.W.~ R R R R R R R R R R R R R R R R R R E.T.P j 5 y y i 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i y 6 u h ! R.R R R R R R R R R R R W E.(.OX+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;XoX X(./.W.W W R R R R R R W T R R R R R R W T R T.R b 7 y y i 6 i i i i i i i i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 6 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 5 u h ! R.T R R R R R R R R R R R W.Q. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;XoXoX|.(.W.E.E.Q E E R.E.R.R.R.R.R.Q R.E.R.R.Q Q R.~.I x 6 u y i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i 6 y 6 y i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p u j T R.R R R R R R R R R R R R W.(. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X,X,X>X>X>X>X>X;X3XoX`.(.Q.~ ^ ! Y Y Y Y Y U U I I I Y Y Y Y Y Y T R.R m 7 6 y 6 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i 5 i y u z T R.R R R R R R R R R R R W W./. X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X>X>X1X>X>X,X<X-X at X*X&X].' ] _ K F c l l .... .....7 w 7 7 0 .....| ..h z z Z b k 8 y i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i p i i i i i i i i i 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 5 p 6 y u l R R.R R R R R R R R R R R W W./. X;X<X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X:X,X>X>X>X>X>X,X-X.X%X].` _ D w.#.o.{ 6 5 r y t t u u u t u u t t u t t t t t t t t t t t t t y 5 6 i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXi i i i i i 5 p 6 y 6 p u x E T.E R.R.R.R.R.E Q Q Q R Q W.(.oX;X,X:X:X:X:X:X:X:X:X:X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X>X1X1X>X;X at X=X].` S w. at .e 9 5 r r 1 1 r r y y y 5 i i p y i i y p p i 5 5 5 5 6 5 5 6 5 6 i y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 6 y i i i 6 i i i i i i i 6 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y y ..m M M G P P I U Y ! R R E R.'._.+X3X1X>X1X>X>X>X>X>X>X,X,X,X,X:X:X:X:X:X,X,X:X:X,X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X1X>X1X,X at X%X]._ q.#.O.q r r r r r u y 4 i i i p p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y 5 6 i i i y 6 i i i 5 i 6 y 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y 5 6 6 6 8 7 [ ..h z x k Z n C C ] ' ].%X*X.X-X-X-X-X;X:X>X>X>X1X1X2X1X1X>X1X,X>X,X,X,X,X,X,X:X,X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X,X>X1X1X>X<X at X&X` S #.+.9 y 1 1 r r y i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i p 6 i i i p i i p y i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i 5 y y u u t t t t u u t u t t t u 5 8 8 e +.O.%.#.5.w.D D _ _ ` ' ].].[.%X=X=X-X:X:X>X>X>X,X>X1X>X>X1X1X>X1X>X,X:X:X:X:X:X:X:X:X>X>X1X>X:X=X[.` D $.+.y r r r u y i p i 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y i i i i 5 6 i i i i i i i i i i i i i i i i i i i i i i i i i 5 p 6 i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i p i 6 p 6 6 5 6 i i i i y 5 5 i 5 y y r u r r 1 1 1 1 u r y i 6 5 6 q +.+. at .#.5.w.e.S S _ ` ' ' ].%X=X.X at X-X;X>X2X1X>X,X,X,X1X2X,X-X%X_ e. at .9 5 r 1 u y 5 5 5 p i i i i i 6 i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y y u u u u u u y y y y y i i p i i i i i i p i i 5 5 i p 5 i i i i y 6 y 5 5 i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i 5 5 i p i p p 6 5 5 i i y y y r u u r r r r r r r r 1 r y i q q e +.O. at .$.#.q._ ].=X:X>X>X;X=X' e.5.+.y 1 1 u r 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i 5 p i i i i i h h X.| [ 0 8 9 6 6 6 i y u t t t t u u u y y y y i y y i i i i i 6 6 6 6 i 6 i i i i i i i i i i p 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 i i i i i i i i i i i i 5 i i i 5 i i 5 5 i i 5 5 i i 5 6 6 5 i i i i i i 5 i y y u u r u r 1 1 1 u y 9 O.q.S K q.O.6 y t 1 y 5 5 6 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u Z ! Y P P / G N V b A Z k x z h ..| [ 7 0 8 6 i y y u u y u u u u u u u u 4 y y y p i 6 i i i i 5 p 5 i p i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i 5 i i i i i i i i i i i 5 5 p 5 i 6 6 5 i y u r r r y r r u i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i u w U T.R.T.T.T.!.R.R.R.Q Q R R R ! U P / N M V m A Z k k l h ..| [ 0 8 8 6 6 4 y y u t t t t t u u u y y y y i y i y i i 6 5 6 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i p 5 i i i i i i i i p 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i 5 6 5 i i i i i y y 5 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i t k R R R R T R R Q Q Q E E E E R.R.R.R.R.T.T.E T.T.Q R R T Y U P / G B M b b Z k x l h h | [ 7 0 8 6 i y 4 4 y u u u u t t u u u u y y p i 6 5 i i 5 i i i i i i i i 6 p i i i i i i i i 5 p i i i i i i 5 5 i i i i i i i i i i i i i i i i i i i 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y 6 p p p 6 6 p i i i i i i i i i i i i i i i i i i i 5 5 i i 5 p i 5 y 6 p y 6 6 5 p i p i i p y 6 6 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 8 / E R R R R R R R R R R R R R R R R R R R R R R Q Q Q E E E T.T.T.E E E E E Q Q R T ! U P G G N V m b n k k l z h | [ w 0 8 8 6 6 y y t t r u t t u u y y y y y y y i y 6 i 5 p 6 5 i i 6 i i i i i 5 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i 4 5 y 4 3 3 3 3 3 3 2 3 3 2 2 2 2 2 g 2 2 3 3 3 2 3 3 3 3 4 3 4 4 4 5 5 5 5 p 6 6 6 y 6 y i p 5 p 5 6 6 y 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i t k R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R Q Q Q Q Q E E R.Q R.R.R.T.R.!.R.T.E Q R T Y Y Y P P G N M m b Z k x x j h h [ 7 0 8 6 y y y y u u u u t t u u u u y y y i i i i p 5 5 i p i i i i i i i p p i i i i i 5 i 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i 4 y 4 2 2 3 3 3 5 3 y p s f &.;.-.<.1.1.1.2.4.9.t.7.t.2.2.<.1.1.:.;.;.f f a i 4 4 3 3 3 3 2 3 3 4 y 6 5 i p i p y y y 5 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 6 G R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R Q E E R.R.R.R.R.T.R.R.R.E R.R.E R R Y U U / / N M V m A Z k l l X...[ [ 0 0 6 6 y y t t t t t u y u u y u y y y y y y i i i 5 6 p 6 6 y 6 i i i i i i i 5 i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 4 3 3 2 2 4 i a f *.:.t.u.h.k.b.A.S.H.wXyXyXaXsXsXsXuXhXjXjXjXjXfXuXdXsXsXuXrXyXwXD.A.B.b.h.d.u.2.-.&.d a 5 3 2 3 3 3 3 p 6 6 6 p 5 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i t l R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R Q Q Q R.E E E E E T.E T.T.R.R.Q R ! ! Y U I I / N M V b Z Z k x j h h [ 7 0 9 6 y i i y u t u t t t t t u y y y y i 5 5 i i i i i i 6 6 i p i i i i i i i i i i 5 6 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p y i i i i i i i i i i i i 4 2 3 3 3 5 a *.2.t.h.v.n.wXtXuXfXhXkXkXvXvXvXcXvXcXcXcXkXkXkXkXjXkXkXjXjXjXcXcXkXkXkXcXcXcXcXcXvXcXkXjXfXsXtXyXD.Z.c.s.9.:.&.p y 3 3 2 3 3 p p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 5 H R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R R R R R Q W Q E E R.R.R.R.R.R.R.R.E R.R.E.R R R T P P P G G N V b n Z k x l h ..[ [ 0 0 6 6 6 y t r u t t u t u u u u u y y y i y i i 6 5 p 6 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 p p i i i p 5 4 r 3 2 3 a f <.t.h.b.H.yXdXjXjXcXcXvXcXcXkXjXhXjXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXjXjXhXjXhXjXjXjXcXcXcXcXcXkXjXjXuXwXS.c.s.2.;.f 6 2 3 3 4 4 i p i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i t j T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R Q R E R.Q E E Q R.R.R.R.T.R.R.R R R ! Y Y I P / N M V b A Z k k l h X. .[ 0 6 6 i i y y y y t t t t t t u u y y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p p i i 3 2 3 4 s -.t.h.B.wXuXfXjXcXcXcXjXjXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXjXjXjXcXcXvXcXjXfXuXG.v.s.2.&.p 3 2 2 y i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y i N R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R R R R R R R E E E E R.R.R.R.R.R.R.R.E R.R.E R ! ! Y I P / / N M V b A k x l h ..| [ w 0 8 6 5 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 5 3 3 2 3 s -.u.v.G.tXhXkXkXcXcXkXjXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXcXcXkXkXdXrXS.h.4.*.p 2 2 3 4 i p i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 t X.T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R Q Q Q E E R.R.R.R.R.R.R.R.Q Q R R ! ! ! U P / B M B M Z w i i i i i i i i i i i i i i i i i i i i i i i i i p i i p i y 3 2 3 6 } 9.h.G.uXhXkXkXkXkXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXcXvXjXfXrXA.s.<.d 4 2 2 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p y y M E R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R Q R.E E.R.R.R.R.~.~.R V h 6 i i i i i i i i i i i i i i i i i i i i i i i i i p i i 3 2 3 s <.u.B.yXfXkXlXlXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXcXcXjXuXwXc.t.*.i 3 3 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y y u ..T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E ~.R V h 6 u i i i i i i i i i i i i i i i i i i i i i i i p p p 3 2 3 a <.h.D.aXhXcXcXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXcXjXhXyXn.u.*.6 2 3 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i p i i i i i i i 6 6 y y V E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.R.B h 6 u y y p i i i i i i i i i i i i i i i i i p i i p i 3 3 3 p <.h.H.aXjXcXcXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXkXcXcXhXrXB.u.;.4 3 2 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 u [ T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R.T.P k 8 y u y i 6 5 i i i i i i i i 5 i i i i i i i i p i i 3 3 p -.h.S.aXjXkXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXkXjXyXB.u.f 3 g y i p i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p y y b E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E ~.Y Z [ y u y 6 6 i 5 p i i i i i i i i i i i i i i i p i 3 2 3 f t.A.uXhXcXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXlXkXfXrXc.1.i 3 3 4 i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 5 u 7 Y E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.R.V | 6 u y i 6 p i i i i i i i i i i i i i i i p i p i 3 2 i -.c.wXfXcXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXcXjXaXG.u.f 4 g 4 i i i i i i i i i i i i i i i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 5 5 y n E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E !.I x 6 u y y 6 i i i i i i i i i i i i i i i i i i 6 y 3 3 s u.A.dXjXkXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXcXjXyXv.2.i 3 4 5 i i i i i i i i i i i i i i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i u 0 U E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R !.R m 7 u y p 6 5 p 5 6 y 6 y 6 6 6 6 y 5 y 6 i i i i i 2 3 f h.yXhXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXaXS.4.a 2 3 5 6 5 i i 5 p i i 5 6 i i i i i i i i i 5 i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i u Z E Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T T.T.P j 6 y y y 5 y 6 6 y 6 y p 5 6 y y 5 6 p y 6 i i 4 3 4 -.c.rXjXjXjXjXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXjXjXhXH.u.d 3 3 y p i i 5 i 5 p y i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 9 I E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.R Z 0 u y 6 6 6 p 6 y 6 y p 5 6 6 p 6 6 p y 5 6 p 4 2 i <.n.uXjXkXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXcXhXyXd.&.2 3 5 5 5 i i i p i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i 5 i i i i i i i 5 p u k E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T Q T.G ..i y i i 5 y y 6 6 5 p 6 5 6 y y 5 y y 6 6 5 5 3 4 :.A.dXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXhXyXh.} 2 3 5 p i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 6 P W R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.Q n 0 y y 6 y i i i i i y 6 y 6 p 5 6 p i i i p 5 3 3 <.n.sXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXhXyXh.f 2 3 5 5 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y c Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E.T.Y l 4 y i i i 6 i i i i i 5 p 6 6 6 y y p i i 5 3 3 -.v.sXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXhXyXs.d 3 3 p 6 p i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 i 6 / Q R W W ~ ~ ~ R ~ W R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R.R.V 7 y y i i i i i i i i i i y y 6 y 6 p 5 p 5 3 3 =.b.aXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXhXyXu.s 2 y 6 i i i i i p i i i i i i i i i i i p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p 5 u l Q ~ W.W./.W.W.W.W.W.W.~ ~ ~ ~ ~ R ~ ~ W W W W W Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.T L 6 y y i i i i i i i i i i i 6 6 p 5 y 6 p 3 3 s h.tXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXjXG.4.3 3 5 p i i i 5 i i i i i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 5 i i i i i i i i i i i y 6 H '.(.(.{.{.{.(.}.}.(.(.(./.).Q.Q.^.).Q.W.Q.W.W.W.W.W.W.~ ~ ~ ~ ~ R R Q R W R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T./ | y i i i i i i i i i i i i i i i i i i 6 y 2 y y.yXjXjXjXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXkXsXA.-.2 3 5 5 5 5 p i 5 p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 6 y i i y 6 u j W.(. XoXoXoXoXXXXXXXXX X X|. X|.(.|.|.(.(.(.(.(././././././.W.^.Q.Q.^.W.W.W.W.~ W.~ W ~ ~ ~ W W W ~ R R R R R R R R R R R R R W R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.R.m 0 u i i i i i i i i i i i i i i i i i i p 3 3 :.G.hXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXsXk.f 3 4 p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i 6 6 i i 6 p y y N _.OX+X;X;X-X;X;X+X;X+XoX;X+XoXoXoXoXoXoXXX XoXoX X X X|.|.|.{.(.(.|.(.(.}.(.(./././.^.W.Q.Q.W.W.W.W.W.~ W.W.~ W.E.E.R ~ R R Q R R R R R R R R T R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.T x i y 5 i i i i i i i i i i i i i i i i i 4 2 } b.sXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXtXu.5 3 5 i p p i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i y 5 p i p 5 6 u o./.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X;X;X:X;X;X;X;X+X;X+X;X+X+X+X+X+XoXoXoXoXXXXXXX X X|.|.|.{.(.|.}.(.(.(.}./././.).Q.Q.Q.Q.W.W.Q.W W.W.~ W.~ W.W ~ ~ W W W W W R W R R R T R W W R R R R R R R R R R R R R R R R R R R.P h y y i 5 5 i i i i i i i 5 p i i i i i p 3 5 u.tXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXD.-.3 3 p i i i i i i i i i i i i i i i p 5 i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i 6 i i i y 6 6 y y C _.oX#X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X;X;X;X;X;X;X;X;X#X;X+X+X+X+X+X+XoXoXoXoXXXXXXX X X X X|.|.|.}.}.}.(.(.(.(.(././.Q./.).W.).Q.).W.Q.W.Q.W.W.W.E.W.W W W R R E.R W R W T R R R R T R R R R.R.M 7 u i i i i i i i i i i i 6 i i i i i 6 5 3 ;.A.hXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXuXd.a 2 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i y 6 i i 6 6 y p y | Q.`.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X;X;X;X;X;X;X;X;X;X+X+X+X+X+X+XoX+X+XoXoXoXoXXX X X|.|.|.|.|.(.(.(.(.(././.(./././.^./.Q.Q.W.W.W.W.W.W.W.W.E.~ W.~ E.W.R.E.A 6 u i i i i i i i i i i i i y 6 i i i i 3 p d.uXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXwX1.3 4 p i i i i p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i y 6 y 6 5 p y 6 p p C _. X#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X:X;X;X;X;X;X;X;X;X;X+X+X;X+X+X+XoXoXoX+XoXoX XoX X X X|.|. X|.(.|.(.|.}.}./.(././././.Q./.).^ c 5 y i i i i i i i i i i i i i y 6 y p 3 3 <.G.jXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXdXc.a 2 5 i p i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i 5 p 6 5 6 y 6 p y y ..) `.oX;X,X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X;X:X:X;X:X;X;X,X;X;X;X;X;X;X+X;X+X;X+X;X+XoXoX+XoXoXoXoX XoX X X X X|.|.`.) %.u y p 5 i i i i i i i i i i i i 5 p 6 3 p h.aXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXkXwX2.3 3 p i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y b `.OX#X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X<X:X:X:X;X;X;X;X;X;X;X+X;X#X#XoX#X3X' { u y 5 i i i p 5 i i i i i i i i i y i g *.G.hXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXjXfXjXsXjXfXjXfXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXhXhXfXjXfXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXd.5 3 5 p i i i i p i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i e ) _.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X;X:X:X:X,X:X,X>X' { r i 5 6 i i i i i i i i i i i i 5 p 3 y t.uXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXjXjXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXsXjXfXhXhXhXhXhXhXjXfXjXfXhXjXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXjXkXD.;.3 y i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y A _.OX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X>X:X_ 0 3 i i i i i i i i i i i i i i i p 5 3 s b.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXfXjXhXhXjXjXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXuXy.4 3 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 0 ) `.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X;XD y y p i i i i i i i i i i i i i i i 5 3 <.wXlXjXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXjXn.d 2 y i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y A _.OX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-Xw.y y 6 i i i i i i i i i i i i i i p 3 5 u.fXlXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXwX-.3 4 6 6 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i p i i i i y 9 ) (.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X at X5.r y 5 i i i i i i i i i i i i i i i 3 s v.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXfXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXdXt.4 3 p i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y c _.|.;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X at X#.r i 5 5 i i i i i i i i i i i i i i 3 *.G.cXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXlXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXjXk.p 3 6 i i i i i i i p i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 9 ) _.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X.X#.r y i 5 5 i i i i i i i i i i i i 4 4 4.uXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXH.&.3 y i 5 i i i i 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y z ). X;X;X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X*X#.r i i i i i i i i i 6 y 5 p i i p 3 i s.hXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXyX<.3 5 5 y 6 5 p 5 p 6 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 ( _.XX;X;X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X>X=X#.r y i i i i i i i i i 6 5 p 6 i p 3 a c.kXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXdXt.4 4 6 6 y 5 y 6 y y i i 5 p i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y X.).OX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X at X#.1 i i i i i i i i i i i y 6 p y i 3 d B.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXhXs.y 4 6 y 6 6 6 p 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y a J _. X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X*X#.r y i i i i i i i i i i i 5 p p y 3 *.H.cXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXkXk.p 3 5 p 6 y 6 y i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i X.).|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X at X#.r i p i i i i i i i i i i i y 5 5 3 -.wXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXB.d 3 p 6 p 5 6 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 C _. X#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X-X0.1 i i i i i i i i i i i i i i 6 5 5 1.rXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXG.*.3 y p y 6 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y o.Q.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-Xw.r i i i i i i i i i i i p 5 i i 5 5 3.rXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXwX*.3 p i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y C _. X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X,X-Xq.t y i i i i i i i i i i i i i i 3 5 8.rXdXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXtX-.3 5 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y [ Q.`.oX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X,XS u y i i i i i i i i i i i i i i 4 p 8.eXaXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXuX<.3 y p 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 y A `.OX;X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X' 6 r i i i i i i i i i i i i i i 4 6 y.U.pXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXvXaX<.4 5 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y [ ) `.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X,X:X:X:X:X:X:X:X,X>X' q r p i i i i i i i i i i i i i 4 p y.I.rXrXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXsX2.4 5 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i p i i i i y 5 A _. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X%Xe u 6 i i i i i i i i i i i i i 4 p y.P.U.rXaXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXdX1.3 5 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i 5 p 6 y i [ ) `.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X*X+.u 6 i i i i i i i i i i i i i 4 p 8.P.P.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXaX<.4 4 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i y 5 p i y y A _. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-X#.1 5 i i i i i i i i i i i i 5 4 5 4.P.L.L.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXuX-.4 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 6 6 i i 6 y 8 ) _.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X,X;XD r 5 5 i i i i i i i i i i i i 4 5 3.K.P.K.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXtX-.4 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 6 y i i i p y k _. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X,X_ y y i i i i i i i i i i i i i 4 5 3.K.P.F.L.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXyX*.3 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i p 5 6 y y 8 ) `.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X].y u 6 i i i i i i i i i i i i 4 4 ,.J.P.F.K.I.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXwX&.3 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 y 6 u x ).OX+X;X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X*XO.t 6 i i i i i i i i i i i i 5 4 >.F.P.F.J.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXD.f y i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 6 6 6 y 6 ( _.oX;X:X:X:X:X:X:X:X:X,X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-X#.r i i i i i i i i i i i i i i 4 } V.P.F.J.K.I.pXaXfXfXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXjXvXn.a 4 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i y 6 y 6 y z ).OX#X;X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>XK r y i i i i i i i i i i i i i 3 } m.U.K.F.J.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXvXk.i 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p i i i i i i p y y 6 ( `.XX at X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X].9 y i i i i i i i i i i i i 6 4 s x.I.J.F.K.K.L.rXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXcXu.i 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 i 6 y j ).OX+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X*X{ u i i i i i i i i i i i i i y p p.P.K.J.F.J.L.eXtXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXcXkX9.4 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 y 6 C _.oX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X1X-X%X#.r i i i i i i i i i i 5 5 i 4 6 y.P.K.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXsX1.4 5 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y 5 y X./.`.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X1X>X=X' q.e r y i i i i i i i i i i 5 5 4 y 1.P.P.J.J.J.K.K.I.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXhXfXsXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXtX&.4 i i i i i i i p i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 5 C `.OX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X1X-X%XK @.6 t u 5 y 6 y 5 y 6 6 6 y i i i 5 5 =.C.P.Y.J.J.J.J.L.rXaXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXfXfXhXjXjXjXjXlXjXjXjXsXfXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXhXfXfXgXfXfXfXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXH.s y 5 i i i 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y o.Q.`.+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X,X.X` w.e r 1 y i i 5 6 6 6 p 6 6 y i 6 i i y 5 d N.P.F.J.J.J.J.P.I.pXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXjXhXhXhXhXhXjXhXhXhXhXjXhXhXhXhXhXhXfXfXhXkXlXxXCXVXVXZXGXSXGXGXAXAXVXVXCXxXlXjXhXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXfXhXjXjXzXzXxXzXlXlXjXjXhXfXgXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXvXc.p 4 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 5 b `.OX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X1X-X[.S @.y r r y 6 i i i i i y 5 y y i i i i i i i p g.I.J.J.J.J.K.F.K.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXhXkXxXZXSXHXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXSXZXBXzXkXfXgXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXhXhXhXjXhXfXfXhXjXzXCXZXSXGXHXLXLXLXHXHXGXAXVXCXzXkXfXfXgXhXhXhXhXhXhXhXhXhXhXhXjXcXu.4 5 i i i i i i i i i i i i i 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i u o.Q.`.+X-X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X>X1X>X.X` w.e r r y 5 5 i i i i i i i 6 p 6 6 i i i i i 5 p 8.P.K.J.J.J.J.F.K.I.rXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXfXjXhXhXhXjXhXhXhXhXhXhXhXfXdXhXlXCXAXHXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXVXxXjXfXgXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXhXhXhXhXhXhXhXfXfXjXxXZXGXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXVXxXkXfXgXhXhXhXhXhXhXhXhXhXhXcXfX-.4 i i i i i i i i i i i i i p p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y i A `.XX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X1X-X].D @.i r r y 6 i i i i i i i i i i i i i i i i y 6 y 5 ,.K.P.F.J.J.J.J.J.K.wXtXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXsXjXhXhXjXfXhXhXhXhXhXhXhXhXhXgXgXhXzXZXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXVXlXhXgXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXgXjXCXSXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXBXlXhXdXgXhXhXhXhXhXhXhXhXcXyXf 4 i i i i i 6 5 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 u [ ) `.+X;X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X2X>X=X_ 0.0 u 1 y i p 5 i i i i i i i i i i i i i i i i i p p 3 } V.P.F.F.J.J.J.J.J.P.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXjXfXjXhXhXhXhXhXhXhXfXdXhXxXAXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXZXxXjXdXfXhXhXjXhXhXhXhXhXhXhXhXhXhXhXfXhXxXGXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXVXlXhXfXhXhXhXhXhXhXhXhXvXn.6 4 i i i 6 y 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y y A _.OX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X>X-X].e.O.p r u y 5 i i i i i i i i i i i i i i i i i i i i i i 3 p g.U.F.J.J.J.J.J.J.P.L.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXfXhXhXhXhXhXhXhXhXhXhXfXfXlXZXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXSXxXjXgXfXhXhXhXhXhXhXhXhXhXhXhXgXlXAXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXVXcXdXfXhXhXhXhXhXhXjXcXu.4 y i i i p y i i i i i 5 i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 6 u [ ) `.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X1X>X$X_ #.q u 1 u 6 5 5 i i i i i i i i i i i i i i i i i i i i i i 5 5 y.P.K.J.J.J.J.J.J.S.K.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXsXjXjXhXhXhXhXhXhXhXhXhXgXjXBXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXAXzXgXgXhXhXhXhXhXhXhXhXfXfXxXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXxXhXfXhXhXhXhXhXjXcXsX-.3 i i i i i i i i i i p i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y y k _.OX+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X1X at X' D O.y r u y p i i i 5 i i i i i i i i i i i i i i i i i i i i i 5 4 -.J.P.J.J.J.J.J.J.J.K.P.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXfXjXhXjXfXfXjXfXsXjXfXhXhXhXfXgXlXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXVXjXgXfXjXhXhXhXhXfXhXBXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXAXlXgXfXhXhXhXhXhXvXwXa 3 p p 6 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 u 0 ) `.oX;X:X:X:X:X:X:X:X:X:X:X:X,X>X1X1X>X%X_ #.9 r r y 5 6 5 i i i i i i i i i i i i i i i i i i i i i i i i i i 4 s m.L.J.J.J.J.J.J.J.J.K.L.tXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXfXjXfXhXfXjXjXfXjXjXfXjXhXhXfXhXBXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXxXhXgXhXhXhXfXhXZXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXxXfXfXhXhXhXhXhXvXh.y y p y 6 i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p y y k _.`.+X:X:X:X:X:X:X:X,X,X:X>X1X1X-X' q.+.5 r r y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 p.P.F.F.J.J.J.J.J.J.S.P.U.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXfXhXhXjXfXjXjXjXfXjXfXhXfXhXZXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXAXjXdXhXhXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXVXjXfXhXhXhXhXkXjX1.3 p i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i y 6 y 0 ( `.oX;X:X:X:X:X:X:X,X1X1X,X%XK @.9 u r y 5 i 5 i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i 4 >.K.K.F.F.J.J.J.J.J.J.F.L.eXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXjXfXjXhXhXfXjXjXsXfXjXfXjXdXjXAXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXzXgXfXZXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXjXfXfXhXhXhXcXyXs 4 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y u c ).OX+X:X:X:X:X>X1X1X at X` q.+.y r u i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i 4 s m.P.K.J.J.J.J.J.J.J.J.K.I.tXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXjXjXsXhXhXhXhXhXhXhXhXjXjXfXfXkXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXVXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXlXfXhXhXhXhXcXc.5 i i i i i i i i i i i i 5 i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y 6 ( `.oX;X,X1X2X>X%XS @.9 r r y 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i.P.J.J.J.J.J.J.J.J.J.J.P.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXjXsXgXlXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXzXdXhXhXhXjXhX<.3 p i i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p y u l ).`.3X1X at X` 0.{ 4 u r 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 =.K.K.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXfXjXjXfXhXhXhXhXhXhXhXhXfXdXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXzXdXhXhXhXcXwXa 4 i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 6 y 6 / `.' D %.6 r r y i p 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i p 5 i i i i i i i i 4 a m.P.J.J.J.J.J.J.J.J.J.J.K.I.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXjXfXjXjXfXjXhXhXhXhXhXhXhXjXfXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXzXgXhXhXhXkXd.3 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 5 i i i i y y | c e y r y 5 5 i i i i i 5 i i i i i i i i i i i i i i i i 5 6 i y 5 6 i i i i i i p i i i i i p 4 8.P.J.J.J.J.J.J.J.J.J.J.K.K.wXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXlXfXhXhXkXfX;.3 p i i i i 5 p i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i p i i i i 6 i y y y u 5 5 5 y i i i i i i i i i i i i i i i i i i i i i i y t t 6 6 i i i i i i i 5 i i i i i 4 } F.K.J.J.J.J.J.J.J.J.J.J.J.L.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXjXhXfXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXgXhXhXcXH.p 4 i i i i i 5 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i p i p i i i 6 i i i i i i i i i i i i i i i i i i i 6 i y t u 0 k h 5 i i i i i i i i i i i i 5 p j.P.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXhXfXhXhXkXa.3 p p i i y 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p y i i i i i i i i i i p i i i i 5 i i i i i 6 6 y t t p ..A Y P [ y i i i i i i i i i i i p 3 3.P.J.J.J.J.J.J.J.J.J.J.J.J.K.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXfXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXhXhXhXkXtXd 3 i i i 6 6 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 6 6 u u r 0 x M U Q ~.L i y p i i i i i i i i i i 5 s m.P.J.J.J.J.J.J.J.J.J.J.C.K.P.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXfXjXhXcXh.3 i 6 y 6 y i p 5 i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y u t p h b P R R.R.T./ 9 y i 6 i i i i i i i i i i 3 8.K.J.J.J.J.J.J.J.J.J.J.J.K.K.L.rXaXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXjXhXhXhXhXhXhXhXhXfXBXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXfXhXkXfX;.3 6 y 5 p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i u t u 0 k N U Q R.R R W R.l y y i i i i i i i i 5 i i 4 } C.K.J.J.J.J.J.J.J.J.J.J.J.Y.K.P.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXlXfXhXkXA.5 5 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 y t t 6 h b P R R.E R R R R T./ 8 y i i i i i i i i i p 6 5 4 f.K.J.J.J.J.J.J.J.J.J.J.J.J.K.P.I.iXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXfXjXAXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXhXhXhXhX2.3 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 5 6 i y t u 7 k B ! Q E Q R R R R R Q R.l y y 6 p i i i i i i i i y 4 =.F.K.J.J.J.J.J.J.J.J.J.J.J.J.F.P.I.tXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXBXgXhXkXL.a 4 i i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 5 p i i i i i i i i i i i i y 6 y u t 5 h m U R Q E Q R R R R R R R R./ 9 y i i i i i i i i i i i 5 5 m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXJXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXlXfXhXkXu.2 i i i i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 5 y t 3 7 L G T E.Q Q R R R R R R R R R R R.l y i i i i i i i i i i i p 3 >.K.K.F.J.J.J.J.J.J.J.J.J.J.J.J.K.L.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXhXhXkXrXs 3 i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 y u t 6 j V U Q E.R.R R R R R R R R R R R R R.I 0 y p i i i i i i i i i i 5 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.eXpXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXCXgXhXjXs.3 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 6 p y t y .A / T Q Q Q R R R R R R R R R R R R R R T.v y y 6 i i i i i i i i i y y 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.I.tXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXCXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXfXjXuXf 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i p y t t 6 l V Y R Q Q Q R R R R R R R R R R R R R R R T.Y [ y 6 y i i i i i i i i 6 5 p m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXJXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXdXjXjXh.g p p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i u t y [ Z P T R.Q R R R R R R R R R R R R R R R R R R R !.n 6 y p 6 i i i i i i i i 5 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXlXfXjXtXf 3 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 p i i i i i i i i i i i 6 y u u 8 l N ! Q Q Q R R R R R R R R R R R R R R R R R R R R E R | y p y 6 i i i i i i i i 5 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXZXfXjXjXd.3 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 6 5 p i i i i i i i i i i i i i i i i i i i 6 i y y t y h n P T Q Q Q R R R R R R R R R R R R R R R R R R R R R R ~.m 6 y i i i i i i i i i i i 3 1.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.I.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXfXjXtXd 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i 5 p i y 6 y i i i i i i i i i i i i i i i i i i i y u u 0 k H T Q R Q R R R R R R R R R R R R R R R R R R R R R R R R R.R h y i i i i i i i i i i i 5 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.iXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXBXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXgXjXhXd.2 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 i i i i i i i i i i i i i i i p i i i u t y ..b U R R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R.G 9 y i i i i i i i i i i i 3 >.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.P.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXhXhXhXhXhXhXhXhXhXhXhXfXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXkXhXjXyXs 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p y u y 0 k G ! E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.x i i i i i i i i i i i i 5 y x.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.P.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXfXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXfXhXhXu.2 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 y u i X.b Y R E Q R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R T R.Y 7 y i i i i i i i i i i i 4 } C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXcXfXjXwXp 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i y u y 0 k G R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R !.b 6 y 5 i i i i i i i i i 5 4 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXVXfXhXhX4.2 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i i 6 5 y u 6 j b Y Q Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.R h y y i i i i i i i i i i 4 } C.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.I.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXsXjXhXhXhXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXhXhXkXA.5 y 5 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 6 y u y w k / T R.R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.G 0 u 6 i i i i i i i i i i 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.wXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXKXFXDXFXKXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXdXjXdX-.3 6 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i 6 5 p 6 y 6 5 y u 5 h V Y Q E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.v y p i i i i i i i i i i 4 s m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXjXhXhXjXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXNX: - @ o . o $ = 6XFXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXfXhXjXc.3 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i y 6 y 6 y u 4 7 Z / R E Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.U [ u p i i i i i i i i i i 3 3.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXsXfXfXjXfXjXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX0X* . X X O ; mXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXlXfXjXyXd 4 i i p 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i 5 p i i i i i 6 p p y u 6 z V T Q Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R !.V 6 y 6 5 i i i i i i i i 5 y j.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.J.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXsXsXjXjXfXfXjXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXNX* X X : KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXCXgXjXhXu.2 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i y u y 7 Z P R Q R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E E x y y 6 i i i i i i i i p 3 } C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXhXhXfXjXjXjXfXjXjXfXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX8XO X # MXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXfXjXjXS.i y i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i p y 6 6 5 6 y y y 6 j M R E Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.U [ y i i i i i i i i i i i 3 y.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.K.L.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXjXjXsXjXfXjXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXCXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X+ O mXIXPXPXPXPXPXPXPXPXPXPXPXPXPXLXlXfXkXaX-.2 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi p i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 6 6 y i u 6 [ Z P Q R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.m 6 y i i i i i i i i i i 4 s M.K.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.tXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXsXfXjXjXfXjXsXjXjXjXfXuXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X. @ NXPXPXPXPXPXPXPXPXPXPXPXPXPXLXBXgXhXjXk.3 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i p y y y 6 l M T R.Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R.l y i i i i i i i i i 5 y 3 ,.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.P.I.tXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXfXjXfXjXjXfXjXjXfXjXjXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXkXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXqXo @ FXPXPXPXPXPXPXPXPXPXPXPXPXPXAXfXfXjXtXs 3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i u 6 .n I E R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.I [ u i i i i i i i 5 p 5 i i x.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.iXsXhXhXhXhXhXhXhXjXhXhXhXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXjXfXjXfXfXjXsXfXjXfXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXPXIXIXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX@ = KXPXPXPXPXPXPXPXPXPXPXPXPXLXkXfXjXfXu.g p 5 i i i i i i i i i 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p i i i i i i i i i i i i i i i i 5 5 5 p y y y 8 x N R R.Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T Q R R R R R R R T Q R R R R R R R R R R R R R R R R T.m 6 y i i i i i i i i i p 4 d C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXfXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX0X5X; = ; 5X0XFXIXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX- 6XPXPXPXPXPXPXPXPXPXPXPXPXLXzXgXjXjXn.4 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 i i i i i i i 5 p i i i i 5 5 y y 6 ..n Y E R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q Q x y y i i i i i i i i i p 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXsXjXjXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXnX; o X o > 9XIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX6XX O FXPXPXPXPXPXPXPXPXPXPXPXPXZXdXhXjXtX*.3 p i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i p i i i i i i i i i i i i i i i i i i i 6 6 6 y y r y 0 k N R R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R R R R R R R R.Y [ u p i i i i i i i i i i 4 x.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXaXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXjXfXjXjXjXsXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX9X* * 9XIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX# > LXPXPXPXPXPXPXPXPXPXPXPXGXfXhXjXhXu.2 i i i 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y y 6 y 6 h b Y E R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R.V 9 y i i i i i i i i i i 3 } V.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXjXsXjXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX: X X : KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X O MXPXPXPXPXPXPXPXPXPXPXPXLXjXfXhXjXS.5 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y y p 0 k G R E Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T.v y i i i i i i i i i 5 5 3 3.J.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXfXjXjXfXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXCXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX= - FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX* r.PXPXPXPXPXPXPXPXPXPXPXLXzXdXhXjXuX&.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i 5 i i 5 p i i p y y i 6 ..b ! R.R.Q R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q R R R R R R R R R R R R R R R R R E ! X.u i i i i i i i i i 5 5 i l.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXsXjXjXfXjXfXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX* * FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX8X+ @ IXPXPXPXPXPXPXPXPXPXPXLXVXgXhXjXhXu.2 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i 6 i 6 y y y p [ k / E !.E R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R R T.H 0 y i i i i i i i i i i 4 } C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXsXjXjXfXjXsXjXsXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX- - KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX; 9XPXPXPXPXPXPXPXPXPXPXPXZXfXfXjXjXA.y 5 i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i y y y y 8 j V ! T.R.E R R R R R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W '.C p u p i i i i i i i i p 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXsXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXjXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX> X X ; IXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX# > PXPXPXPXPXPXPXPXPXPXPXGXhXhXhXkXyX&.2 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i p 5 6 6 5 y y y 5 [ v P E T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ W.'.(.c i y i i i i i i i i i 4 4 g.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX8X. . 0XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX0Xo # IXPXPXPXPXPXPXPXPXPXPXLXjXhXhXjXfX9.3 p p 6 6 y i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXi i i i i i i i i 5 p i i i i i i i i i i 5 p y y y 5 8 j V T T.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W E.W.Q./.`.}.o.r 6 i i i i i i i i i 3 } m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX$ @ FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X O MXPXPXPXPXPXPXPXPXPXPXLXcXgXhXhXjXb.3 5 5 y 6 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXp 5 i i i i i i i i i i i i i i p 5 p 6 i y y y y 6 [ Z P E T.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W ~ Q.Q.(.}. X3X' 7 r p 5 i i i i i i i i 3 >.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.tXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX> X X : PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLX; 9XPXPXPXPXPXPXPXPXPXPXLXxXgXhXhXjXyXa 3 6 5 y 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXi i i i i i i i i i i i i i i i y 6 5 y y y i 0 l M R !.R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R T R R Q W.^.(.{. XoXoX;X1XK 5 y 6 y i i i i i i i i 4 i.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX@ O DXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX- 7XPXPXPXPXPXPXPXPXPXPXLXCXgXhXhXjXsX1.2 p 6 y p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i 5 i i 6 5 y y y 6 ..A I E !.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W R ~ W.W./.{.|.XXoX+X;X;X,X>XF y y 6 p 5 y i i i i i 4 i m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX: . . > PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXNX$ > PXPXPXPXPXPXPXPXPXPXLXZXgXhXhXjXhXd.2 y p 6 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i 6 6 y y y 5 w l N R !.R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W W.W./.(.{.|.oXoX+X;X:X:X:X>X.X at .r 5 y 6 6 6 i i i i i 4 } V.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.L.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXKX$ $ KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXnX@ = PXPXPXPXPXPXPXPXPXPXPXAXdXhXhXjXkXA.i 3 p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i y y p 6 ..n I R.T.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W W.Q./.(.|.XXoX+X;X;X:X:X:X:X:X2X].{ r 6 6 6 y 6 i i i i 6 3 6.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX8Xo o 8XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9X% - PXPXPXPXPXPXPXPXPXPXPXAXdXhXhXhXkXtX} 3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i 6 [ x N R ~.R.E T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R R W W W.W././.|. XoXoX;X;X:X:X:X:X:X:X:X:X1X_ p u 6 y y 5 p i i i i 5 4 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.I.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXBXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX= X , PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9X% * PXPXPXPXPXPXPXPXPXPXPXGXgXhXhXhXkXfX2.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i h Y T.T.R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ ~ W.Q./.}. X XoXoX;X:X;X:X:X:X:X:X:X:X:X>X>Xq.y 4 i i i i i i i i i 3 a m.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX# $ IXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9XO # PXPXPXPXPXPXPXPXPXPXPXSXhXhXhXhXjXhXh.3 5 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i p i i y 7 m R R.R T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W W.W./.(.{. XoXoX;X;X:X:X:X:X:X:X:X:X:X:X:X:X1X;X at .u i i i i i i i i 6 6 3 } C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.L.rXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9XO O mXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9X% * PXPXPXPXPXPXPXPXPXPXPXGXhXhXhXhXhXjXS.5 y 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i 5 i i i u y z P R.Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ W.Q./.}.|.XXoX+X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X%X+.u i i i i i i i i i y 4 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX7Xo . 7XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9X@ = PXPXPXPXPXPXPXPXPXPXPXHXhXhXhXhXhXkXyXf 3 i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXi i i i i i i i i i i i i 5 y t [ N R R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.W.^.(.|. XoXoX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X` 6 y i i p 5 i i i i i 5 3 f.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX> X X ; PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX$ ; PXPXPXPXPXPXPXPXPXPXPXHXkXfXhXhXhXjXsX2.2 p i i i i i i 5 p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXi i i i i i i i i i i i i i i t 6 n T R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R W ~ Q.Q.).}.|. XoX+X;X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X1XD y 4 5 i i i i i i i 6 y i z.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX- = PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX* r.PXPXPXPXPXPXPXPXPXPXPXHXjXfXhXhXhXjXjXa.2 5 6 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXi i i i i i i i i i i i i i i i y u z P R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W ~ W.W./.(.|. XoX+X;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X<X0.r 5 i i i i i i i 5 p 3 f V.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX$ * IXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX= qXPXPXPXPXPXPXPXPXPXPXPXHXjXfXhXhXhXjXjXb.4 y i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXi i i i i i i i i i i i i i i i p y t [ M E R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R W R E.W.Q.(.|. X XoX;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X.XO.u i i i i i i i i i p 3 >.C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX$ # FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX: X . mXPXPXPXPXPXPXPXPXPXPXPXGXkXfXhXhXhXhXkXG.s 3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXi i i i i i i i i i i i i i i i i i t 6 Z T R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ ~ Q.).}._. XoXoX;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X[.e r p i i i i i i i i 6 3 8.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXCXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX$ $ FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX6XX @ FXPXPXPXPXPXPXPXPXPXPXPXGXhXhXhXhXhXhXkXuX*.2 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXi i i i i i i i i i i i i i i i i i i u u j P R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ ~ W.Q./.(.|. XoX;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X` 6 r 6 5 i i i i i i i y 5 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX$ @ DXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX@ = PXPXPXPXPXPXPXPXPXPXPXPXGXhXgXjXhXhXhXjXsX2.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 6 y t 7 M E R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ W.W./.(.|. XoX#X;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1XD i y i p 5 i i i i i i 4 p l.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.L.rXuXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXDX$ @ DXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX- 6XPXPXPXPXPXPXPXPXPXPXPXPXGXgXfXhXhXhXhXjXhXs.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i y u 6 Z ! R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T R W W.W.Q.(.{. XXX+X+X;X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X,X0.u i i i i i i i i i p 3 d V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX$ # FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5XX . DXPXPXPXPXPXPXPXPXPXPXPXPXSXgXfXhXhXhXhXhXjXZ.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 6 u u h / E E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q ^./.(.|.XXoXoX;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X at X@.r i i i i i i i i p p 3 =.C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.I.iXfXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXAXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX$ & KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX@ = PXPXPXPXPXPXPXPXPXPXPXPXPXAXdXhXhXhXhXhXhXkXD.p 3 i i i i p i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i i i i i i 6 u t w V E R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R E.W W.^.(.{.|.XX+X+X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X%X+.r 5 5 i i i i i i i i 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.rXtXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX* - LXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX; 9XPXPXPXPXPXPXPXPXPXPXPXPXPXZXdXhXhXhXhXhXhXkXyXf 3 i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 6 i t 6 k Y T.Q R R R R R R R R R R R R R R R R R R R R R R R W W W.Q.(.(.|.XXoX+X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X2X' q u 5 5 i i i i i i i i 3 y.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.rXuXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX; , PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX0Xo < IXPXPXPXPXPXPXPXPXPXPXPXPXLXBXdXhXhXhXhXhXhXkXuX<.2 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i y u h / R.R.R R R R R R R R R R R R R T R R R R R R W W.W.Q.(.(. XXXoX+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X2X_ i y 5 i i i i i i i i 5 3 g.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.iXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X. . 5XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX; 0XPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXgXhXhXhXhXhXhXjXfX9.2 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i p i i i i i i i i i i 5 y t 0 m E R.R R R R R R R R R R R R R R R Q R R W Q./.}.|.OXoX+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X.X at .r 4 6 i i i i i i i i 4 p z.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.tXaXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXSXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX8XO o 0XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX@ - PXPXPXPXPXPXPXPXPXPXPXPXPXPXLXkXgXhXhXhXhXhXhXjXjXd.3 y i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i u i k Y R.R.R R R R R R R R R R R W Q W.W./.(.{.|.oXoX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X>X>XD y y p i i i i 6 y 6 y i 4 d m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXpXsXhXhXhXhXhXhXhXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXhXhXhXhXhXhXhXhXhXhXhXfXBXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX@ @ FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX7X. O MXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXhXhXhXhXhXhXhXjXjXc.4 4 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i u y X.G R.R.R R R R R R R R ~ W W.Q./.(.|.XXoX+X;X:X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X` 6 r 6 i i i i i 6 5 p 6 p 3 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.tXsXsXhXhXhXhXhXhXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXfXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLX* * PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX, 8XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXSXhXfXhXhXhXhXhXhXjXjXA.i 4 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 y t 0 b R R.R T W W R ~ ~ W./.(.{. XoXoX;X;X:X;X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X=X+.r i i i i i i i y 6 y 6 p 3 >.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXjXhXhXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX5X. . 7XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX* : PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXZXdXhXhXhXhXhXhXhXhXjXwXs 3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i p 5 i u i k Y R.R ~ E.W././.}.|.XXoX+X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X-X5.r y i i i i i i i 5 p 5 p p 3 3.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXaXfXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX@ @ MXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX# > KXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXxXdXhXhXhXhXhXhXhXjXcXtXf 3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i u u ..H '.)./.(.|. XoXoX;X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1XS y u 5 i i i i i i i y y 6 p i 3 8.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX= X = PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXMX- o : IXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXkXfXhXhXhXhXhXhXhXhXcXuX-.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 i t 8 A }.`.oXoX+X;X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X].q r i i i i i i i i i 6 6 y 5 4 i i.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9Xo o 9XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFXr.o # 8XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXdXhXhXhXjXhXhXhXhXhXkXsX2.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 i t 5 F $X3X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X=XO.r i i i i i i i i 6 y y 5 6 6 4 p f.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX- - LXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIX0X- X o ; NXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXgXhXhXhXhXhXhXhXhXhXjXfXy.3 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 5 5 u y %.' 1X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X<Xq.r i i i i i i i 6 y 6 6 6 p 6 y 4 p x.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.eXiXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXzXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmXO o mXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXDX8X, @ . o # > 9XKXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXgXhXhXhXhXhXhXhXhXhXjXhXd.2 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i p y r q K <X1X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X_ 4 y i i i i i i i i i i i i i i i 3 s m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX> X : PXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFXmX0X7X: : 5X6X9XMXKXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXhXfXhXhXhXhXhXhXhXhXhXjXjXc.3 5 i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 5 5 u i 0..X1X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X[.e r i i 5 i i i i i i i i i i i i p 3 d m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXfXjXhXCXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFX< # FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXAXdXhXhXhXhXhXhXhXhXhXhXjXkXn.3 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i p i i i u y O.' 1X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X1X at X#.r i i i i i i i i i i i i i i i i i 3 } V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXNX@ @ mXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXgXhXhXhXhXhXhXhXhXhXhXhXkXA.5 5 y i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i 5 i i i 6 y u 9 S <X1X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X,XD u y p i i i i i i i i i i i i i i i i 4 =.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX9XO O 0XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXfXhXhXhXhXhXhXhXhXhXhXhXhXjXD.p 4 6 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i p 5 u 4 0.$X2X,X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X' 6 r 6 i i i i i i i i i i i i i i i i i 3 >.C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.P.eXaXaXhXhXhXhXhXjXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPX0X@ @ 0XPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXxXfXhXhXhXhXhXhXhXhXhXhXhXhXjXG.s 3 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 5 i y r +.' 1X1X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X%X{ u i 5 i i i i i i i i i i i i i i i i i 3 ,.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.P.I.pXfXhXhXhXhXhXfXjXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXfXjXjXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXmX* - mXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXfXhXhXhXhXhXhXhXhXhXhXhXhXkXwX} 3 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 6 y r a D ;X1X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X1X-X#.r i i i i i i i i i i i i i i i i i i i i 4 3.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.L.tXaXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXjXhXfXzXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXDX5Xo o : FXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXgXhXhXhXhXhXhXhXhXhXhXhXhXhXkXyX&.3 6 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 i 5 i i i i r y #.*X2X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X>X>XS u y p i i i i i i i i i i i i i i 5 i i i i 3 8.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.L.tXaXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXAXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXKX9X; O O ; 9XKXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXgXjXhXhXhXhXhXhXhXhXhXhXhXjXkXrX-.3 p i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i y y +.` 1X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X].6 r p 5 p i i i i i i i i i i i i i i i i i i 4 8.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.F.P.eXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXFXNX6X; & @ O @ * ; 6XmXFXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXBXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX:.2 i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 6 y u 9 D ;X1X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X*X at .1 5 5 i i i i i i i i i i i i i i i i i i i i 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.K.K.P.eXiXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXIXKXDXMXNXMXMXKXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX:.2 i i i i i i i i i i i i i i i i i i i i p 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i p i i i 4 y y #.%X2X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X<Xq.r 4 i i i i i 5 i i i i i i 5 i i i i i i i i i 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.S.K.K.I.iXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXzXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXzXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXuX2.g p i i i i i i i i i i i i i i i i i i i i 6 i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 i i i i 5 y u +.` 1X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X>X` i u i i i i i i i i i i i i i i i i i i i i i i i 3 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.F.J.K.eXpXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXZXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXdX2.3 i i i i i i i i i i i i i i i i i i i i p y i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i r 9 e.<X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X].e r i i i i i i i i i i i i i i p i i i i i i i 5 i 3 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXlXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXjXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX2.2 i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i y p @.%X2X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X*X at .1 i i i i i i i i i i i i i i i i i i i 5 i i i 5 5 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.eXaXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXdXhXfXjXhXhXhXhXhXhXhXhXhXhXhXjXhXhXkXfX4.g i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i y u +.` >X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:XD u i i i i i i i i i i i i i i i i i i i i i i i i i y 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXiXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXkXSXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXCXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXt.g p i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i p y u p e.:X2X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X1X` i y i i i i i i i i i i i i i i i i i i i i i i i i i 5 3 x.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXzXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXfXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXt.g i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 5 y y @.%X1X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X$X+.u p i i i i i i i i i i i y p 9 6 i p i i i i i i i i i 3 g.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXZXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXfXt.g i i i i i i i i i i p y 5 p 5 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 p y y e ` >X>X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-X5.1 5 i i i i i i i i i i i p t h k 6 y i i i i i i i i i y 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXiXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXfX4.g i i i i i i i i i i p p 3 4 p 5 i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i 5 i i i i i i i i i i i i 6 5 y 6 e.-X2X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X,X_ y y 5 i i i i i i i i i i i y 6 / N 6 y i i i i i i i i i i 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.iXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXvXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXVXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfX9.g i i i i i i i i i i 3 ;.s.} 3 5 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 i i i i i 5 6 y y %.%X2X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X' 9 u i i i i i i i i i i i i y y k ~.M i y i i i i i i i i p p 3 f.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfX2.3 i i i i i i i i i p 3 ;.uXtX-.3 4 i i i i i i i i i p i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i p i i i i i i i i y y e _ >X>X:X:X:X:X:X:X:X:X:X:X:X:X>X=X+.r i i i i i i i i i i p 5 5 u h Y ~.M 6 y i i i i i i i i i i 3 f.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXAXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXdX2.2 p i i i i i i i i i 3 -.uXbXdXt.4 4 5 5 i i i i i i 5 i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 6 6 y 6 q.-X1X:X:X:X:X:X:X:X:X:X:X>X-Xq.r i i i i i i i i i i i 5 5 t 0 G R.~.M 6 y i i i i i i i i i i 3 i.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXjXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXZXxXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXVXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXaX2.3 i i i i i i i i i i 2 :.uXcXjXhXd.5 3 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 i i y y O.%X1X,X:X:X:X:X:X:X:X>X>X_ y y 5 i i i i i i i i 5 6 p u 6 m R.Q T.N 8 y i i i i i i i i i y 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.pXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXzXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXlXdXjXxXGXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXZXkXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXjXuX:.2 i i i i i i i i i i 3 1.uXcXhXkXjXb.a 3 i p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 5 i i p y q _ >X>X:X:X:X:X,X,X>X%Xq u i i i i i i i i i i i 6 y u k R E R R.N 9 y i i i i i i i i 5 5 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.pXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXfXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXCXdXhXhXhXhXzXZXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXVXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXuX:.g i i i i i i i i i 5 3 2.sXcXhXhXjXkXA.a 3 p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i y 5 0.-X1X,X:X:X:X>X at X%.r i i i i i i i i i p y i i u ..Y R.R R R.B 0 y i i i i i i i i i i 3 8.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXhXhXhXhXhXhXhXhXhXhXhXdXBXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXSXhXfXhXhXhXhXfXfXjXzXZXGXIXPXPXPXPXPXPXPXPXPXPXPXLXHXZXxXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXtX-.2 p i i i i i 6 y 5 5 3 2.dXkXhXhXhXjXcXZ.a 4 i i y 6 6 p 5 y i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i 5 p i i i i i i i i i i i i i i y O.[.1X,X:X,X<XD r i i i i i i i i i i 6 6 i u 8 B T.R R R R./ [ u i i i i i i i i i i 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.iXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXlXfXhXhXhXhXhXjXjXhXhXfXjXkXzXxXVXZXAXAXAXZXVXxXzXzXjXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXwX*.3 6 i i i i i 5 5 6 5 3 9.fXkXhXhXhXhXjXcXA.a 3 i 5 p y 6 6 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 5 y q _ >X>X,X` i y 5 5 i i i i i i i i y 6 y i b R.R R R R R.P [ u p 5 i i i i i i i i 3 3.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.yXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXjXhXhXhXhXhXhXhXhXhXhXhXdXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXCXdXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXhXhXfXhXfXfXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXwX} 3 i i i i i i p 5 y 5 4 u.hXjXhXhXhXhXjXjXcXv.p 3 p 6 6 6 y 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 5 y y 0.;X*Xq u 5 5 p i i i i i i i i 6 y u l T E R R R R R.I .u 5 p i i i i i i i i 4 >.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.eXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXsXjXhXhXhXhXhXhXhXhXhXhXhXhXfXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXwXf 3 i i i i i i 6 y 5 5 3 s.jXjXhXhXhXhXhXhXjXkXs.p 5 y y y 5 p i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p i i i i i 5 i i y y o. at .y i i i i i i i i i i i i p u [ U R.R R R R R R.Y ..u i i i i i i i i i i 3 =.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.K.wXtXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXZXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXH.a 3 p i i i i i 6 p 5 4 4 d.jXjXhXhXhXhXhXhXhXkXjX4.3 5 6 6 y 6 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i 5 i i i i i i i i i 6 y y p i i i i i i i i i i i i y 9 N R.R R R R R R E T h t i 5 i i i i i i i i 3 } C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXjXsXhXhXhXhXhXhXhXhXhXhXfXhXVXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXkXgXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXA.i 4 i i i i i i y 6 5 4 4 c.cXjXhXhXhXhXhXhXhXhXcXaX-.3 y 6 p 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i p y i Z R.Q R R R R R R E R j u 6 p i i i i i i i p 4 } C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXjXhXjXjXhXhXhXhXhXhXhXhXhXhXhXfXfXCXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXzXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXB.3 5 i i i i i i i i p 3 5 b.cXhXhXhXhXhXhXhXhXhXhXvXD.d 3 5 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p y y j T R.R R R R R R R E E x u y i i i i i i i i p 3 a m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.iXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXxXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXv.3 y i i i i i i i i p 4 p A.cXhXhXhXhXhXhXhXhXhXhXjXvXa.i 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i p i i i i i i i i i i i u [ / T.! R R R R R R R E E Z y y p i i i i i i i i 3 a z.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXgXxXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXd.3 5 5 i i i i i i i p 3 s D.cXhXhXhXhXhXhXhXhXhXhXhXkXdX;.4 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p i i i i i i i i i i i 5 i i i i i i i i i i y 6 V T.Q R R R R R R R Q E E Z 6 y 6 i i i i i i i i 5 p g.K.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXkXSXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXxXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXu.3 5 5 i i i i i i i p 3 } wXcXhXhXhXhXhXhXhXhXhXhXhXjXvXS.s y 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi 5 i i i i i i i i i i i i i i i i i i i i i i y 3 v E Q R R R R R R R R R Q E V 6 u 6 i i i i i i i i y 5 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXhXVXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXHXzXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXdX2.3 5 i i i i i i i i i 3 -.rXcXhXhXhXhXhXhXhXhXhXhXhXhXjXcXt.4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i y h T E R R R R R R R R R R E E N 8 u i i i i i i i i i i 3 8.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXfXgXxXHXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXGXlXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXv.k.fXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXuX:.3 i i i i i i i i i i 3 1.sXcXhXhXhXhXhXhXhXhXhXhXhXhXhXvXwXd 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 6 i i i u w G E R R R R R R R R R R R R !./ 0 t 6 i i i i i i i i i 3 3.K.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.iXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXgXjXAXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXAXjXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXk.3 3 v.jXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXuXf 3 p i i i i i i i 6 5 3 2.hXkXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXu.i 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i y i i y 6 b !.E Q R R R R R R R R R R R E U [ u 6 i i i i i i i i p 2 ,.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXgXdXxXGXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXBXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXh.4 i 3 f uXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXyXd 3 p i i i i i i i 5 5 3 u.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXwXd 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 6 6 y y x E E R R R R R R R R R Q R R R E Y h u i i i i i i i i i i 3 =.V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXgXfXBXIXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXlXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXv.5 y 6 5 3 B.jXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXS.a 3 p i i i i i i i i y 4 h.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXt.4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i y p i y [ Y E T R R R R R R R R R R R R R Q R x y y i i i i i i i i i 3 } m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.P.I.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXjXVXLXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXLXBXfXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXB.p 4 i i 6 3 c.cXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXv.i 4 i i i i i i i i i 4 p b.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXS.s 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 y y 8 N !.T R R R R R R R R R R R R R R Q E Z y i i i i i i i i i i 4 p z.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.L.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXdXjXVXHXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXLXVXjXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXS.s 5 y i i i 2 c.kXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXjXjXjXd.4 i i i i i i i i i p 3 d S.cXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhX-.4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p y 6 Z R.R R R R R R R R R R R R R R R R Q !.b y y i i i i i i i i i 5 5 l.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXjXjXfXjXjXfXjXfXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXjXfXdXjXBXGXLXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXHXZXkXgXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXG.d 3 5 6 i i i 4 B.kXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXt.g i i i i i i i i i p 3 &.yXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXh.i 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 6 y y h R R.R R R R R R R R R R R R R R R R R !.M 6 y i i i 5 i i i i i 5 4 i.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXsXjXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXgXhXlXVXGXLXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXGXxXjXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXwX} 3 5 p 5 i i 4 a wXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXaX2.2 i i i i i i i i y 6 3 :.uXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXwXd 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y [ P T.R R R R R R R R R R R R R R R R R T R./ 7 u i i i i i i i 5 6 y 3 3.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.Y.L.I.iXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXsXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXfXgXfXfXzXVXSXHXLXLXPXPXPXPXPXPXPXPXPXPXPXPXPXPXLXLXLXHXAXBXkXdXgXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXwXf 3 i 6 6 y i p 3 :.jXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXyX&.3 i i i i i i i i p i 3 t.hXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjX<.4 i i i i i p i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i 6 y 6 i i i i y 6 M ~.R R R R R R R R R R R R R R R R R R R R.U | u i i i i i i i i i i 3 =.V.K.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXfXfXjXfXjXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXjXhXhXjXhXhXhXhXhXhXgXdXfXjXlXxXZXGXGXHXLXLXLXLXLXLXLXHXHXSXZXCXlXkXfXdXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXwX&.3 5 i y 6 p p i 4 b.jXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXwXa 4 i i i i i i i i i 4 3 d.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXvXs.4 4 i i i i 5 i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i 6 y i i p 6 i i k R.R.R R T R R R R R R R R R R R R R R R R Q R j u i i i i i i i i i 5 3 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXfXsXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXjXhXhXhXhXhXhXhXhXhXfXgXfXfXhXjXkXlXzXzXzXzXcXjXfXgXgXdXfXfXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXH.} 3 i i i p 6 y y 3 &.uXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXn.3 y i i i i i i i i i 4 i v.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXS.a 4 i 5 i i i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 i i i y y | T R.R R R R R R R R R R R R R R R R R R R R Q R.v y y p i i i i i i 5 p 5 p z.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXfXjXsXjXjXfXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXgXgXdXfXgXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXkXA.d 3 5 i i i 5 6 y i 4 v.jXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXjXjXh.2 i i i i i i i i i i 4 s D.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXuXf 4 i p i i i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p i i i y 0 / ~.T R R R R R R R R R R R R R R R R R R R R Q R.b 6 y i i i i i i i 5 5 5 5 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.wXiXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXhXhXhXjXfXjXjXfXjXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXjXb.a 3 5 i i i i p 5 6 2 <.fXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXdXt.2 i i i i i i i i i i 3 *.rXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjX:.4 i i i i i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i 5 b T.R R R R R R R R R R R R R R R R R R R R R R R T.N 0 u 6 y 6 i i p i i i 5 3 8.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXfXd.p 3 i p i i i i i i 4 a wXjXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXkXuX-.3 p i i i i i i i i i 2 2.fXkXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXu.i 5 i i i i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y x R.E.R R R R R R R R R R R R R R R R R R R R R R R T.I [ u p 5 p i i 5 i i i 6 3 ,.C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXuXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXtX4.3 3 p p 5 i i i i i 4 4 h.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXwXd 3 i i i i i i i i i i 3 u.kXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXh.4 4 i i i i i i i i 5 p i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y .Y R.R R R R R R R R R R R R R R R R R R R R R R R R W T j u i p 5 i i i i i i p 3 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXuXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXhXS.;.2 4 i i i i i i i i 5 3 4.hXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXn.i 4 i i i i i i i i i 4 i v.cXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXn.p 5 5 5 i i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y 9 N T.R R R R R R R R R R R R R R R R R R R R R R R R R R R.v y y 6 y i i i i i i y 5 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.L.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXkXuXs.p 2 5 i i i i i i i i i 3 -.sXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXh.2 i i i i i i i i i i 2 s G.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXwXa y 5 i i i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y 4 Z T.R R R R R R R R R R R R R R R R R R R R R R R R R R R ~.b p y 6 i i i i i i 5 6 y 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXkXdXA.-.3 3 p i i i i i i i 5 5 3 &.yXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdXt.g i i i i i i i i i i 3 ;.tXvXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXcXwXf 5 i i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y h Q R.R R R R R R R R R R R R R R R R R R R R R R R R R R R T.N 0 u y p i i i i i i 5 5 3 8.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.I.iXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXkXkXdXn.2.5 3 4 p i i i i i i i i 5 3 f wXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtX*.3 i i i i i i i i i i 3 4.fXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXrXf 4 i i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y w U R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R.! | u 6 5 i i i i i i i p 3 =.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.L.yXuXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXjXcXkXhXyXv.<.5 2 3 p i i i i i i i i p 5 3 &.G.cXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXwXi 4 i i i i i i i i i i y d.cXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXuX&.5 5 i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y 6 M T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E.W l y y p i i i i i i i p 3 d m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.Y.L.I.tXdXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXcXjXuXA.u.&.4 2 4 5 p i i i i i i i i p 5 3 =.wXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXv.3 i i i i i i i i i i 3 a n.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXuX&.4 5 i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y k R.E R R R R R R R R R R R R R R R R R R R R R R T Q R R R R R R R.b p y 5 y y 6 i 5 i i i i y f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXjXkXcXcXjXuXD.s.-.i 3 3 4 i p i i i i i i i i 5 5 4 3 :.yXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXt.3 5 5 i i i i i i i p 3 &.yXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXjXsXhXkXuX&.4 4 i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y X.T R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ _.( q u 6 6 6 i i p i i i i 3 8.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXcXkXkXfXtXA.d.:.a 3 2 4 5 p i i i i i i i i i i i 5 4 4 2.uXvXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX*.3 i 5 i i i i i i i 6 3 <.fXkXjXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXfXjXhXkXuX&.4 i i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y 0 P R.R R R R R R R R R R R R R T R R R R R R R R R R R R R R R R ~ W._.4XO.u p i i i i i i i i 6 3 -.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.K.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXkXkXkXjXjXjXjXjXjXjXjXjXjXjXkXkXkXkXkXcXjXsXrXS.h.t.;.p 3 3 3 4 p i i i i i i i i i i i i i 5 3 p u.sXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXD.p 4 i i i i i i i i p 5 4 u.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXkXyX&.4 i i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y i b R.R R R R R R R R R R R R R R R R R R R R R Q R R R R R R R R Q W.^. X#X0.u y i i i i i i i i i 4 a m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.Y.Y.K.P.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXkXjXkXjXhXjXhXjXkXjXkXjXkXkXkXjXkXjXhXfXtXyXS.b.s.9.&.a 4 2 2 4 5 i p 5 i i i i i i i i i i i i i 5 3 f b.kXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXc.3 i i i i i i i i i p 3 p b.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXjXfXjXjXcXyXf 4 i i i i i i i i i i i i UXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y x R.Q R R R R R R R R R R R R R R R R R R R R R T R R R R R R R R W ^.|.oX3XS 5 y i i i i i i i i i i 4 f.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXhXwXB.h.h.a.u.u.u.a.h.h.h.h.h.k.h.h.h.a.t.2.-.&.a 5 3 3 3 3 5 i p i i i i i i i i i i i i i i i p 5 3 3 1.wXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX4.2 p i i i i i i i i p 3 f L.vXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXvXH.a 5 6 6 y i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 u | Y R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ^.(.OX+X2X' q y i i i 5 i i i i i i 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXfXjXfXjXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXuXu.} p 4 4 3 3 3 3 3 4 5 y 3 5 4 y 3 5 3 2 2 2 3 3 5 5 5 i p i i i i i i i i i i i i i i i i i i 4 3 a a.uXcXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXyXf 3 i i i i i i i i i i 3 1.sXcXfXjXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXjXfXjXfXhXvXA.p 4 y 6 5 i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 y 9 G R.T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ /. XoX;X1X.X+.r i i i i i i i i i i 3 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXjXfXjXfXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfX1.3 3 3 5 4 5 i 4 i i 4 4 4 4 4 4 4 5 5 y i i p 6 i i y 5 i i i i i i i i i i i i i i i i i i 5 3 4 1.D.kXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXA.4 5 i i i i i i p 5 p i 3 u.cXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXjXfXfXjXfXjXhXvXk.5 5 y 6 p i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y Z R.R R R R R R R R R R R R R R R R R Q R R R R R R R R R R R R W W /.|.oX:X:X>X:X#.y i i i i i i i i i i 4 p l.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.eXiXdXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXsXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXc.3 y p p p i i i i i i i i i i i i 6 5 5 i i i i i i i i 6 i i i i i i i i i i i i i i 5 p i 3 3 f h.dXvXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXu.2 i i i i i i i p y p 3 p n.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXsXjXjXfXjXfXjXjXu.5 5 5 y 6 i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 5 5 u j R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W /.{.oX;X;X:X,X1XS p y p i i i i i i i i p 3 8.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXdXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkX1.4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 3 2 a t.wXkXlXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX;.3 i i i i i i i i i p 3 } wXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXjXhX<.5 y 6 p 6 i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i 5 5 u w P Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R T ~ W W.(.XX+X;X,X:X:X2X' 9 r p i i i i i i i p p 3 =.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.tXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhX;.3 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i 3 3 p 7.S.jXcXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXG.a 4 i i i i i p i i i 5 3 :.dXkXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXsXjXhXhXhXhXcXsXf 5 6 6 5 y i i i i i i i i UXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i p i i i i i i 5 y 6 M T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W./. XoX;X:X:X:X:X1X.XO.r 5 i i i i i i i i i 4 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXtXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhX-.4 i i i i i i i i i i i i i i i i i i i i i i y 6 i 5 i i i i i i i i i i i i y 2 3 s 9.G.hXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXh.2 i i i i i i 5 6 y 5 y 3 s.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXcXD.p y 5 y 6 6 i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 u k E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ Q.|.oX;X:X:X:X:X:X,X1Xq.y y i i i i i i i i i i 4 8.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXkX<.3 i i i i i i i i i i i i i i i i i i i i i i 6 6 i i i i i i i i i p p i 4 2 4 d t.D.fXlXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX-.2 i i i i i i y 6 6 p 3 a A.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXfXvXa.p 6 p 6 y y i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 u X.T E.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R E.W.(.oX+X:X:X:X:X:X:X:X1X` 6 y 5 5 i i i i i i i i 3 =.C.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXtXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXs.3 i 5 p 5 i i i i i i i i p i i i i i i i i i 6 y i i i 5 i i i p i y 2 2 i -.s.wXhXcXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXwXp 4 i i i i i i i i i i 3 -.tXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXhXhXhXhXfXhXfX1.3 i p y p 5 i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y 8 / R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.(.OX;X;X:X:X:X:X:X:X:X1X%X{ y 5 5 i i i i i i i i 5 p l.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.L.eXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXL.i y 5 i i i i i i i i i i i i i i i i i 6 i i 6 y i i i 6 p 5 4 3 g 4 f t.n.uXjXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXh.3 i i i i i i i i i i i 3 y.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXdXdXgXH.f 5 6 p 6 i i i i i i i i i UXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y b R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.Q.|.oX;X:X:X:X:X:X:X:X:X>X:X$.y 5 i i i i i i i i i 5 3 8.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.P.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXt.3 5 i i i i i i i i i i i i i i i i i y i y 6 p i p 5 3 2 3 3 } 7.c.wXhXvXcXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsX-.2 p i i i i i i i i i 4 i c.vXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXfXdXdXtXiXp.p 5 5 y y 6 i i i i i p i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t x Q Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W Q.|.oX;X:X:X:X:X:X:X:X:X:X:X1XS i y i i i i i i i i i 5 4 =.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.I.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXsX-.2 4 i p i i i i i i i i i i i i i p p p 5 5 3 2 2 3 a &.y.v.yXhXkXcXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXD.p 4 i i i i i i i i i i 3 f wXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXsXaXuXtXwXrXI.-.5 5 y 6 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 t [ Y R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W W.}.oX;X:X:X:X:X:X:X:X:X:X:X:X1X[.e r i i i i i i i i i i 4 i m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.F.F.J.Y.J.K.eXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXkXyX9.4 2 2 4 p p p p i p p p i i i 4 3 3 g 4 r p -.9.s.A.rXjXjXcXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXd.3 i i i i i i i i p 6 y 3 3.hXcXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXsXfXsXiXtXrXI.P.U.m.a 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y 6 N R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.(.|.oX:X:X:X:X:X:X:X:X:X:X:X,X;X<X#.3 i i i i i i i i i i i 3 8.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.J.P.P.U.P.U.U.U.P.U.U.U.U.U.P.P.P.P.K.I.pXiXaXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXdXn.2.d 4 g 2 2 3 3 2 2 2 2 g 2 y p f <.u.v.G.rXfXjXlXcXkXjXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXaX*.3 p i i i i i i i y p 3 p h.vXhXhXhXhXhXhXhXhXhXhXjXhXfXfXaXaXiXiXrXrXI.L.P.K.I.3.5 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i y Z R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W ~ Q.|.oX;X:X:X:X:X:X:X:X:X:X:X:X,X,X1XS 6 y i i i i i i i i i i 4 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.U.P.P.J.C.m.l.f.i.i.y.8.8.8.8.y.i.p.f.l.m.Y.K.L.pXgXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXkXkXuXG.c.u.2.<.-.&.-.<.<.2.u.d.v.A.wXuXhXjXlXkXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXA.3 5 i i i i i i i i i p 3 f wXvXhXhXfXhXfXhXfXhXfXdXaXaXaXaXiXrXrXeXL.L.P.J.F.P.V.d 4 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i 5 i i i i i i i i i i i t j R R W R R R R R R R R R R R R R R R R R R R R R R R R R R R R W E./.(.oX+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X%Xe r i i i i i i i i i i i 3 f.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.P.U.P.J.m.x.8.,.=.} } d p p 5 5 5 5 5 y i p p a d } &.=.3.i.m.L.dXcXvXcXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXcXkXjXdXuXuXyXtXuXuXdXhXjXkXkXcXkXjXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhX9.3 p i i i i i i i i i p 3 1.fXhXfXfXfXfXdXdXdXaXaXiXiXtXrXeXeXI.L.K.K.K.F.K.F.P.8.5 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p i 5 i i i i i i 5 5 u 0 U Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W W.}. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X;X,X#.y y i i i i i i i i i i 3 >.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.P.P.Y.m.p.3.-.} p p i 3 4 4 4 4 5 5 4 5 5 3 5 5 5 3 4 4 4 4 4 5 i s &.3.a.b.yXhXcXvXvXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXkXkXkXkXkXkXkXkXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXwXa 3 p i i i i i i i i p 4 p h.gXaXiXaXiXiXiXiXpXtXrXeXI.I.L.L.P.K.J.J.F.J.J.J.P.V.} 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i p i i i i i i 5 y i M Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W./.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2XK 5 y i i i i i i i i i i 5 p m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.C.z.i.3.&.s p i 4 4 4 4 i i i i i i 5 i 5 5 i i 6 y p i i i i i 6 5 4 3 3 4 5 a &.:.u.b.wXjXvXvXjXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXjXk.2 y 6 i i i i i i i i p 3 d C.iXeXrXI.eXeXeXeXI.L.L.L.P.K.K.F.F.J.J.J.F.J.J.J.P.4.5 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y t k Q Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T E.Q.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2X%X{ y 5 i i i i i i i i i 5 4 8.K.J.J.J.J.J.J.J.J.J.J.J.K.P.P.C.g.8.=.s i i 4 4 i y i i i i i i i i i i i i 5 i i i i i i i i i i i i i p i y 5 5 3 3 3 y p } 1.h.L.hXcXvXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX*.3 6 6 i i i i i i i i 5 3 ,.L.U.P.P.P.P.K.H.K.K.K.J.J.J.J.J.J.F.F.J.J.J.J.J.P.m.d 4 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 p r h ! Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ ).(. X;X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X,X,X>X#.y y i i i i i i i i i i 4 } C.K.J.J.J.J.J.J.Y.J.P.P.F.m.7.} a i 4 4 4 6 5 i i 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p p p p 5 4 3 4 6 s -.h.wXjXvXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXS.y 5 5 y i i i i i i i i 4 p p.I.K.J.K.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.P.K.-.5 5 i i i i i i i i i i p i i UXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 u 8 / Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W.(. X+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X` 6 y 6 i i i i i i i i i i y g.J.J.J.J.F.J.J.P.P.V.p.=.a i 4 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 4 4 4 d 3.A.sXvXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXy.3 p i i i i i i i i i y 3 } V.P.J.J.J.J.S.F.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.I.i.6 5 i i i i i i p 5 i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y m Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W W.Q.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X at XO.r i i i i i i i i i i i 3 >.K.J.J.J.K.K.U.m.8.} p i 4 y 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 4 5 a -.v.hXvXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXyXp 3 i i i i i i i i i i 5 6 3.P.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.m.d 3 p i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t x T Q R R R R R R R R R R T R R R R R R R R R R R R R R R R R R R E.Q.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1XD 4 y 5 i i i i i i i i i 5 i l.K.J.J.P.F.8.&.i 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i 5 i i 5 4 4 p -.b.jXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXs.3 p p i i i i i i i i p 4 a l.I.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.J.F.F.P.K.-.5 y i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t .Y Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ W.(.OX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X1X&Xe y 5 i i i i i i i i i i 3 3.J.U.K.p.&.i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 4 4 p -.D.cXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX} 3 i i i i i i i i i i i 3 >.J.P.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.K.P.7.y 5 6 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i u 6 N R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W.(. X+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X,X>X#.y y i i i i i i i i i i 5 p N.N.-.p 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 4 a u.uXvXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXc.3 5 i i i i i i i i i i 5 5 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.f.p 4 i 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y u b R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ R ~ /.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X_ 6 4 i i i i i i i i i i i 4 =.d 5 5 4 i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i 5 5 4 4 f b.cXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsX=.3 6 i i i i i i i i i i 4 } V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.x.d 3 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 t z Y E.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ ^.{.XX;X<X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X1X at XO.r i i i i i i i i i i i i y 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i p p p p i i i 5 i i i 4 p i i p i i p p p p i i i i i i i i i i i i i i i i i i i i i i i i 5 5 3 a 4.uXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXB.3 y 6 i i i i i i i i i i 4 1.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.I.z.} y 6 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 t 7 P R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ W.(. X;X;X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1XD y i i i i i i i i i i i i 5 5 5 5 i i i i i i i i i i i i i i i i i i i i i i 6 4 3 3 3 3 3 3 4 3 3 3 i 4 3 3 3 3 3 3 3 3 3 3 4 i p i i i i i i i i i i i i i i i i i i i i i 5 5 5 5 4 &.A.cXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhX-.3 5 p i i 5 i i i i i i 4 a l.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.m.} 4 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y 4 M E.R R R R R R R R R R R R R R R R R Q R R R R R R R R R R R R W W.(.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X*X{ y 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 i i i 5 3 3 3 i d &.<.t.h.b.B.S.G.wXG.wXG.G.S.n.v.s.t.-.&.a i 2 2 3 5 i i i i i i i i i i i i i i i i i i i i i i i 5 4 p u.hXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXA.5 5 5 5 5 p i i i i i i 4 4 >.K.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.z.} 3 5 i i i i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t Z R Q R R R R R R R R R R R R R R R R R T R R Q R R R R R R R R ~ ~ /.{.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1Xq.y y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y 4 3 3 5 *.t.c.S.yXdXjXfXhXjXhXjXjXjXjXjXjXjXjXjXhXhXhXfXdXwXA.h.4.} 5 3 3 3 i p i i i i i i i i i i i i i i i i i i i i i i 2.sXvXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXjXfXjXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfX:.3 y 5 5 i i i i i i i i 4 a f.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.z.} 4 p i i i i i i i i i i i i i i 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i i i t X.Y E.R R R R R R R R R R R R R R R R T R R R R R R R R R T Q R R Q Q.{.XX#X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X[.q y i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 1 2 d 1.v.yXuXfXjXjXhXjXjXjXhXhXjXhXhXhXhXhXhXhXjXhXhXjXjXjXjXjXjXjXsXuXwXd.<.a 3 3 y p i i i i i i i i i i i i i i i i i i i y 4 ;.G.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXjXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXA.3 5 p 6 6 i i i i i i i 5 4 =.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.f.s 4 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t 9 / E.R R R R R R R R R R R R R R R R R Q R R R R R R R R R R R R W W.(.XX+X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X>X5.y i i i i i i i i i i i i i i i i i i i i i 6 i i i 3 3 a t.b.rXhXjXjXjXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXjXjXjXjXhXwXc.1.p 3 3 i i i i i i i i i i i i i i i i i i i 5 4 a c.cXjXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXfXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhX<.3 5 6 y y i i i i i i i 4 i p.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.P.y.p 4 5 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 y y m Q Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W ~ /.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X' 9 y 6 i i i i i i i i i i i i i i i i i i i p i 3 3 ;.k.yXhXlXjXjXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXjXjXjXsXyXu.f 3 3 p p p i i 5 p i i i i i i i i i i i i y p k.cXjXhXhXhXhXhXhXhXhXhXhXhXfXsXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXjXjXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXB.5 y 6 6 y p 6 6 p i i i 5 4 } F.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.I.V.,.y 5 5 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t k T Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W.^.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>X at .y 5 i i i i i i i i i i i i i i i i p p y 3 4 :.A.dXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXjXjXjXjXkXaXv.=.3 3 i i i i 5 i i i i i i i i i i i i i 5 p h.vXkXhXhXhXhXhXhXhXhXhXhXjXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdX;.3 5 y 5 6 5 y y 5 6 i i 4 i 8.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.x.} 5 5 5 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 t | I E.R R R R R R R R R R R R R R R R R R R R T Q R R R R R R R R R Q.(.OX;X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X:X at .5 5 i i i i i p i i i i i i i 5 i i p 3 3 -.B.hXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXjXjXfXc.&.3 3 p y 6 i i i i i i i i i i i i i i y 6 d.cXjXhXhXhXhXhXhXhXhXhXsXjXjXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXv.3 p p i p i i 6 i 6 y i i 4 } V.K.J.J.J.J.J.J.J.J.J.J.J.F.J.P.C.3.p 4 i i 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 t 6 G R.R R R R R R R R T R R R R R R R R R R R R R R R R R R R R R R W./. X+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X1X;X0.y y i i i i i i i i i i i i i i 6 y 5 3 *.B.fXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXjXhXkXaXh.f 3 5 i i i i i i i i i i i i i i i i 4 p d.vXjXhXhXhXhXhXhXhXhXjXjXfXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXsXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXiX} 4 y 6 i i i i i i 6 y i 4 i 8.P.J.J.J.J.J.J.J.J.J.J.J.J.P.K.f.} 5 5 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i p 5 i i i i i 5 5 5 y r b R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W W.(.|.oX;X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X,X0.4 y i i i i i i i i i i i i i i i y 3 p s.aXcXjXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXsXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXtX4.5 4 i i i i i i i i i i i i i i i i 5 p h.vXjXhXhXhXhXhXhXhXfXjXjXfXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXf.3 5 p 6 y 6 6 y 6 6 y 5 i 4 } V.K.J.J.J.J.J.J.J.J.J.J.K.P.m.-.i 4 i i i i i i i i i 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i p 5 5 u l T Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W E.Q.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X>XD 5 y 6 i i i i i i i i i i i i i i 4 4 -.D.kXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXjXjXjXfXfXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXjXA.f 3 5 i i i i i i i i i i i i i i i 4 a n.vXhXhXhXhXhXhXhXjXfXfXjXjXsXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXL.p 5 6 y 6 6 y p 6 y 5 6 p 4 i 8.U.J.J.J.J.J.J.J.J.J.P.P.m.,.p 4 i i i i i i i i i i i p i p 5 i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 6 u 7 P E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W Q.(. XoX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2X` a y 5 i i i i i i i i i i i i i i 4 6 s.aXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXhXhXhXhXsXjXfXjXfXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXuX9.4 4 i i i i i i i i i i i i i i i 4 d wXvXhXhXhXhXhXhXfXjXjXfXjXsXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXaXsX4.3 6 y p i p 6 5 y 5 p 5 5 4 } V.K.J.J.J.J.J.J.K.K.K.l.>.p 4 5 i 5 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 u 6 N E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T ~ W.(. XoX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X%X+.y 5 5 6 i i i i i i i i i i i i 3 d M.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXjXfXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXjXc.a 4 i i i i i i i i i i i i i i i 4 <.dXkXhXhXhXhXhXjXfXsXjXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXM.p 5 6 y 5 i 5 y 6 6 6 y 6 5 p i.P.F.J.J.J.K.P.K.m.i.} p 4 5 6 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i u Z R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W.Q.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X-X at .r i i i i i i i i i i i i i i 6 3 =.L.hXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXsXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXD.f 4 i i i i i i i i i i i i i i 4 i t.lXjXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXiXeX=.3 p p p i i y 6 y 6 6 y y 5 } F.P.K.K.K.K.m.i.=.p 4 4 4 i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 t h Y R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.Q.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1Xe.i y i i i i i i i i i i i i i 5 3 1.I.aXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXtX:.4 i 5 i i i i i i i i i i i i 4 p n.vXhXhXhXhXhXhXhXjXfXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXjXfXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXdXtXrXf.5 i i 6 y i i y 6 5 p 6 6 p p j.U.V.m.g.3.} s 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 t 0 P R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.(. X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X1X] 9 y 5 i i i i i i i i i i i i p 3 4.P.iXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXuX:.4 5 i i i i i i i i i i i i i 4 f wXlXhXhXhXhXhXjXsXfXjXsXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXdXrXrXC.d 4 5 i p 6 6 i 6 y 6 6 y i 5 s 8.,.} a 4 5 4 5 5 i i i i i i i i i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y p V R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W./.|.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2X=XO.u i 5 i i i i i i i i i i i i i 4.L.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXsX2.4 i i i i i i i i i i i i i 4 r 7.hXjXhXhXhXhXjXfXjXfXjXfXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXrXrXP.1.4 5 6 i 5 y y 6 p 5 6 y 6 i p p 4 4 4 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i p i i i i y u k R R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W W.Q.}.+X-X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X>Xq.y y i i 5 i i i i i i i i 6 5 3 4.K.I.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhX2.3 i i i i i i i i i i i i i 5 p k.cXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXaXiXrXL.P.j.i 5 i i i i i i i i i i i i i i i i i i i i i 6 i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i 5 i i 5 5 r h U R.T R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W Q.}.XX#X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X1X` 9 u i i i p i i i i i i i i y 5 3.K.K.I.pXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX1.3 i 5 i i i i i i i i i i p 3 d wXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXaXpXeXI.P.C.f 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i 5 i i i i i i i i i i 5 6 t 8 / T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.(.OX#X;X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X.X at .u 5 5 i i i i i i i i i i p 3 >.J.J.P.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXhXhXkXsX*.3 p i i i i i i i i i i i 5 y y.kXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXaXrXwXI.K.P.3.3 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 y y b E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W./.|.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1XS 4 y i 5 i i i i i i i i i p 4 } V.K.K.P.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXwXd 4 i i i i i i i i i i i i 4 p B.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXiXpXI.L.K.P.l.p p i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i t x R Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ ^.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X%X+.u 5 i i i i i i i i y 6 p 3 a m.K.J.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXB.5 4 i i i i i i i 5 p i 6 5 4 <.hXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXtXeXL.P.J.K.C.&.5 i i i i i i i i i i 5 i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i t | U R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ W.(.oX;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X>X>XD y y 5 i i i i i i i i p p 5 5 f.K.J.J.K.I.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXu.3 i i i i i i i i i i y 5 3 p Z.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXrXrXL.P.K.J.P.4.4 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 6 u 9 M T.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W./. XoX:X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1X.X+.r 5 i i i i i i i i i i p 3 1.J.K.J.H.K.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX;.3 p p i i i i i i 5 6 5 5 5 1.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXfXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXfXaXiXrXP.L.K.F.J.P.j.p 5 y 6 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y y Z R.E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R T W.Q.|.oX:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1XK 5 u 5 5 i i i i i i i i i 3 d N.K.J.Y.K.P.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXG.p y 6 i i i i i i 6 y p p 3 a A.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXsXaXtXrXL.K.K.K.F.P.V.f 4 6 5 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i u j T E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W Q.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X-X$.u i i i i i i i i i 6 6 5 5 i.K.K.J.K.J.P.eXuXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXjXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXu.3 5 y 6 5 p i i i i i i 5 5 u.kXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXgXtXpXrXP.K.J.J.F.K.K.1.4 i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i p 6 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i u 7 P R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Q Q.(. X+X;X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X2X' q y i i i i i i i i i y y 3 =.F.K.J.J.J.J.L.wXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuXf 4 6 6 y 6 i i i i i i y 3 f uXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXuXtXrXP.K.J.J.J.J.K.P.p.y 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i p 5 i i i u 6 V T.Q R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W./.|.+X;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X>Xq.y y i i i i i i i i i 6 5 y g.K.J.J.J.J.K.P.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXh.4 5 p 6 y i i i i 5 p 6 4 p c.vXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXsXdXiXrXI.L.K.J.J.J.J.C.P.m.a 5 i i i i i i p i i i i i i i i i i i i i i i i i i i i i p i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y y k E E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R ~ /.|.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X>X at XO.r i i i i i i i i i i i 3 >.J.K.J.J.J.J.K.K.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXaX} 3 5 6 y i i i i i 5 5 5 4 9.kXkXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXsXuXtXU.L.K.K.J.J.J.J.J.P.C.&.3 5 i i i i i 5 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p i t h Y E R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W Q.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X:X:X:X:X:X:X:X:X2X' q y i i i i i i i i i i 5 5 f.K.J.J.J.J.Y.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXh.3 p p 5 i i i i i i i y 3 =.rXcXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXdXiXwXI.L.K.Y.K.J.J.J.J.K.K.3.3 6 i i i i i i p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 t 0 / R.R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R W W.(. XoX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X1XD y y i i i i i i i i i p 3 =.C.K.J.J.J.J.J.Y.L.rXtXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtXd 3 5 p i i i i i i 6 6 4 p A.cXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXtXrXI.L.K.Y.Y.K.Y.J.J.J.J.P.p.i 5 p i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 6 y 6 V !.R.Q E E R Q R R R Q R R R R R R R R R R R R R R R R R R R R ~ W./.|.oX:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X,X;X0.y 3 i i i i i i i i 6 y y i.K.J.J.J.J.J.J.K.K.rXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXu.3 p i i i i i i i y 6 5 y u.jXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXdXiXtXI.L.P.K.K.Y.K.K.Y.J.J.J.P.l.s 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 u j U T Y Y T R R Q E E E Q E E Q Q Q Q Q Q R Q Q R R R R R R R T R ~ ^.(.oX;X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2X*XO.u p i i i i i i i i i 3 s N.K.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXD.p 3 i i i i i i i i i p 4 <.iXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXdXdXtXwXI.L.L.J.J.Y.K.Y.Y.K.J.J.P.V.} 4 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 8 7 [ ..j x k Z n V M N H / P P U Y R R R W R R E.E.R.R.R.R.Q E.W.Q._.OX;X:X,X,X:X,X:X:X,X:X:X,X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X2X' q u 5 5 5 i i i i i i p 3 3.C.J.J.J.J.J.J.J.J.P.rXuXfXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX;.3 p i i i i i i i i i 3 } K.iXiXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXpXrXeXL.K.K.J.J.J.J.J.J.J.J.J.K.J.-.4 5 i i i i i i i i i i i i 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i y t t u t t t t t t u y 6 9 7 [ ..h j x k Z n V V N G P P I Y ! ^ Q.|.;X3X>X>X1X>X>X>X>X1X1X>X,X>X,X,X,X,X:X:X:X:X,X:X:X:X:X:X,X:X:X:X:X:X:X:X:X:X:X:X:X,X1X_ p y p 5 5 i i i i i i 5 4 f.K.K.J.J.J.J.J.J.J.K.rXiXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXs.2 i i i i i i i i i i 5 s j.pXI.tXtXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXpXtXeXI.H.K.J.J.J.J.J.J.J.J.J.J.K.K.7.y 4 i i i i i i i i i i i i i p p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p 6 i p i i i i i y i y y u u t t t t t t u y i 5 6 6 8 w [ ..X.l F D S _ ` ' ' ].%X*X*X*X-X-X-X<X:X,X>X>X1X1X>X1X>X>X>X>X,X,X,X,X,X,X:X,X,X,X;X:X,X:X,X>X>X0.u y 5 i i i i i i y p 3 d m.K.J.J.J.J.J.J.C.K.P.I.iXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXD.4 4 i i i i p i i i i 5 5 y.eXK.P.eXrXtXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXuXuXrXeXI.L.J.J.J.J.J.J.J.J.J.F.F.J.K.P.i.5 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y 6 i i i i i i i i p i 5 6 i i i y i i y y y y u u t u u u r r r r 1 y y 6 q +.+. at .#.#.q.e.D _ _ ` ' [.[.=X=X=X at X-X-X,X>X>X>X>X>X>X>X>X1X1X>X>X>X,X1X at X%.r i i i i i i i i 6 6 3 *.C.P.J.J.J.J.J.J.K.Y.L.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXtXd 4 i i i i i i i i i y 4 >.K.P.K.P.I.eXrXiXaXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXdXsXtXrXrXL.K.K.J.J.J.J.J.J.J.J.J.J.F.F.K.L.g.p 3 6 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i p 5 5 p p 5 i i i i i i 5 y y y u u r 1 r 1 r r r y y 5 p 6 9 +.+. at .#.w.D D K _ ` ' ' ].%X=X.X at X-X-X;X;X1X[.+.r i i i i i i i i 6 5 3 8.J.J.J.J.J.J.J.J.Y.K.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXjXdX2.g p i i i i i i i 6 y 3 *.V.P.F.J.K.L.I.eXrXiXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdXfXfXaXtXrXwXL.K.K.K.J.J.J.J.J.J.J.J.J.J.J.F.K.P.l.s 3 p y i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i 5 i i i i p i i i i i i 6 5 5 i 6 p 5 5 5 6 i y 5 4 y y y u r u r u r r 1 1 1 u y 5 a q e O.%. at .#.w.e.D _ w.6 y i i i i i i i i y 5 3 f.J.J.J.J.J.J.J.J.K.C.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXs.g i i i i i i i i p p 4 d z.P.F.J.C.K.K.K.I.U.rXiXaXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXdXuXtXrXI.I.P.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.m.} 3 5 p p i i i i i i i i i i i 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i i i i 5 y i p 6 6 p 6 5 p 5 i 5 y y 5 y y y r u r 1 1 1 t u r y y 4 i i i i i i i i i 5 4 p l.K.J.J.J.J.J.J.J.J.J.K.P.eXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXv.4 5 i i i i i i i i i 3 p p.P.J.J.J.J.C.K.K.P.P.rXrXtXiXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXdXtXtXrXI.L.K.K.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.V.&.4 5 i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i 5 6 i i 6 y 5 p 5 5 i i 5 5 6 5 5 i 5 6 i p 5 5 i i 5 y y i i i i i i i i i i i i 4 } m.P.J.J.J.J.J.J.J.J.J.K.K.I.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXjXG.p 3 i i i i i i i i i 4 6 y.P.K.J.J.Y.K.K.C.K.J.P.P.eXrXpXiXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXgXdXiXtXrXI.L.L.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.F.>.3 5 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i 3 &.V.K.J.J.J.J.J.J.J.J.J.J.J.L.rXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXwXs 3 i i i i i i i i i 5 5 3.P.J.J.J.J.J.J.J.J.J.J.K.P.P.I.eXtXpXsXfXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXuXtXrXrXL.L.K.K.J.K.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.F.>.5 5 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 3 >.V.K.J.J.J.J.J.J.J.J.J.J.K.P.rXiXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtXd 3 p i i i i i i i i p 3 >.P.J.J.J.J.J.J.J.J.J.J.S.J.K.K.L.L.I.rXpXiXsXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXdXdXtXtXrXI.L.P.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.F.3.3 y 5 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 2 >.F.K.J.J.J.J.J.J.J.J.J.J.J.L.L.tXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsX&.3 p i i i i i i i i i 3 =.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.L.I.wXtXtXiXdXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXsXiXiXrXI.I.L.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.3.4 5 p i i i i i 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 2 3.F.K.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX*.3 p i i i i i i i i i 4 =.J.P.J.J.J.J.J.J.J.J.J.J.J.J.J.S.J.J.J.K.P.L.I.rXrXiXiXdXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXaXiXiXrXeXP.L.P.K.K.J.K.Y.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.4 4 5 i i i i i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 2 3.J.K.J.J.J.J.J.J.J.J.J.J.J.K.P.eXiXgXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsX-.3 p 5 i i i i i i i i 3 =.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.H.K.K.L.I.I.rXtXtXiXaXdXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXsXaXiXiXrXrXU.P.L.K.K.K.J.Y.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.8.i 3 i 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 2 3.J.K.J.J.J.J.J.J.J.J.J.J.J.Y.K.L.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX=.3 p i i i i i i i i i 4 =.F.P.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.Y.K.J.K.K.P.I.I.rXtXpXaXdXaXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXdXdXaXtXtXrXrXrXP.P.K.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.5 4 p i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 2 1.J.K.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXtXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsX*.3 5 i i i i i i i i i 4 =.J.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.P.L.I.I.eXrXpXiXaXaXsXsXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXdXaXaXiXrXrXeXI.L.P.P.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.5 3 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 3 >.C.K.J.J.J.J.J.J.J.J.J.J.J.J.Y.K.L.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsX&.3 p i i i i i i i i i 3 =.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.C.J.J.J.P.P.I.P.eXtXpXpXiXaXsXsXsXsXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXfXhXaXaXaXaXiXiXpXrXeXP.L.P.K.K.K.K.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.5 4 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 3 -.V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.eXiXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtXf 3 i i i i i i i i i i 4 >.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.L.L.L.eXeXeXtXtXiXaXaXsXaXsXfXfXhXfXjXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXsXfXdXaXaXaXiXtXtXtXeXeXI.L.L.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.6.5 3 i i i i i i i i i i i i i p 5 i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 3 &.N.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXwXa y i i i i i i i i i 4 i 3.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.K.L.L.L.I.eXeXrXrXtXiXiXaXaXaXaXfXaXfXfXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXfXfXfXfXfXaXsXaXaXaXiXaXpXtXrXeXI.I.P.P.P.K.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.1.4 4 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i p i i i i i i i p i i i i i p 3 d m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.pXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXG.p 3 i i i i i i i i i 4 i 8.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.K.L.L.eXeXeXrXpXtXtXiXiXaXaXsXaXdXaXfXdXfXfXfXfXhXfXfXhXhXfXfXhXfXhXhXhXhXhXhXhXhXfXhXhXfXfXfXfXfXfXfXdXdXdXaXaXaXiXiXtXiXtXtXrXwXI.I.L.L.K.K.K.K.J.J.J.J.S.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.C.>.y 4 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 5 z.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.eXaXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXjXc.3 i i i i i i i i i i 4 a f.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.F.K.K.K.K.K.L.P.I.I.eXeXeXrXrXtXtXtXtXiXaXiXaXaXaXaXaXaXdXdXaXaXsXsXsXaXfXaXaXaXaXaXdXaXaXaXaXaXaXuXtXtXtXtXtXrXrXeXeXI.I.L.L.P.L.K.K.K.K.J.K.K.S.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.V.=.3 4 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 3 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXaXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXs.2 i i i i i i i i i i 4 s m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.J.K.P.K.P.L.L.L.P.I.eXeXeXeXeXrXrXrXtXrXtXtXtXtXtXpXtXpXtXtXtXtXrXtXrXtXpXpXrXrXrXeXrXeXwXI.I.P.L.L.P.K.K.K.K.K.Y.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.z.} 3 y 6 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 3 3.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.wXtXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX1.2 p i i i i i i i i i 4 &.V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.K.P.K.K.P.P.L.P.L.L.I.L.L.L.I.L.I.L.I.eXI.L.L.I.I.I.L.L.L.L.L.L.L.P.K.P.K.P.K.K.K.K.K.J.J.J.J.K.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.x.d 3 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 3 =.C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.P.I.iXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtXs 5 i i i i i i i i i 5 4 3.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.S.K.J.J.K.F.J.J.K.J.K.K.K.K.K.K.K.P.K.K.K.K.K.K.K.K.K.K.K.J.K.C.F.K.F.F.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.i.a 3 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 4 a m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.S.K.L.eXtXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXA.3 5 i i i i i i i i i 4 i 8.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.J.F.F.J.J.K.S.F.F.J.J.J.J.F.F.J.J.F.J.F.F.J.J.F.J.J.F.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.p 3 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 i i i i i i i i i i 5 4 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.rXiXaXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXjXfXjXfXsXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXu.3 i i i i i i i i i i 4 s g.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.C.,.5 4 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i 6 3 >.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXaXfXhXhXhXhXhXhXhXhXhXfXjXfXjXfXjXjXjXjXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXuX&.3 p i i i i i i i i 5 4 } V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.z.} 4 4 p i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i 5 y 5 s m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.P.L.rXiXaXhXhXhXhXhXhXhXhXhXjXfXhXhXfXjXfXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXA.4 4 i i i i i i i i i i 4 >.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.f.s 3 5 5 i i i i i i i i i i i i i i i p p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 i i i i i i i i i 5 5 5 3 i.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.J.K.I.rXiXaXfXhXhXhXhXhXhXhXfXjXhXhXjXfXjXfXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXt.3 i i i i i i i i i i 4 i 8.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.C.7.p 3 y 5 i i i i i i i i i i i i i i i i 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i p 3 =.V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.I.eXtXaXfXfXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXL.s 4 i i i i i i i i i i 4 a g.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.m.>.i 4 i i i i i i i i i i i i i i i i i p p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i 5 4 5 f.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.eXpXaXsXhXhXhXhXhXhXhXhXhXjXfXfXjXjXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXa.3 i i i i i i i i i i 5 4 } V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.f.} 4 4 i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 3 =.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.U.tXaXaXdXhXjXhXhXhXhXhXfXjXjXfXsXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXsXaXaXP.d 4 5 i i i i i i i i i 5 4 ,.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.I.C.3.p 3 y 6 i i i i i i p 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 4 f.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.tXpXaXdXfXhXhXhXhXhXjXfXsXjXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXsXuXpXrX8.3 5 5 i i i i i i i i i 4 p p.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.l.&.5 y i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 3 } V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.U.pXaXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXaXiXrXeXV.p 5 i i i i i i i i i i i 3 } m.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.i.a 4 4 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i 5 p i i i i i i 5 3 i.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.I.rXpXaXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXdXdXiXtXeXL.P.1.3 5 i i i i i i i i i i i 5 3.P.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.m.-.5 4 5 p i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 s m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.I.I.tXiXaXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXdXrXeXI.P.P.g.5 5 5 i i i i i i i i i i 4 p j.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.s 5 4 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 >.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.K.L.eXrXiXaXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXfXfXfXdXiXiXrXI.P.P.K.C.} 4 y 5 i i i i i i i i i i 4 >.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.l.=.y 4 5 i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 4 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.K.P.L.I.rXiXiXaXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXhXhXhXhXhXhXhXhXhXhXfXfXdXdXiXiXrXI.L.K.K.K.K.3.3 6 i i i i i i i i i i i 4 p g.U.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.F.6.a 4 4 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 p l.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.K.P.L.I.rXpXiXaXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXhXhXhXhXhXfXhXfXfXdXsXiXiXrXeXI.L.K.K.J.S.P.i.y 5 i i i i i i i i i i i 5 3 >.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.x.} 4 4 i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 3 } m.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.P.L.U.eXrXtXiXiXaXdXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXfXfXdXgXsXuXtXaXtXrXI.P.P.K.K.K.C.Y.K.l.p 4 5 i i i i i i i i i 5 i y s l.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.m.>.p 4 5 i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 4 =.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.J.K.P.L.I.eXrXrXiXiXiXaXaXaXfXdXfXfXhXfXfXhXfXfXfXfXfXfXfXfXsXdXgXaXaXuXuXtXtXrXI.L.L.K.P.J.J.C.K.K.P.m.d i i i i i i i i i i i i 5 5 5 3.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.C.6.s 4 5 i i i i i i i i i i i i i i i i i i i i i i p i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 3 >.F.J.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.L.I.I.I.rXrXtXtXiXiXaXaXaXaXaXaXaXdXdXdXuXuXiXiXtXuXtXtXyXrXrXI.L.P.P.J.J.J.J.J.J.J.J.P.V.} 4 i i i i i i i i i i i i i 4 d V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.p.} 4 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p i i i i i i i i i i 4 3.J.K.J.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.K.P.P.P.L.I.I.I.eXeXeXrXrXrXtXtXrXrXrXrXrXrXrXrXI.L.I.I.K.K.H.K.J.J.J.J.J.J.J.J.J.K.C.=.4 i i i i i i i i i i i i i 4 p i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.K.l.=.i 5 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 4 3.J.K.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.F.J.K.K.K.P.K.P.P.L.P.L.L.L.L.L.L.L.L.L.K.P.K.K.K.K.K.J.K.Y.J.J.J.J.J.J.J.J.J.P.C.=.4 i i i i i i i i i i i i i i 4 >.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.K.l.>.a 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i 5 i i i i i i i i i i i 5 4 3.F.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.J.J.J.J.J.S.F.K.K.K.K.K.K.K.K.K.K.Y.K.L.K.J.Y.Y.Y.K.J.J.J.J.J.J.J.J.J.J.J.P.m.=.4 i i i i i i i 5 i i i i i 5 3 } m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.l.>.p 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 5 4 -.V.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.K.Y.Y.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.m.} 4 i i i i i i i i i i i i i i 4 a x.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.m.>.p 5 5 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p 5 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i y 4 } z.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.Y.Y.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.f.s i i i i i i i i i i i i i i i 5 4 3.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.K.z.,.p 5 5 5 5 i i i i i i i i i i i i i i i i i i i 3 4 6 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 p p.K.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.8.i i i i i i i i i i i i i i 5 p 5 4 >.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.P.J.g.-.p 5 4 5 i 6 y i i i i i i i i i i i i i i i i p 3 5 ;.;.3 5 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 i 3.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.P.P.m.=.i i i i i i i i i i i i i i i 5 y 4 } m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.F.p.} i i i i i 6 y 6 p i i i i i i i i i i i i i i i 4 3 d h.hXeX} 3 p i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 4 } f.P.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.K.i.s 4 i i i i i i i i i i i i i i i i 5 a x.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.P.M.y.d y 5 5 5 6 y 6 y 6 6 5 i i i i i i i i i i i i i i y y 1.wXcXjXcXA.a 3 p p p 6 6 y 6 y 6 i 6 6 y i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 5 i ,.V.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.m.=.4 i i i i i i i i i i i i i i i i i 5 p i.U.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.J.J.J.J.J.J.J.J.P.P.F.g.>.s 4 5 6 i i y 6 i i 5 p y 6 i i i i i i i i i i i i y 3 d v.hXkXhXhXjXcXc.i 3 i 5 y i 6 6 y i i y 5 6 i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 5 4 s 8.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.V.3.a 4 6 i i i i i i i i i i i i i i i i i i p >.f.V.P.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.K.K.m.8.} i 4 5 i 5 i i i i i i i i i i i i i i i i i i i i i i 3 a u.uXkXjXhXhXhXhXjXhXa.3 5 i p i i i 5 i i i p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i 4 } i.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.C.8.s 4 4 i i i i i i i i i i i i i i i i i i i i i 4 i } 6.m.F.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.K.F.f.>.a 4 y i i i i p 5 i i i i i i i i i i i i i i i i i i i 3 4 2.wXcXjXfXhXhXhXhXhXhXcXuX:.3 i p i i i p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i p 5 i i i i i i i i i i y 4 } i.N.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.Y.K.K.P.m.8.s 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i 4 4 i } 8.m.J.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.K.K.K.C.f.3.s i 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i 4 4 ;.B.kXlXhXhXhXhXhXhXhXhXhXhXvXS.a 3 6 i i i i i i i i p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i 5 4 s 3.m.J.P.K.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.C.x.>.a 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 p &.8.m.F.K.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.P.K.V.x.,.} y 4 i i 6 i i i i i i i i i i i i i i i i i 6 y i i i i i 4 4 f k.fXcXhXhXhXhXhXhXhXhXhXhXhXhXjXjXs.3 y i i i i i i i i i i i 5 i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i 4 4 i =.i.M.K.K.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.K.K.J.m.y.} 4 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i y 4 3 i =.8.x.V.K.P.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.J.N.p.3.d 5 3 4 5 5 i i i i i i i i i i i i i i i i i i i p 5 6 i i i 5 y d s.uXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXyX*.2 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 p i i i i i i i i i i i i i i i i i i i i i i 4 3 9 *.y.z.V.C.K.K.K.J.J.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.K.K.K.C.V.l.4.} p 3 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 i i i 4 3 i } >.p.m.F.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.K.V.l.8.*.a 5 3 6 5 p i i 5 i i i i i i i i i i i i i i i i i i i i y 6 i i i d s.tXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXc.i 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i 5 i i i i i i i 4 4 4 5 a >.8.f.m.V.J.J.J.J.J.P.J.K.K.K.K.K.J.J.K.F.J.C.V.z.p.3.&.a 4 4 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 4 4 4 p =.6.f.N.K.K.J.K.J.J.J.J.J.F.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.J.K.K.J.F.m.i.3.d y 4 4 4 5 i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i y 4 a u.tXcXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXtX-.2 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i 5 i y 3 3 4 p s } -.3.8.i.p.f.x.z.l.f.f.f.i.6.3.*.f s p 4 3 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 3 4 5 a } 3.f.m.V.J.K.J.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.F.N.l.i.>.} p 4 3 4 i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 i 4 f u.wXcXjXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXc.5 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 5 p 5 i i i i i i i i i i i i i i i i i i i i i i 5 5 i i i 4 3 3 4 4 4 3 4 3 3 3 4 3 4 3 3 3 4 4 4 y i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 i 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 4 4 3 i } >.8.f.m.V.F.F.J.J.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.F.J.K.K.K.J.J.C.V.x.i.3.=.s 5 3 4 4 4 i i i i i 6 i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 5 f d.uXcXjXjXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXyX&.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i p p i i i i i p p i 6 5 p i p p 5 p 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i 4 a } 4 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i p i 4 3 3 y i s } 3.i.g.z.m.C.J.P.J.J.J.J.P.J.J.J.J.J.K.J.J.K.J.J.K.J.J.K.J.K.J.J.K.J.P.J.J.J.J.J.J.J.K.J.K.J.J.P.J.C.V.m.l.f.8.>.} a i 4 3 3 5 i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 4 p ;.v.fXcXjXjXhXjXhXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXu.4 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i a f.m.8.} i 4 5 i i i i i i 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 4 4 4 3 3 3 p d } -.3.8.p.g.m.m.C.C.C.C.F.F.F.J.J.K.J.J.K.K.K.K.K.K.J.J.J.J.J.J.F.C.C.C.C.V.m.l.f.i.3.>.=.} a 5 4 3 4 4 y 4 i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 i i 5 5 4 y a <.n.jXlXjXjXjXfXjXfXjXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXS.s 4 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 } P.P.P.F.f.=.a i 4 4 5 i i 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i p i i i 4 4 3 3 3 i i p p a d } =.>.3.3.i.i.8.y.i.f.f.f.f.f.i.y.i.8.i.8.3.3.>.&.} s a a p i 4 4 3 3 4 4 5 5 5 5 i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 5 5 4 y *.u.wXjXcXjXjXfXjXfXjXfXjXfXfXjXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXdX<.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 ,.P.J.J.K.P.P.m.8.} 4 5 5 4 i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i 5 5 5 i y 4 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 3 3 4 4 4 4 5 y i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 4 i p <.v.uXbXjXjXjXfXfXjXfXjXfXjXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXkXs.4 4 i i i i p i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 8.K.J.J.J.J.J.P.P.F.f.>.d i y 5 5 5 i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i 5 i i 5 p 5 5 i p p i p p y p p i i p 6 y p i p p i i p i i i i i i i i 5 i 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 4 5 a ;.a.yXkXvXjXfXjXjXfXjXjXfXjXfXjXfXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXS.a 3 p 5 i i 5 i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 8.K.J.J.J.J.J.J.F.K.P.P.N.i.-.a p 4 4 4 5 5 i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 4 4 s f t.S.dXvXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXvXrX-.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i i i i i i i i i i i i i i i i i i i i 4 g.K.J.J.J.J.J.J.J.F.F.K.P.P.P.B.a.:.d 5 5 4 5 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 4 5 i a f 9.n.sXjXvXlXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXfXt.3 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 m.J.J.J.J.J.J.J.J.J.J.J.F.F.K.U.dXdXL.c.1.f p 5 4 4 4 i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i 5 i i 5 4 4 4 i a f t.n.uXvXcXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXd.3 5 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 m.J.J.J.J.J.J.J.J.J.J.F.F.F.C.P.L.iXjXcXkXuXB.u.:.s p 4 4 4 4 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 5 4 4 4 5 p f 2.d.G.jXcXvXcXjXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXb.p 3 i i i i i 5 p i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXp i i i i i i i i i i i i 4 m.K.F.F.J.J.J.J.J.J.J.J.J.J.J.K.L.rXaXfXjXkXvXvXfXG.c.2.&.a 5 4 4 4 4 5 i i i i i i p y 6 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p p i 5 4 4 4 4 4 p d *.u.n.tXjXvXvXjXjXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXD.s 3 p p i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 m.F.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.I.iXaXhXhXhXhXlXvXvXkXsXD.h.4.;.a i 4 4 4 4 4 5 i 5 5 6 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i y 5 4 3 3 5 5 a f :.u.c.wXhXcXcXcXkXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXyX} 3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 6 4 m.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.L.rXsXhXhXhXhXhXhXhXjXkXvXvXjXuXwXc.9.;.f p 6 4 3 5 5 5 p i p i i 5 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p 5 p 5 3 4 4 p s &.-.u.Z.yXdXvXvXcXkXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXtX;.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 j.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXiXaXhXhXhXhXhXhXhXhXjXjXjXcXvXvXvXhXL.Z.s.3.&.d p i 3 4 3 4 4 4 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i 5 5 p d -.8.h.A.tXkXvXvXcXcXjXjXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXlXuX-.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i 5 i i i i i i i i 4 f.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXvXvXjXuXwXn.s.4.-.&.s i 5 5 4 3 3 4 4 4 4 i i 4 4 i i p i 6 y p p 5 i 5 5 i 6 i i p p i i i 5 5 5 5 5 i i 5 5 i i i i i i i i i i i i 4 7.tXhXjXvXvXcXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXsX:.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 5 i i p i i i i i i i i i i.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.eXtXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXcXcXcXvXcXhXyXA.k.s.y.1.=.} d a a i 4 3 4 4 4 3 4 3 3 4 4 3 3 4 4 4 4 3 4 3 4 3 4 y 3 4 3 4 4 3 4 4 p p i i i 5 i i i i i i i 4 p k.vXvXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXfX:.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 8.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXjXcXvXvXvXhXhXsXyXL.n.h.s.t.4.2.<.-.=.&.} d d s d d p i 6 p p a d d d d d } &.;.-.1.2.t.a.d.t.5 4 i i i i i 5 i i i 4 p z.jXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXdX:.2 6 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 ,.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.K.K.I.iXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXkXcXkXcXvXlXvXcXvXvXvXkXhXuXtXwXwXS.S.S.D.D.n.b.b.b.M.B.D.D.A.S.H.yXyXuXdXjXcXvXvXvXc.3 5 i i i p i i i i i 3 s B.hXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXuX:.3 5 i i i i i i i 5 p i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i 4 } P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.I.rXtXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXhXjXhXhXhXjXjXjXcXvXvXvXvXvXvXvXvXbXvXbXvXvXvXvXvXvXcXcXvXcXkXjXjXhXkXhXu.g 5 i i i i i i i i p 3 f S.hXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXuX;.3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i 4 s C.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXjXhXhXjXhXhXhXhXgXjXkXhXhXhXjXhXhXhXhXhXhXhXhXjXdX1.2 i i i i i i i i i i 3 =.P.gXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXwX&.3 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 a m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.Y.K.K.L.I.tXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXjXyX&.3 i i i i i i i i i 5 3 3.L.iXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXH.f 3 p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.K.K.L.rXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXH.5 5 i i i i i i i i i 4 5 y.U.I.iXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXvXB.a 3 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 3.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.rXaXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXc.3 5 i i i i i i i i i 4 p f.U.P.eXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXcXh.4 5 5 5 5 p 5 i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 } F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.I.rXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXdX2.3 i i i i i i i i i 5 4 } m.P.K.L.rXdXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXt.3 5 i y 6 i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i m.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.wXtXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXtXf 3 p i i i i i i i i 5 3 -.F.K.K.P.wXrXsXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXuX:.3 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 8.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.S.J.P.eXtXdXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXjXlXn.4 4 i i i i i i i i i 5 5 3.K.K.J.K.K.rXpXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXvXwXf 3 p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 } K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.I.tXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXt.3 i i i i i i i i i i 4 a p.P.K.J.C.K.L.U.iXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXcXc.5 4 p 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.S.P.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXwXd 4 i i i i i i i i i i 3 d z.P.Y.J.K.K.K.L.eXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXhX2.3 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 3.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.I.tXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXc.3 p i i i i i i i i 5 5 4 -.C.P.Y.J.C.K.J.K.P.eXuXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXcXwXf 3 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 5 d V.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.I.rXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXiX-.2 y i i i i i i i i i 5 4 4.P.K.J.K.C.K.J.J.K.I.rXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXs.4 5 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i 4 i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.P.L.rXtXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXM.5 4 i i i i i i i i i i 4 p f.I.J.J.J.J.J.J.J.K.K.I.eXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXfXjXjXfXjXfXjXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXcXrX>.3 p p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 } J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.rXtXuXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXeX<.3 i i i i i i 5 i i i i 3 } V.P.J.J.J.J.J.J.J.F.S.K.L.eXpXaXsXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXjXfXfXjXfXjXjXsXhXhXhXhXhXhXhXhXhXhXhXhXhXfXhXfXgXv.6 3 p p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 i.P.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.I.rXiXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXaXpXtXz.5 4 i i i i i i i i i i 5 4 3.P.J.J.J.J.J.J.J.J.J.J.J.K.L.I.tXaXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXsXfXjXjXsXfXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXaXfXrX1.3 6 5 y i i i i i i p i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i 4 4 } C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.K.P.L.rXrXiXgXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXdXtXrXrXP.-.3 5 i i i i i i i i i i 3 a x.P.J.J.J.J.J.J.J.J.J.J.J.K.K.P.I.rXiXdXdXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXjXfXjXfXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXaXiXiXz.p 3 y 6 6 i i i i i i 5 i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i y 6.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.K.P.I.rXtXuXdXfXhXhXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXaXiXtXeXI.P.f.4 4 i i i i i i i i i i i 3 =.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.I.eXiXaXaXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXfXfXjXfXjXsXjXhXhXhXhXhXhXhXhXhXhXhXfXfXdXaXtXpXP.>.3 p p 5 i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 4 a m.P.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.F.F.K.K.L.I.rXtXtXsXfXfXfXhXhXjXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXdXaXiXtXeXP.L.L.V.f 3 5 i p i i i i i i i i 5 i y.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.L.I.tXiXaXdXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXjXjXfXsXjXjXjXhXhXhXhXhXhXhXhXhXhXhXdXaXiXrXI.rXp.i 3 p 5 i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 >.K.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.I.eXtXiXaXaXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXfXfXdXdXaXtXpXrXI.L.K.K.P.3.3 i i i i i i i i i i i 5 3 f N.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.K.K.L.eXtXiXaXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXjXsXjXjXfXjXfXhXhXhXjXhXjXhXhXfXfXdXiXrXeXL.U.N.} 3 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i 5 i i.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.I.I.rXtXaXaXaXaXsXfXhXhXfXhXhXhXhXfXhXhXhXfXhXhXfXfXfXfXaXaXiXtXtXrXI.L.P.K.K.K.P.g.5 4 i i i i i i i i i i i 4 y 7.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.F.J.J.P.I.eXpXiXaXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXfXjXjXfXfXjXfXjXhXhXjXsXhXsXsXdXaXiXrXU.L.P.P.K.3.3 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 a m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.L.I.eXrXtXiXtXdXaXsXdXdXgXfXfXdXfXfXfXfXdXaXdXaXiXiXiXpXrXeXI.L.L.J.J.J.J.K.V.d 3 i i i i i i i i i i i i 4 } m.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.P.P.rXyXiXaXdXdXfXfXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXhXjXhXhXfXfXdXsXsXpXrXeXP.L.K.P.L.p.i 3 p i p i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 &.C.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.L.I.I.eXrXrXrXtXtXtXiXtXiXiXtXtXpXpXtXrXrXrXI.I.L.L.K.P.J.J.J.J.J.J.J.>.3 i i i i i i i i i i i i 5 i 8.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.L.eXrXrXiXaXdXdXfXfXfXfXfXhXhXhXhXhXjXhXhXhXjXhXhXhXhXhXhXhXfXhXfXdXaXaXtXtXeXU.L.L.K.J.J.P.z.d 3 i p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i 5 i i i i i i i i i i i 4 3.K.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.P.P.L.I.I.I.I.I.I.rXI.I.eXI.L.L.L.P.K.K.K.J.J.J.J.J.J.J.J.P.8.3 i i i i i i p i i i i i i 5 4 3.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.L.L.I.rXrXrXiXaXdXdXdXdXfXfXfXfXfXhXfXhXhXhXfXfXfXfXdXdXaXaXaXaXiXtXeXeXI.P.K.K.K.J.J.P.V.} 3 5 p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 4 i 3.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.C.K.C.K.F.K.P.K.L.L.K.K.L.P.K.K.K.K.K.K.J.J.J.J.J.J.J.J.J.J.K.P.i.i 4 i i i i i i i i i i i i i i 4 a f.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.C.J.J.K.K.P.P.I.wXrXrXtXiXiXiXiXaXaXaXdXaXaXaXaXaXaXaXaXaXiXtXtXeXeXI.L.L.K.P.K.J.F.J.J.P.C.>.3 6 i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i 5 p 8.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.C.Y.J.K.Y.J.J.K.J.K.J.J.J.J.J.J.J.J.J.J.F.J.J.K.L.f.p 4 i i i i i i i i i i i i i i i i 3 s f.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.P.L.L.I.eXeXrXrXrXtXtXrXtXtXrXtXrXrXrXrXeXI.L.L.L.P.J.J.K.J.J.J.J.J.P.J.3.4 4 p i i i 5 i i p i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i i 5 4 p i.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.Y.Y.K.J.J.J.J.S.J.J.J.J.J.J.J.J.J.J.F.J.J.P.g.p 4 i i i i i i i i i i i i i i i i i i y s x.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.J.K.K.K.K.L.L.L.P.I.I.L.P.P.P.I.P.L.L.K.K.P.K.K.J.K.J.J.J.J.J.J.J.P.J.3.4 4 i 5 i i i i i i i 5 i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i a i.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.K.P.g.a 4 5 i i i i i i i i i i i i i i i i i i i 3 d g.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.K.K.K.K.K.K.K.K.K.K.C.J.J.J.J.J.J.J.J.J.J.J.F.P.F.3.3 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i 5 p y p 8.K.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.P.p.p 4 i i i i i i i i i i i i i i i i i i i i i 5 4 s i.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.K.C.K.F.J.J.J.J.C.J.J.K.J.J.J.J.J.J.J.J.J.J.J.I.C.,.5 4 i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 4 p 3.J.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.K.8.p y 5 i i i i i i i i i i i i i i i 5 i i i i i i i 4 p y.K.P.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.F.J.J.J.J.J.J.J.J.J.J.J.J.P.m.=.4 4 i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i 5 i >.N.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.P.V.3.i 4 p p i i i i i i i i i i i i i i i i i i i i i i i i 4 5 3.V.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.x.d 3 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i y 5 } f.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.l.} 5 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 5 } l.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.F.8.a 4 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i 5 5 4 p 8.J.U.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.J.i.s 5 y i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 5 y 4 a 8.J.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.P.P.m.=.5 4 i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i 5 4 i =.l.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.z.>.6 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 4 4 i &.g.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.C.K.K.P.V.6.a 3 5 5 p i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 3 p 3.m.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.V.3.s 4 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i p -.x.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.P.I.C.y.d 5 5 6 6 y 6 i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i 5 4 5 d 6.m.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.C.J.K.P.P.C.8.} 4 5 5 i i i i i i i i i i i 5 i i i i p p UXUXp i i i i i i i i i i i i i i i i i i 4 4 a 1.z.K.I.P.J.J.K.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.V.i.&.y 5 5 6 p y 6 y i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i 5 y 5 d 3.z.P.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.K.P.P.P.m.8.d i 5 4 i i i i i i i i i i i i i p i i i i 5 UXUXUXUXi i i i i i i i i i i i i i i i i i i 4 y i p =.f.C.P.P.K.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.K.K.P.P.m.6.} p y 5 5 5 y p 6 6 y i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i 4 i a -.f.V.P.P.P.J.J.J.J.F.J.S.F.F.J.J.J.J.J.J.J.J.J.J.J.J.F.K.K.P.P.C.g.>.s 5 4 5 i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i 5 5 4 p } 3.m.F.P.P.P.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.P.P.J.V.p.>.s 5 5 5 5 y y 6 p 6 6 y 5 i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i p i i i i i i i i i i i i i i i 4 4 5 5 s >.f.m.K.P.P.P.P.P.J.J.K.J.J.J.J.J.J.J.J.P.P.P.P.P.P.N.f.3.} p 5 5 5 i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i 5 5 5 5 i } 6.g.m.J.P.P.P.P.K.J.P.J.J.J.J.J.J.K.J.J.P.K.P.P.P.P.J.m.p.>.d y 5 5 5 5 6 y 6 6 y 5 y 5 6 p i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i p i i i i i i i 5 5 4 i a } 3.i.l.V.V.F.K.P.P.P.U.P.P.K.K.J.J.m.z.i.3.*.s p 4 4 5 i i i i i i i i i i i i i i i i i i i i i i p UXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i 5 4 4 4 p } &.3.f.m.m.V.F.J.P.J.P.I.I.P.P.K.J.F.V.m.l.i.>.} a i 4 5 5 i i 5 5 p 6 y 5 6 6 5 p 6 y i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i 5 i i i i i i i i i 5 i i i i i i i i i 5 i 5 5 5 5 p p } =.>.1.3.3.8.8.3.3.,.-.} s p i y 5 i 5 5 5 5 i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i p 5 i i i i i i i i i i 5 5 4 y 5 i i a } =.>.3.3.6.8.4.3.1.3.>.} d p p i i 4 i i i i i i i 5 5 y 6 6 p 6 y 6 y 6 p i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 i y 5 5 4 i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i 4 5 4 4 4 4 4 4 4 4 4 4 5 4 i 4 i i i i i i i i i i i i i i i 6 y 6 y 6 p 6 5 i p i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 5 i i 5 5 5 5 i 5 i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 6 i i i i 5 5 5 i i i i i i i i i i i i i i i i i i i p 6 6 y y 5 y 6 i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi 5 i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 6 y 5 6 6 5 6 i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p y 6 6 p 6 y p y i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXy 6 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp p i i i i i 6 6 p 6 p 5 6 6 i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX6 y p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 p i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i y y 5 y 5 6 y y i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 5 i i i i i i i i i 5 p i i i i i i i i i i i i i i i i i i i i i i i i p i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 6 y 6 6 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 5 i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXy 6 y 6 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp 5 p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp p i i i 5 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp i p i i i i i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
-"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi i i i i i i i i i i i i i i i i i i i i i i i i UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
-};
diff --git a/debian/menu b/debian/menu
deleted file mode 100644
index 0521d63..0000000
--- a/debian/menu
+++ /dev/null
@@ -1,3 +0,0 @@
-?package(hedgewars):needs="x11" section="Games/Action"\
- title="Hedgewars" \
- command="/usr/games/hedgewars"
diff --git a/debian/patches/fix-ftbfs-with-ghc-7.6.patch b/debian/patches/fix-ftbfs-with-ghc-7.6.patch
deleted file mode 100644
index 0df9d43..0000000
--- a/debian/patches/fix-ftbfs-with-ghc-7.6.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-The new haskell compiler (7.6) already defines "instance NFData B.ByteString",
-so this will result in a double definition and a FTBFS.
-Patch taken from upstream commit
-https://code.google.com/p/hedgewars/source/detail?r=0a39b2f9c7489e4b6376b1cadc9596e5a97aff55
-Author: Gianfranco Costamagna <costamagnagianfranco at yahoo.it>
-Bug-Debian: http://bugs.debian.org/691986
-Bug-Ubuntu: https://bugs.launchpad.net/bugs/1073730
-
---- hedgewars-0.9.18.orig/gameServer/Actions.hs
-+++ hedgewars-0.9.18/gameServer/Actions.hs
-@@ -82,8 +82,10 @@ type CmdHandler = [B.ByteString] -> Read
- instance NFData Action where
- rnf (AnswerClients chans msg) = chans `deepseq` msg `deepseq` ()
- rnf a = a `seq` ()
--
-+#if __GLASGOW_HASKELL__ < 706
- instance NFData B.ByteString
-+#endif
-+
- instance NFData (Chan a)
-
-
-
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index f8badf9..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1 +0,0 @@
-fix-ftbfs-with-ghc-7.6.patch
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index e0d0b1e..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/make -f
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/cmake.mk
-
-DPKG_EXPORT_BUILDFLAGS = 1
-include /usr/share/dpkg/buildflags.mk
-CFLAGS+=$(CPPFLAGS)
-CXXFLAGS+=$(CPPFLAGS)
-
-DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
-#Helping libc >= 2.17, see launchpad bug #1179850
-TYPE_FLAGS = -DFPFLAGS="-k/lib/$(DEB_HOST_MULTIARCH)/libgcc_s.so.1"
-
-DEB_CMAKE_INSTALL_PREFIX := /usr/lib/hedgewars
-DEB_CMAKE_EXTRA_FLAGS := -DNOSERVER=0 \
- -DDATA_INSTALL_DIR=/usr/share/games $(TYPE_FLAGS)
-
-# Leftover file in upstream tarball
-DEB_CLEAN_EXCLUDE := QTfrontend/main.cpp.orig
-
-UPSTREAM_VERSION := $(shell dpkg-parsechangelog \
- |grep ^Version|awk '{print $$2}'|sed 's/-[[:digit:]]\+$$//' \
-)
-
-clean::
- rm -fr tmp-icon stamp-icon
-
-pre-build:: stamp-icon
-
-stamp-icon:
- rm -fr tmp-icon
- mkdir -p tmp-icon
- for icon in `find debian/hicolor-icons -type f`; do \
- dirname=`dirname $$icon`; \
- dirname=`basename $$dirname`; \
- basename=`basename $$icon .xpm`; \
- mkdir -p tmp-icon/$$dirname/apps; \
- convert $$icon tmp-icon/$$dirname/apps/$$basename.png; \
- done
-
-tarball:
- cd .. && \
- tar --exclude=debian \
- --exclude=.git \
- -czf hedgewars_$(UPSTREAM_VERSION).orig.tar.gz \
- hedgewars-$(UPSTREAM_VERSION)
-
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index 9ee6701..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=3
-http://hedgewars.org/download.html .*/hedgewars-src-(\d.*)\.(?:tgz|tbz2|tar\.(?:gz|bz2|xz))
diff --git a/gameServer/Actions.hs b/gameServer/Actions.hs
index d0f501c..71ea7bf 100644
--- a/gameServer/Actions.hs
+++ b/gameServer/Actions.hs
@@ -1,10 +1,10 @@
-{-# LANGUAGE CPP, OverloadedStrings #-}
+{-# LANGUAGE CPP, OverloadedStrings, ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Actions where
import Control.Concurrent
import qualified Data.Set as Set
-import qualified Data.Sequence as Seq
+import qualified Data.Map as Map
import qualified Data.List as L
import qualified Control.Exception as Exception
import System.Log.Logger
@@ -20,6 +20,7 @@ import Control.Arrow
import Control.Exception
import System.Process
import Network.Socket
+import System.Random
-----------------------------
#if defined(OFFICIAL_SERVER)
import OfficialServer.GameReplayStore
@@ -32,60 +33,9 @@ import Consts
import ConfigFile
import EngineInteraction
-data Action =
- AnswerClients ![ClientChan] ![B.ByteString]
- | SendServerMessage
- | SendServerVars
- | MoveToRoom RoomIndex
- | MoveToLobby B.ByteString
- | RemoveTeam B.ByteString
- | SendTeamRemovalMessage B.ByteString
- | RemoveRoom
- | FinishGame
- | UnreadyRoomClients
- | JoinLobby
- | ProtocolError B.ByteString
- | Warning B.ByteString
- | NoticeMessage Notice
- | ByeClient B.ByteString
- | KickClient ClientIndex
- | KickRoomClient ClientIndex
- | BanClient NominalDiffTime B.ByteString ClientIndex
- | BanIP B.ByteString NominalDiffTime B.ByteString
- | BanList
- | Unban B.ByteString
- | ChangeMaster
- | RemoveClientTeams ClientIndex
- | ModifyClient (ClientInfo -> ClientInfo)
- | ModifyClient2 ClientIndex (ClientInfo -> ClientInfo)
- | ModifyRoomClients (ClientInfo -> ClientInfo)
- | ModifyRoom (RoomInfo -> RoomInfo)
- | ModifyServerInfo (ServerInfo -> ServerInfo)
- | AddRoom B.ByteString B.ByteString
- | SendUpdateOnThisRoom
- | CheckRegistered
- | ClearAccountsCache
- | ProcessAccountInfo AccountInfo
- | AddClient ClientInfo
- | DeleteClient ClientIndex
- | PingAll
- | StatsAction
- | RestartServer
- | AddNick2Bans B.ByteString B.ByteString UTCTime
- | AddIP2Bans B.ByteString B.ByteString UTCTime
- | CheckBanned
- | SaveReplay
-
type CmdHandler = [B.ByteString] -> Reader (ClientIndex, IRnC) [Action]
-instance NFData Action where
- rnf (AnswerClients chans msg) = chans `deepseq` msg `deepseq` ()
- rnf a = a `seq` ()
-
-instance NFData B.ByteString
-instance NFData (Chan a)
-
othersChans :: StateT ServerState IO [ClientChan]
othersChans = do
@@ -142,22 +92,22 @@ processAction (ByeClient msg) = do
chan <- client's sendChan
clNick <- client's nick
- loggedIn <- client's logonPassed
+ loggedIn <- client's isVisible
when (ri /= lobbyId) $ do
processAction $ MoveToLobby ("quit: " `B.append` msg)
return ()
- clientsChans <- liftM (Prelude.map sendChan . Prelude.filter logonPassed) $! allClientsS
+ clientsChans <- liftM (Prelude.map sendChan . Prelude.filter isVisible) $! allClientsS
io $
infoM "Clients" (show ci ++ " quits: " ++ B.unpack msg)
when loggedIn $ processAction $ AnswerClients clientsChans ["LOBBY:LEFT", clNick, msg]
- mapM processAction
+ mapM_ processAction
[
AnswerClients [chan] ["BYE", msg]
- , ModifyClient (\c -> c{nick = "", logonPassed = False}) -- this will effectively hide client from others while he isn't deleted from list
+ , ModifyClient (\c -> c{nick = "", isVisible = False}) -- this will effectively hide client from others while he isn't deleted from list
]
s <- get
@@ -212,7 +162,7 @@ processAction (MoveToRoom ri) = do
rnc <- gets roomsClients
io $ do
- modifyClient rnc (\cl -> cl{teamsInGame = 0, isReady = False, isMaster = False, isInGame = False}) ci
+ modifyClient rnc (\cl -> cl{teamsInGame = 0, isReady = False, isMaster = False, isInGame = False, clientClan = Nothing}) ci
modifyRoom rnc (\r -> r{playersIn = playersIn r + 1}) ri
moveClientToRoom rnc ri ci
@@ -234,11 +184,11 @@ processAction (MoveToLobby msg) = do
if master then
if playersNum > 1 then
- mapM_ processAction [ChangeMaster, NoticeMessage AdminLeft, RemoveClientTeams ci, AnswerClients chans ["LEFT", clNick, msg]]
+ mapM_ processAction [ChangeMaster Nothing, NoticeMessage AdminLeft, RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]]
else
processAction RemoveRoom
else
- mapM_ processAction [RemoveClientTeams ci, AnswerClients chans ["LEFT", clNick, msg]]
+ mapM_ processAction [RemoveClientTeams, AnswerClients chans ["LEFT", clNick, msg]]
-- when not removing room
ready <- client's isReady
@@ -250,33 +200,36 @@ processAction (MoveToLobby msg) = do
moveClientToLobby rnc ci
-processAction ChangeMaster = do
+processAction (ChangeMaster delegateId)= do
(Just ci) <- gets clientIndex
proto <- client's clientProto
ri <- clientRoomA
rnc <- gets roomsClients
- newMasterId <- liftM (head . filter (/= ci)) . io $ roomClientsIndicesM rnc ri
+ newMasterId <- liftM (\ids -> fromMaybe (last . filter (/= ci) $ ids) delegateId) . io $ roomClientsIndicesM rnc ri
newMaster <- io $ client'sM rnc id newMasterId
+ oldMasterId <- io $ room'sM rnc masterID ri
+ oldMaster <- io $ client'sM rnc id oldMasterId
oldRoomName <- io $ room'sM rnc name ri
- oldMaster <- client's nick
+ kicked <- client's isKickedFromServer
thisRoomChans <- liftM (map sendChan) $ roomClientsS ri
- let newRoomName = if proto < 42 then nick newMaster else oldRoomName
+ let newRoomName = if (proto < 42) || kicked then nick newMaster else oldRoomName
mapM_ processAction [
ModifyRoom (\r -> r{masterID = newMasterId
, name = newRoomName
, isRestrictedJoins = False
, isRestrictedTeams = False
- , readyPlayers = if isReady newMaster then readyPlayers r else readyPlayers r + 1})
- , ModifyClient2 newMasterId (\c -> c{isMaster = True, isReady = True})
+ , isRegisteredOnly = False}
+ )
+ , ModifyClient2 newMasterId (\c -> c{isMaster = True})
+ , ModifyClient2 oldMasterId (\c -> c{isMaster = False})
, AnswerClients [sendChan newMaster] ["ROOM_CONTROL_ACCESS", "1"]
- , AnswerClients thisRoomChans ["WARNING", "New room admin is " `B.append` nick newMaster]
- , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", oldMaster]
- , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+hr", nick newMaster]
+ , AnswerClients thisRoomChans ["CLIENT_FLAGS", "-h", nick oldMaster]
+ , AnswerClients thisRoomChans ["CLIENT_FLAGS", "+h", nick newMaster]
]
newRoom' <- io $ room'sM rnc id ri
chans <- liftM (map sendChan) $! sameProtoClientsS proto
- processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo newRoomName newRoom')
+ processAction $ AnswerClients chans ("ROOM" : "UPD" : oldRoomName : roomInfo (nick newMaster) newRoom')
processAction (AddRoom roomName roomPassword) = do
@@ -299,7 +252,7 @@ processAction (AddRoom roomName roomPassword) = do
chans <- liftM (map sendChan) $! sameProtoClientsS proto
mapM_ processAction [
- AnswerClients chans ("ROOM" : "ADD" : roomInfo n rm)
+ AnswerClients chans ("ROOM" : "ADD" : roomInfo n rm{playersIn = 1})
]
@@ -326,8 +279,9 @@ processAction SendUpdateOnThisRoom = do
rnc <- gets roomsClients
ri <- io $ clientRoomM rnc clId
rm <- io $ room'sM rnc id ri
+ n <- io $ client'sM rnc nick (masterID rm)
chans <- liftM (map sendChan) $! sameProtoClientsS proto
- processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo (name rm) rm)
+ processAction $ AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo n rm)
processAction UnreadyRoomClients = do
@@ -360,6 +314,7 @@ processAction FinishGame = do
)
: UnreadyRoomClients
: SendUpdateOnThisRoom
+ : AnswerClients thisRoomChans ["ROUND_FINISHED"]
: answerRemovedTeams
@@ -370,7 +325,7 @@ processAction (SendTeamRemovalMessage teamName) = do
ModifyRoom (\r -> r{
gameInfo = liftM (\g -> g{
teamsInGameNumber = teamsInGameNumber g - 1
- , roundMsgs = roundMsgs g Seq.|> rmTeamMsg
+ , roundMsgs = rmTeamMsg : roundMsgs g
}) $ gameInfo r
})
]
@@ -378,34 +333,39 @@ processAction (SendTeamRemovalMessage teamName) = do
rnc <- gets roomsClients
ri <- clientRoomA
gi <- io $ room'sM rnc gameInfo ri
- when (isJust gi && 0 == teamsInGameNumber (fromJust gi)) $
+ when (0 == teamsInGameNumber (fromJust gi)) $
processAction FinishGame
where
rmTeamMsg = toEngineMsg $ 'F' `B.cons` teamName
processAction (RemoveTeam teamName) = do
+ (Just ci) <- gets clientIndex
rnc <- gets roomsClients
ri <- clientRoomA
- inGame <- io $ room'sM rnc (isJust . gameInfo) ri
+ inGame <- io $ do
+ r <- room'sM rnc (isJust . gameInfo) ri
+ c <- client'sM rnc isInGame ci
+ return $ r && c
chans <- othersChans
mapM_ processAction $
ModifyRoom (\r -> r{
teams = Prelude.filter (\t -> teamName /= teamname t) $ teams r
, gameInfo = liftM (\g -> g{leftTeams = teamName : leftTeams g}) $ gameInfo r
})
+ : SendUpdateOnThisRoom
: AnswerClients chans ["REMOVE_TEAM", teamName]
: [SendTeamRemovalMessage teamName | inGame]
-processAction (RemoveClientTeams clId) = do
+processAction RemoveClientTeams = do
+ (Just ci) <- gets clientIndex
rnc <- gets roomsClients
removeTeamActions <- io $ do
- clNick <- client'sM rnc nick clId
- rId <- clientRoomM rnc clId
+ rId <- clientRoomM rnc ci
roomTeams <- room'sM rnc teams rId
- return . Prelude.map (RemoveTeam . teamname) . Prelude.filter (\t -> teamowner t == clNick) $ roomTeams
+ return . Prelude.map (RemoveTeam . teamname) . Prelude.filter (\t -> teamownerId t == ci) $ roomTeams
mapM_ processAction removeTeamActions
@@ -416,21 +376,20 @@ processAction CheckRegistered = do
n <- client's nick
h <- client's host
p <- client's clientProto
+ checker <- client's isChecker
uid <- client's clUID
- haveSameNick <- liftM (not . null . tail . filter (\c -> caseInsensitiveCompare (nick c) n)) allClientsS
- if haveSameNick then
+ -- allow multiple checker logins
+ haveSameNick <- liftM (not . null . tail . filter (\c -> (not $ isChecker c) && caseInsensitiveCompare (nick c) n)) allClientsS
+ if (not checker) && haveSameNick then
if p < 38 then
- mapM_ processAction [ByeClient "Nickname is already in use", removeNick]
+ processAction $ ByeClient $ loc "Nickname is already in use"
else
- mapM_ processAction [NoticeMessage NickAlreadyInUse, removeNick]
+ mapM_ processAction [NoticeMessage NickAlreadyInUse, ModifyClient $ \c -> c{nick = B.empty}]
else
do
db <- gets (dbQueries . serverInfo)
io $ writeChan db $ CheckAccount ci (hashUnique uid) n h
return ()
- where
- removeNick = ModifyClient (\c -> c{nick = ""})
-
processAction ClearAccountsCache = do
dbq <- gets (dbQueries . serverInfo)
@@ -438,25 +397,43 @@ processAction ClearAccountsCache = do
return ()
-processAction (ProcessAccountInfo info) =
+processAction (ProcessAccountInfo info) = do
case info of
HasAccount passwd isAdmin -> do
- chan <- client's sendChan
- mapM_ processAction [AnswerClients [chan] ["ASKPASSWORD"], ModifyClient (\c -> c{webPassword = passwd, isAdministrator = isAdmin})]
- Guest ->
- processAction JoinLobby
+ b <- isBanned
+ c <- client's isChecker
+ when (not b) $ (if c then checkerLogin else playerLogin) passwd isAdmin
+ Guest -> do
+ b <- isBanned
+ c <- client's isChecker
+ when (not b) $
+ if c then
+ checkerLogin "" False
+ else
+ processAction JoinLobby
Admin -> do
mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby]
chan <- client's sendChan
processAction $ AnswerClients [chan] ["ADMIN_ACCESS"]
-
+ where
+ isBanned = do
+ processAction $ CheckBanned False
+ liftM B.null $ client's nick
+ checkerLogin _ False = processAction $ ByeClient $ loc "No checker rights"
+ checkerLogin p True = do
+ wp <- client's webPassword
+ processAction $
+ if wp == p then ModifyClient $ \c -> c{logonPassed = True} else ByeClient $ loc "Authentication failed"
+ playerLogin p a = do
+ chan <- client's sendChan
+ mapM_ processAction [AnswerClients [chan] ["ASKPASSWORD"], ModifyClient (\c -> c{webPassword = p, isAdministrator = a})]
processAction JoinLobby = do
chan <- client's sendChan
clientNick <- client's nick
isAuthenticated <- liftM (not . B.null) $ client's webPassword
isAdmin <- client's isAdministrator
- loggedInClients <- liftM (Prelude.filter logonPassed) $! allClientsS
+ loggedInClients <- liftM (Prelude.filter isVisible) $! allClientsS
let (lobbyNicks, clientsChans) = unzip . L.map (nick &&& sendChan) $ loggedInClients
let authenticatedNicks = L.map nick . L.filter (not . B.null . webPassword) $ loggedInClients
let adminsNicks = L.map nick . L.filter isAdministrator $ loggedInClients
@@ -467,7 +444,7 @@ processAction JoinLobby = do
, [AnswerClients [chan] ("CLIENT_FLAGS" : "+u" : authenticatedNicks) | not $ null authenticatedNicks]
, [AnswerClients [chan] ("CLIENT_FLAGS" : "+a" : adminsNicks) | not $ null adminsNicks]
, [AnswerClients (chan : clientsChans) ["CLIENT_FLAGS", B.concat["+" , clFlags], clientNick] | not $ B.null clFlags]
- , [ModifyClient (\cl -> cl{logonPassed = True})]
+ , [ModifyClient (\cl -> cl{logonPassed = True, isVisible = True})]
, [SendServerMessage]
]
@@ -477,8 +454,9 @@ processAction (KickClient kickId) = do
clHost <- client's host
currentTime <- io getCurrentTime
mapM_ processAction [
- AddIP2Bans clHost "60 seconds cooldown after kick" (addUTCTime 60 currentTime),
- ByeClient "Kicked"
+ AddIP2Bans clHost (loc "60 seconds cooldown after kick") (addUTCTime 60 currentTime)
+ , ModifyClient (\c -> c{isKickedFromServer = True})
+ , ByeClient "Kicked"
]
@@ -492,28 +470,47 @@ processAction (BanClient seconds reason banId) = do
, KickClient banId
]
+
processAction (BanIP ip seconds reason) = do
currentTime <- io getCurrentTime
let msg = B.concat ["Ban for ", B.pack . show $ seconds, " (", reason, ")"]
processAction $
AddIP2Bans ip msg (addUTCTime seconds currentTime)
+
+processAction (BanNick n seconds reason) = do
+ currentTime <- io getCurrentTime
+ let msg =
+ if seconds > 60 * 60 * 24 * 365 then
+ B.concat ["Permanent ban (", reason, ")"]
+ else
+ B.concat ["Ban for ", B.pack . show $ seconds, " (", reason, ")"]
+ processAction $
+ AddNick2Bans n msg (addUTCTime seconds currentTime)
+
+
processAction BanList = do
+ time <- io $ getCurrentTime
ch <- client's sendChan
- b <- gets (B.pack . unlines . map show . bans . serverInfo)
+ b <- gets (B.intercalate "\n" . concatMap (ban2Str time) . bans . serverInfo)
processAction $
AnswerClients [ch] ["BANLIST", b]
+ where
+ ban2Str time (BanByIP b r t) = ["I", b, r, B.pack . show $ t `diffUTCTime` time]
+ ban2Str time (BanByNick b r t) = ["N", b, r, B.pack . show $ t `diffUTCTime` time]
+
processAction (Unban entry) = do
- processAction $ ModifyServerInfo (\s -> s{bans = filter f $ bans s})
+ processAction $ ModifyServerInfo (\s -> s{bans = filter (not . f) $ bans s})
where
f (BanByIP bip _ _) = bip == entry
f (BanByNick bn _ _) = bn == entry
+
processAction (KickRoomClient kickId) = do
modify (\s -> s{clientIndex = Just kickId})
ch <- client's sendChan
- mapM_ processAction [AnswerClients [ch] ["KICKED"], MoveToLobby "kicked"]
+ mapM_ processAction [AnswerClients [ch] ["KICKED"], MoveToLobby $ loc "kicked"]
processAction (AddClient cl) = do
@@ -531,7 +528,7 @@ processAction (AddClient cl) = do
mapM_ processAction
[
AnswerClients [sendChan cl] ["CONNECTED", "Hedgewars server http://www.hedgewars.org/", serverVersion]
- , CheckBanned
+ , CheckBanned True
, AddIP2Bans (host cl) "Reconnected too fast" (addUTCTime 10 $ connectTime cl)
]
@@ -545,24 +542,27 @@ processAction (AddIP2Bans ip reason expiring) = do
when (not $ ci `Set.member` rc)
$ processAction $ ModifyServerInfo (\s -> s{bans = BanByIP ip reason expiring : bans s})
-processAction CheckBanned = do
+
+processAction (CheckBanned byIP) = do
clTime <- client's connectTime
clNick <- client's nick
clHost <- client's host
si <- gets serverInfo
let validBans = filter (checkNotExpired clTime) $ bans si
- let ban = L.find (checkBan clHost clNick) $ validBans
+ let ban = L.find (checkBan byIP clHost clNick) $ validBans
mapM_ processAction $
ModifyServerInfo (\s -> s{bans = validBans})
: [ByeClient (getBanReason $ fromJust ban) | isJust ban]
where
checkNotExpired testTime (BanByIP _ _ time) = testTime `diffUTCTime` time <= 0
checkNotExpired testTime (BanByNick _ _ time) = testTime `diffUTCTime` time <= 0
- checkBan ip _ (BanByIP bip _ _) = bip `B.isPrefixOf` ip
- checkBan _ n (BanByNick bn _ _) = bn == n
+ checkBan True ip _ (BanByIP bip _ _) = bip `B.isPrefixOf` ip
+ checkBan False _ n (BanByNick bn _ _) = caseInsensitiveCompare bn n
+ checkBan _ _ _ _ = False
getBanReason (BanByIP _ msg _) = msg
getBanReason (BanByNick _ msg _) = msg
+
processAction PingAll = do
rnc <- gets roomsClients
io (allClientsM rnc) >>= mapM_ (kickTimeouted rnc)
@@ -575,7 +575,7 @@ processAction PingAll = do
pq <- io $ client'sM rnc pingsQueue ci
when (pq > 0) $ do
withStateT (\as -> as{clientIndex = Just ci}) $
- processAction (ByeClient "Ping timeout")
+ processAction (ByeClient $ loc "Ping timeout")
-- when (pq > 1) $
-- processAction $ DeleteClient ci -- smth went wrong with client io threads, issue DeleteClient here
@@ -602,13 +602,59 @@ processAction RestartServer = do
return ()
processAction $ ModifyServerInfo (\s -> s{shutdownPending = True})
+processAction Stats = do
+ cls <- allClientsS
+ rms <- allRoomsS
+ let clientsMap = Map.fromListWith (+) . map (\c -> (clientProto c, 1 :: Int)) $ cls
+ let roomsMap = Map.fromListWith (+) . map (\c -> (roomProto c, 1 :: Int)) . filter ((/=) 0 . roomProto) $ rms
+ let keys = Map.keysSet clientsMap `Set.union` Map.keysSet roomsMap
+ let versionsStats = B.concat . ((:) "<table border=1>") . (flip (++) ["</table>"])
+ . concatMap (\p -> [
+ "<tr><td>", protoNumber2ver p
+ , "</td><td>", showB $ Map.findWithDefault 0 p clientsMap
+ , "</td><td>", showB $ Map.findWithDefault 0 p roomsMap
+ , "</td></tr>"])
+ . Set.toList $ keys
+ processAction $ Warning versionsStats
+
+
+processAction (Random chans items) = do
+ let i = if null items then ["heads", "tails"] else items
+ n <- io $ randomRIO (0, length i - 1)
+ processAction $ AnswerClients chans ["CHAT", "[random]", i !! n]
+
+
#if defined(OFFICIAL_SERVER)
processAction SaveReplay = do
ri <- clientRoomA
rnc <- gets roomsClients
+
io $ do
r <- room'sM rnc id ri
saveReplay r
+
+
+processAction CheckRecord = do
+ p <- client's clientProto
+ c <- client's sendChan
+ (cinfo, l) <- io $ loadReplay (fromIntegral p)
+ when (not . null $ l) $
+ mapM_ processAction [
+ AnswerClients [c] ("REPLAY" : l)
+ , ModifyClient $ \c -> c{checkInfo = cinfo}
+ ]
+
+processAction (CheckFailed msg) = do
+ Just (CheckInfo fileName _) <- client's checkInfo
+ io $ moveFailedRecord fileName
+
+processAction (CheckSuccess info) = do
+ Just (CheckInfo fileName _) <- client's checkInfo
+ io $ moveCheckedRecord fileName
+
#else
processAction SaveReplay = return ()
+processAction CheckRecord = return ()
+processAction (CheckFailed _) = return ()
+processAction (CheckSuccess _) = return ()
#endif
diff --git a/gameServer/CMakeLists.txt b/gameServer/CMakeLists.txt
index adb3fe6..f1d573f 100644
--- a/gameServer/CMakeLists.txt
+++ b/gameServer/CMakeLists.txt
@@ -1,4 +1,7 @@
+include(${CMAKE_MODULE_PATH}/utils.cmake)
+
+find_package_or_disable(GHC NOSERVER)
set(hwserver_sources
OfficialServer/DBInteraction.hs
@@ -34,7 +37,7 @@ set(ghc_flags
${haskell_flags})
add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXECUTABLE_SUFFIX}"
- COMMAND "${ghc_executable}"
+ COMMAND "${GHC_EXECUTABLE}"
ARGS ${ghc_flags}
MAIN_DEPENDENCY ${hwserv_main}
DEPENDS ${hwserver_sources}
@@ -42,4 +45,4 @@ add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXE
add_custom_target(hedgewars-server ALL DEPENDS "${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXECUTABLE_SUFFIX}")
-install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_dir})
+install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/hedgewars-server${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_binary_install_dir})
diff --git a/gameServer/ClientIO.hs b/gameServer/ClientIO.hs
index 8e57967..f6dd584 100644
--- a/gameServer/ClientIO.hs
+++ b/gameServer/ClientIO.hs
@@ -30,25 +30,26 @@ takePacks
return (B.splitWith (== '\n') packet : packets)
listenLoop :: Socket -> Chan CoreMessage -> ClientIndex -> IO ()
-listenLoop sock chan ci = recieveWithBufferLoop B.empty
+listenLoop sock chan ci = receiveWithBufferLoop B.empty
where
- recieveWithBufferLoop recvBuf = do
+ receiveWithBufferLoop recvBuf = do
recvBS <- recv sock 4096
unless (B.null recvBS) $ do
let (packets, newrecvBuf) = bs2Packets $ B.append recvBuf recvBS
forM_ packets sendPacket
- recieveWithBufferLoop newrecvBuf
+ receiveWithBufferLoop $ B.copy newrecvBuf
sendPacket packet = writeChan chan $ ClientMessage (ci, packet)
clientRecvLoop :: Socket -> Chan CoreMessage -> Chan [B.ByteString] -> ClientIndex -> (forall a. IO a -> IO a) -> IO ()
clientRecvLoop s chan clChan ci restore =
(myThreadId >>=
- \t -> (restore $ forkIO (clientSendLoop s t clChan ci) >>
+ (\t -> (restore $ forkIO (clientSendLoop s t clChan ci) >>
listenLoop s chan ci >> return "Connection closed")
`Exception.catch` (\(e :: ShutdownThreadException) -> return . B.pack . show $ e)
`Exception.catch` (\(e :: Exception.IOException) -> return . B.pack . show $ e)
`Exception.catch` (\(e :: Exception.SomeException) -> return . B.pack . show $ e)
+ )
>>= clientOff) `Exception.finally` remove
where
clientOff msg = writeChan chan $ ClientMessage (ci, ["QUIT", msg])
diff --git a/gameServer/ConfigFile.hs b/gameServer/ConfigFile.hs
index d0c596e..f35e481 100644
--- a/gameServer/ConfigFile.hs
+++ b/gameServer/ConfigFile.hs
@@ -58,4 +58,3 @@ writeServerConfig ServerInfo{
, ("sv_message", sm)
, ("sv_messageOld", smo)
]
-
\ No newline at end of file
diff --git a/gameServer/CoreTypes.hs b/gameServer/CoreTypes.hs
index 93578de..8f40980 100644
--- a/gameServer/CoreTypes.hs
+++ b/gameServer/CoreTypes.hs
@@ -1,10 +1,9 @@
-{-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-}
+{-# LANGUAGE CPP, OverloadedStrings, DeriveDataTypeable #-}
module CoreTypes where
import Control.Concurrent
import Data.Word
import qualified Data.Map as Map
-import Data.Sequence(Seq, empty)
import Data.Time
import Network
import Data.Function
@@ -13,11 +12,80 @@ import Data.Unique
import Control.Exception
import Data.Typeable
import Data.TConfig
+import Control.DeepSeq
-----------------------
import RoomsAndClients
+
+#if __GLASGOW_HASKELL__ < 706
+instance NFData B.ByteString
+#endif
+
+instance NFData (Chan a)
+
+instance NFData Action where
+ rnf (AnswerClients chans msg) = chans `deepseq` msg `deepseq` ()
+ rnf a = a `seq` ()
+
+data Action =
+ AnswerClients ![ClientChan] ![B.ByteString]
+ | SendServerMessage
+ | SendServerVars
+ | MoveToRoom RoomIndex
+ | MoveToLobby B.ByteString
+ | RemoveTeam B.ByteString
+ | SendTeamRemovalMessage B.ByteString
+ | RemoveRoom
+ | FinishGame
+ | UnreadyRoomClients
+ | JoinLobby
+ | ProtocolError B.ByteString
+ | Warning B.ByteString
+ | NoticeMessage Notice
+ | ByeClient B.ByteString
+ | KickClient ClientIndex
+ | KickRoomClient ClientIndex
+ | BanClient NominalDiffTime B.ByteString ClientIndex
+ | BanIP B.ByteString NominalDiffTime B.ByteString
+ | BanNick B.ByteString NominalDiffTime B.ByteString
+ | BanList
+ | Unban B.ByteString
+ | ChangeMaster (Maybe ClientIndex)
+ | RemoveClientTeams
+ | ModifyClient (ClientInfo -> ClientInfo)
+ | ModifyClient2 ClientIndex (ClientInfo -> ClientInfo)
+ | ModifyRoomClients (ClientInfo -> ClientInfo)
+ | ModifyRoom (RoomInfo -> RoomInfo)
+ | ModifyServerInfo (ServerInfo -> ServerInfo)
+ | AddRoom B.ByteString B.ByteString
+ | SendUpdateOnThisRoom
+ | CheckRegistered
+ | ClearAccountsCache
+ | ProcessAccountInfo AccountInfo
+ | AddClient ClientInfo
+ | DeleteClient ClientIndex
+ | PingAll
+ | StatsAction
+ | RestartServer
+ | AddNick2Bans B.ByteString B.ByteString UTCTime
+ | AddIP2Bans B.ByteString B.ByteString UTCTime
+ | CheckBanned Bool
+ | SaveReplay
+ | Stats
+ | CheckRecord
+ | CheckFailed B.ByteString
+ | CheckSuccess [B.ByteString]
+ | Random [ClientChan] [B.ByteString]
+
type ClientChan = Chan [B.ByteString]
+data CheckInfo =
+ CheckInfo
+ {
+ recordFileName :: String,
+ recordTeams :: [TeamInfo]
+ }
+
data ClientInfo =
ClientInfo
{
@@ -29,6 +97,7 @@ data ClientInfo =
nick :: B.ByteString,
webPassword :: B.ByteString,
logonPassed :: Bool,
+ isVisible :: Bool,
clientProto :: !Word16,
roomID :: RoomIndex,
pingsQueue :: !Word,
@@ -36,7 +105,10 @@ data ClientInfo =
isReady :: !Bool,
isInGame :: Bool,
isAdministrator :: Bool,
- clientClan :: Maybe B.ByteString,
+ isChecker :: Bool,
+ isKickedFromServer :: Bool,
+ clientClan :: !(Maybe B.ByteString),
+ checkInfo :: Maybe CheckInfo,
teamsInGame :: Word
}
@@ -64,14 +136,17 @@ data TeamInfo =
}
deriving (Show, Read)
+instance Eq TeamInfo where
+ (==) = (==) `on` teamname
+
data GameInfo =
GameInfo
{
- roundMsgs :: Seq B.ByteString,
+ roundMsgs :: [B.ByteString],
leftTeams :: [B.ByteString],
teamsAtStart :: [TeamInfo],
teamsInGameNumber :: Int,
- allPlayersHaveRegisteredAccounts :: Bool,
+ allPlayersHaveRegisteredAccounts :: !Bool,
giMapParams :: Map.Map B.ByteString B.ByteString,
giParams :: Map.Map B.ByteString [B.ByteString]
} deriving (Show, Read)
@@ -84,7 +159,7 @@ newGameInfo :: [TeamInfo]
-> GameInfo
newGameInfo =
GameInfo
- Data.Sequence.empty
+ []
[]
data RoomInfo =
@@ -100,7 +175,8 @@ data RoomInfo =
readyPlayers :: !Int,
isRestrictedJoins :: Bool,
isRestrictedTeams :: Bool,
- roomBansList :: [B.ByteString],
+ isRegisteredOnly :: Bool,
+ roomBansList :: ![B.ByteString],
mapParams :: Map.Map B.ByteString B.ByteString,
params :: Map.Map B.ByteString [B.ByteString]
}
@@ -118,6 +194,7 @@ newRoom =
0
False
False
+ False
[]
(
Map.fromList $ Prelude.zipWith (,)
@@ -161,8 +238,8 @@ newServerInfo =
ServerInfo
True
"<h2><p align=center><a href=\"http://www.hedgewars.org/\">http://www.hedgewars.org/</a></p></h2>"
- "<font color=yellow><h3 align=center>Hedgewars 0.9.18 is out! Please update.</h3><p align=center><a href=http://hedgewars.org/download.html>Download page here</a></font>"
- 43 -- latestReleaseVersion
+ "<font color=yellow><h3 align=center>Hedgewars 0.9.19 is out! Please update.</h3><p align=center><a href=http://hedgewars.org/download.html>Download page here</a></font>"
+ 45 -- latestReleaseVersion
41 -- earliestCompatibleVersion
46631
""
diff --git a/gameServer/EngineInteraction.hs b/gameServer/EngineInteraction.hs
index 7d03045..abdc923 100644
--- a/gameServer/EngineInteraction.hs
+++ b/gameServer/EngineInteraction.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE OverloadedStrings #-}
+
module EngineInteraction where
import qualified Data.Set as Set
@@ -5,8 +7,14 @@ import Control.Monad
import qualified Codec.Binary.Base64 as Base64
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString as BW
+import qualified Data.Map as Map
+import qualified Data.List as L
+import Data.Word
+import Data.Bits
+import Control.Arrow
-------------
import CoreTypes
+import Utils
toEngineMsg :: B.ByteString -> B.ByteString
@@ -20,19 +28,130 @@ fromEngineMsg msg = liftM BW.pack (Base64.decode (B.unpack msg) >>= removeLength
removeLength _ = Nothing
-checkNetCmd :: B.ByteString -> (Bool, Bool)
+splitMessages :: B.ByteString -> [B.ByteString]
+splitMessages = L.unfoldr (\b -> if B.null b then Nothing else Just $ B.splitAt (1 + fromIntegral (BW.head b)) b)
+
+
+checkNetCmd :: B.ByteString -> (B.ByteString, B.ByteString)
checkNetCmd msg = check decoded
where
- decoded = fromEngineMsg msg
- check Nothing = (False, False)
- check (Just ms) | B.length ms > 0 = let m = B.head ms in (m `Set.member` legalMessages, m == '+')
- | otherwise = (False, False)
+ decoded = liftM (splitMessages . BW.pack) $ Base64.decode $ B.unpack msg
+ check Nothing = (B.empty, B.empty)
+ check (Just msgs) = let (a, b) = (filter isLegal msgs, filter isNonEmpty a) in (encode a, encode b)
+ encode = B.pack . Base64.encode . BW.unpack . B.concat
+ isLegal m = (B.length m > 1) && (flip Set.member legalMessages . B.head . B.tail $ m)
+ isNonEmpty = (/=) '+' . B.head . B.tail
legalMessages = Set.fromList $ "M#+LlRrUuDdZzAaSjJ,sNpPwtghbc12345" ++ slotMessages
slotMessages = "\128\129\130\131\132\133\134\135\136\137\138"
-gameInfo2Replay :: GameInfo -> B.ByteString
-gameInfo2Replay GameInfo{roundMsgs = rm,
- teamsAtStart = teams,
- giMapParams = params1,
- giParams = params2} = undefined
+replayToDemo :: [TeamInfo]
+ -> Map.Map B.ByteString B.ByteString
+ -> Map.Map B.ByteString [B.ByteString]
+ -> [B.ByteString]
+ -> [B.ByteString]
+replayToDemo teams mapParams params msgs = concat [
+ [em "TD"]
+ , maybeScript
+ , maybeMap
+ , [eml ["etheme ", head $ params Map.! "THEME"]]
+ , [eml ["eseed ", mapParams Map.! "SEED"]]
+ , [eml ["e$gmflags ", showB gameFlags]]
+ , schemeFlags
+ , [eml ["e$template_filter ", mapParams Map.! "TEMPLATE"]]
+ , [eml ["e$mapgen ", mapgen]]
+ , mapgenSpecific
+ , concatMap teamSetup teams
+ , msgs
+ , [em "!"]
+ ]
+ where
+ em = toEngineMsg
+ eml = em . B.concat
+ mapGenTypes = ["+rnd+", "+maze+", "+drawn+"]
+ maybeScript = let s = head $ params Map.! "SCRIPT" in if s == "Normal" then [] else [eml ["escript Scripts/Multiplayer/", s, ".lua"]]
+ maybeMap = let m = mapParams Map.! "MAP" in if m `elem` mapGenTypes then [] else [eml ["emap ", m]]
+ scheme = tail $ params Map.! "SCHEME"
+ mapgen = mapParams Map.! "MAPGEN"
+ mapgenSpecific = case mapgen of
+ "+maze+" -> [eml ["e$maze_size ", head $ params Map.! "MAZE_SIZE"]]
+ "+drawn" -> drawnMapData . head $ params Map.! "DRAWNMAP"
+ _ -> []
+ gameFlags :: Word32
+ gameFlags = foldl (\r (b, f) -> if b == "false" then r else r .|. f) 0 $ zip scheme gameFlagConsts
+ schemeFlags = map (\(v, (n, m)) -> eml [n, " ", showB $ (readInt_ v) * m])
+ $ filter (\(_, (n, _)) -> not $ B.null n)
+ $ zip (drop (length gameFlagConsts) scheme) schemeParams
+ ammoStr :: B.ByteString
+ ammoStr = head . tail $ params Map.! "AMMO"
+ ammo = let l = B.length ammoStr `div` 4; ((a, b), (c, d)) = (B.splitAt l . fst &&& B.splitAt l . snd) . B.splitAt (l * 2) $ ammoStr in
+ (map (\(x, y) -> eml [x, " ", y]) $ zip ["eammloadt", "eammprob", "eammdelay", "eammreinf"] [a, b, c, d])
+ ++ [em "eammstore" | scheme !! 14 == "true" || scheme !! 20 == "false"]
+ initHealth = scheme !! 27
+ teamSetup :: TeamInfo -> [B.ByteString]
+ teamSetup t = (++) ammo $
+ eml ["eaddteam <hash> ", showB $ (1 + (readInt_ $ teamcolor t) :: Int) * 2113696, " ", teamname t]
+ : em "erdriven"
+ : eml ["efort ", teamfort t]
+ : take (2 * hhnum t) (
+ concatMap (\(HedgehogInfo hname hhat) -> [
+ eml ["eaddhh ", showB $ difficulty t, " ", initHealth, " ", hname]
+ , eml ["ehat ", hhat]
+ ])
+ $ hedgehogs t
+ )
+
+drawnMapData :: B.ByteString -> [B.ByteString]
+drawnMapData = error "drawnMapData"
+
+schemeParams :: [(B.ByteString, Int)]
+schemeParams = [
+ ("e$damagepct", 1)
+ , ("e$turntime", 1000)
+ , ("", 0)
+ , ("e$sd_turns", 1)
+ , ("e$casefreq", 1)
+ , ("e$minestime", 1000)
+ , ("e$minesnum", 1)
+ , ("e$minedudpct", 1)
+ , ("e$explosives", 1)
+ , ("e$healthprob", 1)
+ , ("e$hcaseamount", 1)
+ , ("e$waterrise", 1)
+ , ("e$healthdec", 1)
+ , ("e$ropepct", 1)
+ , ("e$getawaytime", 1)
+ ]
+
+
+gameFlagConsts :: [Word32]
+gameFlagConsts = [
+ 0x00001000
+ , 0x00000010
+ , 0x00000004
+ , 0x00000008
+ , 0x00000020
+ , 0x00000040
+ , 0x00000080
+ , 0x00000100
+ , 0x00000200
+ , 0x00000400
+ , 0x00000800
+ , 0x00002000
+ , 0x00004000
+ , 0x00008000
+ , 0x00010000
+ , 0x00020000
+ , 0x00040000
+ , 0x00080000
+ , 0x00100000
+ , 0x00200000
+ , 0x00400000
+ , 0x00800000
+ , 0x01000000
+ , 0x02000000
+ , 0x04000000
+ ]
+
+
+
diff --git a/gameServer/HWProtoChecker.hs b/gameServer/HWProtoChecker.hs
new file mode 100644
index 0000000..53f5789
--- /dev/null
+++ b/gameServer/HWProtoChecker.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE OverloadedStrings #-}
+module HWProtoChecker where
+
+import qualified Data.Map as Map
+import Data.Maybe
+import Data.List
+import Control.Monad.Reader
+--------------------------------------
+import CoreTypes
+import Actions
+import Utils
+import HandlerUtils
+import RoomsAndClients
+import EngineInteraction
+
+
+handleCmd_checker :: CmdHandler
+
+handleCmd_checker ["READY"] = return [CheckRecord]
+
+handleCmd_checker ["CHECKED", "FAIL", msg] = do
+ isChecking <- liftM (isJust . checkInfo) thisClient
+ if not isChecking then
+ return []
+ else
+ return [CheckFailed msg, ModifyClient $ \c -> c{checkInfo = Nothing}]
+
+
+handleCmd_checker ("CHECKED" : "OK" : info) = do
+ isChecking <- liftM (isJust . checkInfo) thisClient
+ if not isChecking then
+ return []
+ else
+ return [CheckSuccess info, ModifyClient $ \c -> c{checkInfo = Nothing}]
+
+handleCmd_checker _ = return [ProtocolError "Unknown command"]
diff --git a/gameServer/HWProtoCore.hs b/gameServer/HWProtoCore.hs
index 6237017..1acc865 100644
--- a/gameServer/HWProtoCore.hs
+++ b/gameServer/HWProtoCore.hs
@@ -4,12 +4,14 @@ module HWProtoCore where
import Control.Monad.Reader
import Data.Maybe
import qualified Data.ByteString.Char8 as B
+import qualified Data.List as L
--------------------------------------
import CoreTypes
import Actions
import HWProtoNEState
import HWProtoLobbyState
import HWProtoInRoomState
+import HWProtoChecker
import HandlerUtils
import RoomsAndClients
import Utils
@@ -22,7 +24,7 @@ handleCmd ["PING"] = answerClient ["PONG"]
handleCmd ("QUIT" : xs) = return [ByeClient msg]
where
- msg = if not $ null xs then head xs else "bye"
+ msg = if not $ null xs then head xs else loc "bye"
handleCmd ["PONG"] = do
@@ -32,10 +34,33 @@ handleCmd ["PONG"] = do
else
return [ModifyClient (\c -> c{pingsQueue = pingsQueue c - 1})]
+handleCmd ("CMD" : parameters) =
+ let c = concatMap B.words parameters in
+ if not $ null c then
+ h $ (upperCase . head $ c) : tail c
+ else
+ return []
+ where
+ h ["DELEGATE", n] = handleCmd ["DELEGATE", n]
+ h ["STATS"] = handleCmd ["STATS"]
+ h ("PART":m:ms) = handleCmd ["PART", B.unwords $ m:ms]
+ h ("QUIT":m:ms) = handleCmd ["QUIT", B.unwords $ m:ms]
+ h ("RND":rs) = handleCmd ("RND":rs)
+ h ("GLOBAL":m:ms) = do
+ cl <- thisClient
+ rnc <- liftM snd ask
+ let chans = map (sendChan . client rnc) $ allClients rnc
+ return [AnswerClients chans ["CHAT", "[global notice]", B.unwords $ m:ms] | isAdministrator cl]
+ h c = return [Warning . B.concat . L.intersperse " " $ "Unknown cmd" : c]
+
handleCmd cmd = do
(ci, irnc) <- ask
- if logonPassed (irnc `client` ci) then
- handleCmd_loggedin cmd
+ let cl = irnc `client` ci
+ if logonPassed cl then
+ if isChecker cl then
+ handleCmd_checker cmd
+ else
+ handleCmd_loggedin cmd
else
handleCmd_NotEntered cmd
@@ -49,9 +74,9 @@ handleCmd_loggedin ["INFO", asknick] = do
let cl = rnc `client` fromJust maybeClientId
let roomId = clientRoom rnc clientId
let clRoom = room rnc roomId
- let roomMasterSign = if isMaster cl then "@" else ""
+ let roomMasterSign = if isMaster cl then "+" else ""
let adminSign = if isAdministrator cl then "@" else ""
- let rInfo = if roomId /= lobbyId then B.concat [roomMasterSign, "room ", name clRoom] else adminSign `B.append` "lobby"
+ let rInfo = if roomId /= lobbyId then B.concat [adminSign, roomMasterSign, "room ", name clRoom] else adminSign `B.append` "lobby"
let roomStatus = if isJust $ gameInfo clRoom then
if teamsInGame cl > 0 then "(playing)" else "(spectating)"
else
diff --git a/gameServer/HWProtoInRoomState.hs b/gameServer/HWProtoInRoomState.hs
index 718b34c..ccd587f 100644
--- a/gameServer/HWProtoInRoomState.hs
+++ b/gameServer/HWProtoInRoomState.hs
@@ -2,7 +2,6 @@
module HWProtoInRoomState where
import qualified Data.Map as Map
-import Data.Sequence((|>))
import Data.List as L
import Data.Maybe
import qualified Data.ByteString.Char8 as B
@@ -28,7 +27,7 @@ handleCmd_inRoom ["PART", msg] = return [MoveToLobby $ "part: " `B.append` msg]
handleCmd_inRoom ("CFG" : paramName : paramStrs)
- | null paramStrs = return [ProtocolError "Empty config entry"]
+ | null paramStrs = return [ProtocolError $ loc "Empty config entry"]
| otherwise = do
chans <- roomOthersChans
cl <- thisClient
@@ -37,7 +36,7 @@ handleCmd_inRoom ("CFG" : paramName : paramStrs)
ModifyRoom f,
AnswerClients chans ("CFG" : paramName : paramStrs)]
else
- return [ProtocolError "Not room master"]
+ return [ProtocolError $ loc "Not room master"]
where
f r = if paramName `Map.member` (mapParams r) then
r{mapParams = Map.insert paramName (head paramStrs) (mapParams r)}
@@ -45,7 +44,7 @@ handleCmd_inRoom ("CFG" : paramName : paramStrs)
r{params = Map.insert paramName paramStrs (params r)}
handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag : difStr : hhsInfo)
- | length hhsInfo /= 16 = return [ProtocolError "Corrupted hedgehogs info"]
+ | length hhsInfo /= 16 = return [ProtocolError $ loc "Corrupted hedgehogs info"]
| otherwise = do
(ci, _) <- ask
rm <- thisRoom
@@ -55,38 +54,41 @@ handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag :
roomChans <- roomClientsChans
cl <- thisClient
teamColor <-
- if clientProto cl < 42 then
+ if clientProto cl < 42 then
return color
else
liftM (head . (L.\\) (map B.singleton ['0'..]) . map teamcolor . teams) thisRoom
+ let roomTeams = teams rm
+ let hhNum = let p = if not $ null roomTeams then minimum [hhnum $ head roomTeams, canAddNumber roomTeams] else 4 in newTeamHHNum roomTeams p
+ let newTeam = clNick `seq` TeamInfo ci clNick tName teamColor grave fort voicepack flag dif hhNum (hhsList hhsInfo)
return $
- if not . null . drop (maxTeams rm - 1) $ teams rm then
- [Warning "too many teams"]
- else if canAddNumber rm <= 0 then
- [Warning "too many hedgehogs"]
+ if not . null . drop (maxTeams rm - 1) $ roomTeams then
+ [Warning $ loc "too many teams"]
+ else if canAddNumber roomTeams <= 0 then
+ [Warning $ loc "too many hedgehogs"]
else if isJust $ findTeam rm then
- [Warning "There's already a team with same name in the list"]
+ [Warning $ loc "There's already a team with same name in the list"]
else if isJust $ gameInfo rm then
- [Warning "round in progress"]
+ [Warning $ loc "round in progress"]
else if isRestrictedTeams rm then
- [Warning "restricted"]
+ [Warning $ loc "restricted"]
else
- [ModifyRoom (\r -> r{teams = teams r ++ [newTeam ci clNick r teamColor]}),
+ [ModifyRoom (\r -> r{teams = teams r ++ [newTeam]}),
SendUpdateOnThisRoom,
ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1, clientClan = Just teamColor}),
AnswerClients clChan ["TEAM_ACCEPTED", tName],
- AnswerClients othChans $ teamToNet $ newTeam ci clNick rm teamColor,
- AnswerClients roomChans ["TEAM_COLOR", tName, teamColor]
+ AnswerClients othChans $ teamToNet $ newTeam,
+ AnswerClients roomChans ["TEAM_COLOR", tName, teamColor],
+ AnswerClients roomChans ["HH_NUM", tName, showB $ hhnum newTeam]
]
where
- canAddNumber r = 48 - (sum . map hhnum $ teams r)
+ canAddNumber rt = (48::Int) - (sum $ map hhnum rt)
findTeam = find (\t -> tName == teamname t) . teams
- newTeam ci clNick r tColor = TeamInfo ci clNick tName tColor grave fort voicepack flag dif (newTeamHHNum r) (hhsList hhsInfo)
dif = readInt_ difStr
hhsList [] = []
hhsList [_] = error "Hedgehogs list with odd elements number"
hhsList (n:h:hhs) = HedgehogInfo n h : hhsList hhs
- newTeamHHNum r = min 4 (canAddNumber r)
+ newTeamHHNum rt p = min p (canAddNumber rt)
maxTeams r
| roomProto r < 38 = 6
| otherwise = 8
@@ -95,43 +97,44 @@ handleCmd_inRoom ("ADD_TEAM" : tName : color : grave : fort : voicepack : flag :
handleCmd_inRoom ["REMOVE_TEAM", tName] = do
(ci, _) <- ask
r <- thisRoom
- clNick <- clientNick
let maybeTeam = findTeam r
let team = fromJust maybeTeam
return $
- if isNothing $ findTeam r then
- [Warning "REMOVE_TEAM: no such team"]
- else if clNick /= teamowner team then
- [ProtocolError "Not team owner!"]
+ if isNothing $ maybeTeam then
+ [Warning $ loc "REMOVE_TEAM: no such team"]
+ else if ci /= teamownerId team then
+ [ProtocolError $ loc "Not team owner!"]
else
[RemoveTeam tName,
- SendUpdateOnThisRoom,
ModifyClient
(\c -> c{
teamsInGame = teamsInGame c - 1,
- clientClan = if teamsInGame c == 1 then Nothing else Just $ anotherTeamClan ci r
+ clientClan = if teamsInGame c == 1 then Nothing else Just $ anotherTeamClan ci team r
})
]
where
- anotherTeamClan ci = teamcolor . fromJust . find (\t -> teamownerId t == ci) . teams
+ anotherTeamClan ci team = teamcolor . fromMaybe (error "CHECKPOINT 011") . find (\t -> (teamownerId t == ci) && (t /= team)) . teams
findTeam = find (\t -> tName == teamname t) . teams
handleCmd_inRoom ["HH_NUM", teamName, numberStr] = do
cl <- thisClient
- others <- roomOthersChans
r <- thisRoom
+ clChan <- thisClientChans
+ others <- roomOthersChans
let maybeTeam = findTeam r
let team = fromJust maybeTeam
return $
if not $ isMaster cl then
- [ProtocolError "Not room master"]
- else if hhNumber < 1 || hhNumber > 8 || isNothing maybeTeam || hhNumber > canAddNumber r + hhnum team then
+ [ProtocolError $ loc "Not room master"]
+ else if isNothing maybeTeam then
[]
+ else if hhNumber < 1 || hhNumber > 8 || hhNumber > canAddNumber r + hhnum team then
+ [AnswerClients clChan ["HH_NUM", teamName, showB $ hhnum team]]
else
[ModifyRoom $ modifyTeam team{hhnum = hhNumber},
AnswerClients others ["HH_NUM", teamName, showB hhNumber]]
@@ -152,7 +155,7 @@ handleCmd_inRoom ["TEAM_COLOR", teamName, newColor] = do
return $
if not $ isMaster cl then
- [ProtocolError "Not room master"]
+ [ProtocolError $ loc "Not room master"]
else if isNothing maybeTeam then
[]
else
@@ -166,17 +169,16 @@ handleCmd_inRoom ["TEAM_COLOR", teamName, newColor] = do
handleCmd_inRoom ["TOGGLE_READY"] = do
cl <- thisClient
chans <- roomClientsChans
- if isMaster cl then
- return []
- else
- return [
- ModifyRoom (\r -> r{readyPlayers = readyPlayers r + (if isReady cl then -1 else 1)}),
- ModifyClient (\c -> c{isReady = not $ isReady cl}),
- AnswerClients chans $ if clientProto cl < 38 then
- [if isReady cl then "NOT_READY" else "READY", nick cl]
- else
- ["CLIENT_FLAGS", if isReady cl then "-r" else "+r", nick cl]
- ]
+
+ return [
+ ModifyRoom (\r -> r{readyPlayers = readyPlayers r + (if isReady cl then -1 else 1)}),
+ ModifyClient (\c -> c{isReady = not $ isReady cl}),
+ AnswerClients chans $ if clientProto cl < 38 then
+ [if isReady cl then "NOT_READY" else "READY", nick cl]
+ else
+ ["CLIENT_FLAGS", if isReady cl then "-r" else "+r", nick cl]
+ ]
+
handleCmd_inRoom ["START_GAME"] = do
(ci, rnc) <- ask
@@ -187,7 +189,7 @@ handleCmd_inRoom ["START_GAME"] = do
let nicks = map (nick . client rnc) . roomClients rnc $ clientRoom rnc ci
let allPlayersRegistered = all ((<) 0 . B.length . webPassword . client rnc . teamownerId) $ teams rm
- if isMaster cl && playersIn rm == readyPlayers rm && not (isJust $ gameInfo rm) then
+ if isMaster cl && (playersIn rm == readyPlayers rm || clientProto cl > 43) && not (isJust $ gameInfo rm) then
if enoughClans rm then
return [
ModifyRoom
@@ -201,7 +203,7 @@ handleCmd_inRoom ["START_GAME"] = do
, ModifyRoomClients (\c -> c{isInGame = True})
]
else
- return [Warning "Less than two clans!"]
+ return [Warning $ loc "Less than two clans!"]
else
return []
where
@@ -213,15 +215,16 @@ handleCmd_inRoom ["EM", msg] = do
rm <- thisRoom
chans <- roomOthersChans
- if teamsInGame cl > 0 && (isJust $ gameInfo rm) && isLegal then
- return $ AnswerClients chans ["EM", msg] : [ModifyRoom (\r -> r{gameInfo = liftM (\g -> g{roundMsgs = roundMsgs g |> msg}) $ gameInfo r}) | not isKeepAlive]
+ if teamsInGame cl > 0 && (isJust $ gameInfo rm) && (not $ B.null legalMsgs) then
+ return $ AnswerClients chans ["EM", legalMsgs]
+ : [ModifyRoom (\r -> r{gameInfo = liftM (\g -> g{roundMsgs = nonEmptyMsgs : roundMsgs g}) $ gameInfo r}) | not $ B.null nonEmptyMsgs]
else
return []
where
- (isLegal, isKeepAlive) = checkNetCmd msg
+ (legalMsgs, nonEmptyMsgs) = checkNetCmd msg
-handleCmd_inRoom ["ROUNDFINISHED", correctly] = do
+handleCmd_inRoom ["ROUNDFINISHED", _] = do
cl <- thisClient
rm <- thisRoom
chans <- roomClientsChans
@@ -231,16 +234,13 @@ handleCmd_inRoom ["ROUNDFINISHED", correctly] = do
if isInGame cl then
if isJust $ gameInfo rm then
- if (isMaster cl && isCorrect) then
- return $ FinishGame : unsetInGameState
- else
- return $ unsetInGameState ++ map SendTeamRemovalMessage clTeams
+ return $ unsetInGameState ++ map SendTeamRemovalMessage clTeams
else
return unsetInGameState
else
return [] -- don't accept this message twice
where
- isCorrect = correctly == "1"
+-- isCorrect = correctly == "1"
-- compatibility with clients with protocol < 38
handleCmd_inRoom ["ROUNDFINISHED"] =
@@ -250,7 +250,7 @@ handleCmd_inRoom ["TOGGLE_RESTRICT_JOINS"] = do
cl <- thisClient
return $
if not $ isMaster cl then
- [ProtocolError "Not room master"]
+ [ProtocolError $ loc "Not room master"]
else
[ModifyRoom (\r -> r{isRestrictedJoins = not $ isRestrictedJoins r})]
@@ -259,11 +259,20 @@ handleCmd_inRoom ["TOGGLE_RESTRICT_TEAMS"] = do
cl <- thisClient
return $
if not $ isMaster cl then
- [ProtocolError "Not room master"]
+ [ProtocolError $ loc "Not room master"]
else
[ModifyRoom (\r -> r{isRestrictedTeams = not $ isRestrictedTeams r})]
+handleCmd_inRoom ["TOGGLE_REGISTERED_ONLY"] = do
+ cl <- thisClient
+ return $
+ if not $ isMaster cl then
+ [ProtocolError $ loc "Not room master"]
+ else
+ [ModifyRoom (\r -> r{isRegisteredOnly = not $ isRegisteredOnly r})]
+
+
handleCmd_inRoom ["ROOM_NAME", newName] = do
cl <- thisClient
rs <- allRoomInfos
@@ -272,10 +281,10 @@ handleCmd_inRoom ["ROOM_NAME", newName] = do
return $
if not $ isMaster cl then
- [ProtocolError "Not room master"]
+ [ProtocolError $ loc "Not room master"]
else
if isJust $ find (\r -> newName == name r) rs then
- [Warning "Room with such name already exists"]
+ [Warning $ loc "Room with such name already exists"]
else
[ModifyRoom roomUpdate,
AnswerClients chans ("ROOM" : "UPD" : name rm : roomInfo (nick cl) (roomUpdate rm))]
@@ -287,10 +296,34 @@ handleCmd_inRoom ["KICK", kickNick] = do
(thisClientId, rnc) <- ask
maybeClientId <- clientByNick kickNick
master <- liftM isMaster thisClient
+ rm <- thisRoom
let kickId = fromJust maybeClientId
+ let kickCl = rnc `client` kickId
let sameRoom = clientRoom rnc thisClientId == clientRoom rnc kickId
+ let notOnly2Players = (length . group . sort . map teamowner . teams $ rm) > 2
return
- [KickRoomClient kickId | master && isJust maybeClientId && (kickId /= thisClientId) && sameRoom]
+ [KickRoomClient kickId |
+ master
+ && isJust maybeClientId
+ && (kickId /= thisClientId)
+ && sameRoom
+ && ((isNothing $ gameInfo rm) || notOnly2Players || teamsInGame kickCl == 0)
+ ]
+
+
+handleCmd_inRoom ["DELEGATE", newAdmin] = do
+ (thisClientId, rnc) <- ask
+ maybeClientId <- clientByNick newAdmin
+ master <- liftM isMaster thisClient
+ serverAdmin <- liftM isAdministrator thisClient
+ let newAdminId = fromJust maybeClientId
+ let sameRoom = clientRoom rnc thisClientId == clientRoom rnc newAdminId
+ return
+ [ChangeMaster (Just newAdminId) |
+ (master || serverAdmin)
+ && isJust maybeClientId
+ && ((newAdminId /= thisClientId) || (serverAdmin && not master))
+ && sameRoom]
handleCmd_inRoom ["TEAMCHAT", msg] = do
@@ -298,15 +331,27 @@ handleCmd_inRoom ["TEAMCHAT", msg] = do
chans <- roomSameClanChans
return [AnswerClients chans ["EM", engineMsg cl]]
where
- engineMsg cl = toEngineMsg $ B.concat ["b", nick cl, "(team): ", msg, "\x20\x20"]
+ engineMsg cl = toEngineMsg $ B.concat ["b", nick cl, " (team): ", msg, "\x20\x20"]
+
handleCmd_inRoom ["BAN", banNick] = do
- (_, rnc) <- ask
+ (thisClientId, rnc) <- ask
maybeClientId <- clientByNick banNick
- let banId = fromJust maybeClientId
master <- liftM isMaster thisClient
- return [ModifyRoom (\r -> r{roomBansList = (host $ rnc `client` banId) : roomBansList r}) | master && isJust maybeClientId]
+ let banId = fromJust maybeClientId
+ let sameRoom = clientRoom rnc thisClientId == clientRoom rnc banId
+ if master && isJust maybeClientId && (banId /= thisClientId) && sameRoom then
+ return [
+-- ModifyRoom (\r -> r{roomBansList = let h = host $ rnc `client` banId in h `deepseq` h : roomBansList r})
+ KickRoomClient banId
+ ]
+ else
+ return []
+handleCmd_inRoom ("RND":rs) = do
+ n <- clientNick
+ s <- roomClientsChans
+ return [AnswerClients s ["CHAT", n, B.unwords $ "/rnd" : rs], Random s rs]
handleCmd_inRoom ["LIST"] = return [] -- for old clients (<= 0.9.17)
diff --git a/gameServer/HWProtoLobbyState.hs b/gameServer/HWProtoLobbyState.hs
index 241b34f..ad2e11e 100644
--- a/gameServer/HWProtoLobbyState.hs
+++ b/gameServer/HWProtoLobbyState.hs
@@ -2,11 +2,9 @@
module HWProtoLobbyState where
import qualified Data.Map as Map
-import qualified Data.Foldable as Foldable
import Data.Maybe
import Data.List
import Control.Monad.Reader
-import qualified Data.ByteString.Char8 as B
--------------------------------------
import CoreTypes
import Actions
@@ -43,7 +41,7 @@ handleCmd_lobby ["CHAT", msg] = do
return [AnswerClients s ["CHAT", n, msg]]
handleCmd_lobby ["CREATE_ROOM", rName, roomPassword]
- | illegalName rName = return [Warning "Illegal room name"]
+ | illegalName rName = return [Warning $ loc "Illegal room name"]
| otherwise = do
rs <- allRoomInfos
cl <- thisClient
@@ -77,11 +75,13 @@ handleCmd_lobby ["JOIN_ROOM", roomName, roomPassword] = do
let isBanned = host cl `elem` roomBansList jRoom
return $
if isNothing maybeRI || not sameProto then
- [Warning "No such room"]
+ [Warning $ loc "No such room"]
else if isRestrictedJoins jRoom then
- [Warning "Joining restricted"]
+ [Warning $ loc "Joining restricted"]
+ else if isRegisteredOnly jRoom then
+ [Warning $ loc "Registered users only"]
else if isBanned then
- [Warning "You are banned in this room"]
+ [Warning $ loc "You are banned in this room"]
else if roomPassword /= password jRoom then
[NoticeMessage WrongPassword]
else
@@ -89,20 +89,21 @@ handleCmd_lobby ["JOIN_ROOM", roomName, roomPassword] = do
MoveToRoom jRI
, AnswerClients [sendChan cl] $ "JOINED" : nicks
, AnswerClients chans ["CLIENT_FLAGS", "-r", nick cl]
- , AnswerClients [sendChan cl] $ ["WARNING", "Room admin is " `B.append` ownerNick]
, AnswerClients [sendChan cl] $ ["CLIENT_FLAGS", "+h", ownerNick]
]
- ++ map (readynessMessage cl) jRoomClients
+ ++ (if clientProto cl < 38 then map (readynessMessage cl) jRoomClients else [sendStateFlags cl jRoomClients])
++ answerFullConfig cl (mapParams jRoom) (params jRoom)
++ answerTeams cl jRoom
- ++ watchRound cl jRoom
+ ++ watchRound cl jRoom chans
where
- readynessMessage cl c = AnswerClients [sendChan cl] $
- if clientProto cl < 38 then
- [if isReady c then "READY" else "NOT_READY", nick c]
- else
- ["CLIENT_FLAGS", if isReady c then "+r" else "-r", nick c]
+ readynessMessage cl c = AnswerClients [sendChan cl] [if isReady c then "READY" else "NOT_READY", nick c]
+ sendStateFlags cl clients = AnswerClients [sendChan cl] . concat . intersperse [""] . filter (not . null) . concat $
+ [f "+r" ready, f "-r" unready, f "+g" ingame, f "-g" inroomlobby]
+ where
+ (ready, unready) = partition isReady clients
+ (ingame, inroomlobby) = partition isInGame clients
+ f fl lst = ["CLIENT_FLAGS" : fl : map nick lst | not $ null lst]
toAnswer cl (paramName, paramStrs) = AnswerClients [sendChan cl] $ "CFG" : paramName : paramStrs
@@ -119,11 +120,13 @@ handleCmd_lobby ["JOIN_ROOM", roomName, roomPassword] = do
answerTeams cl jRoom = let f = if isJust $ gameInfo jRoom then teamsAtStart . fromJust . gameInfo else teams in answerAllTeams cl $ f jRoom
- watchRound cl jRoom = if isNothing $ gameInfo jRoom then
+ watchRound cl jRoom chans = if isNothing $ gameInfo jRoom then
[]
else
- [AnswerClients [sendChan cl] ["RUN_GAME"],
- AnswerClients [sendChan cl] $ "EM" : toEngineMsg "e$spectate 1" : Foldable.toList (roundMsgs . fromJust . gameInfo $ jRoom)]
+ [AnswerClients [sendChan cl] ["RUN_GAME"]
+ , AnswerClients chans ["CLIENT_FLAGS", "+g", nick cl]
+ , ModifyClient (\c -> c{isInGame = True})
+ , AnswerClients [sendChan cl] $ "EM" : toEngineMsg "e$spectate 1" : (reverse . roundMsgs . fromJust . gameInfo $ jRoom)]
handleCmd_lobby ["JOIN_ROOM", roomName] =
@@ -132,13 +135,19 @@ handleCmd_lobby ["JOIN_ROOM", roomName] =
handleCmd_lobby ["FOLLOW", asknick] = do
(_, rnc) <- ask
+ clChan <- liftM sendChan thisClient
ci <- clientByNick asknick
let ri = clientRoom rnc $ fromJust ci
- let clRoom = room rnc ri
+ let roomName = name $ room rnc ri
if isNothing ci || ri == lobbyId then
return []
else
- handleCmd_lobby ["JOIN_ROOM", name clRoom]
+ liftM ((:) (AnswerClients [clChan] ["JOINING", roomName])) $ handleCmd_lobby ["JOIN_ROOM", roomName]
+
+
+handleCmd_lobby ("RND":rs) = do
+ c <- liftM sendChan thisClient
+ return [Random [c] rs]
---------------------------
-- Administrator's stuff --
@@ -150,16 +159,20 @@ handleCmd_lobby ["KICK", kickNick] = do
return [KickClient $ fromJust kickId | isAdministrator cl && isJust kickId && fromJust kickId /= ci]
-handleCmd_lobby ["BAN", banNick, reason] = do
+handleCmd_lobby ["BAN", banNick, reason, duration] = do
(ci, _) <- ask
cl <- thisClient
banId <- clientByNick banNick
- return [BanClient 60 reason (fromJust banId) | isAdministrator cl && isJust banId && fromJust banId /= ci]
+ return [BanClient (readInt_ duration) reason (fromJust banId) | isAdministrator cl && isJust banId && fromJust banId /= ci]
handleCmd_lobby ["BANIP", ip, reason, duration] = do
cl <- thisClient
return [BanIP ip (readInt_ duration) reason | isAdministrator cl]
+handleCmd_lobby ["BANNICK", n, reason, duration] = do
+ cl <- thisClient
+ return [BanNick n (readInt_ duration) reason | isAdministrator cl]
+
handleCmd_lobby ["BANLIST"] = do
cl <- thisClient
return [BanList | isAdministrator cl]
@@ -196,5 +209,8 @@ handleCmd_lobby ["RESTART_SERVER"] = do
cl <- thisClient
return [RestartServer | isAdministrator cl]
+handleCmd_lobby ["STATS"] = do
+ cl <- thisClient
+ return [Stats | isAdministrator cl]
handleCmd_lobby _ = return [ProtocolError "Incorrect command (state: in lobby)"]
diff --git a/gameServer/HWProtoNEState.hs b/gameServer/HWProtoNEState.hs
index bdcac75..3cb0ca9 100644
--- a/gameServer/HWProtoNEState.hs
+++ b/gameServer/HWProtoNEState.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings, CPP #-}
module HWProtoNEState where
import Control.Monad.Reader
@@ -14,9 +14,9 @@ handleCmd_NotEntered :: CmdHandler
handleCmd_NotEntered ["NICK", newNick] = do
(ci, irnc) <- ask
let cl = irnc `client` ci
- if not . B.null $ nick cl then return [ProtocolError "Nickname already chosen"]
+ if not . B.null $ nick cl then return [ProtocolError $ loc "Nickname already chosen"]
else
- if illegalName newNick then return [ByeClient "Illegal nickname"]
+ if illegalName newNick then return [ByeClient $ loc "Illegal nickname"]
else
return $
ModifyClient (\c -> c{nick = newNick}) :
@@ -26,9 +26,9 @@ handleCmd_NotEntered ["NICK", newNick] = do
handleCmd_NotEntered ["PROTO", protoNum] = do
(ci, irnc) <- ask
let cl = irnc `client` ci
- if clientProto cl > 0 then return [ProtocolError "Protocol already known"]
+ if clientProto cl > 0 then return [ProtocolError $ loc "Protocol already known"]
else
- if parsedProto == 0 then return [ProtocolError "Bad number"]
+ if parsedProto == 0 then return [ProtocolError $ loc "Bad number"]
else
return $
ModifyClient (\c -> c{clientProto = parsedProto}) :
@@ -48,4 +48,18 @@ handleCmd_NotEntered ["PASSWORD", passwd] = do
return [ByeClient "Authentication failed"]
+#if defined(OFFICIAL_SERVER)
+handleCmd_NotEntered ["CHECKER", protoNum, newNick, password] = do
+ (ci, irnc) <- ask
+ let cl = irnc `client` ci
+
+ if parsedProto == 0 then return [ProtocolError $ loc "Bad number"]
+ else
+ return $ [
+ ModifyClient (\c -> c{clientProto = parsedProto, nick = newNick, webPassword = password, isChecker = True})
+ , CheckRegistered]
+ where
+ parsedProto = readInt_ protoNum
+#endif
+
handleCmd_NotEntered _ = return [ProtocolError "Incorrect command (state: not entered)"]
diff --git a/gameServer/NetRoutines.hs b/gameServer/NetRoutines.hs
index c9f2b89..aa2180b 100644
--- a/gameServer/NetRoutines.hs
+++ b/gameServer/NetRoutines.hs
@@ -34,6 +34,7 @@ acceptLoop servSock chan = forever $
""
""
False
+ False
0
lobbyId
0
@@ -41,6 +42,9 @@ acceptLoop servSock chan = forever $
False
False
False
+ False
+ False
+ Nothing
Nothing
0
)
diff --git a/gameServer/OfficialServer/GameReplayStore.hs b/gameServer/OfficialServer/GameReplayStore.hs
index c0066dc..3ec41a2 100644
--- a/gameServer/OfficialServer/GameReplayStore.hs
+++ b/gameServer/OfficialServer/GameReplayStore.hs
@@ -9,18 +9,57 @@ import System.Log.Logger
import Data.Maybe
import Data.Unique
import Control.Monad
+import Data.List
+import qualified Data.ByteString as B
+import System.Directory
---------------
import CoreTypes
+import EngineInteraction
+pickReplayFile :: Int -> IO String
+pickReplayFile p = do
+ files <- liftM (filter (isSuffixOf ('.' : show p))) $ getDirectoryContents "replays"
+ if (not $ null files) then
+ return $ "replays/" ++ head files
+ else
+ return ""
+
saveReplay :: RoomInfo -> IO ()
saveReplay r = do
- time <- getCurrentTime
- u <- liftM hashUnique newUnique
- let fileName = "replays/" ++ show time ++ "-" ++ show u
let gi = fromJust $ gameInfo r
- let replayInfo = (teamsAtStart gi, Map.toList $ mapParams r, Map.toList $ params r, roundMsgs gi)
- E.catch
- (writeFile fileName (show replayInfo))
- (\(e :: IOException) -> warningM "REPLAYS" $ "Couldn't write to " ++ fileName ++ ": " ++ show e)
-
\ No newline at end of file
+ when (allPlayersHaveRegisteredAccounts gi) $ do
+ time <- getCurrentTime
+ u <- liftM hashUnique newUnique
+ let fileName = "replays/" ++ show time ++ "-" ++ show u ++ "." ++ show (roomProto r)
+ let replayInfo = (teamsAtStart gi, Map.toList $ mapParams r, Map.toList $ params r, roundMsgs gi)
+ E.catch
+ (writeFile fileName (show replayInfo))
+ (\(e :: IOException) -> warningM "REPLAYS" $ "Couldn't write to " ++ fileName ++ ": " ++ show e)
+
+
+loadReplay :: Int -> IO (Maybe CheckInfo, [B.ByteString])
+loadReplay p = E.handle (\(e :: SomeException) -> warningM "REPLAYS" "Problems reading replay" >> return (Nothing, [])) $ do
+ fileName <- pickReplayFile p
+ if (not $ null fileName) then
+ loadFile fileName
+ else
+ return (Nothing, [])
+ where
+ loadFile :: String -> IO (Maybe CheckInfo, [B.ByteString])
+ loadFile fileName = E.handle (\(e :: SomeException) ->
+ warningM "REPLAYS" ("Problems reading " ++ fileName ++ ": " ++ show e) >> return (Nothing, [])) $ do
+ (teams, params1, params2, roundMsgs) <- liftM read $ readFile fileName
+ return $ (
+ Just (CheckInfo fileName teams)
+ , replayToDemo teams (Map.fromList params1) (Map.fromList params2) (reverse roundMsgs)
+ )
+
+moveFailedRecord :: String -> IO ()
+moveFailedRecord fn = E.handle (\(e :: SomeException) -> warningM "REPLAYS" $ show e) $
+ renameFile fn ("failed/" ++ drop 8 fn)
+
+
+moveCheckedRecord :: String -> IO ()
+moveCheckedRecord fn = E.handle (\(e :: SomeException) -> warningM "REPLAYS" $ show e) $
+ renameFile fn ("checked/" ++ drop 8 fn)
diff --git a/gameServer/OfficialServer/checker.hs b/gameServer/OfficialServer/checker.hs
new file mode 100644
index 0000000..af06485
--- /dev/null
+++ b/gameServer/OfficialServer/checker.hs
@@ -0,0 +1,183 @@
+{-# LANGUAGE CPP, ScopedTypeVariables, OverloadedStrings #-}
+module Main where
+
+import qualified Control.Exception as Exception
+import System.IO
+import System.Log.Logger
+import qualified Data.ConfigFile as CF
+import Control.Monad.Error
+import System.Directory
+import Control.Monad.State
+import Control.Concurrent.Chan
+import Control.Concurrent
+import Network
+import Network.BSD
+import Network.Socket hiding (recv)
+import Network.Socket.ByteString
+import qualified Data.ByteString.Char8 as B
+import qualified Data.ByteString as BW
+import qualified Codec.Binary.Base64 as Base64
+import System.Process
+import Data.Maybe
+import qualified Data.List as L
+#if !defined(mingw32_HOST_OS)
+import System.Posix
+#endif
+
+data Message = Packet [B.ByteString]
+ | CheckFailed B.ByteString
+ | CheckSuccess [B.ByteString]
+ deriving Show
+
+serverAddress = "netserver.hedgewars.org"
+protocolNumber = "43"
+
+getLines :: Handle -> IO [String]
+getLines h = g
+ where
+ g = do
+ l <- liftM Just (hGetLine h) `Exception.catch` (\(_ :: Exception.IOException) -> return Nothing)
+ if isNothing l then
+ return []
+ else
+ do
+ lst <- g
+ return $ fromJust l : lst
+
+
+engineListener :: Chan Message -> Handle -> IO ()
+engineListener coreChan h = do
+ output <- getLines h
+ debugM "Engine" $ show output
+ if isNothing $ L.find start output then
+ writeChan coreChan $ CheckFailed "No stats msg"
+ else
+ writeChan coreChan $ CheckSuccess []
+ where
+ start = flip L.elem ["WINNERS", "DRAW"]
+
+
+checkReplay :: Chan Message -> [B.ByteString] -> IO ()
+checkReplay coreChan msgs = do
+ tempDir <- getTemporaryDirectory
+ (fileName, h) <- openBinaryTempFile tempDir "checker-demo"
+ B.hPut h . BW.pack . concat . map (fromJust . Base64.decode . B.unpack) $ msgs
+ hFlush h
+ hClose h
+
+ (_, Just hOut, _, _) <- createProcess (proc "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.18/bin/hwengine"
+ ["/usr/home/unC0Rr/.hedgewars"
+ , "/usr/home/unC0Rr/Sources/Hedgewars/Releases/0.9.18/share/hedgewars/Data"
+ , fileName
+ , "--set-audio"
+ , "0"
+ , "0"
+ , "0"
+ ])
+ {std_out = CreatePipe}
+ hSetBuffering hOut LineBuffering
+ void $ forkIO $ engineListener coreChan hOut
+
+
+takePacks :: State B.ByteString [[B.ByteString]]
+takePacks = do
+ modify (until (not . B.isPrefixOf pDelim) (B.drop 2))
+ packet <- state $ B.breakSubstring pDelim
+ buf <- get
+ if B.null buf then put packet >> return [] else
+ if B.null packet then return [] else do
+ packets <- takePacks
+ return (B.splitWith (== '\n') packet : packets)
+ where
+ pDelim = "\n\n"
+
+
+recvLoop :: Socket -> Chan Message -> IO ()
+recvLoop s chan =
+ ((receiveWithBufferLoop B.empty >> return "Connection closed")
+ `Exception.catch` (\(e :: Exception.SomeException) -> return . B.pack . show $ e)
+ )
+ >>= disconnected
+ where
+ disconnected msg = writeChan chan $ Packet ["BYE", msg]
+ receiveWithBufferLoop recvBuf = do
+ recvBS <- recv s 4096
+ unless (B.null recvBS) $ do
+ let (packets, newrecvBuf) = runState takePacks $ B.append recvBuf recvBS
+ forM_ packets sendPacket
+ receiveWithBufferLoop $ B.copy newrecvBuf
+
+ sendPacket packet = writeChan chan $ Packet packet
+
+
+session :: B.ByteString -> B.ByteString -> Socket -> IO ()
+session l p s = do
+ noticeM "Core" "Connected"
+ coreChan <- newChan
+ forkIO $ recvLoop s coreChan
+ forever $ do
+ p <- readChan coreChan
+ case p of
+ Packet p -> do
+ debugM "Network" $ "Recv: " ++ show p
+ onPacket coreChan p
+ CheckFailed msg -> do
+ warningM "Check" "Check failed"
+ answer ["CHECKED", "FAIL", msg]
+ answer ["READY"]
+ CheckSuccess msgs -> do
+ warningM "Check" "Check succeeded"
+ answer ("CHECKED" : "OK" : msgs)
+ answer ["READY"]
+ where
+ answer :: [B.ByteString] -> IO ()
+ answer p = do
+ debugM "Network" $ "Send: " ++ show p
+ sendAll s $ B.unlines p `B.snoc` '\n'
+ onPacket :: Chan Message -> [B.ByteString] -> IO ()
+ onPacket _ ("CONNECTED":_) = do
+ answer ["CHECKER", protocolNumber, l, p]
+ answer ["READY"]
+ onPacket _ ["PING"] = answer ["PONG"]
+ onPacket chan ("REPLAY":msgs) = do
+ checkReplay chan msgs
+ warningM "Check" "Started check"
+ onPacket _ ("BYE" : xs) = error $ show xs
+ onPacket _ _ = return ()
+
+
+main :: IO ()
+main = withSocketsDo $ do
+#if !defined(mingw32_HOST_OS)
+ installHandler sigPIPE Ignore Nothing
+ installHandler sigCHLD Ignore Nothing
+#endif
+
+ updateGlobalLogger "Core" (setLevel DEBUG)
+ updateGlobalLogger "Network" (setLevel DEBUG)
+ updateGlobalLogger "Check" (setLevel DEBUG)
+ updateGlobalLogger "Engine" (setLevel DEBUG)
+
+ Right (login, password) <- runErrorT $ do
+ d <- liftIO $ getHomeDirectory
+ conf <- join . liftIO . CF.readfile CF.emptyCP $ d ++ "/.hedgewars/hedgewars.ini"
+ l <- CF.get conf "net" "nick"
+ p <- CF.get conf "net" "passwordhash"
+ return (B.pack l, B.pack p)
+
+
+ Exception.bracket
+ setupConnection
+ (\s -> noticeM "Core" "Shutting down" >> sClose s)
+ (session login password)
+ where
+ setupConnection = do
+ noticeM "Core" "Connecting to the server..."
+
+ proto <- getProtocolNumber "tcp"
+ let hints = defaultHints { addrFlags = [AI_ADDRCONFIG, AI_CANONNAME] }
+ (addr:_) <- getAddrInfo (Just hints) (Just serverAddress) Nothing
+ let (SockAddrInet _ host) = addrAddress addr
+ sock <- socket AF_INET Stream proto
+ connect sock (SockAddrInet 46631 host)
+ return sock
diff --git a/gameServer/OfficialServer/extdbinterface.hs b/gameServer/OfficialServer/extdbinterface.hs
index 67bd936..3e4a41d 100644
--- a/gameServer/OfficialServer/extdbinterface.hs
+++ b/gameServer/OfficialServer/extdbinterface.hs
@@ -14,7 +14,7 @@ import CoreTypes
dbQueryAccount =
- "SELECT users.pass, users_roles.rid FROM users LEFT JOIN users_roles ON users.uid = users_roles.uid WHERE users.name = ?"
+ "SELECT users.pass, users_roles.rid FROM users LEFT JOIN users_roles ON (users.uid = users_roles.uid AND users_roles.rid = 3) WHERE users.name = ?"
dbQueryStats =
"INSERT INTO gameserver_stats (players, rooms, last_update) VALUES (?, ?, UNIX_TIMESTAMP())"
@@ -29,7 +29,7 @@ dbInteractionLoop dbConn = forever $ do
execute statement [SqlByteString clNick]
passAndRole <- fetchRow statement
finish statement
- let response =
+ let response =
if isJust passAndRole then
(
clId,
diff --git a/gameServer/RoomsAndClients.hs b/gameServer/RoomsAndClients.hs
index 6ae37df..627c201 100644
--- a/gameServer/RoomsAndClients.hs
+++ b/gameServer/RoomsAndClients.hs
@@ -23,6 +23,7 @@ module RoomsAndClients(
room'sM,
allClientsM,
clientsM,
+ roomsM,
roomClientsM,
roomClientsIndicesM,
withRoomsAndClients,
@@ -160,6 +161,9 @@ allClientsM (MRoomsAndClients (_, clients)) = liftM (map ClientIndex) $ indicesM
clientsM :: MRoomsAndClients r c -> IO [c]
clientsM (MRoomsAndClients (_, clients)) = indicesM clients >>= mapM (liftM client' . readElem clients)
+roomsM :: MRoomsAndClients r c -> IO [r]
+roomsM (MRoomsAndClients (rooms, _)) = indicesM rooms >>= mapM (liftM room' . readElem rooms)
+
roomClientsIndicesM :: MRoomsAndClients r c -> RoomIndex -> IO [ClientIndex]
roomClientsIndicesM (MRoomsAndClients (rooms, _)) (RoomIndex ri) = liftM roomClients' (rooms `readElem` ri)
diff --git a/gameServer/ServerState.hs b/gameServer/ServerState.hs
index b163394..9b41990 100644
--- a/gameServer/ServerState.hs
+++ b/gameServer/ServerState.hs
@@ -5,6 +5,7 @@ module ServerState
ServerState(..),
client's,
allClientsS,
+ allRoomsS,
roomClientsS,
sameProtoClientsS,
io
@@ -40,6 +41,9 @@ client's f = do
allClientsS :: StateT ServerState IO [ClientInfo]
allClientsS = gets roomsClients >>= liftIO . clientsM
+allRoomsS :: StateT ServerState IO [RoomInfo]
+allRoomsS = gets roomsClients >>= liftIO . roomsM
+
roomClientsS :: RoomIndex -> StateT ServerState IO [ClientInfo]
roomClientsS ri = do
rnc <- gets roomsClients
@@ -49,6 +53,6 @@ sameProtoClientsS :: Word16 -> StateT ServerState IO [ClientInfo]
sameProtoClientsS p = liftM f allClientsS
where
f = filter (\c -> clientProto c == p)
-
+
io :: IO a -> StateT ServerState IO a
io = liftIO
diff --git a/gameServer/Utils.hs b/gameServer/Utils.hs
index 86cdfe6..b7ac1ab 100644
--- a/gameServer/Utils.hs
+++ b/gameServer/Utils.hs
@@ -56,7 +56,7 @@ modifyTeam team room = room{teams = replaceTeam team $ teams room}
t : replaceTeam tm ts
illegalName :: B.ByteString -> Bool
-illegalName s = B.null s || B.all isSpace s || isSpace (B.head s) || isSpace (B.last s) || B.any isIllegalChar s
+illegalName s = B.null s || B.length s > 40 || B.all isSpace s || isSpace (B.head s) || isSpace (B.last s) || B.any isIllegalChar s
where
isIllegalChar c = c `List.elem` "$()*+?[]^{|}"
@@ -90,6 +90,8 @@ protoNumber2ver v = Map.findWithDefault "Unknown" v vermap
, (42, "0.9.18-dev")
, (43, "0.9.18")
, (44, "0.9.19-dev")
+ , (45, "0.9.19")
+ , (46, "0.9.20-dev")
]
askFromConsole :: B.ByteString -> IO B.ByteString
@@ -118,10 +120,10 @@ cutHost :: B.ByteString -> B.ByteString
cutHost = B.intercalate "." . flip (++) ["*","*"] . List.take 2 . B.split '.'
caseInsensitiveCompare :: B.ByteString -> B.ByteString -> Bool
-caseInsensitiveCompare a b = f a == f b
- where
- f = map Char.toUpper . UTF8.toString
+caseInsensitiveCompare a b = upperCase a == upperCase b
+upperCase :: B.ByteString -> B.ByteString
+upperCase = UTF8.fromString . map Char.toUpper . UTF8.toString
roomInfo :: B.ByteString -> RoomInfo -> [B.ByteString]
roomInfo n r = [
@@ -134,3 +136,6 @@ roomInfo n r = [
head (Map.findWithDefault ["Default"] "SCHEME" (params r)),
head (Map.findWithDefault ["Default"] "AMMO" (params r))
]
+
+loc :: B.ByteString -> B.ByteString
+loc = id
diff --git a/gameServer/hedgewars-server.cabal b/gameServer/hedgewars-server.cabal
index 5d75355..14062e5 100644
--- a/gameServer/hedgewars-server.cabal
+++ b/gameServer/hedgewars-server.cabal
@@ -22,6 +22,7 @@ Executable hedgewars-server
bytestring,
bytestring-show,
network >= 2.3,
+ random,
time,
mtl >= 2,
dataenc,
diff --git a/hedgewars/ArgParsers.inc b/hedgewars/ArgParsers.inc
index 503cec2..ae209ff 100644
--- a/hedgewars/ArgParsers.inc
+++ b/hedgewars/ArgParsers.inc
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,232 +16,333 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*)
-
-procedure internalStartGameWithParameters();
-var tmp: LongInt;
+procedure GciEasterEgg;
begin
- UserPathPrefix:= ParamStr(1);
- cScreenWidth:= StrToInt(ParamStr(2));
- cScreenHeight:= StrToInt(ParamStr(3));
- cBits:= StrToInt(ParamStr(4));
- ipcPort:= StrToInt(ParamStr(5));
- cFullScreen:= ParamStr(6) = '1';
- SetSound(ParamStr(7) = '1');
- SetMusic(ParamStr(8) = '1');
- SetVolume(StrToInt(ParamStr(9)));
- cTimerInterval:= StrToInt(ParamStr(10));
- PathPrefix:= ParamStr(11);
- cShowFPS:= ParamStr(12) = '1';
- cAltDamage:= ParamStr(13) = '1';
- UserNick:= DecodeBase64(ParamStr(14));
- cReducedQuality:= StrToInt(ParamStr(15));
- tmp:= StrToInt(ParamStr(16));
- GrayScale:= false;
- if (tmp > 9) and (tmp < 16) then
- begin
- GrayScale:= true;
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-9)))
- end
- else if tmp <= 9 then
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp)))
- else
- cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
- cLocaleFName:= ParamStr(17);
+ WriteLn(stdout, ' ');
+ WriteLn(stdout, ' /\\\\\\\\\\\\ /\\\\\\\\\ /\\\\\\\\\\\ ');
+ WriteLn(stdout, ' /\\\////////// /\\\//////// \/////\\\/// ');
+ WriteLn(stdout, ' /\\\ /\\\/ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ /\\\\\\\ /\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/////\\\ \/\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/\\\ \//\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\ \/\\\ \///\\\ \/\\\ ');
+ WriteLn(stdout, ' \/\\\\\\\\\\\\\/ \////\\\\\\\\\ /\\\\\\\\\\\ ');
+ WriteLn(stdout, ' \///////////// \///////// \/////////// ');
+ WriteLn(stdout, ' ');
+ WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student ');
+ WriteLn(stdout, ' ASCII Art easter egg idea by @sheepluva ');
+ WriteLn(stdout, ' ');
end;
-{$IFDEF USE_VIDEO_RECORDING}
-procedure internalStartVideoRecordingWithParameters();
+procedure DisplayUsage;
begin
- internalStartGameWithParameters();
- GameType:= gmtRecord;
- cVideoFramerateNum:= StrToInt(ParamStr(18));
- cVideoFramerateDen:= StrToInt(ParamStr(19));
- RecPrefix:= ParamStr(20);
- cAVFormat:= ParamStr(21);
- cVideoCodec:= ParamStr(22);
- cVideoQuality:= StrToInt(ParamStr(23));
- cAudioCodec:= ParamStr(24);
+ WriteLn(stdout, 'Usage: hwengine <path to replay file> [options]');
+ WriteLn(stdout, '');
+ WriteLn(stdout, 'where [options] can be any of the following:');
+ WriteLn(stdout, ' --prefix [path to folder]');
+ WriteLn(stdout, ' --user-prefix [path to folder]');
+ WriteLn(stdout, ' --locale [name of language file]');
+ WriteLn(stdout, ' --nick [string]');
+ WriteLn(stdout, ' --fullscreen-width [fullscreen width in pixels]');
+ WriteLn(stdout, ' --fullscreen-height [fullscreen height in pixels]');
+ WriteLn(stdout, ' --width [window width in pixels]');
+ WriteLn(stdout, ' --height [window height in pixels]');
+ WriteLn(stdout, ' --volume [sound level]');
+ WriteLn(stdout, ' --frame-interval [milliseconds]');
+ Writeln(stdout, ' --stereo [value]');
+ WriteLn(stdout, ' --raw-quality [flags]');
+ WriteLn(stdout, ' --low-quality');
+ WriteLn(stdout, ' --nomusic');
+ WriteLn(stdout, ' --nosound');
+ WriteLn(stdout, ' --fullscreen');
+ WriteLn(stdout, ' --showfps');
+ WriteLn(stdout, ' --altdmg');
+ WriteLn(stdout, ' --stats-only');
+ WriteLn(stdout, ' --help');
+ WriteLn(stdout, '');
+ WriteLn(stdout, 'For more detailed help and examples go to:');
+ WriteLn(stdout, 'http://code.google.com/p/hedgewars/wiki/CommandLineOptions');
+ GameType:= gmtSyntax;
end;
-{$ENDIF}
-procedure setVideo(screenWidth: LongInt; screenHeight: LongInt; bitsStr: LongInt);
+procedure setDepth(var paramIndex: LongInt);
begin
- cScreenWidth:= screenWidth;
- cScreenHeight:= screenHeight;
- cBits:= bitsStr
+ WriteLn(stdout, 'WARNING: --depth is a deprecated command, which could be removed in a future version!');
+ WriteLn(stdout, ' This option no longer does anything, please consider removing it');
+ WriteLn(stdout, '');
+ inc(ParamIndex);
end;
-procedure setVideoWithParameters(screenWidthParam: string; screenHeightParam: string; bitsParam: string);
-var screenWidthAsInt, screenHeightAsInt, bitsStrAsInt, c: LongInt;
+procedure statsOnlyGame;
begin
- val(screenWidthParam, screenWidthAsInt, c);
- val(screenHeightParam, screenHeightAsInt, c);
- val(bitsParam, bitsStrAsInt, c);
- setVideo(screenWidthAsInt,screenHeightAsInt,bitsStrAsInt)
+ cOnlyStats:= true;
+ cReducedQuality:= $FFFFFFFF xor rqLowRes;
+ SetSound(false);
+ SetMusic(false);
+ SetVolume(0);
end;
-procedure setOtherOptions(languageFile: string; fullScreen: boolean);
+procedure setIpcPort(port: LongInt; var wrongParameter:Boolean);
begin
- cLocaleFName:= languageFile;
- cFullScreen:= fullScreen
+ if isInternal then
+ ipcPort := port
+ else
+ begin
+ WriteLn(stderr, 'ERROR: use of --port is not allowed');
+ wrongParameter := true;
+ end
end;
-procedure setShowFPS(showFPS: boolean);
+function parseNick(nick: String): String;
begin
- cShowFPS:= showFPS
+ if isInternal then
+ parseNick:= DecodeBase64(nick)
+ else
+ parseNick:= nick;
end;
-procedure setOtherOptionsWithParameters(languageFileParam: string; fullScreenParam: string; showFPSParam: string);
-var fullScreen, showFPS: boolean;
+procedure setStereoMode(tmp: LongInt);
begin
- fullScreen:= fullScreenParam = '1';
- showFPS:= showFPSParam = '1';
- setOtherOptions(languageFileParam,fullScreen);
- setShowFPS(showFPS)
+ GrayScale:= false;
+{$IFDEF USE_S3D_RENDERING}
+ if (tmp > 6) and (tmp < 13) then
+ begin
+ // set the gray anaglyph rendering
+ GrayScale:= true;
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)))
+ end
+ else if tmp <= 6 then
+ // set the fullcolor anaglyph
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp)))
+ else
+ // any other mode
+ cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
+{$ELSE}
+ tmp:= tmp;
+ cStereoMode:= smNone;
+{$ENDIF}
end;
-procedure setAudio(initialVolume: LongInt; musicEnabled: boolean; soundEnabled: boolean);
+procedure startVideoRecording(var paramIndex: LongInt);
begin
- SetVolume(initialVolume);
- SetMusic(musicEnabled);
- SetSound(soundEnabled);
+ // Silence the hint that appears when USE_VIDEO_RECORDING is not defined
+ paramIndex:= paramIndex;
+{$IFDEF USE_VIDEO_RECORDING}
+ GameType:= gmtRecord;
+ inc(paramIndex);
+ cVideoFramerateNum:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ cVideoFramerateDen:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ RecPrefix:= ParamStr(paramIndex); inc(paramIndex);
+ cAVFormat:= ParamStr(paramIndex); inc(paramIndex);
+ cVideoCodec:= ParamStr(paramIndex); inc(paramIndex);
+ cVideoQuality:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
+ cAudioCodec:= ParamStr(paramIndex); inc(paramIndex);
+{$ENDIF}
end;
-procedure setAudioWithParameters(initialVolumeParam: string; musicEnabledParam: string; soundEnabledParam: string);
-var initialVolumeAsInt, c: LongInt;
- musicEnabled, soundEnabled: boolean;
+function getLongIntParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
+var tmpInt, c: LongInt;
begin
- val(initialVolumeParam, initialVolumeAsInt, c);
- musicEnabled:= musicEnabledParam = '1';
- soundEnabled:= soundEnabledParam = '1';
- setAudio(initialVolumeAsInt,musicEnabled, soundEnabled)
+ inc(paramIndex);
+ val(str, tmpInt, c);
+ wrongParameter:= c <> 0;
+ if wrongParameter then
+ WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a number, you passed "'+str+'"');
+ getLongIntParameter:= tmpInt;
end;
-procedure setMultimediaOptionsWithParameters(screenWidthParam, screenHeightParam, bitsParam: string;
- initialVolumeParam, musicEnabledParam, soundEnabledParam: string;
- languageFileParam, fullScreenParam: string);
+function getStringParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): String;
begin
- setVideoWithParameters(screenWidthParam,screenHeightParam, bitsParam);
- setAudioWithParameters(initialVolumeParam,musicEnabledParam,soundEnabledParam);
- setOtherOptions(languageFileParam,fullScreenParam = '1')
+ inc(paramIndex);
+ wrongParameter:= (str='') or (Copy(str,1,2) = '--');
+ if wrongParameter then
+ WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a string, you passed "'+str+'"');
+ getStringParameter:= str;
end;
-procedure setAltDamageTimerValueAndQuality(altDamage: boolean; timeIterval: LongInt; reducedQuality: boolean);
+
+procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt); Forward;
+
+function parseParameter(cmd:String; arg:String; var paramIndex:LongInt): Boolean;
+const videoArray: Array [1..5] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
+ audioArray: Array [1..3] of String = ('--volume','--nomusic','--nosound');
+ otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps');
+ mediaArray: Array [1..10] of String = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
+ allArray: Array [1..14] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality');
+ reallyAll: array[0..30] of shortstring = (
+ '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
+ '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
+ '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
+ {deprecated} '--depth', '--set-video', '--set-audio', '--set-other', '--set-multimedia', '--set-everything',
+ {internal} '--internal', '--port', '--recorder', '--landpreview',
+ {misc} '--stats-only', '--gci', '--help');
+var cmdIndex: byte;
begin
- cAltDamage:= altDamage;
- cTimerInterval:= timeIterval;
- if (reducedQuality) then //HACK
- cReducedQuality:= $FFFFFFFF xor rqLowRes
+ parseParameter:= false;
+ cmdIndex:= 0;
+
+ //NOTE: Any update to the list of parameters must be reflected in the case statement below, the reallyAll array above,
+ // the the DisplayUsage() procedure, the HWForm::getDemoArguments() function, and the online wiki
+
+ while (cmdIndex <= High(reallyAll)) and (cmd <> reallyAll[cmdIndex]) do inc(cmdIndex);
+ case cmdIndex of
+ {--prefix} 0 : PathPrefix := getStringParameter (arg, paramIndex, parseParameter);
+ {--user-prefix} 1 : UserPathPrefix := getStringParameter (arg, paramIndex, parseParameter);
+ {--locale} 2 : cLocaleFName := getStringParameter (arg, paramIndex, parseParameter);
+ {--fullscreen-width} 3 : cFullscreenWidth := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenWidth);
+ {--fullscreen-height} 4 : cFullscreenHeight := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenHeight);
+ {--width} 5 : cWindowedWidth := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenWidth);
+ {--height} 6 : cWindowedHeight := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenHeight);
+ {--frame-interval} 7 : cTimerInterval := getLongIntParameter(arg, paramIndex, parseParameter);
+ {--volume} 8 : SetVolume ( max(getLongIntParameter(arg, paramIndex, parseParameter), 0) );
+ {--nomusic} 9 : SetMusic ( false );
+ {--nosound} 10 : SetSound ( false );
+ {--fullscreen} 11 : cFullScreen := true;
+ {--showfps} 12 : cShowFPS := true;
+ {--altdmg} 13 : cAltDamage := true;
+ {--low-quality} 14 : cReducedQuality := $FFFFFFFF xor rqLowRes;
+ {--raw-quality} 15 : cReducedQuality := getLongIntParameter(arg, paramIndex, parseParameter);
+ {--stereo} 16 : setStereoMode ( getLongIntParameter(arg, paramIndex, parseParameter) );
+ {--nick} 17 : UserNick := parseNick( getStringParameter(arg, paramIndex, parseParameter) );
+ {deprecated options}
+ {--depth} 18 : setDepth(paramIndex);
+ {--set-video} 19 : parseClassicParameter(videoArray,5,paramIndex);
+ {--set-audio} 20 : parseClassicParameter(audioArray,3,paramIndex);
+ {--set-other} 21 : parseClassicParameter(otherArray,3,paramIndex);
+ {--set-multimedia} 22 : parseClassicParameter(mediaArray,10,paramIndex);
+ {--set-everything} 23 : parseClassicParameter(allArray,14,paramIndex);
+ {"internal" options}
+ {--internal} 24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
+ {--port} 25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
+ {--recorder} 26 : startVideoRecording(paramIndex);
+ {--landpreview} 27 : GameType := gmtLandPreview;
+ {anything else}
+ {--stats-only} 28 : statsOnlyGame();
+ {--gci} 29 : GciEasterEgg();
+ {--help} 30 : DisplayUsage();
+ else
+ begin
+ //Asusme the first "non parameter" is the replay file, anything else is invalid
+ if (recordFileName = '') and (Copy(cmd,1,2) <> '--') then
+ recordFileName := cmd
+ else
+ begin
+ WriteLn(stderr, '"'+cmd+'" is not a valid option');
+ parseParameter:= true;
+ end;
+ end;
+ end;
end;
-procedure setAllOptionsWithParameters(screenWidthParam:string; screenHeightParam:string; bitsParam:string;
- initialVolumeParam:string; musicEnabledParam:string; soundEnabledParam:string;
- languageFileParam:string; fullScreenParam:string; showFPSParam:string;
- altDamageParam:string; timeItervalParam:string; reducedQualityParam: string);
-var showFPS, altDamage, reducedQuality: boolean;
- timeIterval, c: LongInt;
+procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt);
+var index, tmpInt: LongInt;
+ isBool, isValid: Boolean;
+ cmd, arg, newSyntax: String;
begin
- setMultimediaOptionsWithParameters(screenWidthParam,screenHeightParam, bitsParam,
- initialVolumeParam,musicEnabledParam,soundEnabledParam,
- languageFileParam,fullScreenParam);
- showFPS := showFPSParam = '1';
- setShowFPS(showFPS);
-
- altDamage:= altDamageParam = '1';
- val(timeItervalParam, timeIterval, c);
- reducedQuality:= reducedQualityParam = '1';
- setAltDamageTimerValueAndQuality(altDamage,timeIterval,reducedQuality);
+ WriteLn(stdout, 'WARNING: you are using a deprecated command, which could be removed in a future version!');
+ WriteLn(stdout, ' Consider updating to the latest syntax, which is much more flexible!');
+ WriteLn(stdout, ' Run `hwegine --help` to learn it!');
+ WriteLn(stdout, '');
+
+ index:= 0;
+ tmpInt:= 1;
+ while (index < size) do
+ begin
+ newSyntax:= '';
+ inc(paramIndex);
+ cmd:= cmdArray[index];
+ arg:= ParamStr(paramIndex);
+ isValid:= (cmd<>'--depth');
+
+ // check if the parameter is a boolean one
+ isBool:= (cmd = '--nomusic') or (cmd = '--nosound') or (cmd = '--fullscreen') or (cmd = '--showfps') or (cmd = '--altdmg');
+ if isBool and (arg='0') then
+ isValid:= false;
+ if (cmd='--nomusic') or (cmd='--nosound') then
+ isValid:= not isValid;
+
+ if isValid then
+ begin
+ parseParameter(cmd, arg, tmpInt);
+ newSyntax := newSyntax + cmd + ' ';
+ if not isBool then
+ newSyntax := newSyntax + arg + ' ';
+ end;
+ inc(index);
+ end;
+
+ WriteLn(stdout, 'Attempted to automatically convert to the new syntax:');
+ WriteLn(stdout, newSyntax);
+ WriteLn(stdout, '');
end;
-procedure playReplayFileWithParameters();
+procedure parseCommandLine{$IFDEF HWLIBRARY}(argc: LongInt; argv: PPChar){$ENDIF};
var paramIndex: LongInt;
+ paramTotal: LongInt;
+ index, nextIndex: LongInt;
wrongParameter: boolean;
+//var tmpInt: LongInt;
begin
- UserPathPrefix:= ParamStr(1);
- PathPrefix:= ParamStr(2);
- recordFileName:= ParamStr(3);
- paramIndex:= 4;
+ paramIndex:= {$IFDEF HWLIBRARY}0{$ELSE}1{$ENDIF};
+ paramTotal:= {$IFDEF HWLIBRARY}argc-1{$ELSE}ParamCount{$ENDIF}; //-1 because pascal enumeration is inclusive
+ (*
+ WriteLn(stdout, 'total parameters: ' + inttostr(paramTotal));
+ tmpInt:= 0;
+ while (tmpInt <= paramTotal) do
+ begin
+ WriteLn(stdout, inttostr(tmpInt) + ': ' + {$IFDEF HWLIBRARY}argv[tmpInt]{$ELSE}paramCount(tmpInt){$ENDIF});
+ inc(tmpInt);
+ end;
+ *)
wrongParameter:= false;
- while (paramIndex <= ParamCount) and (not wrongParameter) do
+ while (paramIndex <= paramTotal) do
begin
- if ParamStr(paramIndex) = '--set-video' then
-//--set-video [screen width] [screen height] [color dept]
- begin
- if(ParamCount-paramIndex < 3) then
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end;
- setVideoWithParameters(ParamStr(paramIndex+1), ParamStr(paramIndex+2), ParamStr(paramIndex+3));
- paramIndex:= paramIndex + 4
- end
- else
-//--set-audio [volume] [enable music] [enable sounds]
- if ParamStr(paramIndex) = '--set-audio' then
- begin
- if(ParamCount-paramIndex < 3) then
- begin
- wrongParameter := true;
- GameType:= gmtSyntax
- end;
- setAudioWithParameters(ParamStr(paramIndex+1),ParamStr(paramIndex+2), ParamStr(paramIndex+3));
- paramIndex:= paramIndex + 4
- end
- else
-// --set-other [language file] [full screen] [show FPS]
- if ParamStr(paramIndex) = '--set-other' then
- begin
- if(ParamCount-paramIndex < 3) then
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end;
- setOtherOptionsWithParameters(ParamStr(paramIndex+1),ParamStr(paramIndex+2), ParamStr(paramIndex+3));
- paramIndex:= paramIndex + 4
- end
- else
-//--set-multimedia [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]
- if ParamStr(paramIndex) = '--set-multimedia' then
- begin
- if ParamCount-paramIndex < 8 then
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end;
- setMultimediaOptionsWithParameters(ParamStr(paramIndex+1),ParamStr(paramIndex+2),ParamStr(paramIndex+3),
- ParamStr(paramIndex+4),ParamStr(paramIndex+5),ParamStr(paramIndex+6),
- ParamStr(paramIndex+7),ParamStr(paramIndex+8));
- paramIndex:= paramIndex + 9
- end
- else
-//--set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]
- if ParamStr(paramIndex) = '--set-everything' then
- begin
- if ParamCount-paramIndex < 12 then
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end;
- setAllOptionsWithParameters(ParamStr(paramIndex+1),ParamStr(paramIndex+2),ParamStr(paramIndex+3),
- ParamStr(paramIndex+4),ParamStr(paramIndex+5),ParamStr(paramIndex+6),
- ParamStr(paramIndex+7),ParamStr(paramIndex+8),ParamStr(paramIndex+9),
- ParamStr(paramIndex+10),ParamStr(paramIndex+11),ParamStr(paramIndex+12));
- paramIndex:= paramIndex + 13
- end
- else
- if ParamStr(paramIndex) = '--stats-only' then
- begin
- cOnlyStats:= true;
- SetSound(false);
- SetMusic(false);
- cReducedQuality:= $FFFFFFFF xor rqLowRes; // HACK
- paramIndex:= paramIndex + 1
- end
- else
- begin
- wrongParameter:= true;
- GameType:= gmtSyntax
- end
- end
+ // avoid going past the number of paramTotal (esp. w/ library)
+ index:= paramIndex;
+ if index = paramTotal then nextIndex:= index
+ else nextIndex:= index+1;
+ {$IFDEF HWLIBRARY}
+ wrongParameter:= parseParameter( argv[index], argv[nextIndex], paramIndex);
+ {$ELSE}
+ wrongParameter:= parseParameter( ParamStr(index), ParamStr(nextIndex), paramIndex);
+ {$ENDIF}
+ inc(paramIndex);
+ end;
+ if wrongParameter = true then
+ GameType:= gmtSyntax;
end;
+{$IFNDEF HWLIBRARY}
+procedure GetParams;
+begin
+ isInternal:= (ParamStr(1) = '--internal');
+
+ UserPathPrefix := '.';
+ PathPrefix := cDefaultPathPrefix;
+ recordFileName := '';
+ parseCommandLine();
+
+ if (isInternal) and (ParamCount<=1) then
+ begin
+ WriteLn(stderr, '--internal should not be manually used');
+ GameType := gmtSyntax;
+ end;
+
+ if (not isInternal) and (recordFileName = '') then
+ begin
+ WriteLn(stderr, 'You must specify a replay file');
+ GameType := gmtSyntax;
+ end
+ else if (recordFileName <> '') then
+ WriteLn(stdout, 'Attempting to play demo file "' + recordFilename + '"');
+
+ if (GameType = gmtSyntax) then
+ WriteLn(stderr, 'Please use --help to see possible arguments and their usage');
+
+ (*
+ WriteLn(stdout,'PathPrefix: ' + PathPrefix);
+ WriteLn(stdout,'UserPathPrefix: ' + UserPathPrefix);
+ *)
+end;
+{$ENDIF}
+
diff --git a/hedgewars/CMakeLists.txt b/hedgewars/CMakeLists.txt
index 6bf3766..4432bbf 100644
--- a/hedgewars/CMakeLists.txt
+++ b/hedgewars/CMakeLists.txt
@@ -4,13 +4,35 @@ find_package(SDL_net)
find_package(SDL_ttf)
find_package(SDL_mixer)
-include(${CMAKE_MODULE_PATH}/FindSDL_Extras.cmake)
+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()
+
-configure_file(${hedgewars_SOURCE_DIR}/hedgewars/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.inc.in ${CMAKE_CURRENT_BINARY_DIR}/config.inc)
#SOURCE AND PROGRAMS SECTION
-set(hwengine_project ${hedgewars_SOURCE_DIR}/hedgewars/hwengine.pas)
-set(engine_output_name "hwengine")
+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}
@@ -53,7 +75,7 @@ set(engine_sources
uLandTexture.pas
uLocale.pas
uMisc.pas
- uMobile.pas
+ uPhysFSLayer.pas
uRandom.pas
uRender.pas
uRenderUtils.pas
@@ -79,50 +101,36 @@ set(engine_sources
${CMAKE_CURRENT_BINARY_DIR}/config.inc
)
-if(BUILD_ENGINE_LIBRARY)
- message(STATUS "Engine will be built as library (experimental)")
- set(hwengine_project ${hedgewars_SOURCE_DIR}/hedgewars/hwLibrary.pas)
- set(pascal_flags "-dHWLIBRARY" ${pascal_flags})
+if(${BUILD_ENGINE_LIBRARY})
+ message(${WARNING} "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")
- set(pascal_flags "-Cg" ${pascal_flags})
+ 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 GREATER "10.5")
- set(pascal_flags "-k-no_order_inits" ${pascal_flags})
+ 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})
- if (APPLE)
- set(engine_output_name "hwengine.dylib")
- endif (APPLE)
-endif(BUILD_ENGINE_LIBRARY)
-
-IF(FPC)
- set(fpc_executable ${FPC})
-ELSE()
- find_program(fpc_executable fpc)
-ENDIF()
-
-if(fpc_executable)
- exec_program(${fpc_executable} ARGS "-iV" OUTPUT_VARIABLE fpc_output)
-endif(fpc_executable)
-set(noexecstack_flags "-k-z" "-knoexecstack")
-file(WRITE ${EXECUTABLE_OUTPUT_PATH}/checkstack.pas "begin end.")
+include(${CMAKE_MODULE_PATH}/utils.cmake)
-exec_program(${fpc_executable} ${EXECUTABLE_OUTPUT_PATH}
- ARGS ${noexecstack_flags} checkstack.pas
- OUTPUT_VARIABLE noout
- RETURN_VALUE testnoexecstack
- )
+find_package_or_fail(FreePascal)
-if(${testnoexecstack})
- set (noexecstack_flags "")
-endif(${testnoexecstack})
+#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}")
+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}")
@@ -133,116 +141,95 @@ if(APPLE)
endif()
#on OSX we need to provide the SDL_main() function when building as executable
- if(NOT BUILD_ENGINE_LIBRARY)
+ 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_dir "${SDL_LIBRARY}")
+ string(REGEX REPLACE "(.*);-.*" "\\1" sdl_library_only "${SDL_LIBRARY}")
#find libsdmain.a
- find_file(SDLMAIN_LIB libSDLMain.a PATHS ${sdl_dir}/Resources/)
+ 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
- set(engine_sources ${engine_sources} SDLmain)
+ list(APPEND engine_sources SDLmain)
set(SDLMAIN_LIB "${LIBRARY_OUTPUT_PATH}/libSDLmain.a")
endif()
- set(pascal_flags "-k${SDLMAIN_LIB}" ${pascal_flags})
+ list(APPEND pascal_flags "-k${SDLMAIN_LIB}")
endif()
-endif(APPLE)
-
-#PASCAL DETECTION SECTION
-string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" fpc_version "${fpc_output}")
-
-if(fpc_version)
- string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" fpc_vers_major "${fpc_version}")
- string(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" fpc_vers_minor "${fpc_version}")
- string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" fpc_vers_patch "${fpc_version}")
- message(STATUS "Found Freepascal: ${fpc_executable} (version ${fpc_vers_major}.${fpc_vers_minor})")
- math(EXPR fpc_version "${fpc_vers_major}*10000 + ${fpc_vers_minor}*100 + ${fpc_vers_patch}")
+ #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}")
+endif(APPLE)
- if(fpc_version LESS "020200")
- message(FATAL_ERROR "Minimum required version of FreePascal is 2.2.0")
- elseif(APPLE AND (fpc_version LESS "020600"))
- message(FATAL_ERROR "Minimum required version of FreePascal is 2.6.0 on Mac OS X")
- endif()
-else()
- message(FATAL_ERROR "No FreePascal compiler found!")
+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
+ get_filename_component(PNG_LIBRARY_DIR ${PNG_LIBRARIES} PATH)
+ list(APPEND pascal_flags "-dPNG_SCREENSHOTS" "-Fl${PNG_LIBRARY_DIR}" "-k-L${PNG_LIBRARY_DIR}")
endif()
-#DEPENDECIES AND EXECUTABLES SECTION
-if(NOT NOPNG)
- find_package(PNG)
- if(${PNG_FOUND})
- set(pascal_flags "-dPNG_SCREENSHOTS" ${pascal_flags})
- if(APPLE) # fpc png unit doesn't pull the library (see bug 21833)
- set(pascal_flags "-k${PNG_LIBRARY}" ${pascal_flags})
- 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()
- message(STATUS "Screenshots will be in BMP format because libpng was not found")
+ set(SAFE_BUILD_TOOL ${CMAKE_BUILD_TOOL})
endif()
-else()
- message(STATUS "Screenshots will be in BMP format per user request")
+ add_custom_target(ENGINECLEAN COMMAND ${SAFE_BUILD_TOOL} "clean" "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
+if(${FFMPEG_FOUND})
+ # 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)
-#this command is a workaround to some inlining issues present in older FreePascal versions and fixed in 2.6
-if(fpc_version LESS "020600")
- add_custom_target(ENGINECLEAN COMMAND ${CMAKE_BUILD_TOOL} "clean" "${PROJECT_BINARY_DIR}" "${hedgewars_SOURCE_DIR}/hedgewars")
-endif()
-
-
-if(NOT NOVIDEOREC)
- set(FFMPEG_FIND_QUIETLY true)
- find_package(FFMPEG)
- if(${FFMPEG_FOUND})
- include_directories(${FFMPEG_INCLUDE_DIR})
- set(pascal_flags "-dUSE_VIDEO_RECORDING" ${pascal_flags})
- IF (WIN32)
- # there are some problems with linking our avwrapper as static lib, so link it as shared
- add_library(avwrapper SHARED avwrapper.c)
- target_link_libraries(avwrapper ${FFMPEG_LIBRARIES})
- install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}avwrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" DESTINATION ${target_dir})
- ELSE()
- add_library(avwrapper STATIC avwrapper.c)
- set(pascal_flags "-k${FFMPEG_LIBAVCODEC}" "-k${FFMPEG_LIBAVFORMAT}" "-k${FFMPEG_LIBAVUTIL}" ${pascal_flags})
- ENDIF()
- if(fpc_version LESS "020600")
- add_dependencies(avwrapper ENGINECLEAN)
- endif()
+ #TODO: convert avwrapper to .pas unit so we can skip this step
+ include_directories(${FFMPEG_INCLUDE_DIR})
+ list(APPEND pascal_flags "-dUSE_VIDEO_RECORDING")
+ if(WIN32)
+ # there are some problems with linking our avwrapper as static lib, so link it as shared
+ add_library(avwrapper SHARED avwrapper.c)
+ target_link_libraries(avwrapper ${FFMPEG_LIBRARIES})
+ install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}avwrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" DESTINATION ${target_library_install_dir})
else()
- message(STATUS "Could NOT find FFMPEG/LibAV, video recording will be disabled")
+ add_library(avwrapper STATIC avwrapper.c)
endif()
-else()
- message(STATUS "Video recording disabled by user")
endif()
-set(fpc_flags ${noexecstack_flags} ${pascal_flags} ${hwengine_project})
-IF(NOT APPLE)
+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}${CMAKE_EXECUTABLE_SUFFIX}"
- COMMAND "${fpc_executable}"
- ARGS ${fpc_flags}
- MAIN_DEPENDENCY ${hwengine_project}
+ 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()
+else()
#these are the dependencies for building a universal binary on Mac OS X
foreach (build_arch ${powerpc_build} ${i386_build} ${x86_64_build})
- set(lipo_args_list "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}" ${lipo_args_list})
+ list(APPEND lipo_args_list "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}")
add_custom_command(OUTPUT "${EXECUTABLE_OUTPUT_PATH}/hwengine.${build_arch}"
- COMMAND "${fpc_executable}"
+ COMMAND "${FREEPASCAL_EXECUTABLE}"
ARGS ${fpc_flags} -ohwengine.${build_arch} -P${build_arch}
- MAIN_DEPENDENCY ${hwengine_project}
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}"
@@ -250,19 +237,32 @@ ELSE()
ARGS ${lipo_args_list} -create -output ${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}
DEPENDS ${lipo_args_list}
)
-ENDIF()
+endif()
-add_custom_target(${engine_output_name} ALL DEPENDS "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}${CMAKE_EXECUTABLE_SUFFIX}")
+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(${engine_output_name} lua)
+ 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((fpc_version LESS "020600") AND (NOVIDEOREC OR NOT ${FFMPEG_FOUND}))
- add_dependencies(${engine_output_name} ENGINECLEAN)
+if((FREEPASCAL_VERSION VERSION_LESS "2.6") AND (NOT ${FFMPEG_FOUND}))
+ add_dependencies(hwengine ENGINECLEAN)
endif()
-install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}${CMAKE_EXECUTABLE_SUFFIX}" DESTINATION ${target_dir})
+install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${engine_output_name}" DESTINATION ${destination_dir})
diff --git a/hedgewars/GSHandlers.inc b/hedgewars/GSHandlers.inc
index c915a40..03e4d3e 100644
--- a/hedgewars/GSHandlers.inc
+++ b/hedgewars/GSHandlers.inc
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ begin
sX:= dX / steps;
sY:= dY / steps;
end
-
+
else
begin
sX:= dX;
@@ -75,7 +75,7 @@ begin
end;
procedure makeHogsWorry(x, y: hwFloat; r: LongInt);
-var
+var
gi: PGear;
d: LongInt;
begin
@@ -89,23 +89,23 @@ begin
begin
if (CurrentHedgehog^.Gear = gi) then
PlaySoundV(sndOops, gi^.Hedgehog^.Team^.voicepack)
-
+
else
begin
- if (gi^.State and gstMoving) = 0 then
+ if ((gi^.State and gstMoving) = 0) and (gi^.Hedgehog^.Effects[heFrozen] = 0) then
begin
gi^.dX.isNegative:= X<gi^.X;
gi^.State := gi^.State or gstLoser;
end;
-
+
if d > r div 2 then
- PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack)
+ PlaySoundV(sndNooo, gi^.Hedgehog^.Team^.voicepack)
else
PlaySoundV(sndUhOh, gi^.Hedgehog^.Team^.voicepack);
end;
end;
end;
-
+
gi := gi^.NextGear
end;
end;
@@ -116,10 +116,10 @@ begin
DeleteCI(HH^.Gear);
if FollowGear = HH^.Gear then
FollowGear:= nil;
-
+
if lastGearByUID = HH^.Gear then
lastGearByUID := nil;
-
+
HH^.Gear^.Message:= HH^.Gear^.Message or gmRemoveFromList;
with HH^.Gear^ do
begin
@@ -165,7 +165,7 @@ procedure doStepDrowningGear(Gear: PGear);
////////////////////////////////////////////////////////////////////////////////
procedure doStepFallingGear(Gear: PGear);
-var
+var
isFalling: boolean;
//tmp: QWord;
tdX, tdY: hwFloat;
@@ -173,23 +173,17 @@ var
land: word;
begin
// clip velocity at 2 - over 1 per pixel, but really shouldn't cause many actual problems.
-{$IFNDEF WEB}
if Gear^.dX.Round > 2 then
Gear^.dX.QWordValue:= 8589934592;
if Gear^.dY.Round > 2 then
Gear^.dY.QWordValue:= 8589934592;
-{$ELSE}
- if Gear^.dX.Round > 2 then
- begin
- Gear^.dX.Round:= 2;
- Gear^.dX.Frac:= 0
- end;
- if Gear^.dY.QWordValue > 2 then
+
+ if (Gear^.State and gstSubmersible <> 0) and (hwRound(Gear^.Y) > cWaterLine) then
begin
- Gear^.dY.Round:= 2;
- Gear^.dY.Frac:= 0
+ Gear^.dX:= Gear^.dX * _0_999;
+ Gear^.dY:= Gear^.dY * _0_999
end;
-{$ENDIF}
+
Gear^.State := Gear^.State and (not gstCollision);
collV := 0;
collH := 0;
@@ -197,6 +191,7 @@ begin
tdY := Gear^.dY;
+
// might need some testing/adjustments - just to avoid projectiles to fly forever (accelerated by wind/skips)
if (hwRound(Gear^.X) < min(LAND_WIDTH div -2, -2048))
or (hwRound(Gear^.X) > max(LAND_WIDTH * 3 div 2, 6144)) then
@@ -220,16 +215,16 @@ begin
else if (Gear^.AdvBounce=1) and (TestCollisionYwithGear(Gear, 1) <> 0) then
collV := 1;
end
- else
+ else
begin // Gear^.dY.isNegative is false
land:= TestCollisionYwithGear(Gear, 1);
if land <> 0 then
begin
collV := 1;
isFalling := false;
- if land and lfIce <> 0 then
+ if land and lfIce <> 0 then
Gear^.dX := Gear^.dX * (_0_9 + Gear^.Friction * _0_1)
- else
+ else
Gear^.dX := Gear^.dX * Gear^.Friction;
Gear^.dY := - Gear^.dY * Gear^.Elasticity;
@@ -252,7 +247,7 @@ begin
Gear^.State := Gear^.State or gstCollision
end
else if (Gear^.AdvBounce=1) and TestCollisionXwithGear(Gear, -hwSign(Gear^.dX)) then
- collH := -hwSign(Gear^.dX);
+ collH := -hwSign(Gear^.dX);
//if Gear^.AdvBounce and (collV <>0) and (collH <> 0) and (hwSqr(tdX) + hwSqr(tdY) > _0_08) then
if (Gear^.AdvBounce=1) and (collV <>0) and (collH <> 0) and ((collV=-1)
or ((tdX.QWordValue + tdY.QWordValue) > _0_2.QWordValue)) then
@@ -285,20 +280,20 @@ begin
else
Gear^.State := Gear^.State or gstMoving;
- if (Gear^.nImpactSounds > 0) and
+ if (Gear^.nImpactSounds > 0) and
(Gear^.State and gstCollision <> 0) and
(((Gear^.Kind <> gtMine) and (Gear^.Damage <> 0)) or (Gear^.State and gstMoving <> 0)) and
(((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
- ((Gear^.Radius >= 3) and
+ ((Gear^.Radius >= 3) and
((Gear^.dX.QWordValue > _0_1.QWordValue) or (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepBomb(Gear: PGear);
-var
+var
i, x, y: LongInt;
- dX, dY: hwFloat;
+ dX, dY, gdX: hwFloat;
vg: PVisualGear;
begin
AllInactive := false;
@@ -307,7 +302,7 @@ begin
dec(Gear^.Timer);
if Gear^.Timer = 1000 then // might need adjustments
- case Gear^.Kind of
+ case Gear^.Kind of
gtGrenade: makeHogsWorry(Gear^.X, Gear^.Y, 50);
gtClusterBomb: makeHogsWorry(Gear^.X, Gear^.Y, 20);
gtWatermelon: makeHogsWorry(Gear^.X, Gear^.Y, 75);
@@ -331,35 +326,37 @@ begin
if Gear^.Timer = 0 then
begin
- case Gear^.Kind of
+ case Gear^.Kind of
gtGrenade: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
gtBall: doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 40, Gear^.Hedgehog, EXPLAutoSound);
- gtClusterBomb:
+ gtClusterBomb:
begin
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
+ gdX:= Gear^.dX;
doMakeExplosion(x, y, 20, Gear^.Hedgehog, EXPLAutoSound);
for i:= 0 to 4 do
begin
- dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5;
+ dX := rndSign(GetRandomf * _0_1) + gdX / 5;
dY := (GetRandomf - _3) * _0_08;
FollowGear := AddGear(x, y, gtCluster, 0, dX, dY, 25)
end
end;
- gtWatermelon:
+ gtWatermelon:
begin
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
+ gdX:= Gear^.dX;
doMakeExplosion(x, y, 75, Gear^.Hedgehog, EXPLAutoSound);
for i:= 0 to 5 do
begin
- dX := rndSign(GetRandomf * _0_1) + Gear^.dX / 5;
+ dX := rndSign(GetRandomf * _0_1) + gdX / 5;
dY := (GetRandomf - _1_5) * _0_3;
FollowGear:= AddGear(x, y, gtMelonPiece, 0, dX, dY, 75);
FollowGear^.DirAngle := i * 60
end
end;
- gtHellishBomb:
+ gtHellishBomb:
begin
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
@@ -375,7 +372,7 @@ begin
AddGear(x, y, gtFlame, 0, dX, -dY, 0)
end
else
- begin
+ begin
AddGear(x, y, gtFlame, 0, dX, dY, 0);
AddGear(x, y, gtFlame, gstTmpFlag, dX, -dY, 0)
end;
@@ -415,7 +412,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepMolotov(Gear: PGear);
-var
+var
s: Longword;
i, gX, gY: LongInt;
dX, dY: hwFloat;
@@ -427,15 +424,14 @@ begin
CalcRotationDirAngle(Gear);
// let's add some smoke depending on speed
- s:= max(32,152 - hwRound(Distance(Gear^.dX,Gear^.dY)*120))+random(10);
+ s:= max(32,152 - round((abs(hwFloat2FLoat(Gear^.dX))+abs(hwFloat2Float(Gear^.dY)))*120))+random(10);
if (GameTicks mod s) = 0 then
begin
// adjust angle to match the texture
if Gear^.dX.isNegative then
- i:= 130
- else
- i:= 50;
-
+ i:= 130
+ else i:= 50;
+
smoke:= AddVisualGear(hwRound(Gear^.X)-round(cos((Gear^.DirAngle+i) * pi / 180)*20), hwRound(Gear^.Y)-round(sin((Gear^.DirAngle+i) * pi / 180)*20), vgtSmoke);
if smoke <> nil then
smoke^.Scale:= 0.75;
@@ -502,7 +498,11 @@ begin
or (Gear^.Kind = gtBall) then
CalcRotationDirAngle(Gear)
else if (GameTicks and $1F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
end;
////////////////////////////////////////////////////////////////////////////////
@@ -519,24 +519,31 @@ begin
exit
end;
if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepSnowball(Gear: PGear);
var kick, i: LongInt;
particle: PVisualGear;
+ gdX, gdY: hwFloat;
begin
AllInactive := false;
if (GameFlags and gfMoreWind) = 0 then
Gear^.dX := Gear^.dX + cWindSpeed;
+ gdX := Gear^.dX;
+ gdY := Gear^.dY;
doStepFallingGear(Gear);
CalcRotationDirAngle(Gear);
if (Gear^.State and gstCollision) <> 0 then
begin
- kick:= hwRound((hwAbs(Gear^.dX)+hwAbs(Gear^.dY)) * _20);
- Gear^.dY.isNegative:= not Gear^.dY.isNegative;
- Gear^.dX.isNegative:= not Gear^.dX.isNegative;
+ kick:= hwRound((hwAbs(gdX)+hwAbs(gdY)) * _20);
+ Gear^.dX:= gdX;
+ Gear^.dY:= gdY;
AmmoShove(Gear, 0, kick);
for i:= 15 + kick div 10 downto 0 do
begin
@@ -614,6 +621,7 @@ We aren't using frametick right now, so just a waste of cycles.
else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
begin
lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
+ if lf = 0 then lf:= lfObject;
// If there's room below keep falling
if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
begin
@@ -677,7 +685,7 @@ if draw then
begin
rx:= rx div 2;ry:= ry div 2;
end;
- if Land[yy + py, xx + px] and $FF00 = 0 then
+ if Land[yy + py, xx + px] <= lfAllObjMask then
if gun then
begin
LandDirty[yy div 32, xx div 32]:= 1;
@@ -694,10 +702,10 @@ if draw then
end;
p:= @(p^[s^.pitch shr 2])
end;
-
- // Why is this here. For one thing, there's no test on +1 being safe.
+
+ // Why is this here. For one thing, there's no test on +1 being safe.
//Land[py, px+1]:= lfBasic;
-
+
if allpx then
UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w), true)
else
@@ -722,7 +730,7 @@ if move then
end;
Gear^.Pos:= 0;
Gear^.X:= int2hwFloat(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft);
- Gear^.Y:= int2hwFloat(LongInt(LAND_HEIGHT + GetRandom(50)) - 1325);
+ Gear^.Y:= int2hwFloat(LAND_HEIGHT + LongInt(GetRandom(50)) - 1325);
Gear^.State:= Gear^.State or gstInvisible;
end
end;
@@ -762,7 +770,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepBeeWork(Gear: PGear);
-var
+var
t: hwFloat;
gX,gY,i: LongInt;
uw, nuw: boolean;
@@ -877,7 +885,7 @@ begin
Gear^.Hedgehog^.Gear^.Message:= Gear^.Hedgehog^.Gear^.Message and (not gmAttack);
Gear^.Hedgehog^.Gear^.State:= Gear^.Hedgehog^.Gear^.State and (not gstAttacking);
AttackBar:= 0;
-
+
Gear^.SoundChannel := LoopSound(sndBee);
Gear^.Timer := 5000;
// save initial speed in otherwise unused Friction variable
@@ -899,7 +907,7 @@ begin
end;
procedure doStepShotgunShot(Gear: PGear);
-var
+var
i: LongWord;
shell: PVisualGear;
begin
@@ -975,7 +983,7 @@ begin
// Bullet trail
VGear := AddVisualGear(hwRound(ox), hwRound(oy), vgtLineTrail);
-
+
if VGear <> nil then
begin
VGear^.X:= hwFloat2Float(ox);
@@ -998,7 +1006,7 @@ begin
end;
procedure doStepBulletWork(Gear: PGear);
-var
+var
i, x, y: LongWord;
oX, oY: hwFloat;
VGear: PVisualGear;
@@ -1013,11 +1021,11 @@ begin
Gear^.Y := Gear^.Y + Gear^.dY;
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
-
+
if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] <> 0) then
inc(Gear^.Damage);
// let's interrupt before a collision to give portals a chance to catch the bullet
- if (Gear^.Damage = 1) and (Gear^.Tag = 0) and (Land[y, x] > 255) then
+ if (Gear^.Damage = 1) and (Gear^.Tag = 0) and not(CheckLandValue(x, y, lfLandMask)) then
begin
Gear^.Tag := 1;
Gear^.Damage := 0;
@@ -1035,7 +1043,7 @@ begin
else
AmmoShove(Gear, Gear^.Timer, 20);
CheckGearDrowning(Gear);
- dec(i)
+ dec(i)
until (i = 0) or (Gear^.Damage > Gear^.Health) or ((Gear^.State and gstDrowning) <> 0);
if Gear^.Damage > 0 then
@@ -1063,7 +1071,7 @@ begin
cLaserSighting := false;
if (Ammoz[Gear^.AmmoType].Ammo.NumPerTurn <= CurrentHedgehog^.MultiShootAttacks) and ((GameFlags and gfArtillery) = 0) then
cArtillery := false;
-
+
// Bullet Hit
if (hwRound(Gear^.X) and LAND_WIDTH_MASK = 0) and (hwRound(Gear^.Y) and LAND_HEIGHT_MASK = 0) then
begin
@@ -1073,7 +1081,7 @@ begin
VGear^.Angle := DxDy2Angle(-Gear^.dX, Gear^.dY);
end;
end;
-
+
spawnBulletTrail(Gear);
Gear^.doStep := @doStepShotIdle
end;
@@ -1089,7 +1097,7 @@ begin
end;
procedure doStepSniperRifleShot(Gear: PGear);
-var
+var
HHGear: PGear;
shell: PVisualGear;
begin
@@ -1120,7 +1128,7 @@ begin
Gear^.dY := -AngleCos(HHGear^.Angle) * _0_5;
PlaySound(sndGun);
// add 3 initial steps to avoid problem with ammoshove related to calculation of radius + 1 radius as gear widths, and also just weird angles
- Gear^.X := Gear^.X + Gear^.dX * 3;
+ Gear^.X := Gear^.X + Gear^.dX * 3;
Gear^.Y := Gear^.Y + Gear^.dY * 3;
Gear^.doStep := @doStepBulletWork;
end
@@ -1149,16 +1157,16 @@ procedure doStepActionTimer(Gear: PGear);
begin
dec(Gear^.Timer);
case Gear^.Kind of
- gtATStartGame:
- begin
+ gtATStartGame:
+ begin
AllInactive := false;
if Gear^.Timer = 0 then
begin
AddCaption(trmsg[sidStartFight], cWhiteColor, capgrpGameState);
end
- end;
- gtATFinishGame:
- begin
+ end;
+ gtATFinishGame:
+ begin
AllInactive := false;
if Gear^.Timer = 1000 then
begin
@@ -1172,15 +1180,15 @@ case Gear^.Kind of
SendIPC(_S'q');
GameState := gsExit
end
+ end;
end;
-end;
if Gear^.Timer = 0 then
DeleteGear(Gear)
end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepPickHammerWork(Gear: PGear);
-var
+var
i, ei, x, y: LongInt;
HHGear: PGear;
begin
@@ -1239,7 +1247,7 @@ begin
end
else
begin
- if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), $FF00) then
+ if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfLandMask) then
begin
Gear^.dY := Gear^.dY + cGravity;
Gear^.Y := Gear^.Y + Gear^.dY
@@ -1249,7 +1257,7 @@ begin
end;
Gear^.X := Gear^.X + HHGear^.dX;
- if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, $FF00) then
+ if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, lfLandMask) then
begin
HHGear^.X := Gear^.X;
HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius)
@@ -1271,7 +1279,7 @@ begin
end;
procedure doStepPickHammer(Gear: PGear);
-var
+var
i, y: LongInt;
ar: TRangeArray;
HHGear: PGear;
@@ -1298,11 +1306,11 @@ begin
end;
////////////////////////////////////////////////////////////////////////////////
-var
+var
BTPrevAngle, BTSteps: LongInt;
procedure doStepBlowTorchWork(Gear: PGear);
-var
+var
HHGear: PGear;
b: boolean;
prevX: LongInt;
@@ -1311,7 +1319,7 @@ begin
dec(Gear^.Timer);
if ((GameFlags and gfInfAttack) <> 0) and (TurnTimeLeft > 0) then
dec(TurnTimeLeft);
-
+
HHGear := Gear^.Hedgehog^.Gear;
HedgehogChAngle(HHGear);
@@ -1392,12 +1400,20 @@ begin
end;
procedure doStepBlowTorch(Gear: PGear);
-var
+var
HHGear: PGear;
begin
BTPrevAngle := High(LongInt);
BTSteps := 0;
HHGear := Gear^.Hedgehog^.Gear;
+ HedgehogChAngle(HHGear);
+ Gear^.dX := SignAs(AngleSin(HHGear^.Angle) * _0_5, Gear^.dX);
+ Gear^.dY := AngleCos(HHGear^.Angle) * ( - _0_5);
+ DrawTunnel(HHGear^.X,
+ HHGear^.Y + Gear^.dY * cHHRadius - _1 -
+ ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
+ Gear^.dX, Gear^.dY,
+ cHHStepTicks, cHHRadius * 2 + 7);
HHGear^.Message := 0;
HHGear^.State := HHGear^.State or gstNotKickable;
Gear^.doStep := @doStepBlowTorchWork
@@ -1406,7 +1422,9 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepMine(Gear: PGear);
var vg: PVisualGear;
+ dxdy: hwFloat;
begin
+ if Gear^.Health = 0 then dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
if (Gear^.State and gstMoving) <> 0 then
begin
DeleteCI(Gear);
@@ -1424,15 +1442,9 @@ begin
doStepFallingGear(Gear);
if (Gear^.Health = 0) then
begin
- if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
- inc(Gear^.Damage, hwRound(Gear^.dY * _70))
- else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
- inc(Gear^.Damage, hwRound(Gear^.dX * _70))
- else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
- inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
- else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
- inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
-
+ if (dxdy > _0_4) and (Gear^.State and gstCollision <> 0) then
+ inc(Gear^.Damage, hwRound(dxdy * _50));
+
if ((GameTicks and $FF) = 0) and (Gear^.Damage > random(30)) then
begin
vg:= AddVisualGear(hwRound(Gear^.X) - 4 + Random(8), hwRound(Gear^.Y) - 4 - Random(4), vgtSmoke);
@@ -1494,9 +1506,9 @@ end;
procedure doStepSMine(Gear: PGear);
begin
// TODO: do real calculation?
- if TestCollisionXwithGear(Gear, 2)
- or (TestCollisionYwithGear(Gear, -2) <> 0)
- or TestCollisionXwithGear(Gear, -2)
+ if TestCollisionXwithGear(Gear, 2)
+ or (TestCollisionYwithGear(Gear, -2) <> 0)
+ or TestCollisionXwithGear(Gear, -2)
or (TestCollisionYwithGear(Gear, 2) <> 0) then
begin
if (not isZero(Gear^.dX)) or (not isZero(Gear^.dY)) then
@@ -1565,46 +1577,38 @@ end;
///////////////////////////////////////////////////////////////////////////////
-(*
-TODO
-Increase damage as barrel smokes?
-Try tweaking friction some more
-*)
procedure doStepRollingBarrel(Gear: PGear);
-var
+var
i: LongInt;
particle: PVisualGear;
+ dxdy: hwFloat;
begin
if (Gear^.dY.QWordValue = 0) and (Gear^.dY.QWordValue = 0) and (TestCollisionYwithGear(Gear, 1) = 0) then
SetLittle(Gear^.dY);
Gear^.State := Gear^.State or gstAnimation;
-
+ if Gear^.Health < cBarrelHealth then Gear^.State:= Gear^.State and not gstFrozen;
+
if ((Gear^.dX.QWordValue <> 0)
or (Gear^.dY.QWordValue <> 0)) then
begin
DeleteCI(Gear);
AllInactive := false;
- if not Gear^.dY.isNegative and (Gear^.dY > _0_2) and (TestCollisionYwithGear(Gear, 1) <> 0) then
+ dxdy:= hwAbs(Gear^.dX)+hwAbs(Gear^.dY);
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstCollision <> 0) and(dxdy > _0_4) then
begin
- Gear^.State := Gear^.State or gsttmpFlag;
- inc(Gear^.Damage, hwRound(Gear^.dY * _70));
- for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
+ if (TestCollisionYwithGear(Gear, 1) <> 0) then
begin
- particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
- if particle <> nil then
- particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
- end
- end
- else if not Gear^.dX.isNegative and (Gear^.dX > _0_2) and TestCollisionXwithGear(Gear, 1) then
- inc(Gear^.Damage, hwRound(Gear^.dX * _70))
-
- else if Gear^.dY.isNegative and (Gear^.dY < -_0_2) and (TestCollisionYwithGear(Gear, -1) <> 0) then
- inc(Gear^.Damage, hwRound(Gear^.dY * -_70))
-
- else if Gear^.dX.isNegative and (Gear^.dX < -_0_2) and TestCollisionXwithGear(Gear, -1) then
- inc(Gear^.Damage, hwRound(Gear^.dX * -_70));
-
- doStepFallingGear(Gear);
+ Gear^.State := Gear^.State or gsttmpFlag;
+ for i:= min(12, hwRound(dxdy*_10)) downto 0 do
+ begin
+ particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12,vgtDust);
+ if particle <> nil then
+ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480)
+ end
+ end;
+ inc(Gear^.Damage, hwRound(dxdy * _50))
+ end;
CalcRotationDirAngle(Gear);
//CheckGearDrowning(Gear)
end
@@ -1643,23 +1647,19 @@ Attempt to make a barrel knock itself over an edge. Would need more checks to a
dec(Gear^.Health, Gear^.Damage);
Gear^.Damage := 0;
if Gear^.Health <= 0 then
- Gear^.doStep := @doStepCase;
- // Hand off to doStepCase for the explosion
-
+ doStepCase(Gear);
end;
procedure doStepCase(Gear: PGear);
-var
+var
i, x, y: LongInt;
k: TGearType;
- exBoom: boolean;
dX, dY: HWFloat;
hog: PHedgehog;
sparkles: PVisualGear;
gi: PGear;
begin
k := Gear^.Kind;
- exBoom := false;
if (Gear^.Message and gmDestroy) > 0 then
begin
@@ -1672,26 +1672,58 @@ begin
Gear^.Message := Gear^.Message and (not (gmLJump or gmHJump));
exit
end;
+ if (k = gtExplosives) and (Gear^.Health < cBarrelHealth) then Gear^.State:= Gear^.State and not gstFrozen;
+
+ if ((k <> gtExplosives) and (Gear^.Damage > 0)) or ((k = gtExplosives) and (Gear^.Health<=0)) then
+ begin
+ x := hwRound(Gear^.X);
+ y := hwRound(Gear^.Y);
+ hog:= Gear^.Hedgehog;
+
+ DeleteGear(Gear);
+ // <-- delete gear!
+
+ if k = gtCase then
+ begin
+ doMakeExplosion(x, y, 25, hog, EXPLAutoSound);
+ for i:= 0 to 63 do
+ AddGear(x, y, gtFlame, 0, _0, _0, 0);
+ end
+ else if k = gtExplosives then
+ begin
+ doMakeExplosion(x, y, 75, hog, EXPLAutoSound);
+ for i:= 0 to 31 do
+ begin
+ dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1);
+ dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1);
+ AddGear(x, y, gtFlame, 0, dX, dY, 0);
+ AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
+ end
+ end;
+ exit
+ end;
if k = gtExplosives then
begin
//if V > _0_03 then Gear^.State:= Gear^.State or gstAnimation;
if (hwAbs(Gear^.dX) > _0_15) or ((hwAbs(Gear^.dY) > _0_15) and (hwAbs(Gear^.dX) > _0_02)) then
+ begin
Gear^.doStep := @doStepRollingBarrel;
+ exit;
+ end
+ else Gear^.dX:= _0;
- if (Gear^.Health > 0) and ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
+ if ((Gear^.Health * 100 div cBarrelHealth) < random(90)) and ((GameTicks and $FF) = 0) then
if (cBarrelHealth div Gear^.Health) > 2 then
AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmoke)
- else
- AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
+ else
+ AddVisualGear(hwRound(Gear^.X) - 16 + Random(32), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
dec(Gear^.Health, Gear^.Damage);
Gear^.Damage := 0;
- if Gear^.Health <= 0 then
- exBoom := true;
end
else
- begin
- if (Gear^.Pos <> posCaseHealth) and (GameTicks and $3FF = 0) then // stir it up every second or so
+ begin
+ if (Gear^.Pos <> posCaseHealth) and (GameTicks and $1FFF = 0) then // stir 'em up periodically
begin
gi := GearsList;
while gi <> nil do
@@ -1727,46 +1759,18 @@ begin
sparkles^.dX:= 0;
sparkles^.dY:= 0;
sparkles^.Angle:= 270;
- if Gear^.Tag = 1 then
+ if Gear^.Tag = 1 then
sparkles^.Tint:= $3744D7FF
else sparkles^.Tint:= $FAB22CFF
end;
end;
- if Gear^.Timer < 1000 then
+ if Gear^.Timer < 1000 then
begin
AllInactive:= false;
exit
end
end;
- if (Gear^.Damage > 0) or exBoom then
- begin
- x := hwRound(Gear^.X);
- y := hwRound(Gear^.Y);
- hog:= Gear^.Hedgehog;
-
- DeleteGear(Gear);
- // <-- delete gear!
-
- if k = gtCase then
- begin
- doMakeExplosion(x, y, 25, hog, EXPLAutoSound);
- for i:= 0 to 63 do
- AddGear(x, y, gtFlame, 0, _0, _0, 0);
- end
- else if k = gtExplosives then
- begin
- doMakeExplosion(x, y, 75, hog, EXPLAutoSound);
- for i:= 0 to 31 do
- begin
- dX := AngleCos(i * 64) * _0_5 * (getrandomf + _1);
- dY := AngleSin(i * 64) * _0_5 * (getrandomf + _1);
- AddGear(x, y, gtFlame, 0, dX, dY, 0);
- AddGear(x, y, gtFlame, gstTmpFlag, -dX, -dY, 0);
- end
- end;
- exit
- end;
if (Gear^.dY.QWordValue <> 0)
or (TestCollisionYwithGear(Gear, 1) = 0) then
@@ -1781,7 +1785,7 @@ begin
Gear^.Y := Gear^.Y + Gear^.dY;
if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then
- SetAllHHToActive;
+ SetAllHHToActive(false);
if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
begin
@@ -1791,7 +1795,7 @@ begin
if Gear^.dY > _0_2 then
for i:= min(12, hwRound(Gear^.dY*_10)) downto 0 do
AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
-
+
Gear^.dY := - Gear^.dY * Gear^.Elasticity;
if Gear^.dY > - _0_001 then
Gear^.dY := _0
@@ -1845,7 +1849,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepShover(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -1861,7 +1865,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepWhip(Gear: PGear);
-var
+var
HHGear: PGear;
i: LongInt;
begin
@@ -1883,7 +1887,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepFlame(Gear: PGear);
-var
+var
gX,gY,i: LongInt;
sticky: Boolean;
vgt: PVisualGear;
@@ -1910,10 +1914,10 @@ begin
if Gear^.dX.QWordValue > _0_01.QWordValue then
Gear^.dX := Gear^.dX * _0_995;
-
+
Gear^.dY := Gear^.dY + cGravity;
// if sticky then Gear^.dY := Gear^.dY + cGravity;
-
+
if Gear^.dY.QWordValue > _0_2.QWordValue then
Gear^.dY := Gear^.dY * _0_995;
@@ -1974,13 +1978,13 @@ begin
Gear^.Radius := 1;
end
else if ((GameTicks and $3) = 3) then
- doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
+ doMakeExplosion(gX, gY, 8, Gear^.Hedgehog, 0);//, EXPLNoDamage);
//DrawExplosion(gX, gY, 4);
-
+
if ((GameTicks and $7) = 0) and (Random(2) = 0) then
for i:= Random(2) downto 0 do
AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
-
+
if Gear^.Health > 0 then
dec(Gear^.Health);
Gear^.Timer := 450 - Gear^.Tag * 8
@@ -2023,7 +2027,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepFirePunchWork(Gear: PGear);
-var
+var
HHGear: PGear;
begin
AllInactive := false;
@@ -2060,7 +2064,7 @@ begin
end;
procedure doStepFirePunch(Gear: PGear);
-var
+var
HHGear: PGear;
begin
AllInactive := false;
@@ -2083,7 +2087,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepParachuteWork(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -2112,13 +2116,13 @@ begin
if (Gear^.Message and gmLeft) <> 0 then
HHGear^.X := HHGear^.X - cMaxWindSpeed * 80
-
+
else if (Gear^.Message and gmRight) <> 0 then
HHGear^.X := HHGear^.X + cMaxWindSpeed * 80;
-
+
if (Gear^.Message and gmUp) <> 0 then
HHGear^.Y := HHGear^.Y - cGravity * 40
-
+
else if (Gear^.Message and gmDown) <> 0 then
HHGear^.Y := HHGear^.Y + cGravity * 40;
@@ -2131,7 +2135,7 @@ begin
end;
procedure doStepParachute(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -2158,7 +2162,7 @@ begin
if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
begin
dec(Gear^.Health);
- case Gear^.State of
+ case Gear^.State of
0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine, 0, cBombsSpeed * Gear^.Tag, _0, 0);
2: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtNapalmBomb, 0, cBombsSpeed * Gear^.Tag, _0, 0);
@@ -2201,7 +2205,7 @@ begin
// calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
if (Gear^.State = 2) then
- Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
+ Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900
// calcs for regular falling gears
else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
@@ -2223,7 +2227,9 @@ begin
begin
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, Gear^.Hedgehog, EXPLAutoSound);
DeleteGear(Gear);
- performRumble();
+ with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
exit
end;
if (GameTicks and $3F) = 0 then
@@ -2233,7 +2239,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepGirder(Gear: PGear);
-var
+var
HHGear: PGear;
x, y, tx, ty: hwFloat;
begin
@@ -2255,7 +2261,7 @@ begin
isCursorVisible := true;
DeleteGear(Gear)
end
- else
+ else
begin
PlaySound(sndPlaced);
DeleteGear(Gear);
@@ -2268,7 +2274,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepTeleportAfter(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -2302,7 +2308,7 @@ begin
end;
procedure doStepTeleport(Gear: PGear);
-var
+var
HHGear: PGear;
begin
AllInactive := false;
@@ -2343,7 +2349,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepSwitcherWork(Gear: PGear);
-var
+var
HHGear: PGear;
hedgehog: PHedgehog;
State: Longword;
@@ -2378,10 +2384,12 @@ begin
repeat
CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
- until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
+ until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and
+ (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
- AmmoMenuInvalidated:= true;
+ AmmoMenuInvalidated:= true;
HHGear := CurrentHedgehog^.Gear;
HHGear^.State := State;
@@ -2395,7 +2403,7 @@ begin
end;
procedure doStepSwitcher(Gear: PGear);
-var
+var
HHGear: PGear;
begin
Gear^.doStep := @doStepSwitcherWork;
@@ -2411,26 +2419,27 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepMortar(Gear: PGear);
-var
- dX, dY: hwFloat;
+var
+ dX, dY, gdX, gdY: hwFloat;
i: LongInt;
- dxn, dyn: boolean;
begin
AllInactive := false;
- dxn := Gear^.dX.isNegative;
- dyn := Gear^.dY.isNegative;
+ gdX := Gear^.dX;
+ gdY := Gear^.dY;
doStepFallingGear(Gear);
if (Gear^.State and gstCollision) <> 0 then
begin
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLAutoSound);
+ gdX.isNegative := not gdX.isNegative;
+ gdY.isNegative := not gdY.isNegative;
+ gdX:= gdX*_0_2;
+ gdY:= gdY*_0_2;
- Gear^.dX.isNegative := not dxn;
- Gear^.dY.isNegative := not dyn;
for i:= 0 to 4 do
begin
- dX := Gear^.dX + (GetRandomf - _0_5) * _0_03;
- dY := Gear^.dY + (GetRandomf - _0_5) * _0_03;
+ dX := gdX + rndSign(GetRandomf) * _0_03;
+ dY := gdY + rndSign(GetRandomf) * _0_03;
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtCluster, 0, dX, dY, 25);
end;
@@ -2439,12 +2448,16 @@ begin
end;
if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end
end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepKamikazeWork(Gear: PGear);
-var
+var
i: LongWord;
HHGear: PGear;
sparkles: PVisualGear;
@@ -2456,6 +2469,12 @@ begin
Gear^.AdvBounce:= 1;
HHGear := Gear^.Hedgehog^.Gear;
+ if HHGear = nil then
+ begin
+ DeleteGear(Gear);
+ exit
+ end;
+
HHGear^.State := HHGear^.State or gstNoDamage;
DeleteCI(HHGear);
@@ -2473,7 +2492,7 @@ begin
i := 2;
repeat
-
+
Gear^.X := Gear^.X + HHGear^.dX;
Gear^.Y := Gear^.Y + HHGear^.dY;
HHGear^.X := Gear^.X;
@@ -2556,7 +2575,7 @@ begin
end;
procedure doStepKamikaze(Gear: PGear);
-var
+var
HHGear: PGear;
begin
AllInactive := false;
@@ -2577,7 +2596,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
const cakeh = 27;
-var
+var
CakePoints: array[0..Pred(cakeh)] of record
x, y: hwFloat;
end;
@@ -2597,7 +2616,7 @@ begin
end;
procedure doStepCakeDown(Gear: PGear);
-var
+var
gi: PGear;
dmg, dmgBase: LongInt;
fX, fY, tdX, tdY: hwFloat;
@@ -2683,7 +2702,7 @@ begin
end;
procedure doStepCakeUp(Gear: PGear);
-var
+var
i: Longword;
begin
AllInactive := false;
@@ -2723,14 +2742,14 @@ begin
end;
procedure doStepCake(Gear: PGear);
-var
+var
HHGear: PGear;
begin
AllInactive := false;
HHGear := Gear^.Hedgehog^.Gear;
HHGear^.Message := HHGear^.Message and (not gmAttack);
- Gear^.CollisionMask:= $FF7F;
+ Gear^.CollisionMask:= lfNotCurrentMask;
FollowGear := Gear;
@@ -2827,7 +2846,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepWaterUp(Gear: PGear);
-var
+var
i: LongWord;
begin
if (Gear^.Tag = 0)
@@ -2861,34 +2880,36 @@ procedure doStepDrill(Gear: PGear);
forward;
procedure doStepDrillDrilling(Gear: PGear);
-var
+var
t: PGearArray;
- ox, oy: hwFloat;
+ tempColl: Word;
begin
AllInactive := false;
+ if (Gear^.Timer > 0) and (Gear^.Timer mod 10 <> 0) then
+ begin
+ dec(Gear^.Timer);
+ exit;
+ end;
- if (Gear^.Timer > 0) and ((Gear^.Timer mod 10) = 0) then
- begin
- ox := Gear^.X;
- oy := Gear^.Y;
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + Gear^.dY;
- DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 2, 6);
- if (Gear^.Timer mod 30) = 0 then
- AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust);
- if (CheckGearDrowning(Gear)) then
- begin
- StopSoundChan(Gear^.SoundChannel);
- exit
- end
+ DrawTunnel(Gear^.X, Gear^.Y, Gear^.dX, Gear^.dY, 2, 6);
+ Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + Gear^.dY;
+ if (Gear^.Timer mod 30) = 0 then
+ AddVisualGear(hwRound(Gear^.X + _20 * Gear^.dX), hwRound(Gear^.Y + _20 * Gear^.dY), vgtDust);
+ if (CheckGearDrowning(Gear)) then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ exit
end;
- if GameTicks > Gear^.FlightTime then
+ tempColl:= Gear^.CollisionMask;
+ Gear^.CollisionMask:= $007F;
+ if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
t := CheckGearsCollision(Gear)
-
else t := nil;
+ Gear^.CollisionMask:= tempColl;
//fixes drill not exploding when touching HH bug
-
+
if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
or ( ((Gear^.State and gsttmpFlag) = 0) and (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))))
// CheckLandValue returns true if the type isn't matched
@@ -2903,7 +2924,7 @@ begin
DeleteGear(Gear);
exit
end
-
+
else if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) = 0) and (not TestCollisionXWithGear(Gear, hwSign(Gear^.dX))) then
begin
StopSoundChan(Gear^.SoundChannel);
@@ -2915,7 +2936,7 @@ begin
end;
procedure doStepDrill(Gear: PGear);
-var
+var
t: PGearArray;
oldDx, oldDy: hwFloat;
t2: hwFloat;
@@ -2931,7 +2952,11 @@ begin
doStepFallingGear(Gear);
if (GameTicks and $3F) = 0 then
- AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
+ begin
+ if hwRound(Gear^.Y) > cWaterLine then
+ AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtBubble)
+ else AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace)
+ end;
if ((Gear^.State and gstCollision) <> 0) then
begin
@@ -2939,7 +2964,7 @@ begin
Gear^.dX := oldDx;
Gear^.dY := oldDy;
- if GameTicks > Gear^.FlightTime then
+ if GameTicks > Gear^.FlightTime then
t := CheckGearsCollision(Gear)
else
t := nil;
@@ -2950,7 +2975,7 @@ begin
Gear^.dX := Gear^.dX * t2;
Gear^.dY := Gear^.dY * t2;
end
-
+
else if (t <> nil) then
begin
//explode right on contact with HH
@@ -2964,14 +2989,14 @@ begin
Gear^.SoundChannel := LoopSound(sndDrillRocket);
Gear^.doStep := @doStepDrillDrilling;
-
+
if (Gear^.State and gsttmpFlag) <> 0 then
gear^.RenderTimer:= true;
if Gear^.Timer > 0 then dec(Gear^.Timer)
end
else if ((Gear^.State and gsttmpFlag) <> 0) and (Gear^.Tag <> 0) then
begin
- if Gear^.Timer > 0 then
+ if Gear^.Timer > 0 then
dec(Gear^.Timer)
else
begin
@@ -2983,7 +3008,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepBallgunWork(Gear: PGear);
-var
+var
HHGear, ball: PGear;
rx, ry: hwFloat;
gX, gY: LongInt;
@@ -3000,7 +3025,7 @@ begin
ry := rndSign(getRandomf * _0_1);
ball:= AddGear(gx, gy, gtBall, 0, SignAs(AngleSin(HHGear^.Angle) * _0_8, HHGear^.dX) + rx, AngleCos(HHGear^.Angle) * ( - _0_8) + ry, 0);
- ball^.CollisionMask:= $FF7F;
+ ball^.CollisionMask:= lfNotCurrentMask;
PlaySound(sndGun);
end;
@@ -3013,7 +3038,7 @@ begin
end;
procedure doStepBallgun(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -3026,7 +3051,7 @@ end;
procedure doStepRCPlaneWork(Gear: PGear);
const cAngleSpeed = 3;
-var
+var
HHGear: PGear;
i: LongInt;
dX, dY: hwFloat;
@@ -3135,7 +3160,7 @@ begin
begin
if TagTurnTimeLeft = 0 then
TagTurnTimeLeft:= TurnTimeLeft;
-
+
TurnTimeLeft:= 14 * 125;
end;
@@ -3145,7 +3170,7 @@ begin
end;
procedure doStepRCPlane(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -3153,7 +3178,7 @@ begin
HHGear^.State := HHGear^.State or gstNotKickable;
Gear^.Angle := HHGear^.Angle;
Gear^.Tag := hwSign(HHGear^.dX);
-
+
if HHGear^.dX.isNegative then
Gear^.Angle := 4096 - Gear^.Angle;
Gear^.doStep := @doStepRCPlaneWork
@@ -3161,7 +3186,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepJetpackWork(Gear: PGear);
-var
+var
HHGear: PGear;
fuel, i: LongInt;
move: hwFloat;
@@ -3181,10 +3206,11 @@ begin
move:= _0_02;
fuel:= 5;
end;*)
-
- if Gear^.Health > 0 then
+ if HHGear^.Message and gmPrecise <> 0 then
+ HedgehogChAngle(HHGear)
+ else if Gear^.Health > 0 then
begin
- if (HHGear^.Message and gmUp) <> 0 then
+ if HHGear^.Message and gmUp <> 0 then
begin
if (not HHGear^.dY.isNegative) or (HHGear^.Y > -_256) then
begin
@@ -3240,9 +3266,9 @@ begin
if Gear^.Health < 0 then
Gear^.Health := 0;
-
+
i:= Gear^.Health div 20;
-
+
if (i <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
begin
Gear^.Damage:= i;
@@ -3251,10 +3277,12 @@ begin
Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(i) + '%', cWhiteColor, fntSmall)
end;
- if HHGear^.Message and (gmAttack or gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
+ if (HHGear^.Message and (gmAttack or gmUp or gmLeft or gmRight) <> 0) and
+ (HHGear^.Message and gmPrecise = 0) then
Gear^.State := Gear^.State and (not gsttmpFlag);
-
- HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
+
+ if HHGear^.Message and gmPrecise = 0 then
+ HHGear^.Message := HHGear^.Message and (not (gmUp or gmLeft or gmRight));
HHGear^.State := HHGear^.State or gstMoving;
Gear^.X := HHGear^.X;
@@ -3263,7 +3291,7 @@ begin
if not isUnderWater and hasBorder and ((HHGear^.X < _0)
or (hwRound(HHGear^.X) > LAND_WIDTH)) then
HHGear^.dY.isNegative:= false;
-
+
if ((Gear^.State and gsttmpFlag) = 0)
or (HHGear^.dY < _0) then
doStepHedgehogMoving(HHGear);
@@ -3271,7 +3299,7 @@ begin
if // (Gear^.Health = 0)
(HHGear^.Damage <> 0)
//or CheckGearDrowning(HHGear)
- or (cWaterLine + 512 < hwRound(HHGear^.Y))
+ or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
or (TurnTimeLeft = 0)
// allow brief ground touches - to be fair on this, might need another counter
or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
@@ -3295,7 +3323,7 @@ begin
end;
procedure doStepJetpack(Gear: PGear);
-var
+var
HHGear: PGear;
begin
Gear^.Pos:= 0;
@@ -3308,7 +3336,7 @@ begin
begin
State := State and (not gstAttacking);
Message := Message and (not (gmAttack or gmUp or gmPrecise or gmLeft or gmRight));
-
+
if (dY < _0_1) and (dY > -_0_1) then
begin
Gear^.State := Gear^.State or gsttmpFlag;
@@ -3331,13 +3359,13 @@ begin
end;
procedure doStepBirdyFly(Gear: PGear);
-var
+var
HHGear: PGear;
fuel, i: LongInt;
move: hwFloat;
begin
HHGear := Gear^.Hedgehog^.Gear;
- if HHGear = nil then
+ if HHGear = nil then
begin
DeleteGear(Gear);
exit
@@ -3361,11 +3389,11 @@ begin
if (not HHGear^.dY.isNegative)
or (HHGear^.Y > -_256) then
HHGear^.dY := HHGear^.dY - move;
-
+
dec(Gear^.Health, fuel);
Gear^.MsgParam := Gear^.MsgParam or gmUp;
end;
-
+
if (HHGear^.Message and gmLeft) <> 0 then move.isNegative := true;
if (HHGear^.Message and (gmLeft or gmRight)) <> 0 then
begin
@@ -3376,7 +3404,7 @@ begin
if Gear^.Health < 0 then
Gear^.Health := 0;
-
+
if ((GameTicks and $FF) = 0) and (Gear^.Health < 500) then
for i:= ((500-Gear^.Health) div 250) downto 0 do
AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtFeather);
@@ -3394,7 +3422,7 @@ begin
if HHGear^.Message and (gmUp or gmPrecise or gmLeft or gmRight) <> 0 then
Gear^.State := Gear^.State and (not gsttmpFlag);
-
+
HHGear^.Message := HHGear^.Message and (not (gmUp or gmPrecise or gmLeft or gmRight));
HHGear^.State := HHGear^.State or gstMoving;
@@ -3437,7 +3465,7 @@ begin
end;
procedure doStepBirdyDescend(Gear: PGear);
-var
+var
HHGear: PGear;
begin
if Gear^.Timer > 0 then
@@ -3478,12 +3506,12 @@ begin
end;
procedure doStepBirdy(Gear: PGear);
-var
+var
HHGear: PGear;
begin
gear^.State := gear^.State or gstAnimation and (not gstTmpFlag);
Gear^.doStep := @doStepBirdyAppear;
-
+
if CurrentHedgehog = nil then
begin
DeleteGear(Gear);
@@ -3508,7 +3536,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepEggWork(Gear: PGear);
-var
+var
vg: PVisualGear;
i: LongInt;
begin
@@ -3549,18 +3577,18 @@ begin
if (CurAmmoType = amPortalGun) then
begin
CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and (not gmSwitch);
-
+
CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
if CurWeapon^.Pos <> 0 then
CurWeapon^.Pos := 0
-
+
else
CurWeapon^.Pos := 1;
end;
end;
procedure doStepPortal(Gear: PGear);
-var
+var
iterator, conPortal: PGear;
s, r, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed,
resetx, resety, resetdx, resetdy: hwFloat;
@@ -3570,7 +3598,7 @@ begin
doPortalColorSwitch();
// destroy portal if ground it was attached too is gone
- if ((Land[hwRound(Gear^.Y), hwRound(Gear^.X)] and $FF00) = 0)
+ if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
or (Gear^.Timer < 1)
or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
or (hwRound(Gear^.Y) > cWaterLine) then
@@ -3610,7 +3638,7 @@ begin
break;
// don't port portals or other gear that wouldn't make sense
- if (iterator^.Kind in [gtPortal, gtRope, gtAirAttack])
+ if (iterator^.Kind in [gtPortal, gtRope, gtAirAttack, gtIceGun])
or (iterator^.PortalCounter > 32) then
continue;
@@ -3670,7 +3698,11 @@ begin
// wow! good candidate there, let's see if the distance and direction is okay!
if hasdxy then
begin
- s := r / Distance(iterator^.dX, iterator^.dY);
+ s := Distance(iterator^.dX, iterator^.dY);
+ // if the resulting distance is 0 skip this gear
+ if s.QWordValue = 0 then
+ continue;
+ s := r / s;
ox:= iterator^.X + s * iterator^.dX;
oy:= iterator^.Y + s * iterator^.dY;
end
@@ -3847,7 +3879,7 @@ begin
begin
inc(iterator^.PortalCounter);
iterator^.Active:= true;
- iterator^.State:= iterator^.State and (not gstHHHJump)
+ iterator^.State:= iterator^.State and (not gstHHHJump) or gstMoving;
end;
// is it worth adding an arcsin table? Just how often would we end up doing something like this?
@@ -3861,7 +3893,7 @@ begin
resetx.QWordValue:= 4294967296 * 35;
resetdx.isNegative:= false;
resetdx.QWordValue:= 4294967296 * 1152;
-
+
resetdy:=hwAbs(iterator^.dX*4);
resetdy:= resetdy + hwPow(resetdy,3)/_6 + _3 * hwPow(resetdy,5) / _40 + _5 * hwPow(resetdy,7) / resety + resetx * hwPow(resetdy,9) / resetdx;
iterator^.Angle:= hwRound(resetdy*_2048 / _PI);
@@ -3882,7 +3914,7 @@ begin
and (CurAmmoGear^.Kind =gtRope) then
CurAmmoGear^.PortalCounter:= 1;
- if not isbullet and (iterator^.State and gstInvisible = 0)
+ if not isbullet and (iterator^.State and gstInvisible = 0)
and (iterator^.Kind <> gtFlake) then
FollowGear := iterator;
@@ -3928,7 +3960,7 @@ begin
end;
procedure doStepMovingPortal_real(Gear: PGear);
-var
+var
x, y, tx, ty: LongInt;
s: hwFloat;
begin
@@ -3942,7 +3974,7 @@ begin
begin
Gear^.State := Gear^.State or gstCollision;
Gear^.State := Gear^.State and (not gstMoving);
-
+
if (Land[y, x] and lfBouncy <> 0)
or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255))
or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain
@@ -3970,7 +4002,7 @@ begin
else
loadNewPortalBall(Gear, true);
end
-
+
else if (y > cWaterLine)
or (y < -max(LAND_WIDTH,4096))
or (x > 2*max(LAND_WIDTH,4096))
@@ -3982,13 +4014,13 @@ procedure doStepMovingPortal(Gear: PGear);
begin
doPortalColorSwitch();
doStepPerPixel(Gear, @doStepMovingPortal_real, true);
- if (Gear^.Timer < 1)
+ if (Gear^.Timer < 1)
or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team) then
deleteGear(Gear);
end;
procedure doStepPortalShot(newPortal: PGear);
-var
+var
iterator: PGear;
s: hwFloat;
CurWeapon: PAmmo;
@@ -4051,7 +4083,7 @@ begin
or ((iterator^.Message and gmAllStoppable) = 0)) then
begin
iterator^.Active:= true;
- if iterator^.dY.QWordValue = _0.QWordValue then
+ if iterator^.dY.QWordValue = 0 then
iterator^.dY.isNegative:= false;
iterator^.State:= iterator^.State or gstMoving;
DeleteCI(iterator);
@@ -4068,15 +4100,15 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepPiano(Gear: PGear);
-var
+var
r0, r1: LongInt;
odY: hwFloat;
begin
AllInactive := false;
- if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
+ if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and
((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
begin
- case CurrentHedgehog^.Gear^.MsgParam of
+ case CurrentHedgehog^.Gear^.MsgParam of
0: PlaySound(sndPiano0);
1: PlaySound(sndPiano1);
2: PlaySound(sndPiano2);
@@ -4156,7 +4188,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepSineGunShotWork(Gear: PGear);
-var
+var
x, y, rX, rY, t, tmp, initHealth: LongInt;
oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
justCollided: boolean;
@@ -4251,7 +4283,7 @@ begin
end;
if random(100) = 0 then
- AddVisualGear(x, y, vgtSmokeTrace);
+ AddVisualGear(x, y, vgtSmokeTrace);
end
else dec(Gear^.Health, 5); // if underwater get additional damage
end;
@@ -4289,7 +4321,7 @@ procedure doStepSineGunShot(Gear: PGear);
var
HHGear: PGear;
begin
- PlaySound(sndSineGun);
+ PlaySound(sndSineGun);
// push the shooting Hedgehog back
HHGear := CurrentHedgehog^.Gear;
@@ -4302,12 +4334,14 @@ begin
Gear^.dY.isNegative := not Gear^.dY.isNegative;
Gear^.doStep := @doStepSineGunShotWork;
- performRumble();
+ with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepFlamethrowerWork(Gear: PGear);
-var
+var
HHGear, flame: PGear;
rx, ry, speed: hwFloat;
i, gX, gY: LongInt;
@@ -4317,7 +4351,7 @@ begin
HedgehogChAngle(HHGear);
gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
-
+
if (GameTicks and $FF) = 0 then
begin
if (HHGear^.Message and gmRight) <> 0 then
@@ -4331,11 +4365,11 @@ begin
begin
if HHGear^.dX.isNegative and (Gear^.Tag > 5) then
dec(Gear^.Tag)
- else if Gear^.Tag < 20 then
+ else if Gear^.Tag < 20 then
inc(Gear^.Tag);
end
end;
-
+
dec(Gear^.Timer);
if Gear^.Timer = 0 then
begin
@@ -4345,18 +4379,18 @@ begin
rx := rndSign(getRandomf * _0_1);
ry := rndSign(getRandomf * _0_1);
speed := _0_5 * (_10 / Gear^.Tag);
-
+
flame:= AddGear(gx, gy, gtFlame, gstTmpFlag,
SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- flame^.CollisionMask:= $FF7F;
-
+ flame^.CollisionMask:= lfNotCurrentMask;
+
if (Gear^.Health mod 30) = 0 then
begin
flame:= AddGear(gx, gy, gtFlame, 0,
SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- flame^.CollisionMask:= $FF7F;
+ flame^.CollisionMask:= lfNotCurrentMask;
end
end;
Gear^.Timer:= Gear^.Tag
@@ -4381,7 +4415,7 @@ begin
end;
procedure doStepFlamethrower(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -4392,7 +4426,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepLandGunWork(Gear: PGear);
-var
+var
HHGear, land: PGear;
rx, ry, speed: hwFloat;
i, gX, gY: LongInt;
@@ -4402,7 +4436,7 @@ begin
HedgehogChAngle(HHGear);
gX := hwRound(Gear^.X) + GetLaunchX(amBallgun, hwSign(HHGear^.dX), HHGear^.Angle);
gY := hwRound(Gear^.Y) + GetLaunchY(amBallgun, HHGear^.Angle);
-
+
if (GameTicks and $FF) = 0 then
begin
if (HHGear^.Message and gmRight) <> 0 then
@@ -4420,7 +4454,7 @@ begin
inc(Gear^.Tag);
end
end;
-
+
dec(Gear^.Timer);
if Gear^.Timer = 0 then
begin
@@ -4430,11 +4464,11 @@ begin
ry := rndSign(getRandomf * _0_1);
speed := (_3 / Gear^.Tag);
- land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
- SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
+ land:= AddGear(gx, gy, gtFlake, gstTmpFlag,
+ SignAs(AngleSin(HHGear^.Angle) * speed, HHGear^.dX) + rx,
AngleCos(HHGear^.Angle) * ( - speed) + ry, 0);
- land^.CollisionMask:= $FF7F;
-
+ land^.CollisionMask:= lfNotCurrentMask;
+
Gear^.Timer:= Gear^.Tag
end;
@@ -4458,7 +4492,7 @@ begin
end;
procedure doStepLandGun(Gear: PGear);
-var
+var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
@@ -4527,7 +4561,7 @@ Gear^.doStep:= @doStepIdle
end;
procedure doStepHammerHitWork(Gear: PGear);
-var
+var
i, j, ei: LongInt;
HitGear: PGear;
begin
@@ -4557,8 +4591,8 @@ begin
if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
, lfIndestructible) then
begin
- Gear^.X := Gear^.X + Gear^.dX;
- Gear^.Y := Gear^.Y + _1_9;
+ //Gear^.X := Gear^.X + Gear^.dX;
+ Gear^.Y := Gear^.Y + _1_9
end;
end;
if TestCollisionYwithGear(Gear, 1) <> 0 then
@@ -4569,20 +4603,21 @@ begin
end
else
begin
- Gear^.dY := Gear^.dY + cGravity;
- Gear^.Y := Gear^.Y + Gear^.dY;
+ //Gear^.dY := Gear^.dY + cGravity;
+ //Gear^.Y := Gear^.Y + Gear^.dY;
if hwRound(Gear^.Y) > cWaterLine then
Gear^.Timer := 1
end;
- Gear^.X := Gear^.X + HitGear^.dX;
+ //Gear^.X := Gear^.X + HitGear^.dX;
HitGear^.X := Gear^.X;
+ HitGear^.Y := Gear^.Y;
SetLittle(HitGear^.dY);
HitGear^.Active:= true;
end;
procedure doStepHammerHit(Gear: PGear);
-var
+var
i, y: LongInt;
ar: TRangeArray;
HHGear: PGear;
@@ -4632,7 +4667,7 @@ begin
begin
if (GameTicks and $F) <> 0 then
exit;
- end
+ end
else if (GameTicks and $1FF) <> 0 then
exit;
@@ -4669,8 +4704,8 @@ begin
inc(graves[i]^.Health);
end;
end; -}
- end
- else
+ end
+ else
begin
// now really resurrect the hogs with the hp saved in the graves
for i:= 0 to graves.size - 1 do
@@ -4704,6 +4739,7 @@ end;
procedure doStepResurrector(Gear: PGear);
var
graves: PGearArrayS;
+ hh: PHedgehog;
i: LongInt;
begin
AllInactive := false;
@@ -4711,14 +4747,26 @@ begin
if graves.size > 0 then
begin
+ hh := Gear^.Hedgehog;
for i:= 0 to graves.size - 1 do
begin
PHedgehog(graves.ar^[i]^.Hedgehog)^.Gear := nil;
graves.ar^[i]^.Health := 0;
end;
Gear^.doStep := @doStepResurrectorWork;
- end
- else
+ if ((Gear^.Message and gmAttack) <> 0) and (hh^.Gear^.Health > 0) and (TurnTimeLeft > 0) then
+ begin
+ if LongInt(graves.size) <= Gear^.Tag then Gear^.Tag:= 0;
+ dec(hh^.Gear^.Health);
+ if (hh^.Gear^.Health = 0) and (hh^.Gear^.Damage = 0) then
+ hh^.Gear^.Damage:= 1;
+ RenderHealth(hh^);
+ RecountTeamHealth(hh^.Team);
+ inc(graves.ar^[Gear^.Tag]^.Health);
+ inc(Gear^.Tag)
+ end
+ end
+ else
begin
StopSoundChan(Gear^.SoundChannel);
Gear^.Timer := 250;
@@ -4738,7 +4786,7 @@ begin
begin
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 10, Gear^.Hedgehog, EXPLAutoSound);
gX := hwRound(Gear^.X);
- gY := hwRound(Gear^.Y);
+ gY := hwRound(Gear^.Y);
for i:= 0 to 10 do
begin
dX := AngleCos(i * 2) * ((_0_1*(i div 5))) * (GetRandomf + _1);
@@ -4766,7 +4814,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepStructure(Gear: PGear);
-var
+var
x, y: LongInt;
HH: PHedgehog;
t: PGear;
@@ -4783,7 +4831,7 @@ begin
dec(Gear^.Health, Gear^.Damage);
Gear^.Damage:= 0;
-
+
if Gear^.Pos = 1 then
begin
AddGearCI(Gear);
@@ -4794,7 +4842,7 @@ begin
HideHog(HH);
Gear^.Pos:= 2
end;
-
+
if Gear^.Pos = 2 then
begin
if ((GameTicks mod 100) = 0) and (Gear^.Timer < 1000) then
@@ -4810,7 +4858,7 @@ begin
if Gear^.Tag <= TotalRounds then
Gear^.Pos:= 3;
end;
-
+
if Gear^.Pos = 3 then
if Gear^.Timer < 1000 then
begin
@@ -4828,7 +4876,7 @@ begin
RestoreHog(HH);
Gear^.Pos:= 4;
end;
-
+
if Gear^.Pos = 4 then
if ((GameTicks mod 1000) = 0) and ((GameFlags and gfInvulnerable) = 0) then
begin
@@ -4840,12 +4888,12 @@ begin
t:= t^.NextGear;
end;
end;
-
+
if Gear^.Health <= 0 then
begin
if HH^.GearHidden <> nil then
RestoreHog(HH);
-
+
x := hwRound(Gear^.X);
y := hwRound(Gear^.Y);
@@ -4858,7 +4906,7 @@ end;
////////////////////////////////////////////////////////////////////////////////
(*
- TARDIS needs
+ TARDIS needs
Warp in. Pos = 1
Pause. Pos = 2
Hide gear (TARDIS hedgehog was nil)
@@ -4884,7 +4932,7 @@ if Gear^.Pos = 2 then
begin
AfterAttack;
if Gear = CurAmmoGear then CurAmmoGear := nil;
- if (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
+ if (HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
((Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
HideHog(HH)
end
@@ -4904,7 +4952,7 @@ if Gear^.Pos = 2 then
if (Gear^.Pos = 1) and (GameTicks and $1F = 0) and (Gear^.Power < 255) then
begin
inc(Gear^.Power);
- if (Gear^.Power = 172) and (HH^.Gear <> nil) and
+ if (Gear^.Power = 172) and (HH^.Gear <> nil) and
(HH^.Gear^.Damage = 0) and (HH^.Gear^.Health > 0) and
((HH^.Gear^.State and (gstMoving or gstHHDeath or gstHHGone)) = 0) then
with HH^.Gear^ do
@@ -4929,7 +4977,7 @@ if (Gear^.Pos = 3) and (Gear^.Power = 0) then
end;
Gear^.Pos:= 4;
// This condition might need tweaking
- Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount*2)+cHedgehogTurnTime*2
+ Gear^.Timer:= GetRandom(cHedgehogTurnTime*TeamsCount)+cHedgehogTurnTime
end;
if (Gear^.Pos = 4) then
@@ -4945,7 +4993,7 @@ if (Gear^.Pos = 4) then
begin
if HH^.GearHidden <> nil then
FindPlace(HH^.GearHidden, false, 0, LAND_WIDTH,true);
-
+
if HH^.GearHidden <> nil then
begin
Gear^.X:= HH^.GearHidden^.X;
@@ -4965,7 +5013,7 @@ if (Gear^.Pos = 4) then
Gear^.Power:= 0;
end
end
- else dec(Gear^.Timer);
+ else if (CurrentHedgehog^.Team^.Clan = Gear^.Hedgehog^.Team^.Clan) then dec(Gear^.Timer)
end;
end;
@@ -5021,64 +5069,97 @@ end;
WIP. The ice gun will have the following effects. It has been proposed by sheepluva that it take the appearance of a large freezer
spewing ice cubes. The cubes will be visual gears only. The scatter from them and the impact snow dust should help hide imprecisions in things like the GearsNear effect.
For now we assume a "ray" like a deagle projected out from the gun.
-All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target".
+All these effects assume the ray's angle is not changed and that the target type was unchanged over a number of ticks. This is a simplifying assumption for "gun was applying freezing effect to the same target".
* When fired at water a layer of ice textured land is added above the water.
- * When fired at non-ice land (land and $FF00 and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
+ * When fired at non-ice land (land and lfLandMask and not lfIce) the land is overlaid with a thin layer of ice textured land around that point (say, 1 or 2px into land, 1px above). For attractiveness, a slope would probably be needed.
* When fired at a hog (land and $00FF <> 0), while the hog is targetted, the hog's state is set to frozen. As long as the gun is on the hog, a frozen hog sprite creeps up from the feet to the head. If the effect is interrupted before reaching the top, the freezing state is cleared.
A frozen hog will animate differently. To be decided, but possibly in a similar fashion to a grave when it comes to explosions. The hog might (possibly) not be damaged by explosions. This might make freezing potentially useful for friendlies in a bad position. It might be better to allow damage though.
A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
*)
+
+
+procedure updateFuel(Gear: PGear);
+var
+ t:LongInt;
+begin
+ t:= Gear^.Health div 10;
+ if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+ begin
+ Gear^.Damage:= t;
+ FreeTexture(Gear^.Tex);
+ Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
+ '%', cWhiteColor, fntSmall)
+ end;
+ if Gear^.Message and (gmUp or gmDown) <> 0 then
+ begin
+ StopSoundChan(Gear^.SoundChannel);
+ Gear^.SoundChannel:= -1;
+ if GameTicks mod 40 = 0 then dec(Gear^.Health)
+ end
+ else
+ begin
+ if Gear^.SoundChannel = -1 then
+ Gear^.SoundChannel := LoopSound(sndIceBeam);
+ if GameTicks mod 10 = 0 then dec(Gear^.Health)
+ end
+end;
+
+
+procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
+// var
+// iter:PGear;
+begin
+ with Gear^ do
+ begin
+ dX:= newX;
+ dY:= newY;
+ Pos:= 0;
+ Target.X:= NoPointX;
+ LastDamage:= nil;
+ X:= Hedgehog^.Gear^.X;
+ Y:= Hedgehog^.Gear^.Y;
+ end;
+end;
+
procedure doStepIceGun(Gear: PGear);
+const iceWaitCollision:Longint = 0;
+const iceCollideWithGround:Longint = 1;
+//const iceWaitNextTarget:Longint = 2;
+//const iceCollideWithHog:Longint = 4;
+const iceCollideWithWater:Longint = 5;
+//const waterFreezingTime:Longint = 500;
+const groundFreezingTime:Longint = 1000;
+const iceRadius = 32;
+const iceHeight = 40;
var
- HHGear: PGear;
+ HHGear, iter: PGear;
+ landRect: TSDL_Rect;
ndX, ndY: hwFloat;
- i, t, gX, gY: LongInt;
+ i, j, t, gX, gY: LongInt;
hogs: PGearArrayS;
+ vg: PVisualGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
- if (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
+ if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) or (HHGear^.dX.QWordValue > 4294967) then
begin
+ StopSoundChan(Gear^.SoundChannel);
DeleteGear(Gear);
AfterAttack;
exit
- end
- else
- begin
- t:= Gear^.Health div 10;
- if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
- begin
- Gear^.Damage:= t;
- FreeTexture(Gear^.Tex);
- Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
- '%', cWhiteColor, fntSmall)
- end
end;
- if GameTicks mod 10 = 0 then dec(Gear^.Health);
+ updateFuel(Gear);
+
with Gear^ do
begin
HedgehogChAngle(HHGear);
ndX:= SignAs(AngleSin(HHGear^.Angle), HHGear^.dX) * _4;
ndY:= -AngleCos(HHGear^.Angle) * _4;
- if (ndX <> dX) or (ndY <> dY) or
- ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
+ if (ndX <> dX) or (ndY <> dY) or
+ ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and
(Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
begin
- dX:= ndX;
- dY:= ndY;
- Pos:= 0;
- Target.X:= NoPointX;
- LastDamage:= nil;
- X:= HHGear^.X;
- Y:= HHGear^.Y;
-(* unfreeze all semifrozen hogs - make this generic hog cleanup
- iter := GearsList;
- while iter <> nil do
- begin
- if (iter^.Kind = gtHedgehog) and
- (iter^.Hedgehog^.Effects[heFrozen] < 0) then
- iter^.Hedgehog^.Effects[heFrozen]:= 0;
- iter:= iter^.NextGear
- end *)
+ updateTarget(Gear, ndX, ndY);
+ Timer := iceWaitCollision;
end
else
begin
@@ -5087,22 +5168,129 @@ begin
gX:= hwRound(X);
gY:= hwRound(Y);
if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
+
if Target.X <> NoPointX then
begin
+ CheckCollision(Gear);
+ if (State and gstCollision) <> 0 then
+ begin
+ if Timer = iceWaitCollision then
+ begin
+ Timer := iceCollideWithGround;
+ Power := GameTicks;
+ end
+ end
+ else if (target.y >= cWaterLine) then
+ begin
+ if Timer = iceWaitCollision then
+ begin
+ Timer := iceCollideWithWater;
+ Power := GameTicks;
+ end;
+ end;
+
if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
begin
X:= HHGear^.X;
Y:= HHGear^.Y
end;
+
+ if (Timer = iceCollideWithGround) and ((GameTicks - Power) > groundFreezingTime) then
+ begin
+ FillRoundInLand(target.x, target.y, iceRadius, icePixel);
+ landRect.x := min(max(target.x - iceRadius, 0), LAND_WIDTH - 1);
+ landRect.y := min(max(target.y - iceRadius, 0), LAND_HEIGHT - 1);
+ landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
+ landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
+ UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
+
+ // Freeze nearby mines/explosives/cases too
+ iter := GearsList;
+ while iter <> nil do
+ begin
+ if (iter^.State and gstFrozen = 0) and
+ ((iter^.Kind = gtExplosives) or (iter^.Kind = gtCase) or (iter^.Kind = gtMine)) and
+ (abs(iter^.X.Round-target.x)+abs(iter^.Y.Round-target.y)+2<2*iceRadius) and (Distance(iter^.X-int2hwFloat(target.x),iter^.Y-int2hwFloat(target.y))<int2hwFloat(iceRadius*2)) then
+ begin
+ for t:= 0 to 5 do
+ begin
+ vg:= AddVisualGear(hwRound(iter^.X)+random(4)-8, hwRound(iter^.Y)+random(8), vgtDust, 1);
+ if vg <> nil then
+ begin
+ i:= random(100) + 155;
+ vg^.Tint:= i shl 24 or i shl 16 or $FF shl 8 or Longword(random(200) + 55);
+ vg^.Angle:= random(360);
+ vg^.dx:= 0.001 * random(80);
+ vg^.dy:= 0.001 * random(80)
+ end
+ end;
+ PlaySound(sndHogFreeze);
+ iter^.State:= iter^.State or gstFrozen;
+ if iter^.Kind = gtMine then // dud mine block
+ begin
+ vg:= AddVisualGear(hwRound(iter^.X) - 4 + Random(8), hwRound(iter^.Y) - 4 - Random(4), vgtSmoke);
+ if vg <> nil then
+ vg^.Scale:= 0.5;
+ PlaySound(sndVaporize);
+ iter^.Health := 0;
+ iter^.Damage := 0;
+ iter^.State := iter^.State and (not gstAttacking)
+ end
+ else if iter^.Kind = gtCase then
+ begin
+ DeleteCI(iter);
+ AddGearCI(iter)
+ end
+ else // gtExplosives
+ iter^.Health:= iter^.Health + cBarrelHealth
+ end;
+ iter:= iter^.NextGear
+ end;
+
+ // FillRoundInLandWithIce(Target.X, Target.Y, iceRadius);
+ SetAllHHToActive;
+ Timer := iceWaitCollision;
+ end;
+
+ if (Timer = iceCollideWithWater) and ((GameTicks - Power) > groundFreezingTime) then
+ begin
+ PlaySound(sndHogFreeze);
+ DrawIceBreak(Target.X, cWaterLine - iceHeight, iceRadius, iceHeight);
+ SetAllHHToActive;
+ Timer := iceWaitCollision;
+ end;
+(*
+ Any ideas for something that would look good here?
+ if (Target.X <> NoPointX) and ((Timer = iceCollideWithGround) or (Timer = iceCollideWithWater)) and (GameTicks mod max((groundFreezingTime-((GameTicks - Power)*2)),2) = 0) then //and CheckLandValue(Target.X, Target.Y, lfIce) then
+ begin
+ vg:= AddVisualGear(Target.X+random(20)-10, Target.Y+random(40)-10, vgtDust, 1);
+ if vg <> nil then
+ begin
+ i:= random(100) + 155;
+ vg^.Tint:= IceColor or $FF;
+ vg^.Angle:= random(360);
+ vg^.dx:= 0.001 * random(80);
+ vg^.dy:= 0.001 * random(80)
+ end
+ end;
+*)
+
// freeze nearby hogs
- if GameTicks mod 10 = 0 then dec(Gear^.Health);
- hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
+ hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
if hogs.size > 0 then
for i:= 0 to hogs.size - 1 do
if hogs.ar^[i] <> HHGear then
- begin
- //if Gear^.Hedgehog^.Effects[heFrozen]:= 0;
- end;
+ if GameTicks mod 5 = 0 then
+ begin
+ hogs.ar^[i]^.Active:= true;
+ if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
+ else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
+ begin
+ hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 200000-1;//cHedgehogTurnTime + cReadyDelay
+ PlaySound(sndHogFreeze);
+ end;
+ end;
inc(Pos)
end
else if (t > 400) and ((gY > cWaterLine) or
@@ -5119,8 +5307,10 @@ begin
(gY < -max(LAND_HEIGHT,4096)) or
(gY > max(LAND_HEIGHT,4096)+512) then
begin
- X:= HHGear^.X;
- Y:= HHGear^.Y
+ //X:= HHGear^.X;
+ //Y:= HHGear^.Y
+ Target.X:= gX;
+ Target.Y:= gY;
end
end
end;
@@ -5143,6 +5333,7 @@ else
begin
with gi^ do CheckSum:= CheckSum xor X.round xor X.frac xor dX.round xor dX.frac xor Y.round xor Y.frac xor dY.round xor dY.frac;
AddRandomness(CheckSum);
+ if gi^.Kind = gtGenericFaller then gi^.State:= gi^.State and not gstTmpFlag;
gi := gi^.NextGear
end;
AddPickup(Gear^.Hedgehog^, a, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
@@ -5160,8 +5351,17 @@ if Gear^.Timer < $FFFFFFFF then
DeleteGear(Gear);
exit
end;
-
-doStepFallingGear(Gear);
+if (Gear^.State and gstTmpFlag <> 0) or (GameTicks and $7 = 0) then
+ begin
+ doStepFallingGear(Gear);
+ if (Gear^.State and gstInvisible <> 0) and (GameTicks and $FF = 0) and (hwRound(Gear^.X) < LongInt(leftX)) or (hwRound(Gear^.X) > LongInt(rightX)) or (hwRound(Gear^.Y) < LongInt(topY)) then
+ begin
+ Gear^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
+ Gear^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
+ Gear^.dX:= _90-(GetRandomf*_360);
+ Gear^.dY:= _90-(GetRandomf*_360)
+ end;
+ end
end;
procedure doStepCreeper(Gear: PGear);
@@ -5187,7 +5387,7 @@ if (Gear^.State and gstTmpFlag <> 0) then
DeleteGear(Gear)
end;
// ssssss he essssscaped
- if (Gear^.Timer > 250) and ((HHGear = nil) or
+ if (Gear^.Timer > 250) and ((HHGear = nil) or
(((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > 180) and
(Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > _180))) then
begin
@@ -5198,7 +5398,7 @@ if (Gear^.State and gstTmpFlag <> 0) then
end;
// Search out a new target, as target seek time has expired, target is dead, target is out of range, or we did not have a target
-if (HHGear = nil) or (Gear^.Timer = 0) or
+if (HHGear = nil) or (Gear^.Timer = 0) or
(((abs(HHGear^.X.Round-Gear^.X.Round) + abs(HHGear^.Y.Round-Gear^.Y.Round) + 2) > Gear^.Angle) and
(Distance(HHGear^.X-Gear^.X,HHGear^.Y-Gear^.Y) > int2hwFloat(Gear^.Angle)))
then
@@ -5247,12 +5447,12 @@ end;
////////////////////////////////////////////////////////////////////////////////
procedure doStepKnife(Gear: PGear);
-var ox, oy: LongInt;
- la: hwFloat;
- a: real;
+//var ox, oy: LongInt;
+// la: hwFloat;
+var a: real;
begin
// Gear is shrunk so it can actually escape the hog without carving into the terrain
- if (Gear^.Radius = 6) and (Gear^.CollisionMask = $FFFF) then Gear^.Radius:= 16;
+ if (Gear^.Radius = 4) and (Gear^.CollisionMask = $FFFF) then Gear^.Radius:= 7;
if Gear^.Damage > 100 then Gear^.CollisionMask:= 0
else if Gear^.Damage > 30 then
if GetRandom(max(4,18-Gear^.Damage div 10)) < 3 then Gear^.CollisionMask:= 0;
@@ -5261,6 +5461,7 @@ begin
if (Gear^.State and gstMoving <> 0) and (Gear^.State and gstCollision = 0) then
begin
DeleteCI(Gear);
+ Gear^.Radius:= 7;
// used for damage and impact calc. needs balancing I think
Gear^.Health:= hwRound(hwSqr((hwAbs(Gear^.dY)+hwAbs(Gear^.dX))*_4));
doStepFallingGear(Gear);
@@ -5271,14 +5472,14 @@ begin
end
else if (Gear^.CollisionIndex = -1) and (Gear^.Timer = 0) then
begin
- ox:= 0; oy:= 0;
+ (*ox:= 0; oy:= 0;
if TestCollisionYwithGear(Gear, -1) <> 0 then oy:= -1;
if TestCollisionXwithGear(Gear, 1) then ox:= 1;
if TestCollisionXwithGear(Gear, -1) then ox:= -1;
if TestCollisionYwithGear(Gear, 1) <> 0 then oy:= 1;
if Gear^.Health > 0 then
PlaySound(sndRopeAttach);
-(*
+
la:= _10000;
if (ox <> 0) or (oy <> 0) then
la:= CalcSlopeNearGear(Gear, ox, oy);
@@ -5296,9 +5497,8 @@ begin
Gear^.dX:= _0;
Gear^.dY:= _0;
Gear^.State:= Gear^.State and (not gstMoving) or gstCollision;
- Gear^.Radius:= 20;
- if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0);
Gear^.Radius:= 16;
+ if Gear^.Health > 0 then AmmoShove(Gear, Gear^.Health, 0);
Gear^.Health:= 0;
Gear^.Timer:= 500;
AddGearCI(Gear)
@@ -5315,7 +5515,7 @@ end;
This didn't end up getting used, but, who knows, might be reasonable for javellin or something
// Make the knife initial angle based on the hog attack angle, or is that too hard?
procedure doStepKnife(Gear: PGear);
-var t,
+var t,
gx, gy, ga, // gear x,y,angle
lx, ly, la, // land x,y,angle
ox, oy, // x,y offset
@@ -5337,9 +5537,9 @@ begin
if Gear^.State and gstDrowning <> 0 then exit;
with Gear^ do
begin
- if CheckLandValue(gx, gy, $FF00) then
+ if CheckLandValue(gx, gy, lfLandMask) then
begin
- t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
+ t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10);
if t < 0 then inc(t, 4096)
else if 4095 < t then dec(t, 4096);
@@ -5376,7 +5576,7 @@ begin
4: begin
ox:= 29; oy:= 8;
w:= 19; h:= 19;
- tx:= 0; ty:= 17
+ tx:= 0; ty:= 17
end;
5: begin
ox:= 29; oy:= 32;
@@ -5386,7 +5586,7 @@ begin
6: begin
ox:= 51; oy:= 3;
w:= 11; h:= 23;
- tx:= 0; ty:= 22
+ tx:= 0; ty:= 22
end;
7: begin
ox:= 51; oy:= 34;
@@ -5394,7 +5594,7 @@ begin
tx:= 0; ty:= 23
end
end;
-
+
surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
// try to make the knife hit point first
@@ -5416,7 +5616,7 @@ begin
AddFileLog('la: '+inttostr(la)+' ga: '+inttostr(ga)+' Angle: '+inttostr(Angle))
end;
case Angle div 1024 of
- 0: begin
+ 0: begin
flipSurface(surf, true);
flipSurface(surf, true);
BlitImageAndGenerateCollisionInfo(gx-(w-tx), gy-(h-ty), w, surf)
diff --git a/hedgewars/LuaPas.pas b/hedgewars/LuaPas.pas
index b847241..123bbd8 100644
--- a/hedgewars/LuaPas.pas
+++ b/hedgewars/LuaPas.pas
@@ -15,9 +15,7 @@ uses uConsts;
{.$DEFINE LUA_GETHOOK}
type
-{$IFNDEF PAS2C}
size_t = Cardinal;
-{$ENDIF}
Psize_t = ^size_t;
PPointer = ^Pointer;
diff --git a/hedgewars/PNGh.pas b/hedgewars/PNGh.pas
index 172f6e7..f98d52b 100644
--- a/hedgewars/PNGh.pas
+++ b/hedgewars/PNGh.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,15 +23,14 @@ interface
uses png;
-{$IFDEF FPC}
- {$PACKRECORDS C}
-{$ELSE}
- {$DEFINE cdecl attribute(cdecl)}
+
+{$IFDEF DARWIN}
+ {$linklib png}
{$ENDIF}
const
// Constants for libpng, they are not defined in png unit.
- // We actually don't need all of them.
+ // We actually do not need all of them.
// These describe the color_type field in png_info.
// color type masks
diff --git a/hedgewars/SDLh.pas b/hedgewars/SDLh.pas
index 4a052e1..7a85f75 100644
--- a/hedgewars/SDLh.pas
+++ b/hedgewars/SDLh.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,14 +36,17 @@ interface
{$IFDEF UNIX}
{$IFNDEF DARWIN}
- {$linklib c}
+ {necessary for statically linking physfs (divdi3 undefined on 32 bit)}
+ {$IFDEF CPU32}
+ {$linklib stdc++}
+ {$ENDIF}
{$ENDIF}
{$IFDEF HAIKU}
{$linklib root}
{$ELSE}
{$IFNDEF ANDROID}
- {$linklib pthread}
- {$ENDIF}
+ {$linklib pthread}
+ {$ENDIF}
{$ENDIF}
{$ENDIF}
@@ -311,6 +314,22 @@ const
IMG_INIT_PNG = $00000002;
IMG_INIT_TIF = $00000004;
+ {* SDL_keysym *}
+ SDLK_BACKSPACE = 8;
+ SDLK_RETURN = 13;
+ SDLK_ESCAPE = 27;
+ SDLK_q = 113;
+ SDLK_w = 119;
+ SDLK_DELETE = 127;
+ SDLK_UP = 273;
+ SDLK_DOWN = 274;
+ SDLK_RIGHT = 275;
+ SDLK_LEFT = 276;
+ SDLK_HOME = 278;
+ SDLK_END = 279;
+ SDLK_PAGEUP = 280;
+ SDLK_PAGEDOWN = 281;
+
/////////////////////////////////////////////////////////////////
/////////////////////// TYPE DEFINITIONS ///////////////////////
@@ -927,12 +946,11 @@ function SDL_SetHint(name, value: PChar): Boolean; cdecl; external SDLLibName;
procedure SDL_StartTextInput; cdecl; external SDLLibName;
function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; minType, maxType: LongWord): LongInt; cdecl; external SDLLibName;
-function SDL_CreateThread(fn: Pointer; name: PChar; data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
{$ELSE}
-function SDL_CreateThread(fn: Pointer; data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
function SDL_PeepEvents(event: PSDL_Event; numevents: LongInt; action: TSDL_eventaction; mask: LongWord): LongInt; cdecl; external SDLLibName;
{$ENDIF}
+
function SDL_GetMouseState(x, y: PLongInt): Byte; cdecl; external SDLLibName;
function SDL_GetKeyName(key: LongWord): PChar; cdecl; external SDLLibName;
function SDL_GetScancodeName(key: LongWord): PChar; cdecl; external SDLLibName;
@@ -950,7 +968,13 @@ procedure SDL_WM_SetIcon(icon: PSDL_Surface; mask : Byte); cdecl; external SDLLi
procedure SDL_WM_SetCaption(title: PChar; icon: PChar); cdecl; external SDLLibName;
function SDL_WM_ToggleFullScreen(surface: PSDL_Surface): LongInt; cdecl; external SDLLibName;
+
+// remember to mark the threaded functions as 'cdecl; export;'
+// (or have fun debugging nil arguments)
+function SDL_CreateThread(fn: Pointer; {$IFDEF SDL13}name: PChar;{$ENDIF} data: Pointer): PSDL_Thread; cdecl; external SDLLibName;
procedure SDL_WaitThread(thread: PSDL_Thread; status: PLongInt); cdecl; external SDLLibName;
+procedure SDL_KillThread(thread: PSDL_Thread); cdecl; external SDLLibName;
+
function SDL_CreateMutex: PSDL_mutex; cdecl; external SDLLibName;
procedure SDL_DestroyMutex(mutex: PSDL_mutex); cdecl; external SDLLibName;
function SDL_LockMutex(mutex: PSDL_mutex): LongInt; cdecl; external SDLLibName name 'SDL_mutexP';
@@ -1004,7 +1028,7 @@ function TTF_RenderUTF8_Solid(font: PTTF_Font; const text: PChar; fg: TSDL_Colo
function TTF_RenderUTF8_Blended(font: PTTF_Font; const text: PChar; fg: TSDL_Color): PSDL_Surface; cdecl; external SDL_TTFLibName;
function TTF_RenderUTF8_Shaded(font: PTTF_Font; const text: PChar; fg, bg: TSDL_Color): PSDL_Surface; cdecl; external SDL_TTFLibName;
-function TTF_OpenFont(const filename: PChar; size: LongInt): PTTF_Font; cdecl; external SDL_TTFLibName;
+function TTF_OpenFontRW(src: PSDL_RWops; freesrc: LongBool; size: LongInt): PTTF_Font; cdecl; external SDL_TTFLibName;
procedure TTF_SetFontStyle(font: PTTF_Font; style: LongInt); cdecl; external SDL_TTFLibName;
(* SDL_mixer *)
@@ -1024,7 +1048,7 @@ procedure Mix_FreeChunk(chunk: PMixChunk); cdecl; external SDL_MixerLibName;
procedure Mix_FreeMusic(music: PMixMusic); cdecl; external SDL_MixerLibName;
function Mix_LoadWAV_RW(src: PSDL_RWops; freesrc: LongInt): PMixChunk; cdecl; external SDL_MixerLibName;
-function Mix_LoadMUS(const filename: PChar): PMixMusic; cdecl; external SDL_MixerLibName;
+function Mix_LoadMUS_RW(src: PSDL_RWops): PMixMusic; cdecl; external SDL_MixerLibName;
function Mix_Playing(channel: LongInt): LongInt; cdecl; external SDL_MixerLibName;
function Mix_PlayingMusic: LongInt; cdecl; external SDL_MixerLibName;
@@ -1048,9 +1072,9 @@ function IMG_Init(flags: LongInt): LongInt; {$IFDEF SDL_IMAGE_NEWER}cdecl; exte
procedure IMG_Quit; {$IFDEF SDL_IMAGE_NEWER}cdecl; external SDL_ImageLibName;{$ENDIF}
function IMG_Load(const _file: PChar): PSDL_Surface; cdecl; external SDL_ImageLibName;
-function IMG_Load_RW(rwop: PSDL_RWops; freesrc: LongInt): PSDL_Surface; cdecl; external SDL_ImageLibName;
+function IMG_Load_RW(rwop: PSDL_RWops; freesrc: LongBool): PSDL_Surface; cdecl; external SDL_ImageLibName;
function IMG_LoadPNG_RW(rwop: PSDL_RWops): PSDL_Surface; cdecl; external SDL_ImageLibName;
-function IMG_LoadTyped_RW(rwop: PSDL_RWops; freesrc: LongInt; type_: PChar): PSDL_Surface; cdecl; external SDL_ImageLibName;
+function IMG_LoadTyped_RW(rwop: PSDL_RWops; freesrc: LongBool; type_: PChar): PSDL_Surface; cdecl; external SDL_ImageLibName;
(* SDL_net *)
function SDLNet_Init: LongInt; cdecl; external SDL_NetLibName;
diff --git a/hedgewars/VGSHandlers.inc b/hedgewars/VGSHandlers.inc
index ea89b27..f6a6e30 100644
--- a/hedgewars/VGSHandlers.inc
+++ b/hedgewars/VGSHandlers.inc
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -697,7 +697,9 @@ for i:= 0 to 15 do
Gear^.doStep:= @doStepBigExplosionWork;
if Steps > 1 then
Gear^.doStep(Gear, Steps-1);
-performRumble();
+with mobileRecord do
+ if (performRumble <> nil) and (not fastUntilLag) then
+ performRumble(kSystemSoundID_Vibrate);
end;
procedure doStepChunk(Gear: PVisualGear; Steps: Longword);
diff --git a/hedgewars/avwrapper.c b/hedgewars/avwrapper.c
index 6e879e1..74473fa 100644
--- a/hedgewars/avwrapper.c
+++ b/hedgewars/avwrapper.c
@@ -1,6 +1,6 @@
/*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include <string.h>
#include <stdarg.h>
#include "libavformat/avformat.h"
+#include "libavutil/mathematics.h"
#ifndef AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE AVIO_WRONLY
@@ -47,13 +48,6 @@ static FILE* g_pSoundFile;
static int16_t* g_pSamples;
static int g_NumSamples;
-/*
-Initially I wrote code for latest ffmpeg, but on Linux (Ubuntu)
-only older version is available from repository. That's why you see here
-all of this #if LIBAVCODEC_VERSION_MAJOR < 54.
-Actually, it may be possible to remove code for newer version
-and use only code for older version.
-*/
#if LIBAVCODEC_VERSION_MAJOR < 54
#define OUTBUFFER_SIZE 200000
@@ -65,7 +59,7 @@ static void (*AddFileLogRaw)(const char* pString);
static void FatalError(const char* pFmt, ...)
{
- const char Buffer[1024];
+ char Buffer[1024];
va_list VaArgs;
va_start(VaArgs, pFmt);
@@ -83,7 +77,7 @@ static void FatalError(const char* pFmt, ...)
// (there is mutex in AddFileLogRaw).
static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs)
{
- const char Buffer[1024];
+ char Buffer[1024];
vsnprintf(Buffer, 1024, pFmt, VaArgs);
AddFileLogRaw(Buffer);
@@ -91,7 +85,7 @@ static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs)
static void Log(const char* pFmt, ...)
{
- const char Buffer[1024];
+ char Buffer[1024];
va_list VaArgs;
va_start(VaArgs, pFmt);
@@ -103,7 +97,7 @@ static void Log(const char* pFmt, ...)
static void AddAudioStream()
{
-#if LIBAVFORMAT_VERSION_MAJOR >= 54
+#if LIBAVFORMAT_VERSION_MAJOR >= 53
g_pAStream = avformat_new_stream(g_pContainer, g_pACodec);
#else
g_pAStream = av_new_stream(g_pContainer, 1);
@@ -175,7 +169,7 @@ static int WriteAudioFrame()
int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);
-#if LIBAVCODEC_VERSION_MAJOR >= 54
+#if LIBAVCODEC_VERSION_MAJOR >= 53
AVFrame* pFrame = NULL;
if (NumSamples > 0)
{
@@ -215,7 +209,7 @@ static int WriteAudioFrame()
// add a video output stream
static void AddVideoStream()
{
-#if LIBAVFORMAT_VERSION_MAJOR >= 54
+#if LIBAVFORMAT_VERSION_MAJOR >= 53
g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec);
#else
g_pVStream = av_new_stream(g_pContainer, 0);
@@ -254,7 +248,7 @@ static void AddVideoStream()
if (g_pFormat->flags & AVFMT_GLOBALHEADER)
g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER;
-#if LIBAVCODEC_VERSION_MAJOR < 54
+#if LIBAVCODEC_VERSION_MAJOR < 53
// for some versions of ffmpeg x264 options must be set explicitly
if (strcmp(g_pVCodec->name, "libx264") == 0)
{
diff --git a/hedgewars/config.inc.in b/hedgewars/config.inc.in
index 35a86a8..f3d085a 100644
--- a/hedgewars/config.inc.in
+++ b/hedgewars/config.inc.in
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,4 +23,7 @@
*)
const cNetProtoVersion = ${HEDGEWARS_PROTO_VER};
cVersionString = '${HEDGEWARS_VERSION}';
+ cRevisionString = '${HEDGEWARS_REVISION}';
+ cHashString = '${HEDGEWARS_HASH}';
cLuaLibrary = '${LUA_LIBRARY}';
+ cDefaultPathPrefix = '${HEDGEWARS_FULL_DATADIR}/Data';
diff --git a/hedgewars/hwLibrary.pas b/hedgewars/hwLibrary.pas
index 4c07a38..5c17e8d 100644
--- a/hedgewars/hwLibrary.pas
+++ b/hedgewars/hwLibrary.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -99,14 +99,18 @@ begin
JNI_HW_versionInfoVersion := envderef^.NewStringUTF(env, PChar(cVersionString));
end;
+procedure JNI_HW_GenLandPreview(env: PJNIEnv; c: JClass; port: JInt); cdecl;
+begin
+ GenLandPreview(port);
+end;
+
exports
JNI_HW_versionInfoNet name Java_Prefix+'HWversionInfoNetProto',
JNI_HW_versionInfoVersion name Java_Prefix+'HWversionInfoVersion',
- GenLandPreview name Java_Prefix + 'GenLandPreview',
+ JNI_HW_GenLandPreview name Java_Prefix + 'HWGenLandPreview',
HW_getNumberOfweapons name Java_Prefix + 'HWgetNumberOfWeapons',
HW_getMaxNumberOfHogs name Java_Prefix + 'HWgetMaxNumberOfHogs',
HW_getMaxNumberOfTeams name Java_Prefix + 'HWgetMaxNumberOfTeams',
- HW_terminate name Java_Prefix + 'HWterminate',
Game;
{$ELSE}
exports
diff --git a/hedgewars/hwengine.pas b/hedgewars/hwengine.pas
index 1a47023..c949793 100644
--- a/hedgewars/hwengine.pas
+++ b/hedgewars/hwengine.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,20 +29,22 @@ interface
program hwengine;
{$ENDIF}
-uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler,
- uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions,
- SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
+uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler
+ , uSound, uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uAILandMarks, uLandTexture, uCollisions
+ , SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
+ , uPhysFSLayer, uCursor, uRandom
{$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}, uTouch {$ENDIF}
{$IFDEF ANDROID}, GLUnit{$ENDIF}
;
+var isInternal: Boolean;
{$IFDEF HWLIBRARY}
procedure preInitEverything();
procedure initEverything(complete:boolean);
procedure freeEverything(complete:boolean);
-procedure Game(gameArgs: PPChar); cdecl; export;
+procedure Game(argc: LongInt; argv: PPChar); cdecl; export;
procedure GenLandPreview(port: Longint); cdecl; export;
implementation
@@ -52,6 +54,8 @@ procedure initEverything(complete:boolean); forward;
procedure freeEverything(complete:boolean); forward;
{$ENDIF}
+{$INCLUDE "ArgParsers.inc"}
+
///////////////////////////////////////////////////////////////////////////////
function DoTimer(Lag: LongInt): boolean;
var s: shortstring;
@@ -75,6 +79,7 @@ begin
DisableSomeWeapons;
AddClouds;
AddFlakes;
+ SetRandomSeed(cSeed, false);
AssignHHCoords;
AddMiscGears;
StoreLoad(false);
@@ -88,17 +93,11 @@ begin
ScriptCall('onGameStart');
GameState:= gsGame;
end;
- gsConfirm, gsGame:
- begin
- DrawWorld(Lag);
- DoGameTick(Lag);
- ProcessVisualGears(Lag);
- end;
- gsChat:
+ gsConfirm, gsGame, gsChat:
begin
- DrawWorld(Lag);
+ if not cOnlyStats then DrawWorld(Lag);
DoGameTick(Lag);
- ProcessVisualGears(Lag);
+ if not cOnlyStats then ProcessVisualGears(Lag);
end;
gsExit:
begin
@@ -108,7 +107,7 @@ begin
exit(false);
end;
- SwapBuffers;
+ if not cOnlyStats then SwapBuffers;
{$IFDEF USE_VIDEO_RECORDING}
if flagPrerecording then
@@ -118,11 +117,7 @@ begin
if flagMakeCapture then
begin
flagMakeCapture:= false;
- {$IFDEF PAS2C}
- s:= '/Screenshots/hw';
- {$ELSE}
s:= '/Screenshots/hw_' + FormatDateTime('YYYY-MM-DD_HH-mm-ss', Now()) + inttostr(GameTicks);
- {$ENDIF}
// flash
playSound(sndShutter);
@@ -156,21 +151,23 @@ begin
while isTerminated = false do
begin
SDL_PumpEvents();
-
+
while SDL_PeepEvents(@event, 1, SDL_GETEVENT, {$IFDEF SDL13}SDL_FIRSTEVENT, SDL_LASTEVENT{$ELSE}SDL_ALLEVENTS{$ENDIF}) > 0 do
begin
case event.type_ of
{$IFDEF SDL13}
SDL_KEYDOWN:
if GameState = gsChat then
+ begin
// sdl on iphone supports only ashii keyboards and the unicode field is deprecated in sdl 1.3
- KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym))//TODO correct for keymodifiers
- else
- ProcessKey(event.key);
+ KeyPressChat(SDL_GetKeyFromScancode(event.key.keysym.sym), event.key.keysym.sym); //TODO correct for keymodifiers
+ end
+ else
+ if GameState >= gsGame then ProcessKey(event.key);
SDL_KEYUP:
- if GameState <> gsChat then
+ if (GameState <> gsChat) and (GameState >= gsGame) then
ProcessKey(event.key);
-
+
SDL_WINDOWEVENT:
if event.window.event = SDL_WINDOWEVENT_SHOWN then
begin
@@ -196,31 +193,34 @@ begin
cNewScreenHeight:= max(2 * (event.window.data2 div 2), cMinScreenHeight);
cScreenResizeDelay:= RealTicks + 500{$IFDEF IPHONEOS}div 2{$ENDIF};
end;
-
+
SDL_FINGERMOTION:
onTouchMotion(event.tfinger.x, event.tfinger.y,event.tfinger.dx, event.tfinger.dy, event.tfinger.fingerId);
-
+
SDL_FINGERDOWN:
onTouchDown(event.tfinger.x, event.tfinger.y, event.tfinger.fingerId);
-
+
SDL_FINGERUP:
onTouchUp(event.tfinger.x, event.tfinger.y, event.tfinger.fingerId);
{$ELSE}
SDL_KEYDOWN:
if GameState = gsChat then
- KeyPressChat(event.key.keysym.unicode)
+ KeyPressChat(event.key.keysym.unicode, event.key.keysym.sym)
else
- ProcessKey(event.key);
+ if GameState >= gsGame then ProcessKey(event.key);
SDL_KEYUP:
- if GameState <> gsChat then
+ if (GameState <> gsChat) and (GameState >= gsGame) then
ProcessKey(event.key);
-
+
SDL_MOUSEBUTTONDOWN:
- ProcessMouse(event.button, true);
-
+ if GameState = gsConfirm then
+ ParseCommand('quit', true)
+ else
+ if (GameState >= gsGame) then ProcessMouse(event.button, true);
+
SDL_MOUSEBUTTONUP:
- ProcessMouse(event.button, false);
-
+ if (GameState >= gsGame) then ProcessMouse(event.button, false);
+
SDL_ACTIVEEVENT:
if (event.active.state and SDL_APPINPUTFOCUS) <> 0 then
begin
@@ -229,7 +229,7 @@ begin
if prevFocusState xor cHasFocus then
onFocusStateChanged()
end;
-
+
SDL_VIDEORESIZE:
begin
// using lower values than cMinScreenWidth or cMinScreenHeight causes widget overlap and off-screen widget parts
@@ -254,24 +254,30 @@ begin
end; //end case event.type_ of
end; //end while SDL_PollEvent(@event) <> 0 do
+ if (CursorMovementX <> 0) or (CursorMovementY <> 0) then
+ handlePositionUpdate(CursorMovementX * cameraKeyboardSpeed, CursorMovementY * cameraKeyboardSpeed);
+
if (cScreenResizeDelay <> 0) and (cScreenResizeDelay < RealTicks) and
((cNewScreenWidth <> cScreenWidth) or (cNewScreenHeight <> cScreenHeight)) then
begin
cScreenResizeDelay:= 0;
- cScreenWidth:= cNewScreenWidth;
- cScreenHeight:= cNewScreenHeight;
+ cWindowedWidth:= cNewScreenWidth;
+ cWindowedHeight:= cNewScreenHeight;
+ cScreenWidth:= cWindowedWidth;
+ cScreenHeight:= cWindowedHeight;
ParseCommand('fullscr '+intToStr(LongInt(cFullScreen)), true);
WriteLnToConsole('window resize: ' + IntToStr(cScreenWidth) + ' x ' + IntToStr(cScreenHeight));
ScriptOnScreenResize();
InitCameraBorders();
InitTouchInterface();
+ SendIPC('W' + IntToStr(cScreenWidth) + 'x' + IntToStr(cScreenHeight));
end;
CurrTime:= SDL_GetTicks();
if PrevTime + longword(cTimerInterval) <= CurrTime then
begin
- isTerminated:= DoTimer(CurrTime - PrevTime);
+ isTerminated := isTerminated or DoTimer(CurrTime - PrevTime);
PrevTime:= CurrTime
end
else SDL_Delay(1);
@@ -313,48 +319,26 @@ end;
{$ENDIF}
///////////////////////////////////////////////////////////////////////////////
-procedure Game{$IFDEF HWLIBRARY}(gameArgs: PPChar); cdecl; export{$ENDIF};
-var p: TPathType;
- s: shortstring;
+procedure Game{$IFDEF HWLIBRARY}(argc: LongInt; argv: PPChar); cdecl; export{$ENDIF};
+//var p: TPathType;
+var s: shortstring;
i: LongInt;
begin
{$IFDEF HWLIBRARY}
preInitEverything();
- cShowFPS:= {$IFDEF DEBUGFILE}true{$ELSE}false{$ENDIF};
- ipcPort:= StrToInt(gameArgs[0]);
- cScreenWidth:= StrToInt(gameArgs[1]);
- cScreenHeight:= StrToInt(gameArgs[2]);
- cReducedQuality:= StrToInt(gameArgs[3]);
- cLocaleFName:= gameArgs[4];
- UserNick:= gameArgs[5];
- SetSound(gameArgs[6] = '1');
- SetMusic(gameArgs[7] = '1');
- cAltDamage:= gameArgs[8] = '1';
- PathPrefix:= gameArgs[9];
- UserPathPrefix:= '../Documents';
- recordFileName:= gameArgs[10];
+ parseCommandLine(argc, argv);
{$ENDIF}
initEverything(true);
-
- WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (network protocol: ' + inttostr(cNetProtoVersion) + ')');
+ WriteLnToConsole('Hedgewars engine ' + cVersionString + '-r' + cRevisionString +
+ ' (' + cHashString + ') with protocol #' + inttostr(cNetProtoVersion));
AddFileLog('Prefix: "' + PathPrefix +'"');
AddFileLog('UserPrefix: "' + UserPathPrefix +'"');
-
+
for i:= 0 to ParamCount do
AddFileLog(inttostr(i) + ': ' + ParamStr(i));
- for p:= Succ(Low(TPathType)) to High(TPathType) do
- if (p <> ptMapCurrent) and (p <> ptData) then
- UserPathz[p]:= UserPathPrefix + '/Data/' + Pathz[p];
-
- UserPathz[ptData]:= UserPathPrefix + '/Data';
-
- for p:= Succ(Low(TPathType)) to High(TPathType) do
- if p <> ptMapCurrent then
- Pathz[p]:= PathPrefix + '/' + Pathz[p];
-
WriteToConsole('Init SDL... ');
- SDLTry(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_NOPARACHUTE) >= 0, true);
+ if not cOnlyStats then SDLTry(SDL_Init(SDL_INIT_VIDEO or SDL_INIT_NOPARACHUTE) >= 0, true);
WriteLnToConsole(msgOK);
SDL_EnableUNICODE(1);
@@ -369,7 +353,7 @@ begin
InitOffscreenOpenGL()
else
{$ENDIF}
- begin
+ begin
// show main window
if cFullScreen then
ParseCommand('fullscr 1', true)
@@ -381,18 +365,15 @@ begin
InitKbdKeyTable();
AddProgress();
- LoadLocale(UserPathz[ptLocale] + '/en.txt'); // Do an initial load with english
- LoadLocale(Pathz[ptLocale] + '/en.txt'); // Do an initial load with english
+ LoadLocale(cPathz[ptLocale] + '/en.txt'); // Do an initial load with english
if cLocaleFName <> 'en.txt' then
begin
// Try two letter locale first before trying specific locale overrides
- if (Length(cLocale) > 2) and (Copy(cLocale,1,2) <> 'en') then
+ if (Length(cLocale) > 3) and (Copy(cLocale, 1, 2) <> 'en') then
begin
- LoadLocale(UserPathz[ptLocale] + '/' + Copy(cLocale,1,2)+'.txt');
- LoadLocale(Pathz[ptLocale] + '/' + Copy(cLocale,1,2)+'.txt')
+ LoadLocale(cPathz[ptLocale] + '/' + Copy(cLocale, 1, 2) + '.txt')
end;
- LoadLocale(UserPathz[ptLocale] + '/' + cLocaleFName);
- LoadLocale(Pathz[ptLocale] + '/' + cLocaleFName)
+ LoadLocale(cPathz[ptLocale] + '/' + cLocaleFName)
end
else cLocale := 'en';
@@ -449,7 +430,6 @@ procedure initEverything (complete:boolean);
begin
uUtils.initModule(complete); // opens the debug file, must be the first
uVariables.initModule; // inits all global variables
- uConsole.initModule; // opens stdout
uCommands.initModule; // helps below
uCommandHandlers.initModule; // registers all messages from frontend
@@ -459,6 +439,7 @@ begin
if complete then
begin
+ uPhysFSLayer.initModule;
{$IFDEF ANDROID}GLUnit.initModule;{$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}uTouch.initModule;{$ENDIF}
{$IFDEF USE_VIDEO_RECORDING}uVideoRec.initModule;{$ENDIF} //stub
@@ -510,6 +491,7 @@ begin
{$IFDEF USE_VIDEO_RECORDING}uVideoRec.freeModule;{$ENDIF}
{$IFDEF USE_TOUCH_INTERFACE}uTouch.freeModule;{$ENDIF} //stub
{$IFDEF ANDROID}GLUnit.freeModule;{$ENDIF}
+ uPhysFSLayer.freeModule;
end;
uIO.freeModule;
@@ -518,7 +500,6 @@ begin
uCommandHandlers.freeModule;
uCommands.freeModule;
- uConsole.freeModule; // closes stdout
uVariables.freeModule;
uUtils.freeModule; // closes debug file
end;
@@ -546,60 +527,6 @@ begin
end;
{$IFNDEF HWLIBRARY}
-///////////////////////////////////////////////////////////////////////////////
-procedure DisplayUsage;
-var i: LongInt;
-begin
- WriteLn(stdout, 'Wrong argument format: correct configurations is');
- WriteLn(stdout, '');
- WriteLn(stdout, ' hwengine <path to user hedgewars folder> <path to global data folder> <path to replay file> [options]');
- WriteLn(stdout, '');
- WriteLn(stdout, 'where [options] must be specified either as:');
- WriteLn(stdout, ' --set-video [screen width] [screen height] [color dept]');
- WriteLn(stdout, ' --set-audio [volume] [enable music] [enable sounds]');
- WriteLn(stdout, ' --set-other [language file] [full screen] [show FPS]');
- WriteLn(stdout, ' --set-multimedia [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen]');
- WriteLn(stdout, ' --set-everything [screen width] [screen height] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]');
- WriteLn(stdout, ' --stats-only');
- WriteLn(stdout, '');
- WriteLn(stdout, 'Read documentation online at http://code.google.com/p/hedgewars/wiki/CommandLineOptions for more information');
- WriteLn(stdout, '');
- Write(stdout, 'PARSED COMMAND: ');
-
- for i:=0 to ParamCount do
- Write(stdout, ParamStr(i) + ' ');
-
- WriteLn(stdout, '');
-end;
-
-///////////////////////////////////////////////////////////////////////////////
-{$INCLUDE "ArgParsers.inc"}
-
-procedure GetParams;
-begin
- if (ParamCount < 3) then
- GameType:= gmtSyntax
- else
- if (ParamCount = 3) and (ParamStr(3) = 'landpreview') then
- begin
- ipcPort:= StrToInt(ParamStr(2));
- GameType:= gmtLandPreview;
- end
- else
- begin
- if (ParamCount = 3) and (ParamStr(3) = '--stats-only') then
- playReplayFileWithParameters()
- else
- if ParamCount = cDefaultParamNum then
- internalStartGameWithParameters()
-{$IFDEF USE_VIDEO_RECORDING}
- else if ParamCount = cVideorecParamNum then
- internalStartVideoRecordingWithParameters()
-{$ENDIF}
- else
- playReplayFileWithParameters();
- end
-end;
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// m a i n ///////////////////////////////////
@@ -610,9 +537,8 @@ begin
if GameType = gmtLandPreview then
GenLandPreview()
- else if GameType = gmtSyntax then
- DisplayUsage()
- else Game();
+ else if GameType <> gmtSyntax then
+ Game();
// return 1 when engine is not called correctly
halt(LongInt(GameType = gmtSyntax));
diff --git a/hedgewars/options.inc b/hedgewars/options.inc
index 0ba62bc..a0a9a6d 100644
--- a/hedgewars/options.inc
+++ b/hedgewars/options.inc
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,10 +29,8 @@
{$DEFINE USE_LUA_SCRIPT}
-
{$IFDEF ANDROID}
{$DEFINE MOBILE}
- {$DEFINE USE_SDLTHREADS}
{$DEFINE USE_CONTEXT_RESTORE}
{$DEFINE Java_Prefix:= 'Java_org_hedgewars_hedgeroid_EngineProtocol_PascalExports_'}
{$ENDIF}
@@ -43,12 +41,12 @@
{$IFDEF MOBILE}
{$DEFINE HWLIBRARY}
- {$DEFINE S3D_DISABLED}
{$DEFINE GLunit:=gles11}
{$DEFINE USE_LANDSCAPE_AMMOMENU}
{$DEFINE USE_TOUCH_INTERFACE}
{$ELSE}
{$DEFINE USE_AM_NUMCOLUMN}
+ {$DEFINE USE_S3D_RENDERING}
{$ENDIF}
@@ -66,14 +64,12 @@
{$DEFINE SDL13}
{$ENDIF}
-{$IFDEF PAS2C}
- {$DEFINE NOCONSOLE}
- {$DEFINE USE_SDLTHREADS}
-{$ENDIF}
+//TODO: cruft to be removed
{$DEFINE _S:=}
{$DEFINE _P:=}
+
//{$DEFINE TRACEAIACTIONS}
//{$DEFINE COUNTTICKS}
diff --git a/hedgewars/pas2c.h b/hedgewars/pas2c.h
deleted file mode 100644
index 2b414e6..0000000
--- a/hedgewars/pas2c.h
+++ /dev/null
@@ -1,144 +0,0 @@
-#pragma once
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <wchar.h>
-
-typedef union string255_
- {
- struct {
- char s[256];
- };
- struct {
- char len;
- char str[255];
- };
- } string255;
-typedef struct string192_
- {
- char s[193];
- } string192;
-typedef struct string31_
- {
- char s[32];
- } string31;
-typedef struct string15_
- {
- char s[16];
- } string15;
-
-typedef string255 shortstring;
-typedef string255 ansistring;
-
-typedef uint8_t Byte;
-typedef int8_t ShortInt;
-typedef uint16_t Word;
-typedef int16_t SmallInt;
-typedef uint32_t LongWord;
-typedef int32_t LongInt;
-typedef uint64_t QWord;
-typedef int64_t Int64;
-typedef LongWord Cardinal;
-
-typedef LongInt Integer;
-typedef float extended;
-typedef float real;
-typedef float single;
-
-typedef bool boolean;
-typedef int LongBool;
-
-typedef void * pointer;
-typedef Byte * PByte;
-typedef char * PChar;
-typedef LongInt * PLongInt;
-typedef LongWord * PLongWord;
-typedef Integer * PInteger;
-typedef int PtrInt;
-typedef wchar_t widechar;
-
-#define new(a) __new((void **)&a, sizeof(*(a)))
-void __new(void ** p, int size);
-#define dispose(a) __dispose(a, sizeof(*(a)))
-void __dispose(pointer p, int size);
-
-void * GetMem(int size);
-void FreeMem(void * p, int size);
-
-#define FillChar(a, b, c) __FillChar(&(a), b, c)
-
-void __FillChar(pointer p, int size, char fill);
-string255 _strconcat(string255 a, string255 b);
-string255 _strappend(string255 s, char c);
-string255 _strprepend(char c, string255 s);
-string255 _chrconcat(char a, char b);
-bool _strcompare(string255 a, string255 b);
-bool _strcomparec(string255 a, char b);
-bool _strncompare(string255 a, string255 b);
-char * _pchar(string255 s);
-string255 pchar2str(char * s);
-
-int Length(string255 a);
-string255 copy(string255 a, int s, int l);
-string255 delete(string255 a, int s, int l);
-string255 trim(string255 a);
-
-#define STRINIT(a) {.len = sizeof(a) - 1, .str = a}
-
-
-int length_ar(void * a);
-
-typedef int file;
-typedef int TextFile;
-extern int FileMode;
-extern int IOResult;
-extern int stdout;
-extern int stderr;
-
-#define assign(a, b) assign_(&(a), b)
-void assign_(int * f, string255 fileName);
-void reset_1(int f, int size);
-void reset_2(int f, int size);
-#define BlockRead(a, b, c, d) BlockRead_(a, &(b), c, &(d))
-void BlockRead_(int f, void * p, int size, int * sizeRead);
-#define BlockWrite(a, b, c) BlockWrite_(a, &(b), c)
-void BlockWrite_(int f, void * p, int size);
-void close(int f);
-
-void write(int f, string255 s);
-void writeLn(int f, string255 s);
-
-bool DirectoryExists(string255 dir);
-bool FileExists(string255 filename);
-
-bool odd(int i);
-
-
-typedef int TThreadId;
-void ThreadSwitch();
-#define InterlockedIncrement(a) __InterlockedIncrement(&(a))
-#define InterlockedDecrement(a) __InterlockedDecrement(&(a))
-void __InterlockedIncrement(int * a);
-void __InterlockedDecrement(int * a);
-
-bool Assigned(void * a);
-
-void randomize();
-int random(int max);
-int abs(int i);
-double sqr(double n);
-double sqrt(double n);
-int trunc(double n);
-int round(double n);
-
-string255 ParamStr(int n);
-int ParamCount();
-
-#define val(a, b, c) _val(a, (LongInt*)&(b), (LongInt*)&(c))
-void _val(string255 str, LongInt * a, LongInt * c);
-
-extern double pi;
-
-string255 EnumToStr(int a);
-string255 ExtractFileName(string255 f);
diff --git a/hedgewars/pas2cSystem.pas b/hedgewars/pas2cSystem.pas
deleted file mode 100644
index d75c5e6..0000000
--- a/hedgewars/pas2cSystem.pas
+++ /dev/null
@@ -1,148 +0,0 @@
-system;
-
-type
- Integer = integer;
- LongInt = integer;
- LongWord = integer;
- Cardinal = integer;
- PtrInt = integer;
- Word = integer;
- Byte = integer;
- SmallInt = integer;
- ShortInt = integer;
- QWord = integer;
- GLint = integer;
- GLuint = integer;
- int = integer;
- size_t = integer;
-
- pointer = pointer;
-
- float = float;
- single = float;
- double = float;
- real = float;
- extended = float;
- GLfloat = float;
-
- boolean = boolean;
- LongBool = boolean;
-
- string = string;
- shortstring = string;
- ansistring = string;
- widechar = string;
-
- char = char;
- PChar = ^char;
- PPChar = ^Pchar;
-
- PByte = ^Byte;
- PWord = ^Word;
- PLongInt = ^LongInt;
- PLongWord = ^LongWord;
- PInteger = ^Integer;
-
- Handle = integer;
-
- png_structp = pointer;
- png_size_t = integer;
-
-var
- false, true: boolean;
-
- write, writeLn, read, readLn: procedure;
-
- StrLen, ord, Succ, Pred : function : integer;
- inc, dec, Low, High, Lo, Hi : function : integer;
- odd, even : function : boolean;
-
- Now : function : integer;
-
- new, dispose, FillChar, Move : procedure;
-
- trunc, round : function : integer;
- abs, sqr : function : integer;
-
- StrPas, FormatDateTime, copy, delete, str, pos, trim, LowerCase : function : shortstring;
- Length, StrToInt : function : integer;
- SetLength, val : procedure;
- _pchar : function : PChar;
- pchar2str : function : string;
- memcpy : procedure;
-
- assign, rewrite, reset, flush, BlockWrite, BlockRead, close : procedure;
- IOResult : integer;
- exit, break, halt, continue : procedure;
- TextFile, file : Handle;
- FileMode : integer;
- FileExists, DirectoryExists, eof : function : boolean;
- ExtractFileName : function : string;
- exitcode : integer;
- stdout, stderr : Handle;
-
- ParamCount : function : integer;
- ParamStr : function : string;
-
- sqrt, arctan2, cos, sin, power : function : float;
- pi : float;
-
- TypeInfo, GetEnumName : function : shortstring;
-
- UTF8ToUnicode, WrapText: function : shortstring;
-
- sizeof : function : integer;
-
- GetMem : function : pointer;
- FreeMem : procedure;
-
- glGetString : function : pchar;
-
- glBegin, glBindTexture, glBlendFunc, glClear, glClearColor,
- glColor4ub, glColorMask, glColorPointer, glDeleteTextures,
- glDisable, glDisableClientState, glDrawArrays, glEnable,
- glEnableClientState, glEnd, glGenTextures, glGetIntegerv,
- glHint, glLineWidth, glLoadIdentity, glMatrixMode, glPopMatrix,
- glPushMatrix, glReadPixels, glRotatef, glScalef, glTexCoord2f,
- glTexCoordPointer, glTexImage2D, glTexParameterf,
- glTexParameteri, glTranslatef, glVertex2d, glVertexPointer,
- glViewport, glext_LoadExtension, glDeleteRenderbuffersEXT,
- glDeleteFramebuffersEXT, glGenFramebuffersEXT,
- glGenRenderbuffersEXT, glBindFramebufferEXT,
- glBindRenderbufferEXT, glRenderbufferStorageEXT,
- glFramebufferRenderbufferEXT, glFramebufferTexture2DEXT : procedure;
-
- GL_BGRA, GL_BLEND, GL_CLAMP_TO_EDGE, GL_COLOR_ARRAY,
- GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_DEPTH_COMPONENT,
- GL_DITHER, GL_EXTENSIONS, GL_FALSE, GL_FASTEST, GL_LINEAR,
- GL_LINE_LOOP, GL_LINES, GL_LINE_SMOOTH, GL_LINE_STRIP,
- GL_MAX_TEXTURE_SIZE, GL_MODELVIEW, GL_ONE_MINUS_SRC_ALPHA,
- GL_PERSPECTIVE_CORRECTION_HINT, GL_PROJECTION, GL_QUADS,
- GL_RENDERER, GL_RGBA, GL_RGBA8, GL_SRC_ALPHA, GL_TEXTURE_2D,
- GL_TEXTURE_COORD_ARRAY, GL_TEXTURE_MAG_FILTER,
- GL_TEXTURE_MIN_FILTER, GL_TEXTURE_PRIORITY, GL_TEXTURE_WRAP_S,
- GL_TEXTURE_WRAP_T, GL_TRIANGLE_FAN, GL_TRUE, GL_VENDOR,
- GL_VERSION, GL_VERTEX_ARRAY, GLenum, GL_FRAMEBUFFER_EXT,
- GL_RENDERBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
- GL_COLOR_ATTACHMENT0_EXT, GL_FLOAT, GL_UNSIGNED_BYTE : integer;
-
- TThreadId : function : integer;
- BeginThread, ThreadSwitch : procedure;
- InterlockedIncrement, InterlockedDecrement : procedure;
-
- random : function : integer;
- randomize : procedure;
-
- Assigned : function : boolean;
-
- _strconcat, _strappend, _strprepend, _chrconcat : function : string;
- _strcompare, _strncompare, _strcomparec : function : boolean;
-
- png_structp, png_set_write_fn, png_get_io_ptr,
- png_get_libpng_ver, png_create_write_struct,
- png_create_info_struct, png_destroy_write_struct,
- png_write_row, png_set_ihdr, png_write_info,
- png_write_end : procedure;
-
- EnumToStr : function : string;
-
diff --git a/hedgewars/uAI.pas b/hedgewars/uAI.pas
index 6d27b28..66e7354 100644
--- a/hedgewars/uAI.pas
+++ b/hedgewars/uAI.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,31 +30,27 @@ procedure FreeActionsList;
implementation
uses uConsts, SDLh, uAIMisc, uAIAmmoTests, uAIActions,
- uAmmos, SysUtils{$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF}, uTypes,
+ uAmmos, SysUtils, uTypes,
uVariables, uCommands, uUtils, uDebug, uAILandMarks;
var BestActions: TActions;
CanUseAmmo: array [TAmmoType] of boolean;
StopThinking: boolean;
-{$IFDEF USE_SDLTHREADS}
- ThinkThread: PSDL_Thread = nil;
-{$ELSE}
- ThinkThread: TThreadID;
-{$ENDIF}
- hasThread: LongInt;
StartTicks: Longword;
+ ThinkThread: PSDL_Thread;
+ ThreadLock: PSDL_Mutex;
procedure FreeActionsList;
begin
AddFileLog('FreeActionsList called');
- if hasThread <> 0 then
- begin
- AddFileLog('Waiting AI thread to finish');
+ if (ThinkThread <> nil) then
+ begin
StopThinking:= true;
- repeat
- SDL_Delay(10)
- until hasThread = 0
- end;
+ SDL_WaitThread(ThinkThread, nil);
+ end;
+ SDL_LockMutex(ThreadLock);
+ ThinkThread:= nil;
+ SDL_UnlockMutex(ThreadLock);
with CurrentHedgehog^ do
if Gear <> nil then
@@ -66,7 +62,6 @@ begin
end;
-
const cBranchStackSize = 12;
type TStackEntry = record
WastedTicks: Longword;
@@ -123,22 +118,18 @@ for i:= 0 to Pred(Targets.Count) do
with Me^.Hedgehog^ do
a:= CurAmmoType;
aa:= a;
-{$IFDEF USE_SDLTHREADS}
- SDL_delay(0); //ThreadSwitch was only a hint
-{$ELSE}
- ThreadSwitch();
-{$ENDIF}
+ SDL_delay(0); // hint to let the context switch run
repeat
- if (CanUseAmmo[a])
- and ((not rareChecks) or ((AmmoTests[a].flags and amtest_Rare) = 0))
- and ((i = 0) or ((AmmoTests[a].flags and amtest_NoTarget) = 0))
+ if (CanUseAmmo[a])
+ and ((not rareChecks) or ((AmmoTests[a].flags and amtest_Rare) = 0))
+ and ((i = 0) or ((AmmoTests[a].flags and amtest_NoTarget) = 0))
then
begin
{$HINTS OFF}
- Score:= AmmoTests[a].proc(Me, Targets.ar[i].Point, BotLevel, ap);
+ Score:= AmmoTests[a].proc(Me, Targets.ar[i], BotLevel, ap);
{$HINTS ON}
if Actions.Score + Score > BestActions.Score then
- if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel) * 2048) then
+ if (BestActions.Score < 0) or (Actions.Score + Score > BestActions.Score + Byte(BotLevel - 1) * 2048) then
begin
BestActions:= Actions;
inc(BestActions.Score, Score);
@@ -150,10 +141,10 @@ for i:= 0 to Pred(Targets.Count) do
AddAction(BestActions, aia_LookRight, 0, 200, 0, 0)
else if (ap.Angle < 0) then
AddAction(BestActions, aia_LookLeft, 0, 200, 0, 0);
-
+
if (Ammoz[a].Ammo.Propz and ammoprop_Timerable) <> 0 then
AddAction(BestActions, aia_Timer, ap.Time div 1000, 400, 0, 0);
-
+
if (Ammoz[a].Ammo.Propz and ammoprop_NoCrosshair) = 0 then
begin
dAngle:= LongInt(Me^.Angle) - Abs(ap.Angle);
@@ -168,23 +159,23 @@ for i:= 0 to Pred(Targets.Count) do
AddAction(BestActions, aia_Down, aim_release, -dAngle, 0, 0)
end
end;
-
+
if (Ammoz[a].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
begin
AddAction(BestActions, aia_Put, 0, 1, ap.AttackPutX, ap.AttackPutY)
end;
-
+
if (Ammoz[a].Ammo.Propz and ammoprop_OscAim) <> 0 then
begin
AddAction(BestActions, aia_attack, aim_push, 350 + random(200), 0, 0);
AddAction(BestActions, aia_attack, aim_release, 1, 0, 0);
-
+
if abs(ap.Angle) > 32 then
begin
AddAction(BestActions, aia_Down, aim_push, 100 + random(150), 0, 0);
AddAction(BestActions, aia_Down, aim_release, 32, 0, 0);
end;
-
+
AddAction(BestActions, aia_waitAngle, ap.Angle, 250, 0, 0);
AddAction(BestActions, aia_attack, aim_push, 1, 0, 0);
AddAction(BestActions, aia_attack, aim_release, 1, 0, 0);
@@ -243,21 +234,21 @@ else
if (Me^.State and gstAttacked) = 0 then
TestAmmos(Actions, Me, false);
-
+
BestRate:= RatePlace(Me);
BaseRate:= Max(BestRate, 0);
-// switch to 'skip' if we can't move because of mouse cursor being shown
+// switch to 'skip' if we cannot move because of mouse cursor being shown
if (Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) <> 0 then
AddAction(Actions, aia_Weapon, Longword(amSkip), 100 + random(200), 0, 0);
-
-if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0))
+
+if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoType].Ammo.Propz and ammoprop_NoMoveAfter) = 0))
and (GameFlags and gfArtillery = 0) then
begin
tmp:= random(2) + 1;
Push(0, Actions, Me^, tmp);
Push(0, Actions, Me^, tmp xor 3);
-
+
while (Stack.Count > 0) and (not StopThinking) do
begin
Pop(ticks, Actions, Me^);
@@ -267,7 +258,7 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
AddAction(Actions, aia_WaitXL, hwRound(Me^.X), 0, 0, 0)
else
AddAction(Actions, aia_WaitXR, hwRound(Me^.X), 0, 0, 0);
-
+
steps:= 0;
while (not StopThinking) do
@@ -280,8 +271,8 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
if ticks > maxticks then
break;
- if (BotLevel < 5)
- and (GoInfo.JumpType = jmpHJump)
+ if (BotLevel < 5)
+ and (GoInfo.JumpType = jmpHJump)
and (not checkMark(hwRound(Me^.X), hwRound(Me^.Y), markHJumped))
then // hjump support
begin
@@ -291,25 +282,20 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
begin
with Stack.States[Pred(Stack.Count)] do
begin
- if Me^.dX.isNegative then
+ if (Me^.Message and gmLeft) <> 0 then
AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0)
else
AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0);
-
+
AddAction(MadeActions, aia_HJump, 0, 305 + random(50), 0, 0);
AddAction(MadeActions, aia_HJump, 0, 350, 0, 0);
-
- if Me^.dX.isNegative then
- AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
- else
- AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
end;
// but first check walking forward
Push(ticks, Stack.States[Pred(Stack.Count)].MadeActions, AltMe, Me^.Message)
end;
end;
- if (BotLevel < 3)
- and (GoInfo.JumpType = jmpLJump)
+ if (BotLevel < 3)
+ and (GoInfo.JumpType = jmpLJump)
and (not checkMark(hwRound(Me^.X), hwRound(Me^.Y), markLJumped))
then // ljump support
begin
@@ -317,11 +303,18 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
// at final check where we go after jump walking backward
if Push(ticks, Actions, AltMe, Me^.Message xor 3) then
with Stack.States[Pred(Stack.Count)] do
+ begin
+ if (Me^.Message and gmLeft) <> 0 then
+ AddAction(MadeActions, aia_LookLeft, 0, 200, 0, 0)
+ else
+ AddAction(MadeActions, aia_LookRight, 0, 200, 0, 0);
+
AddAction(MadeActions, aia_LJump, 0, 305 + random(50), 0, 0);
+ end;
// push current position so we proceed from it after checking jump+forward walk opportunities
if CanGo then Push(ticks, Actions, Me^, Me^.Message);
-
+
// first check where we go after jump walking forward
if Push(ticks, Actions, AltMe, Me^.Message) then
with Stack.States[Pred(Stack.Count)] do
@@ -329,10 +322,10 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
break
end;
- // 'not CanGO' means we can't go straight, possible jumps are checked above
+ // 'not CanGO' means we cannot go straight, possible jumps are checked above
if not CanGo then
break;
-
+
inc(steps);
Actions.actions[Pred(Actions.Count)].Param:= hwRound(Me^.X);
Rate:= RatePlace(Me);
@@ -345,16 +338,17 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
end
else if Rate < BestRate then
break;
-
+
if ((Me^.State and gstAttacked) = 0) and ((steps mod 4) = 0) then
begin
if (steps > 4) and checkMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere) then
- break;
+ break;
addMark(hwRound(Me^.X), hwRound(Me^.Y), markWalkedHere);
TestAmmos(Actions, Me, ticks shr 12 = oldticks shr 12);
+
end;
-
+
if GoInfo.FallPix >= FallPixForBranching then
Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right
end {while};
@@ -365,25 +359,25 @@ if ((CurrentHedgehog^.MultiShootAttacks = 0) or ((Ammoz[Me^.Hedgehog^.CurAmmoTyp
end {if}
end;
-function Think(Me: Pointer): ptrint;
+function Think(Me: PGear): LongInt; cdecl; export;
var BackMe, WalkMe: TGear;
switchCount: LongInt;
StartTicks, currHedgehogIndex, itHedgehog, switchesNum, i: Longword;
switchImmediatelyAvailable: boolean;
Actions: TActions;
begin
-InterlockedIncrement(hasThread);
+dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
StartTicks:= GameTicks;
currHedgehogIndex:= CurrentTeam^.CurrHedgehog;
itHedgehog:= currHedgehogIndex;
switchesNum:= 0;
switchImmediatelyAvailable:= (CurAmmoGear <> nil) and (CurAmmoGear^.Kind = gtSwitcher);
-if PGear(Me)^.Hedgehog^.BotLevel <> 5 then
+if Me^.Hedgehog^.BotLevel <> 5 then
switchCount:= HHHasAmmo(PGear(Me)^.Hedgehog^, amSwitch)
else switchCount:= 0;
-if (PGear(Me)^.State and gstAttacked) = 0 then
+if ((Me^.State and gstAttacked) = 0) or isInMultiShoot then
if Targets.Count > 0 then
begin
// iterate over current team hedgehogs
@@ -399,7 +393,7 @@ if (PGear(Me)^.State and gstAttacked) = 0 then
begin
// when AI has to use switcher, make it cost smth unless they have a lot of switches
if (switchCount < 10) then Actions.Score:= (-27+switchCount*3)*4000;
- AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);
+ AddAction(Actions, aia_Weapon, Longword(amSwitch), 300 + random(200), 0, 0);
AddAction(Actions, aia_attack, aim_push, 300 + random(300), 0, 0);
AddAction(Actions, aia_attack, aim_release, 1, 0, 0);
end;
@@ -411,12 +405,11 @@ if (PGear(Me)^.State and gstAttacked) = 0 then
// find another hog in team
repeat
itHedgehog:= Succ(itHedgehog) mod CurrentTeam^.HedgehogsNumber;
- until (itHedgehog = currHedgehogIndex) or (CurrentTeam^.Hedgehogs[itHedgehog].Gear <> nil);
-
+ until (itHedgehog = currHedgehogIndex) or ((CurrentTeam^.Hedgehogs[itHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[itHedgehog].Effects[heFrozen]=0));
inc(switchesNum);
until (not (switchImmediatelyAvailable or (switchCount > 0)))
- or StopThinking
+ or StopThinking
or (itHedgehog = currHedgehogIndex)
or BestActions.isWalkingToABetterPlace;
@@ -429,11 +422,12 @@ if (PGear(Me)^.State and gstAttacked) = 0 then
AddAction(BestActions, aia_Skip, 0, 250, 0, 0);
end;
- end else
+ end else SDL_Delay(100)
else
begin
- BackMe:= PGear(Me)^;
- while (not StopThinking) and (BestActions.Count = 0) do
+ BackMe:= Me^;
+ i:= 12;
+ while (not StopThinking) and (BestActions.Count = 0) and (i > 0) do
begin
(*
// Maybe this would get a bit of movement out of them? Hopefully not *toward* water. Need to check how often he'd choose that strategy
@@ -446,14 +440,17 @@ else
Actions.Pos:= 0;
Actions.Score:= 0;
Walk(@WalkMe, Actions);
+ dec(i);
if not StopThinking then
SDL_Delay(100)
end
end;
-PGear(Me)^.State:= PGear(Me)^.State and (not gstHHThinking);
+Me^.State:= Me^.State and (not gstHHThinking);
+SDL_LockMutex(ThreadLock);
+ThinkThread:= nil;
+SDL_UnlockMutex(ThreadLock);
Think:= 0;
-InterlockedDecrement(hasThread)
end;
procedure StartThink(Me: PGear);
@@ -482,17 +479,16 @@ if Targets.Count = 0 then
exit
end;
-FillBonuses((Me^.State and gstAttacked) <> 0);
-AddFileLog('Enter Think Thread');
-{$IFDEF USE_SDLTHREADS}
-ThinkThread := SDL_CreateThread(@Think{$IFDEF SDL13}, nil{$ENDIF}, Me);
-{$ELSE}
-BeginThread(@Think, Me, ThinkThread);
-{$ENDIF}
-AddFileLog('Thread started');
+FillBonuses(((Me^.State and gstAttacked) <> 0) and (not isInMultiShoot));
+
+SDL_LockMutex(ThreadLock);
+ThinkThread:= SDL_CreateThread(@Think{$IFDEF SDL13}, 'think'{$ENDIF}, Me);
+SDL_UnlockMutex(ThreadLock);
end;
-//var scoreShown: boolean = false;
+{$IFDEF DEBUGAI}
+var scoreShown: boolean = false;
+{$ENDIF}
procedure ProcessBot;
const cStopThinkTime = 40;
@@ -510,21 +506,25 @@ with CurrentHedgehog^ do
StopMessages(Gear^.Message);
TryDo((Gear^.Message and gmAllStoppable) = 0, 'Engine bug: AI may break demos playing', true);
end;
-
+
if Gear^.Message <> 0 then
exit;
-
- //scoreShown:= false;
+
+{$IFDEF DEBUGAI}
+ scoreShown:= false;
+{$ENDIF}
StartThink(Gear);
StartTicks:= GameTicks
-
+
end else
begin
- {if not scoreShown then
+{$IFDEF DEBUGAI}
+ if not scoreShown then
begin
if BestActions.Score > 0 then ParseCommand('/say Expected score = ' + inttostr(BestActions.Score div 1024), true);
scoreShown:= true
- end;}
+ end;
+{$ENDIF}
ProcessAction(BestActions, Gear)
end
else if ((GameTicks - StartTicks) > cMaxAIThinkTime)
@@ -534,14 +534,15 @@ end;
procedure initModule;
begin
- hasThread:= 0;
StartTicks:= 0;
- ThinkThread:= ThinkThread;
+ ThinkThread:= nil;
+ ThreadLock:= SDL_CreateMutex();
end;
procedure freeModule;
begin
FreeActionsList();
+ SDL_DestroyMutex(ThreadLock);
end;
end.
diff --git a/hedgewars/uAIActions.pas b/hedgewars/uAIActions.pas
index 944eb9c..24c2d67 100644
--- a/hedgewars/uAIActions.pas
+++ b/hedgewars/uAIActions.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uAIAmmoTests.pas b/hedgewars/uAIAmmoTests.pas
index 9e74d22..6c1ad17 100644
--- a/hedgewars/uAIAmmoTests.pas
+++ b/hedgewars/uAIAmmoTests.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,8 +20,8 @@
unit uAIAmmoTests;
interface
-uses SDLh, uConsts, uFloat, uTypes;
-const
+uses SDLh, uConsts, uFloat, uTypes, uAIMisc;
+const
amtest_Rare = $00000001; // check only several positions
amtest_NoTarget = $00000002; // each pos, but no targetting
@@ -34,26 +34,27 @@ type TAttackParams = record
AttackPutX, AttackPutY: LongInt;
end;
-function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-
-type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+
+type TAmmoTestProc = function (Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
TAmmoTest = record
proc: TAmmoTestProc;
flags: Longword;
@@ -91,7 +92,7 @@ const AmmoTests: array[TAmmoType] of TAmmoTest =
(proc: @TestWatermelon; flags: 0), // amWatermelon
(proc: nil; flags: 0), // amHellishBomb
(proc: nil; flags: 0), // amNapalm
- (proc: nil; flags: 0), // amDrill
+ (proc: @TestDrillRocket; flags: 0), // amDrill
(proc: nil; flags: 0), // amBallgun
(proc: nil; flags: 0), // amRCPlane
(proc: nil; flags: 0), // amLowGravity
@@ -115,23 +116,21 @@ const AmmoTests: array[TAmmoType] of TAmmoTest =
(proc: nil; flags: 0), // amDrillStrike
(proc: nil; flags: 0), // amSnowball
(proc: nil; flags: 0), // amTardis
- (proc: nil; flags: 0), // amStructure
+ //(proc: nil; flags: 0), // amStructure
(proc: nil; flags: 0), // amLandGun
(proc: nil; flags: 0), // amIceGun
(proc: nil; flags: 0) // amKnife
);
-const BadTurn = Low(LongInt) div 4;
-
implementation
-uses uAIMisc, uVariables, uUtils, uGearsHandlers;
+uses uVariables, uUtils, uGearsHandlers;
function Metric(x1, y1, x2, y2: LongInt): LongInt; inline;
begin
Metric:= abs(x1 - x2) + abs(y1 - y2)
end;
-function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBazooka(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r, mX, mY: real;
rTime: LongInt;
EX, EY: LongInt;
@@ -148,8 +147,8 @@ ap.ExplR:= 0;
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(300);
- Vx:= - windSpeed * rTime * 0.5 + (Targ.X + AIrndSign(2) - mX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y - mY) / rTime;
+ Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y + 1 - mY) / rTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -164,16 +163,16 @@ repeat
dX:= dX + windSpeed;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
-
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0);
+
EX:= trunc(x);
EY:= trunc(y);
if Level = 1 then
value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
else value:= RateExplosion(Me, EX, EY, 101);
- if value = 0 then
- value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ if (value = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ value:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64;
if valueResult <= value then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
@@ -185,11 +184,92 @@ repeat
end;
end
//until (value > 204800) or (rTime > 4250); not so useful since adding score to the drowning
-until rTime > 4250;
+until rTime > 5050 - Level * 800;
TestBazooka:= valueResult
end;
-function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+
+function TestDrillRocket(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+var Vx, Vy, r, mX, mY: real;
+ rTime: LongInt;
+ EX, EY: LongInt;
+ valueResult: LongInt;
+ x, y, dX, dY: real;
+ t: LongInt;
+ value: LongInt;
+ t2: real;
+ timer: Longint;
+begin
+ if (Level > 3) then exit(BadTurn);
+
+ mX:= hwFloat2Float(Me^.X);
+ mY:= hwFloat2Float(Me^.Y);
+ ap.Time:= 0;
+ rTime:= 350;
+ ap.ExplR:= 0;
+ valueResult:= BadTurn;
+ repeat
+ rTime:= rTime + 300 + Level * 50 + random(300);
+ Vx:= - windSpeed * rTime * 0.5 + (Targ.Point.X + AIrndSign(2) - mX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - 35 - mY) / rTime;
+ r:= sqr(Vx) + sqr(Vy);
+ if not (r > 1) then
+ begin
+ x:= mX;
+ y:= mY;
+ dX:= Vx;
+ dY:= -Vy;
+ t:= rTime;
+ repeat
+ x:= x + dX;
+ y:= y + dY;
+ dX:= dX + windSpeed;
+ dY:= dY + cGravityf;
+ dec(t)
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (y > cWaterLine);
+
+ if TestCollExcludingObjects(trunc(x), trunc(y), 5) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then
+ begin
+ timer := 500;
+ t2 := 0.5 / sqrt(sqr(dX) + sqr(dY));
+ dX := dX * t2;
+ dY := dY * t2;
+ repeat
+ x:= x + dX;
+ y:= y + dY;
+ dec(timer);
+ until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 22)
+ or (x < 0)
+ or (y < 0)
+ or (trunc(x) > LAND_WIDTH)
+ or (trunc(y) > LAND_HEIGHT)
+ or not TestCollExcludingObjects(trunc(x), trunc(y), 5)
+ or (timer = 0)
+ end;
+ EX:= trunc(x);
+ EY:= trunc(y);
+ // Try to prevent AI from thinking firing into water will cause a drowning
+ if (EY < cWaterLine-5) and (Timer > 0) and (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) > 21) then exit(BadTurn);
+ if Level = 1 then
+ value:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
+ else value:= RateExplosion(Me, EX, EY, 101);
+ if valueResult <= value then
+ begin
+ ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random((Level - 1) * 9));
+ ap.Power:= trunc(sqrt(r) * cMaxPower) - random((Level - 1) * 17 + 1);
+ ap.ExplR:= 100;
+ ap.ExplX:= EX;
+ ap.ExplY:= EY;
+ valueResult:= value-2500 // trying to make it slightly less attractive than a bazooka, to prevent waste. AI could use awareness of weapon count
+ end;
+ end
+ until rTime > 5050 - Level * 800;
+ TestDrillRocket:= valueResult
+end;
+
+
+function TestSnowball(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r: real;
rTime: LongInt;
EX, EY: LongInt;
@@ -207,8 +287,8 @@ ap.ExplR:= 0;
valueResult:= BadTurn;
repeat
rTime:= rTime + 300 + Level * 50 + random(1000);
- Vx:= - windSpeed * rTime * 0.5 + ((Targ.X + AIrndSign(2)) - meX) / rTime;
- Vy:= cGravityf * rTime * 0.5 - (Targ.Y - meY) / rTime;
+ Vx:= - windSpeed * rTime * 0.5 + ((Targ.Point.X + AIrndSign(2)) - meX) / rTime;
+ Vy:= cGravityf * rTime * 0.5 - (Targ.Point.Y - meY) / rTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -223,14 +303,15 @@ repeat
dX:= dX + windSpeed;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t <= 0);
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t <= 0);
EX:= trunc(x);
EY:= trunc(y);
- value:= RateShove(trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
- if value = 0 then
- value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64;
+ value:= RateShove(Me, trunc(x), trunc(y), 5, 1, trunc((abs(dX)+abs(dY))*20), -dX, -dY, afTrackFall);
+ // LOL copypasta: this is score for digging with... snowball
+ //if value = 0 then
+ // value:= - Metric(Targ.Point.X, Targ.Point.Y, EX, EY) div 64;
if valueResult <= value then
begin
@@ -242,11 +323,11 @@ repeat
valueResult:= value
end;
end
-until (rTime > 4250);
+until (rTime > 5050 - Level * 800);
TestSnowball:= valueResult
end;
-function TestMolotov(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestMolotov(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
TestTime: Longword;
@@ -260,8 +341,8 @@ TestTime:= 0;
ap.ExplR:= 0;
repeat
inc(TestTime, 300);
- Vx:= (Targ.X - meX) / TestTime;
- Vy:= cGravityf * (TestTime div 2) - Targ.Y - meY / TestTime;
+ Vx:= (Targ.Point.X - meX) / TestTime;
+ Vy:= cGravityf * (TestTime div 2) - Targ.Point.Y - meY / TestTime;
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
@@ -274,15 +355,15 @@ repeat
y:= y + dY;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
if t < 50 then
Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly
else
Score:= BadTurn;
-
+
if valueResult < Score then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
@@ -293,11 +374,11 @@ repeat
valueResult:= Score
end;
end
-until (TestTime > 4250);
+until (TestTime > 5050 - Level * 800);
TestMolotov:= valueResult
end;
-function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestGrenade(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -312,13 +393,13 @@ meX:= hwFloat2Float(Me^.X);
meY:= hwFloat2Float(Me^.Y);
repeat
inc(TestTime, 1000);
- Vx:= (Targ.X - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Y - meY) / (TestTime + tDelta);
+ Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - (Targ.Point.Y - meY) / (TestTime + tDelta);
r:= sqr(Vx) + sqr(Vy);
if not (r > 1) then
begin
x:= meX;
- y:= meY;
+ y:= meY;
dY:= -Vy;
t:= TestTime;
repeat
@@ -326,21 +407,21 @@ repeat
y:= y + dY;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
- if t < 50 then
+ if t < 50 then
if Level = 1 then
Score:= RateExplosion(Me, EX, EY, 101, afTrackFall or afErasesLand)
else Score:= RateExplosion(Me, EX, EY, 101)
- else
+ else
Score:= BadTurn;
- if valueResult < Score then
+ if (valueResult < Score) and (Score > 0) then
begin
- ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
- ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
+ ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 3));
+ ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 20);
ap.Time:= TestTime;
ap.ExplR:= 100;
ap.ExplX:= EX;
@@ -349,11 +430,11 @@ repeat
end;
end
//until (Score > 204800) or (TestTime > 4000);
-until TestTime > 4000;
+until TestTime > 4500 - Level * 512;
TestGrenade:= valueResult
end;
-function TestClusterBomb(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestClusterBomb(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -369,11 +450,11 @@ meY:= hwFloat2Float(Me^.Y);
repeat
inc(TestTime, 900);
// Try to overshoot slightly, seems to pay slightly better dividends in terms of hitting cluster
- if meX<Targ.X then
- Vx:= ((Targ.X+10) - meX) / (TestTime + tDelta)
+ if meX<Targ.Point.X then
+ Vx:= ((Targ.Point.X+10) - meX) / (TestTime + tDelta)
else
- Vx:= ((Targ.X-10) - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
+ Vx:= ((Targ.Point.X-10) - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
r:= sqr(Vx)+sqr(Vy);
if not (r > 1) then
begin
@@ -386,18 +467,18 @@ repeat
y:= y + dY;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 5))) or (t = 0);
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 5)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 5))) or (t = 0);
EX:= trunc(x);
EY:= trunc(y);
- if t < 50 then
+ if t < 50 then
Score:= RateExplosion(Me, EX, EY, 41)
- else
+ else
Score:= BadTurn;
- if valueResult < Score then
+ if Score > 0 then
begin
- ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
+ ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level * 2));
ap.Power:= trunc(sqrt(r) * cMaxPower) + AIrndSign(random(Level) * 15);
ap.Time:= TestTime div 1000 * 1000;
ap.ExplR:= 90;
@@ -410,7 +491,7 @@ until (TestTime = 4100);
TestClusterBomb:= valueResult
end;
-function TestWatermelon(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWatermelon(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const tDelta = 24;
var Vx, Vy, r: real;
Score, EX, EY, valueResult: LongInt;
@@ -425,8 +506,8 @@ meX:= hwFloat2Float(Me^.X);
meY:= hwFloat2Float(Me^.Y);
repeat
inc(TestTime, 900);
- Vx:= (Targ.X - meX) / (TestTime + tDelta);
- Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Y-50) - meY) / (TestTime + tDelta);
+ Vx:= (Targ.Point.X - meX) / (TestTime + tDelta);
+ Vy:= cGravityf * ((TestTime + tDelta) div 2) - ((Targ.Point.Y-50) - meY) / (TestTime + tDelta);
r:= sqr(Vx)+sqr(Vy);
if not (r > 1) then
begin
@@ -439,16 +520,16 @@ repeat
y:= y + dY;
dY:= dY + cGravityf;
dec(t)
- until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, trunc(x), trunc(y), 6))) or (t = 0);
-
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(trunc(x), trunc(y), 6)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, trunc(x), trunc(y), 6))) or (t = 0);
+
EX:= trunc(x);
EY:= trunc(y);
- if t < 50 then
+ if t < 50 then
Score:= RateExplosion(Me, EX, EY, 200) + RateExplosion(Me, EX, EY + 120, 200)
- else
+ else
Score:= BadTurn;
-
+
if valueResult < Score then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
@@ -485,8 +566,8 @@ end;
else
Solve:= 0
end;
-
-function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+
+function TestMortar(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
//const tDelta = 24;
var Vx, Vy: real;
Score, EX, EY: LongInt;
@@ -502,13 +583,13 @@ begin
if (Level > 2) then
exit(BadTurn);
- TestTime:= Solve(Targ.X, Targ.Y, trunc(meX), trunc(meY));
+ TestTime:= Solve(Targ.Point.X, Targ.Point.Y, trunc(meX), trunc(meY));
if TestTime = 0 then
exit(BadTurn);
- Vx:= (Targ.X - meX) / TestTime;
- Vy:= cGravityf * (TestTime div 2) - (Targ.Y - meY) / TestTime;
+ Vx:= (Targ.Point.X - meX) / TestTime;
+ Vy:= cGravityf * (TestTime div 2) - (Targ.Point.Y - meY) / TestTime;
x:= meX;
y:= meY;
@@ -520,15 +601,15 @@ begin
dY:= dY + cGravityf;
EX:= trunc(x);
EY:= trunc(y);
- until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, EX, EY, 4))) or (EY > cWaterLine);
+ until (((Me = CurrentHedgehog^.Gear) and TestColl(EX, EY, 4)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, EX, EY, 4))) or (EY > cWaterLine);
if (EY < cWaterLine) and (dY >= 0) then
begin
Score:= RateExplosion(Me, EX, EY, 91);
if (Score = 0) then
- if (dY > 0.15) then
- Score:= - abs(Targ.Y - EY) div 32
+ if (dY > 0.15) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ Score:= - abs(Targ.Point.Y - EY) div 32
else
Score:= BadTurn
else if (Score < 0) then
@@ -537,7 +618,7 @@ begin
else
Score:= BadTurn;
- if BadTurn < Score then
+ if Score > 0 then
begin
ap.Angle:= DxDy2AttackAnglef(Vx, Vy) + AIrndSign(random(Level));
ap.Power:= 1;
@@ -548,7 +629,7 @@ begin
end;
end;
-function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestShotgun(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const
MIN_RANGE = 80;
MAX_RANGE = 400;
@@ -562,33 +643,33 @@ ap.Time:= 0;
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-range:= Metric(trunc(x), trunc(y), Targ.X, Targ.Y);
+range:= Metric(trunc(x), trunc(y), Targ.Point.X, Targ.Point.Y);
if ( range < MIN_RANGE ) or ( range > MAX_RANGE ) then
exit(BadTurn);
-Vx:= (Targ.X - x) * 1 / 1024;
-Vy:= (Targ.Y - y) * 1 / 1024;
+Vx:= (Targ.Point.X - x) * 1 / 1024;
+Vy:= (Targ.Point.Y - y) * 1 / 1024;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
repeat
x:= x + vX;
y:= y + vY;
rx:= trunc(x);
ry:= trunc(y);
- if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or
- ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me, rx, ry, 2)) then
+ if ((Me = CurrentHedgehog^.Gear) and TestColl(rx, ry, 2)) or
+ ((Me <> CurrentHedgehog^.Gear) and TestCollExcludingMe(Me^.Hedgehog^.Gear, rx, ry, 2)) then
begin
x:= x + vX * 8;
y:= y + vY * 8;
valueResult:= RateShotgun(Me, vX, vY, rx, ry);
-
- if valueResult = 0 then
- valueResult:= - Metric(Targ.X, Targ.Y, rx, ry) div 64
- else
+
+ if (valueResult = 0) and (Targ.Kind = gtHedgehog) and (Targ.Score > 0) then
+ valueResult:= 1024 - Metric(Targ.Point.X, Targ.Point.Y, rx, ry) div 64
+ else
dec(valueResult, Level * 4000);
// 27/20 is reuse bonus
exit(valueResult * 27 div 20)
end
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
+until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4)
or (x < 0)
or (y < 0)
or (trunc(x) > LAND_WIDTH)
@@ -597,27 +678,26 @@ until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
TestShotgun:= BadTurn
end;
-function TestDesertEagle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var Vx, Vy, x, y, t, dmgMod: real;
+function TestDesertEagle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+var Vx, Vy, x, y, t: real;
d: Longword;
fallDmg, valueResult: LongInt;
begin
-if Level > 4 then exit(BadTurn);
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
+if (Level > 4) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn);
Level:= Level; // avoid compiler hint
-ap.ExplR:= 0;
+ap.ExplR:= 1;
ap.Time:= 0;
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 20 then
+if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 20 then
exit(BadTurn);
-t:= 2 / sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y));
-Vx:= (Targ.X - x) * t;
-Vy:= (Targ.Y - y) * t;
+t:= 2 / sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y));
+Vx:= (Targ.Point.X - x) * t;
+Vy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
d:= 0;
@@ -627,47 +707,40 @@ repeat
if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0)
and (Land[trunc(y), trunc(x)] <> 0) then
inc(d);
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5)
+until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5)
or (x < 0)
or (y < 0)
or (trunc(x) > LAND_WIDTH)
or (trunc(y) > LAND_HEIGHT)
or (d > 48);
-if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 5 then
- begin
- fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00125 * 20, vY * 0.00125 * 20);
- if fallDmg < 0 then
- valueResult:= 204800
- else valueResult:= Max(0, (4 - d div 12) * trunc((7 + fallDmg) * dmgMod) * 1024)
- end
-else
- valueResult:= BadTurn;
+if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 5 then
+ valueResult:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, 7, 20, vX*0.125, vY*0.125, afTrackFall)
+else valueResult:= BadTurn;
TestDesertEagle:= valueResult
end;
-function TestSniperRifle(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
-var Vx, Vy, x, y, t, dmg, dmgMod: real;
+function TestSniperRifle(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
+var Vx, Vy, x, y, t, dmg: real;
d: Longword;
fallDmg: LongInt;
begin
-if Level > 3 then exit(BadTurn);
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
+if (Level > 3) or (Targ.Score < 0) or (Targ.Kind <> gtHedgehog) then exit(BadTurn);
Level:= Level; // avoid compiler hint
ap.ExplR:= 0;
ap.Time:= 0;
ap.Power:= 1;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
-if Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) < 40 then
+if Abs(trunc(x) - Targ.Point.X) + Abs(trunc(y) - Targ.Point.Y) < 40 then
exit(BadTurn);
-dmg:= sqrt(sqr(Targ.X - x)+sqr(Targ.Y-y));
+dmg:= sqrt(sqr(Targ.Point.X - x)+sqr(Targ.Point.Y-y));
t:= 1.5 / dmg;
dmg:= dmg * 0.025; // div 40
-Vx:= (Targ.X - x) * t;
-Vy:= (Targ.Y - y) * t;
+Vx:= (Targ.Point.X - x) * t;
+Vy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(Vx, -Vy);
d:= 0;
@@ -677,27 +750,20 @@ repeat
if ((trunc(x) and LAND_WIDTH_MASK) = 0)and((trunc(y) and LAND_HEIGHT_MASK) = 0)
and (Land[trunc(y), trunc(x)] <> 0) then
inc(d);
-until (Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4)
+until (Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4)
or (x < 0)
or (y < 0)
or (trunc(x) > LAND_WIDTH)
or (trunc(y) > LAND_HEIGHT)
or (d > 22);
-if Abs(Targ.X - trunc(x)) + Abs(Targ.Y - trunc(y)) < 4 then
- begin
- fallDmg:= TraceShoveFall(Targ.X, Targ.Y, vX * 0.00166 * dmg, vY * 0.00166 * dmg);
- if fallDmg < 0 then
- TestSniperRifle:= BadTurn
- else
- TestSniperRifle:= Max(0, trunc((dmg + fallDmg) * dmgMod) * 1024)
- end
-else
- TestSniperRifle:= BadTurn
+if Abs(Targ.Point.X - trunc(x)) + Abs(Targ.Point.Y - trunc(y)) < 4 then
+ TestSniperRifle:= RateShove(Me, Targ.Point.X, Targ.Point.Y, 1, trunc(dmg), 20, vX*0.166, vY*0.166, afTrackFall)
+else TestSniperRifle:= BadTurn;
end;
-function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestBaseballBat(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, a, v1, v2: LongInt;
x, y, trackFall: LongInt;
dx, dy: real;
@@ -721,20 +787,20 @@ begin
dx:= sin(a / cMaxAngle * pi) * 0.5;
dy:= cos(a / cMaxAngle * pi) * 0.5;
- v1:= RateShove(x - 10, y + 2
+ v1:= RateShove(Me, x - 10, y + 2
, 32, 30, 115
, -dx, -dy, trackFall);
- v2:= RateShove(x + 10, y + 2
+ v2:= RateShove(Me, x + 10, y + 2
, 32, 30, 115
, dx, -dy, trackFall);
if (v1 > valueResult) or (v2 > valueResult) then
- if (v2 > v1)
+ if (v2 > v1)
or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
begin
ap.Angle:= a;
valueResult:= v2
end
- else
+ else
begin
ap.Angle:= -a;
valueResult:= v1
@@ -742,14 +808,14 @@ begin
a:= a - 15 - random(cMaxAngle div 16)
end;
-
+
if valueResult <= 0 then
valueResult:= BadTurn;
TestBaseballBat:= valueResult;
end;
-function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestFirePunch(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2, i: LongInt;
x, y, trackFall: LongInt;
begin
@@ -767,11 +833,11 @@ begin
v1:= 0;
for i:= 0 to 8 do
begin
- v1:= v1 + RateShove(x - 5, y - 10 * i
+ v1:= v1 + RateShove(Me, x - 5, y - 10 * i
, 19, 30, 40
, -0.45, -0.9, trackFall or afSetSkip);
end;
- v1:= v1 + RateShove(x - 5, y - 90
+ v1:= v1 + RateShove(Me, x - 5, y - 90
, 19, 30, 40
, -0.45, -0.9, trackFall);
@@ -780,26 +846,26 @@ begin
v2:= 0;
for i:= 0 to 8 do
begin
- v2:= v2 + RateShove(x + 5, y - 10 * i
+ v2:= v2 + RateShove(Me, x + 5, y - 10 * i
, 19, 30, 40
, 0.45, -0.9, trackFall or afSetSkip);
end;
- v2:= v2 + RateShove(x + 5, y - 90
+ v2:= v2 + RateShove(Me, x + 5, y - 90
, 19, 30, 40
, 0.45, -0.9, trackFall);
- if (v2 > v1)
+ if (v2 > v1)
or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
begin
ap.Angle:= 1;
valueResult:= v2
end
- else
+ else
begin
ap.Angle:= -1;
valueResult:= v1
end;
-
+
if valueResult <= 0 then
valueResult:= BadTurn;
@@ -807,7 +873,7 @@ begin
end;
-function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestWhip(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2: LongInt;
x, y, trackFall: LongInt;
begin
@@ -823,37 +889,37 @@ begin
y:= hwRound(Me^.Y);
// check left direction
- {first RateShove checks farthermost of two whip's AmmoShove attacks
- to encourage distant attacks (damaged hog is excluded from view of second
+ {first RateShove checks farthermost of two whip's AmmoShove attacks
+ to encourage distant attacks (damaged hog is excluded from view of second
RateShove call)}
- v1:= RateShove(x - 13, y
+ v1:= RateShove(Me, x - 13, y
, 30, 30, 25
, -1, -0.8, trackFall or afSetSkip);
v1:= v1 +
- RateShove(x - 2, y
+ RateShove(Me, x - 2, y
, 30, 30, 25
, -1, -0.8, trackFall);
// now try opposite direction
- v2:= RateShove(x + 13, y
+ v2:= RateShove(Me, x + 13, y
, 30, 30, 25
, 1, -0.8, trackFall or afSetSkip);
v2:= v2 +
- RateShove(x + 2, y
+ RateShove(Me, x + 2, y
, 30, 30, 25
, 1, -0.8, trackFall);
- if (v2 > v1)
+ if (v2 > v1)
or {don't encourage turning for no gain}((v2 = v1) and (not Me^.dX.isNegative)) then
begin
ap.Angle:= 1;
valueResult:= v2
end
- else
+ else
begin
ap.Angle:= -1;
valueResult:= v1
end;
-
+
if valueResult <= 0 then
valueResult:= BadTurn
else
@@ -862,7 +928,7 @@ begin
TestWhip:= valueResult;
end;
-function TestKamikaze(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestKamikaze(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const step = 8;
var valueResult, i, v, tx: LongInt;
trackFall: LongInt;
@@ -872,19 +938,19 @@ begin
ap.Time:= 0;
ap.Power:= 1;
- if Level = 1 then
+ if Level = 1 then
trackFall:= afTrackFall
else if Level = 2 then
trackFall:= 0
else
exit(BadTurn);
-
+
valueResult:= 0;
v:= 0;
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
- d:= sqrt(sqr(Targ.X - x) + sqr(Targ.Y - y));
+ d:= sqrt(sqr(Targ.Point.X - x) + sqr(Targ.Point.Y - y));
if d < 10 then
begin
dx:= 0;
@@ -894,21 +960,21 @@ begin
else
begin
t:= step / d;
- dx:= (Targ.X - x) * t;
- dy:= (Targ.Y - y) * t;
+ dx:= (Targ.Point.X - x) * t;
+ dy:= (Targ.Point.Y - y) * t;
ap.Angle:= DxDy2AttackAnglef(dx, -dy)
end;
-
+
if dx >= 0 then cx:= 0.45 else cx:= -0.45;
for i:= 0 to 512 div step - 2 do
begin
- valueResult:= valueResult +
- RateShove(trunc(x), trunc(y)
+ valueResult:= valueResult +
+ RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall or afSetSkip);
-
+
x:= x + dx;
y:= y + dy;
end;
@@ -917,14 +983,14 @@ begin
x:= hwFloat2Float(Me^.X);
y:= hwFloat2Float(Me^.Y);
tx:= trunc(x);
- v:= RateShove(tx, trunc(y)
+ v:= RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall);
for i:= 1 to 512 div step - 2 do
begin
y:= y + dy;
- v:= v +
- RateShove(tx, trunc(y)
+ v:= v +
+ RateShove(Me, tx, trunc(y)
, 30, 30, 25
, -cx, -0.9, trackFall or afSetSkip);
end
@@ -935,7 +1001,7 @@ begin
valueResult:= v
end;
- v:= RateShove(trunc(x), trunc(y)
+ v:= RateShove(Me, trunc(x), trunc(y)
, 30, 30, 25
, cx, -0.9, trackFall);
valueResult:= valueResult + v - KillScore * friendlyfactor div 100 * 1024;
@@ -946,7 +1012,7 @@ begin
TestKamikaze:= valueResult;
end;
-function TestHammer(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestHammer(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var rate: LongInt;
begin
Level:= Level; // avoid compiler hint
@@ -956,14 +1022,14 @@ ap.ExplR:= 0;
ap.Time:= 0;
ap.Power:= 1;
ap.Angle:= 0;
-
+
rate:= RateHammer(Me);
if rate = 0 then
rate:= BadTurn;
TestHammer:= rate;
end;
-function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestAirAttack(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
const cShift = 4;
var bombsSpeed, X, Y, dY: real;
b: array[0..9] of boolean;
@@ -977,12 +1043,12 @@ if (Level > 3) then
exit(BadTurn);
ap.Angle:= 0;
-ap.AttackPutX:= Targ.X;
-ap.AttackPutY:= Targ.Y;
+ap.AttackPutX:= Targ.Point.X;
+ap.AttackPutY:= Targ.Point.Y;
bombsSpeed:= hwFloat2Float(cBombsSpeed);
-X:= Targ.X - 135 - cShift; // hh center - cShift
-X:= X - bombsSpeed * sqrt(((Targ.Y + 128) * 2) / cGravityf);
+X:= Targ.Point.X - 135 - cShift; // hh center - cShift
+X:= X - bombsSpeed * sqrt(((Targ.Point.Y + 128) * 2) / cGravityf);
Y:= -128;
dY:= 0;
@@ -1014,7 +1080,7 @@ until fexit or (Y > cWaterLine);
for i:= 0 to 5 do inc(valueResult, dmg[i]);
t:= valueResult;
-ap.AttackPutX:= Targ.X - 60;
+ap.AttackPutX:= Targ.Point.X - 60;
for i:= 0 to 3 do
begin
@@ -1023,7 +1089,7 @@ for i:= 0 to 3 do
if t > valueResult then
begin
valueResult:= t;
- ap.AttackPutX:= Targ.X - 30 - cShift + i * 30
+ ap.AttackPutX:= Targ.Point.X - 30 - cShift + i * 30
end
end;
@@ -1033,7 +1099,7 @@ TestAirAttack:= valueResult;
end;
-function TestTeleport(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestTeleport(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var
i, failNum: longword;
maxTop: longword;
@@ -1046,15 +1112,15 @@ begin
begin
if Me^.Health <= 100 then
begin
- maxTop := Targ.Y - cHHRadius * 2;
-
- while not TestColl(Targ.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do
+ maxTop := Targ.Point.Y - cHHRadius * 2;
+
+ while not TestColl(Targ.Point.X, maxTop, cHHRadius) and (maxTop > topY + cHHRadius * 2 + 1) do
dec(maxTop, cHHRadius*2);
- if not TestColl(Targ.X, maxTop + cHHRadius, cHHRadius) then
+ if not TestColl(Targ.Point.X, maxTop + cHHRadius, cHHRadius) then
begin
- ap.AttackPutX := Targ.X;
+ ap.AttackPutX := Targ.Point.X;
ap.AttackPutY := maxTop + cHHRadius;
- TestTeleport := Targ.Y - maxTop;
+ TestTeleport := Targ.Point.Y - maxTop;
end;
end;
end
@@ -1066,7 +1132,7 @@ begin
inc(failNum);
until not TestColl(bonuses.ar[i].X, bonuses.ar[i].Y - cHHRadius - bonuses.ar[i].Radius, cHHRadius)
or (failNum = bonuses.Count*2);
-
+
if failNum < bonuses.Count*2 then
begin
ap.AttackPutX := bonuses.ar[i].X;
@@ -1081,14 +1147,14 @@ procedure checkCakeWalk(Me, Gear: PGear; var ap: TAttackParams);
var i: Longword;
v: LongInt;
begin
-while (not TestColl(hwRound(Gear^.X), hwRound(Gear^.Y), 6)) and (Gear^.Y.Round < LAND_HEIGHT) do
+while (not TestColl(hwRound(Gear^.X), hwRound(Gear^.Y), 6)) and (Gear^.Y.Round < LongWord(LAND_HEIGHT)) do
Gear^.Y:= Gear^.Y + _1;
for i:= 0 to 2040 do
begin
cakeStep(Gear);
v:= RateExplosion(Me, hwRound(Gear^.X), hwRound(Gear^.Y), cakeDmg * 2, afTrackFall);
- if v > ap.Power then
+ if v > ap.Power then
begin
ap.ExplX:= hwRound(Gear^.X);
ap.ExplY:= hwRound(Gear^.Y);
@@ -1097,7 +1163,7 @@ for i:= 0 to 2040 do
end;
end;
-function TestCake(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
+function TestCake(Me: PGear; Targ: TTarget; Level: LongInt; var ap: TAttackParams): LongInt;
var valueResult, v1, v2: LongInt;
cake: TGear;
begin
@@ -1112,7 +1178,7 @@ begin
//FillChar(cake, sizeof(cake), 0);
cake.Radius:= 7;
- cake.CollisionMask:= $FF7F;
+ cake.CollisionMask:= lfNotCurrentMask;
cake.Hedgehog:= Me^.Hedgehog;
// check left direction
diff --git a/hedgewars/uAIMisc.pas b/hedgewars/uAIMisc.pas
index dd5f988..a23dc4d 100644
--- a/hedgewars/uAIMisc.pas
+++ b/hedgewars/uAIMisc.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,15 +28,20 @@ const MAXBONUS = 1024;
afErasesLand = $00000002;
afSetSkip = $00000004;
+ BadTurn = Low(LongInt) div 4;
-type TTarget = record
+type TTarget = record // starting to look more and more like a gear
Point: TPoint;
- Score: LongInt;
- skip: boolean;
+ Score, Radius: LongInt;
+ State: LongWord;
+ Density: real;
+ skip, matters, dead: boolean;
+ Kind: TGearType;
end;
TTargets = record
Count: Longword;
- ar: array[0..Pred(cMaxHHs)] of TTarget;
+ ar: array[0..Pred(256)] of TTarget;
+ reset: boolean;
end;
TJumpType = (jmpNone, jmpHJump, jmpLJump);
TGoInfo = record
@@ -54,6 +59,7 @@ procedure initModule;
procedure freeModule;
procedure FillTargets;
+procedure ResetTargets; inline;
procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); inline;
procedure FillBonuses(isAfterAttack: boolean);
procedure AwareOfExplosion(x, y, r: LongInt); inline;
@@ -62,11 +68,11 @@ function RatePlace(Gear: PGear): LongInt;
function TestColl(x, y, r: LongInt): boolean; inline;
function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
-function TraceShoveFall(x, y, dX, dY: Real): LongInt;
function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
-function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
-function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
+function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
+function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
function RateHammer(Me: PGear): LongInt;
@@ -88,50 +94,82 @@ var ThinkingHH: PGear;
const KillScore = 200;
var friendlyfactor: LongInt = 300;
+var dmgMod: real = 1.0;
implementation
uses uCollisions, uVariables, uUtils, uLandTexture, uGearsUtils;
-var
+var
KnownExplosion: record
X, Y, Radius: LongInt
end = (X: 0; Y: 0; Radius: 0);
+procedure ResetTargets; inline;
+var i: LongWord;
+begin
+if Targets.reset then
+ for i:= 0 to Targets.Count do
+ Targets.ar[i].dead:= false;
+Targets.reset:= false;
+end;
procedure FillTargets;
var i, t: Longword;
f, e: LongInt;
+ Gear: PGear;
begin
Targets.Count:= 0;
+Targets.reset:= false;
f:= 0;
e:= 0;
-for t:= 0 to Pred(TeamsCount) do
- with TeamsArray[t]^ do
- if not hasGone then
+Gear:= GearsList;
+while Gear <> nil do
+ begin
+ if (((Gear^.Kind = gtHedgehog) and
+ (Gear <> ThinkingHH) and
+ (Gear^.Health > Gear^.Damage) and
+ not(Gear^.Hedgehog^.Team^.hasgone)) or
+ ((Gear^.Kind = gtExplosives) and
+ (Gear^.Health > Gear^.Damage)) or
+ ((Gear^.Kind = gtMine) and
+ (Gear^.Health = 0) and
+ (Gear^.Damage < 35))
+ ) and
+ (Targets.Count < 256) then
+ begin
+ with Targets.ar[Targets.Count] do
begin
- for i:= 0 to cMaxHHIndex do
- if (Hedgehogs[i].Gear <> nil)
- and (Hedgehogs[i].Gear <> ThinkingHH)
- and (Hedgehogs[i].Gear^.Health > Hedgehogs[i].Gear^.Damage)
- then
+ skip:= false;
+ dead:= false;
+ Kind:= Gear^.Kind;
+ Radius:= Gear^.Radius;
+ Density:= hwFloat2Float(Gear^.Density)/3;
+ State:= Gear^.State;
+ matters:= (Gear^.AIHints and aihDoesntMatter) = 0;
+
+ Point.X:= hwRound(Gear^.X);
+ Point.Y:= hwRound(Gear^.Y);
+ if (Gear^.Kind = gtHedgehog) then
+ begin
+ if (Gear^.Hedgehog^.Team^.Clan = CurrentTeam^.Clan) then
begin
- with Targets.ar[Targets.Count], Hedgehogs[i] do
- begin
- skip:= false;
- Point.X:= hwRound(Gear^.X);
- Point.Y:= hwRound(Gear^.Y);
- if Clan <> CurrentTeam^.Clan then
- begin
- Score:= Gear^.Health - Gear^.Damage;
- inc(e)
- end else
- begin
- Score:= Gear^.Damage - Gear^.Health;
- inc(f)
- end
- end;
- inc(Targets.Count)
+ Score:= Gear^.Damage - Gear^.Health;
+ inc(f)
+ end
+ else
+ begin
+ Score:= Gear^.Health - Gear^.Damage;
+ inc(e)
end;
+ end
+ else if Gear^.Kind = gtExplosives then
+ Score:= Gear^.Health - Gear^.Damage
+ else if Gear^.Kind = gtMine then
+ Score:= max(0,35-Gear^.Damage);
end;
+ inc(Targets.Count)
+ end;
+ Gear:= Gear^.NextGear
+ end;
if e > f then friendlyfactor:= 300 + (e - f) * 30
else friendlyfactor:= max(30, 300 - f * 80 div max(1,e))
@@ -177,24 +215,24 @@ while Gear <> nil do
gtFlame:
if (Gear^.State and gsttmpFlag) <> 0 then
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 20, -50);
-// avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow
+// avoid mines unless they are very likely to be duds, or are duds. also avoid if they are about to blow
gtMine:
if ((Gear^.State and gstAttacking) = 0) and (((cMineDudPercent < 90) and (Gear^.Health <> 0))
or (isAfterAttack and (Gear^.Health = 0) and (Gear^.Damage > 30))) then
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -50)
else if (Gear^.State and gstAttacking) <> 0 then
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 100, -50); // mine is on
-
+
gtExplosives:
if isAfterAttack then
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 75, -60 + Gear^.Health);
-
+
gtSMine:
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 50, -30);
-
+
gtDynamite:
AddBonus(hwRound(Gear^.X), hwRound(Gear^.Y), 150, -75);
-
+
gtHedgehog:
begin
if Gear^.Damage >= Gear^.Health then
@@ -252,262 +290,380 @@ for i:= 0 to Pred(bonuses.Count) do
RatePlace:= rate;
end;
-// Wrapper to test various approaches. If it works reasonably, will just replace.
-// Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
-function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
-var MeX, MeY: LongInt;
+function CheckBounds(x, y, r: Longint): boolean; inline;
begin
- if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
- begin
- MeX:= hwRound(Me^.X);
- MeY:= hwRound(Me^.Y);
- // We are still inside the hog. Skip radius test
- if ((((x-MeX)*(x-MeX)) + ((y-MeY)*(y-MeY))) < 256) and ((Land[y, x] and $FF00) = 0) then
- exit(false);
- end;
- TestCollExcludingMe:= TestColl(x, y, r)
+ CheckBounds := (((x-r) and LAND_WIDTH_MASK) = 0) and
+ (((x+r) and LAND_WIDTH_MASK) = 0) and
+ (((y-r) and LAND_HEIGHT_MASK) = 0) and
+ (((y+r) and LAND_HEIGHT_MASK) = 0);
+end;
+
+
+function TestCollWithEverything(x, y, r: LongInt): boolean; inline;
+begin
+ if not CheckBounds(x, y, r) then
+ exit(false);
+
+ if (Land[y-r, x-r] <> 0) or
+ (Land[y+r, x-r] <> 0) or
+ (Land[y-r, x+r] <> 0) or
+ (Land[y+r, x+r] <> 0) then
+ exit(true);
+
+ TestCollWithEverything := false;
end;
function TestCollExcludingObjects(x, y, r: LongInt): boolean; inline;
-var b: boolean;
begin
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] and $FF00 <> 0);
- if b then
- exit(true);
-
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] and $FF00 <> 0);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] and $FF00 <> 0);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] and $FF00 <> 0);
- if b then
- exit(true);
-
+ if not CheckBounds(x, y, r) then
+ exit(false);
+
+ if (Land[y-r, x-r] > lfAllObjMask) or
+ (Land[y+r, x-r] > lfAllObjMask) or
+ (Land[y-r, x-r] > lfAllObjMask) or
+ (Land[y+r, x+r] > lfAllObjMask) then
+ exit(true);
+
TestCollExcludingObjects:= false;
end;
function TestColl(x, y, r: LongInt): boolean; inline;
-var b: boolean;
begin
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] and $FF7F <> 0);
- if b then
- exit(true);
-
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] and $FF7F <> 0);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] and $FF7F <> 0);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] and $FF7F <> 0);
- if b then
- exit(true);
-
+ if not CheckBounds(x, y, r) then
+ exit(false);
+
+ if (Land[y-r, x-r] and lfNotCurrentMask <> 0) or
+ (Land[y+r, x-r] and lfNotCurrentMask <> 0) or
+ (Land[y+r, x-r] and lfNotCurrentMask <> 0) or
+ (Land[y+r, x+r] and lfNotCurrentMask <> 0) then
+ exit(true);
+
TestColl:= false;
end;
-function TestCollWithLand(x, y, r: LongInt): boolean; inline;
-var b: boolean;
+
+// Wrapper to test various approaches. If it works reasonably, will just replace.
+// Right now, converting to hwFloat is a tad inefficient since the x/y were hwFloat to begin with...
+function TestCollExcludingMe(Me: PGear; x, y, r: LongInt): boolean; inline;
+var MeX, MeY: LongInt;
begin
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x-r] > 255);
- if b then
- exit(true);
-
- b:= (((x-r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x-r] > 255);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y-r) and LAND_HEIGHT_MASK) = 0) and (Land[y-r, x+r] > 255);
- if b then
- exit(true);
-
- b:= (((x+r) and LAND_WIDTH_MASK) = 0) and (((y+r) and LAND_HEIGHT_MASK) = 0) and (Land[y+r, x+r] > 255);
- if b then
- exit(true);
-
- TestCollWithLand:= false;
+ if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
+ begin
+ MeX:= hwRound(Me^.X);
+ MeY:= hwRound(Me^.Y);
+ // We are still inside the hog. Skip radius test
+ if ((sqr(x-MeX) + sqr(y-MeY)) < 256) and (Land[y, x] and lfObjMask = 0) then
+ exit(false);
+ end;
+ TestCollExcludingMe:= TestCollWithEverything(x, y, r)
end;
-function TraceFall(eX, eY: LongInt; x, y, dX, dY: Real; r: LongWord): LongInt;
+
+
+function TraceFall(eX, eY: LongInt; var x, y: Real; dX, dY: Real; r: LongWord; Target: TTarget): LongInt;
var skipLandCheck: boolean;
- rCorner: real;
+ rCorner, dxdy, odX, odY: real;
dmg: LongInt;
begin
+ odX:= dX;
+ odY:= dY;
skipLandCheck:= true;
- if x - eX < 0 then dX:= -dX;
- if y - eY < 0 then dY:= -dY;
// ok. attempt approximate search for an unbroken trajectory into water. if it continues far enough, assume out of map
rCorner:= r * 0.75;
while true do
- begin
+ begin
x:= x + dX;
y:= y + dY;
dY:= dY + cGravityf;
skipLandCheck:= skipLandCheck and (r <> 0) and (abs(eX-x) + abs(eY-y) < r) and ((abs(eX-x) < rCorner) or (abs(eY-y) < rCorner));
- if not skipLandCheck and TestCollWithLand(trunc(x), trunc(y), cHHRadius) then
- begin
- if 0.4 < dY then
- begin
- dmg := 1 + trunc((abs(dY) - 0.4) * 70);
- if dmg >= 1 then
- exit(dmg);
- end;
+ if not skipLandCheck and TestCollExcludingObjects(trunc(x), trunc(y), Target.Radius) then
+ with Target do
+ begin
+ if (Kind = gtHedgehog) and (0.4 < dY) then
+ begin
+ dmg := 1 + trunc((dY - 0.4) * 70);
+ exit(dmg)
+ end
+ else
+ begin
+ dxdy:= abs(dX)+abs(dY);
+ if ((Kind = gtMine) and (dxdy > 0.35)) or
+ ((Kind = gtExplosives) and
+ (((State and gstTmpFlag <> 0) and (dxdy > 0.35)) or
+ ((State and gstTmpFlag = 0) and
+ ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and
+ (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
+ begin
+ dmg := trunc(dxdy * 25);
+ exit(dmg)
+ end
+ else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
+ begin
+ dmg := trunc(dy * 70);
+ exit(dmg)
+ end
+ end;
exit(0)
- end;
- if (y > cWaterLine) or (x > 4096) or (x < 0) then
- exit(-1);
- end;
+ end;
+ if (y > cWaterLine) or (x > rightX) or (x < leftX) then exit(-1)
+ end
end;
-function TraceShoveFall(x, y, dX, dY: Real): LongInt;
+function TraceShoveFall(var x, y: Real; dX, dY: Real; Target: TTarget): LongInt;
var dmg: LongInt;
+ dxdy, odX, odY: real;
begin
+ odX:= dX;
+ odY:= dY;
//v:= random($FFFFFFFF);
while true do
- begin
+ begin
x:= x + dX;
y:= y + dY;
dY:= dY + cGravityf;
-{ if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then
+{ if ((trunc(y) and LAND_HEIGHT_MASK) = 0) and ((trunc(x) and LAND_WIDTH_MASK) = 0) then
begin
LandPixels[trunc(y), trunc(x)]:= v;
UpdateLandTexture(trunc(X), 1, trunc(Y), 1, true);
end;}
-
- // consider adding dX/dY calc here for fall damage
- if TestCollExcludingObjects(trunc(x), trunc(y), cHHRadius) then
- begin
- if 0.4 < dY then
- begin
- dmg := 1 + trunc((abs(dY) - 0.4) * 70);
- if dmg >= 1 then
+ if TestCollExcludingObjects(trunc(x), trunc(y), Target.Radius) then
+ with Target do
+ begin
+ if (Kind = gtHedgehog) and (0.4 < dY) then
+ begin
+ dmg := trunc((dY - 0.4) * 70);
exit(dmg);
- end;
+ end
+ else
+ begin
+ dxdy:= abs(dX)+abs(dY);
+ if ((Kind = gtMine) and (dxdy > 0.4)) or
+ ((Kind = gtExplosives) and
+ (((State and gstTmpFlag <> 0) and (dxdy > 0.4)) or
+ ((State and gstTmpFlag = 0) and
+ ((abs(odX) > 0.15) or ((abs(odY) > 0.15) and
+ (abs(odX) > 0.02))) and (dxdy > 0.35)))) then
+ begin
+ dmg := trunc(dxdy * 50);
+ exit(dmg)
+ end
+ else if (Kind = gtExplosives) and not((abs(odX) > 0.15) or ((abs(odY) > 0.15) and (abs(odX) > 0.02))) and (dY > 0.2) then
+ begin
+ dmg := trunc(dy * 70);
+ exit(dmg)
+ end
+ end;
exit(0)
end;
- if (y > cWaterLine) or (x > 4096) or (x < 0) then
+ if (y > cWaterLine) or (x > rightX) or (x < leftX) then
// returning -1 for drowning so it can be considered in the Rate routine
exit(-1)
end;
end;
-function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt;
+function RateExplosion(Me: PGear; x, y, r: LongInt): LongInt; inline;
begin
- RateExplosion:= RateExplosion(Me, x, y, r, 0);
+ RateExplosion:= RealRateExplosion(Me, x, y, r, 0);
+ ResetTargets;
+end;
+function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt; inline;
+begin
+ RateExplosion:= RealRateExplosion(Me, x, y, r, Flags);
+ ResetTargets;
end;
-function RateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
-var i, fallDmg, dmg, dmgBase, rate, erasure: LongInt;
- dX, dY, dmgMod: real;
+function RealRateExplosion(Me: PGear; x, y, r: LongInt; Flags: LongWord): LongInt;
+var i, fallDmg, dmg, dmgBase, rate, subrate, erasure: LongInt;
+ pX, pY, dX, dY: real;
+ hadSkips: boolean;
begin
fallDmg:= 0;
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
rate:= 0;
// add our virtual position
with Targets.ar[Targets.Count] do
begin
Point.x:= hwRound(Me^.X);
Point.y:= hwRound(Me^.Y);
+ skip:= false;
+ matters:= true;
+ Kind:= gtHedgehog;
+ Density:= 1;
+ Radius:= cHHRadius;
Score:= - ThinkingHH^.Health
end;
// rate explosion
-dmgBase:= r + cHHRadius div 2;
+
if (Flags and afErasesLand <> 0) and (GameFlags and gfSolidLand = 0) then erasure:= r
else erasure:= 0;
-for i:= 0 to Targets.Count do
- with Targets.ar[i] do
- begin
- dmg:= 0;
- if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
- dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
- if dmg > 0 then
+hadSkips:= false;
+
+for i:= 0 to Targets.Count do
+ if not Targets.ar[i].dead then
+ with Targets.ar[i] do
+ if not matters then hadSkips:= true
+ else
begin
- if (Flags and afTrackFall <> 0) and (dmg < abs(Score)) then
+ dmg:= 0;
+ dmgBase:= r + Radius div 2;
+ if abs(Point.x - x) + abs(Point.y - y) < dmgBase then
+ dmg:= trunc(dmgMod * min((dmgBase - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)))) div 2, r));
+
+ if dmg > 0 then
begin
- dX:= 0.005 * dmg + 0.01;
- dY:= dX;
- if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
- (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
- fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
- else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod)
- end;
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings
- else
- dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
- else if (dmg+fallDmg) >= abs(Score) then
- if Score > 0 then
- inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill
- else
- dec(rate, KillScore * friendlyfactor div 100 * 1024)
- else
- if Score > 0 then
- inc(rate, (dmg + fallDmg) * 1024)
- else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
+ pX:= Point.x;
+ pY:= Point.y;
+ fallDmg:= 0;
+ if (Flags and afTrackFall <> 0) and (Score > 0) and (dmg < Score) then
+ begin
+ dX:= (0.005 * dmg + 0.01) / Density;
+ dY:= dX;
+ if (Kind = gtExplosives) and (State and gstTmpFlag = 0) and
+ (((abs(dY) > 0.15) and (abs(dX) < 0.02)) or
+ ((abs(dY) < 0.15) and (abs(dX) < 0.15))) then
+ dX:= 0;
+
+ if pX - x < 0 then dX:= -dX;
+ if pY - y < 0 then dY:= -dY;
+
+ if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
+ (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
+ fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Targets.ar[i]) * dmgMod)
+ else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Targets.ar[i]) * dmgMod)
+ end;
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if (dmg+fallDmg) >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ begin
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or (Flags and afTrackFall));
+ if abs(subrate) > 2000 then inc(Rate,subrate)
+ end;
+ if Score > 0 then
+ inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill
+ else dec(rate, KillScore * friendlyfactor div 100 * 1024)
+ end
+ else
+ begin
+ if Score > 0 then
+ inc(rate, (dmg + fallDmg) * 1024)
+ else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024)
+ end
+ end
+ else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if Kind = gtExplosives then
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall))
+ else subrate:= RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall));
+ if abs(subrate) > 2000 then inc(Rate,subrate);
+ end
+ end
end;
- end;
-RateExplosion:= rate;
+
+if hadSkips and (rate = 0) then
+ RealRateExplosion:= BadTurn
+ else
+ RealRateExplosion:= rate;
end;
-function RateShove(x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
-var i, fallDmg, dmg, rate: LongInt;
- dX, dY, dmgMod: real;
+function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt;
+var i, fallDmg, dmg, rate, subrate: LongInt;
+ dX, dY, pX, pY: real;
begin
fallDmg:= 0;
dX:= gdX * 0.01 * kick;
dY:= gdY * 0.01 * kick;
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
rate:= 0;
for i:= 0 to Pred(Targets.Count) do
with Targets.ar[i] do
- if skip then
- if (Flags and afSetSkip = 0) then skip:= false else {still skip}
- else
- begin
- dmg:= 0;
- if abs(Point.x - x) + abs(Point.y - y) < r then
- dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
-
- if dmg > 0 then
+ if skip then
begin
- if (Flags and afSetSkip <> 0) then skip:= true;
- if (Flags and afTrackFall <> 0) and (Score > 0) then
- fallDmg:= trunc(TraceShoveFall(Point.x, Point.y - 2, dX, dY) * dmgMod);
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
- else
- dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
- else if power+fallDmg >= abs(Score) then
- if Score > 0 then
- inc(rate, KillScore)
- else
- dec(rate, KillScore * friendlyfactor div 100)
- else
- if Score > 0 then
- inc(rate, power+fallDmg)
- else
- dec(rate, (power+fallDmg) * friendlyfactor div 100)
+ if Flags and afSetSkip = 0 then skip:= false
+ end
+ else if matters then
+ begin
+ dmg:= 0;
+ if abs(Point.x - x) + abs(Point.y - y) < r then
+ dmg:= r - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
+
+ if dmg > 0 then
+ begin
+ pX:= Point.x;
+ pY:= Point.y-2;
+ fallDmg:= 0;
+ if (Flags and afSetSkip <> 0) then skip:= true;
+ if not(dead) and (Flags and afTrackFall <> 0) and (Score > 0) and (power < Score) then
+ if (Kind = gtExplosives) and (State and gstTmpFlag = 0) and
+ (((abs(dY) > 0.15) and (abs(dX) < 0.02)) or
+ ((abs(dY) < 0.15) and (abs(dX) < 0.15))) then
+ fallDmg:= trunc(TraceShoveFall(pX, pY, 0, dY, Targets.ar[i]) * dmgMod)
+ else
+ fallDmg:= trunc(TraceShoveFall(pX, pY, dX, dY, Targets.ar[i]) * dmgMod);
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if power+fallDmg >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ begin
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall);
+ if abs(subrate) > 2000 then inc(Rate,subrate div 1024)
+ end;
+ if Score > 0 then
+ inc(rate, KillScore)
+ else
+ dec(rate, KillScore * friendlyfactor div 100)
+ end
+ else
+ begin
+ if Score > 0 then
+ inc(rate, power+fallDmg)
+ else
+ dec(rate, (power+fallDmg) * friendlyfactor div 100)
+ end
+ end
+ else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if Kind = gtExplosives then
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or (Flags and afTrackFall))
+ else subrate:= RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or (Flags and afTrackFall));
+ if abs(subrate) > 2000 then inc(Rate,subrate div 1024);
+ end
+ end
end;
- end;
-RateShove:= rate * 1024
+RateShove:= rate * 1024;
+ResetTargets
end;
function RateShotgun(Me: PGear; gdX, gdY: real; x, y: LongInt): LongInt;
-var i, dmg, fallDmg, baseDmg, rate, erasure: LongInt;
- dX, dY, dmgMod: real;
+var i, dmg, fallDmg, baseDmg, rate, subrate, erasure: LongInt;
+ pX, pY, dX, dY: real;
+ hadSkips: boolean;
begin
-dmgMod:= 0.01 * hwFloat2Float(cDamageModifier) * cDamagePercent;
rate:= 0;
gdX:= gdX * 0.01;
gdY:= gdX * 0.01;
@@ -516,49 +672,96 @@ with Targets.ar[Targets.Count] do
begin
Point.x:= hwRound(Me^.X);
Point.y:= hwRound(Me^.Y);
+ skip:= false;
+ matters:= true;
+ Kind:= gtHedgehog;
+ Density:= 1;
+ Radius:= cHHRadius;
Score:= - ThinkingHH^.Health
end;
// rate shot
baseDmg:= cHHRadius + cShotgunRadius + 4;
+
if GameFlags and gfSolidLand = 0 then erasure:= cShotgunRadius
else erasure:= 0;
+
+hadSkips:= false;
+
for i:= 0 to Targets.Count do
- with Targets.ar[i] do
- begin
- dmg:= 0;
- if abs(Point.x - x) + abs(Point.y - y) < baseDmg then
- begin
- dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25);
- dmg:= trunc(dmg * dmgMod);
- end;
- if dmg > 0 then
- begin
- dX:= gdX * dmg;
- dY:= gdY * dmg;
- if dX < 0 then dX:= dX - 0.01
- else dX:= dX + 0.01;
- if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
- (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
- fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, 0) * dmgMod)
- else fallDmg:= trunc(TraceFall(x, y, Point.x, Point.y, dX, dY, erasure) * dmgMod);
- if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
- if Score > 0 then
- inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
- else
- dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
- else if (dmg+fallDmg) >= abs(Score) then
- if Score > 0 then
- inc(rate, KillScore)
- else
- dec(rate, KillScore * friendlyfactor div 100)
- else
- if Score > 0 then
- inc(rate, dmg+fallDmg)
+ if not Targets.ar[i].dead then
+ with Targets.ar[i] do
+ if not matters then hadSkips:= true
else
- dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
+ begin
+ dmg:= 0;
+ if abs(Point.x - x) + abs(Point.y - y) < baseDmg then
+ begin
+ dmg:= min(baseDmg - trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y))), 25);
+ dmg:= trunc(dmg * dmgMod);
+ end;
+ if dmg > 0 then
+ begin
+ if not(dead) and (Score > 0) and (dmg < Score) then
+ begin
+ pX:= Point.x;
+ pY:= Point.y;
+ dX:= gdX * dmg / Density;
+ dY:= gdY * dmg / Density;
+ if dX < 0 then dX:= dX - 0.01
+ else dX:= dX + 0.01;
+ if (Kind = gtExplosives) and (State and gstTmpFlag = 0) and
+ (((abs(dY) > 0.15) and (abs(dX) < 0.02)) or
+ ((abs(dY) < 0.15) and (abs(dX) < 0.15))) then
+ dX:= 0;
+ if (x and LAND_WIDTH_MASK = 0) and ((y+cHHRadius+2) and LAND_HEIGHT_MASK = 0) and
+ (Land[y+cHHRadius+2, x] and lfIndestructible <> 0) then
+ fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, 0, Targets.ar[i]) * dmgMod)
+ else fallDmg:= trunc(TraceFall(x, y, pX, pY, dX, dY, erasure, Targets.ar[i]) * dmgMod)
+ end;
+ if Kind = gtHedgehog then
+ begin
+ if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI
+ begin
+ if Score > 0 then
+ inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings
+ else
+ dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs
+ end
+ else if (dmg+fallDmg) >= abs(Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if dX < 0.035 then
+ begin
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 61, afErasesLand or afTrackFall);
+ if abs(subrate) > 2000 then inc(Rate,subrate div 1024)
+ end;
+ if Score > 0 then
+ inc(rate, KillScore)
+ else
+ dec(rate, KillScore * friendlyfactor div 100)
+ end
+ else if Score > 0 then
+ inc(rate, dmg+fallDmg)
+ else dec(rate, (dmg+fallDmg) * friendlyfactor div 100)
+ end
+ else if (fallDmg >= 0) and ((dmg+fallDmg) >= Score) then
+ begin
+ dead:= true;
+ Targets.reset:= true;
+ if Kind = gtExplosives then
+ subrate:= RealRateExplosion(Me, round(pX), round(pY), 151, afErasesLand or afTrackFall)
+ else subrate:= RealRateExplosion(Me, round(pX), round(pY), 101, afErasesLand or afTrackFall);
+ if abs(subrate) > 2000 then inc(Rate,subrate div 1024);
+ end
+ end
end;
- end;
-RateShotgun:= rate * 1024;
+
+if hadSkips and (rate = 0) then
+ RateShotgun:= BadTurn
+ else
+ RateShotgun:= rate * 1024;
+ ResetTargets;
end;
function RateHammer(Me: PGear): LongInt;
@@ -572,12 +775,12 @@ rate:= 0;
for i:= 0 to Pred(Targets.Count) do
with Targets.ar[i] do
// hammer hit radius is 8, shift is 10
- if abs(Point.x - x) + abs(Point.y - y) < 18 then
+ if matters and (Kind = gtHedgehog) and (abs(Point.x - x) + abs(Point.y - y) < 18) then
begin
r:= trunc(sqrt(sqr(Point.x - x)+sqr(Point.y - y)));
if r <= 18 then
- if Score > 0 then
+ if Score > 0 then
inc(rate, Score div 3)
else
inc(rate, Score div 3 * friendlyfactor div 100)
@@ -595,7 +798,7 @@ bX:= hwRound(Gear^.X);
bY:= hwRound(Gear^.Y);
case JumpType of
jmpNone: exit(false);
-
+
jmpHJump:
if TestCollisionYwithGear(Gear, -1) = 0 then
begin
@@ -605,7 +808,7 @@ case JumpType of
end
else
exit(false);
-
+
jmpLJump:
begin
if TestCollisionYwithGear(Gear, -1) <> 0 then
@@ -627,12 +830,12 @@ case JumpType of
end;
repeat
- {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
+ {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
begin
LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= Gear^.Hedgehog^.Team^.Clan^.Color;
UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
end;}
-
+
if not (hwRound(Gear^.Y) + cHHRadius < cWaterLine) then
exit(false);
if (Gear^.State and gstMoving) <> 0 then
@@ -682,7 +885,7 @@ function HHGo(Gear, AltGear: PGear; var GoInfo: TGoInfo): boolean;
var pX, pY, tY: LongInt;
begin
HHGo:= false;
-Gear^.CollisionMask:= $FF7F;
+Gear^.CollisionMask:= lfNotCurrentMask;
AltGear^:= Gear^;
GoInfo.Ticks:= 0;
@@ -690,7 +893,7 @@ GoInfo.FallPix:= 0;
GoInfo.JumpType:= jmpNone;
tY:= hwRound(Gear^.Y);
repeat
- {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
+ {if ((hwRound(Gear^.Y) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X) and LAND_WIDTH_MASK) = 0) then
begin
LandPixels[hwRound(Gear^.Y), hwRound(Gear^.X)]:= random($FFFFFFFF);//Gear^.Hedgehog^.Team^.Clan^.Color;
UpdateLandTexture(hwRound(Gear^.X), 1, hwRound(Gear^.Y), 1, true);
@@ -704,8 +907,8 @@ repeat
AddWalkBonus(pX, tY, 250, -40);
exit(false)
end;
-
- // hog is falling
+
+ // hog is falling
if (Gear^.State and gstMoving) <> 0 then
begin
inc(GoInfo.Ticks);
@@ -714,7 +917,7 @@ repeat
begin
GoInfo.FallPix:= 0;
// try ljump instead of fall with damage
- HHJump(AltGear, jmpLJump, GoInfo);
+ HHJump(AltGear, jmpLJump, GoInfo);
if AltGear^.Hedgehog^.BotLevel < 4 then
AddWalkBonus(pX, tY, 175, -20);
exit(false)
diff --git a/hedgewars/uAmmos.pas b/hedgewars/uAmmos.pas
index b5247d7..30061ac 100644
--- a/hedgewars/uAmmos.pas
+++ b/hedgewars/uAmmos.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uCaptions.pas b/hedgewars/uCaptions.pas
index e14f760..1767e56 100644
--- a/hedgewars/uCaptions.pas
+++ b/hedgewars/uCaptions.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,6 +44,7 @@ var
procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
begin
+ if cOnlyStats then exit;
if Captions[Group].Text <> s then
begin
FreeTexture(Captions[Group].Tex);
diff --git a/hedgewars/uChat.pas b/hedgewars/uChat.pas
index 623bc09..e5dcfed 100644
--- a/hedgewars/uChat.pas
+++ b/hedgewars/uChat.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,10 +25,10 @@ interface
procedure initModule;
procedure freeModule;
procedure ReloadLines;
-
+procedure CleanupInput;
procedure AddChatString(s: shortstring);
procedure DrawChat;
-procedure KeyPressChat(Key: Longword);
+procedure KeyPressChat(Key, Sym: Longword);
implementation
uses SDLh, uInputHandler, uTypes, uVariables, uCommands, uUtils, uTextures, uRender, uIO;
@@ -41,26 +41,40 @@ type TChatLine = record
Width: LongInt;
s: shortstring;
end;
+ TChatCmd = (quit, pause, finish, fullscreen);
var Strs: array[0 .. MaxStrIndex] of TChatLine;
MStrs: array[0 .. MaxStrIndex] of shortstring;
+ LocalStrs: array[0 .. MaxStrIndex] of shortstring;
missedCount: LongWord;
lastStr: LongWord;
+ localLastStr: LongWord;
+ history: LongWord;
visibleCount: LongWord;
InputStr: TChatLine;
InputStrL: array[0..260] of char; // for full str + 4-byte utf-8 char
ChatReady: boolean;
showAll: boolean;
-const colors: array[#0..#6] of TSDL_Color = (
- (r:$FF; g:$FF; b:$FF; unused:$FF), // unused, feel free to take it for anything
- (r:$FF; g:$FF; b:$FF; unused:$FF), // chat message [White]
- (r:$FF; g:$00; b:$FF; unused:$FF), // action message [Purple]
- (r:$90; g:$FF; b:$90; unused:$FF), // join/leave message [Lime]
- (r:$FF; g:$FF; b:$A0; unused:$FF), // team message [Light Yellow]
- (r:$FF; g:$00; b:$00; unused:$FF), // error messages [Red]
- (r:$00; g:$FF; b:$FF; unused:$FF) // input line [Light Blue]
- );
+const
+ colors: array[#0..#6] of TSDL_Color = (
+ (r:$FF; g:$FF; b:$FF; unused:$FF), // unused, feel free to take it for anything
+ (r:$FF; g:$FF; b:$FF; unused:$FF), // chat message [White]
+ (r:$FF; g:$00; b:$FF; unused:$FF), // action message [Purple]
+ (r:$90; g:$FF; b:$90; unused:$FF), // join/leave message [Lime]
+ (r:$FF; g:$FF; b:$A0; unused:$FF), // team message [Light Yellow]
+ (r:$FF; g:$00; b:$00; unused:$FF), // error messages [Red]
+ (r:$00; g:$FF; b:$FF; unused:$FF) // input line [Light Blue]
+ );
+ ChatCommandz: array [TChatCmd] of record
+ ChatCmd: string[31];
+ ProcedureCallChatCmd: string[31];
+ end = (
+ (ChatCmd: '/quit'; ProcedureCallChatCmd: 'halt'),
+ (ChatCmd: '/pause'; ProcedureCallChatCmd: 'pause'),
+ (ChatCmd: '/finish'; ProcedureCallChatCmd: 'finish'),
+ (ChatCmd: '/fullscreen'; ProcedureCallChatCmd: 'fullscr')
+ );
procedure SetLine(var cl: TChatLine; str: shortstring; isInput: boolean);
var strSurface, resSurface: PSDL_Surface;
@@ -181,7 +195,7 @@ and (Strs[i].Tex <> nil) do
i:= MaxStrIndex
else
dec(i);
-
+
inc(cnt);
inc(t)
end;
@@ -197,6 +211,7 @@ end;
procedure AcceptChatString(s: shortstring);
var i: TWave;
+ j: TChatCmd;
c, t: LongInt;
x: byte;
begin
@@ -204,13 +219,13 @@ t:= LocalTeam;
x:= 0;
if (s[1] = '"') and (s[Length(s)] = '"')
then x:= 1
-
+
else if (s[1] = '''') and (s[Length(s)] = '''') then
x:= 2
-
+
else if (s[1] = '-') and (s[Length(s)] = '-') then
x:= 3;
-
+
if not CurrentTeam^.ExtDriven and (x <> 0) then
for c:= 0 to Pred(TeamsCount) do
if (TeamsArray[c] = CurrentTeam) then
@@ -267,46 +282,78 @@ if (s[1] = '/') and (copy(s, 1, 4) <> '/me ') then
ParseCommand('/taunt ' + char(i), true);
exit
end;
+
+ for j:= Low(TChatCmd) to High(TChatCmd) do
+ if (s = ChatCommandz[j].ChatCmd) then
+ begin
+ ParseCommand(ChatCommandz[j].ProcedureCallChatCmd, true);
+ exit
+ end;
end
else
ParseCommand('/say ' + s, true);
end;
-procedure KeyPressChat(Key: Longword);
+procedure CleanupInput;
+begin
+ FreezeEnterKey;
+ history:= 0;
+ SDL_EnableKeyRepeat(0,0);
+ GameState:= gsGame;
+ ResetKbd;
+end;
+
+procedure KeyPressChat(Key, Sym: Longword);
const firstByteMark: array[0..3] of byte = (0, $C0, $E0, $F0);
-var i, btw: integer;
+var i, btw, index: integer;
utf8: shortstring;
+ action: boolean;
begin
-if Key <> 0 then
- case Key of
- {Backspace}
- 8, 127: if Length(InputStr.s) > 0 then
+ action:= true;
+ case Sym of
+ SDLK_BACKSPACE:
+ begin
+ if Length(InputStr.s) > 0 then
begin
InputStr.s[0]:= InputStrL[byte(InputStr.s[0])];
SetLine(InputStr, InputStr.s, true)
- end;
- {Esc}
- 27: if Length(InputStr.s) > 0 then SetLine(InputStr, '', true)
- else
- begin
- FreezeEnterKey;
- SDL_EnableKeyRepeat(0,0);
- GameState:= gsGame;
- ResetKbd;
- end;
- {Return}
- 3, 13, 271: begin
+ end
+ end;
+ SDLK_ESCAPE:
+ begin
+ if Length(InputStr.s) > 0 then
+ SetLine(InputStr, '', true)
+ else CleanupInput
+ end;
+ SDLK_RETURN:
+ begin
if Length(InputStr.s) > 0 then
begin
AcceptChatString(InputStr.s);
SetLine(InputStr, '', false)
end;
- FreezeEnterKey;
- SDL_EnableKeyRepeat(0,0);
- GameState:= gsGame;
- ResetKbd;
+ CleanupInput
end;
- else
+ SDLK_UP, SDLK_DOWN:
+ begin
+ if (Sym = SDLK_UP) and (history < localLastStr) then inc(history);
+ if (Sym = SDLK_DOWN) and (history > 0) then dec(history);
+ index:= localLastStr - history + 1;
+ if (index > localLastStr) then
+ SetLine(InputStr, '', true)
+ else SetLine(InputStr, LocalStrs[index], true)
+ end;
+ SDLK_RIGHT, SDLK_LEFT, SDLK_DELETE,
+ SDLK_HOME, SDLK_END,
+ SDLK_PAGEUP, SDLK_PAGEDOWN:
+ begin
+ // ignore me!!!
+ end;
+ else
+ action:= false;
+ end;
+ if not action and (Key <> 0) then
+ begin
if (Key < $80) then
btw:= 1
else if (Key < $800) then
@@ -316,22 +363,22 @@ if Key <> 0 then
else
btw:= 4;
- utf8:= '';
+ utf8:= '';
- for i:= btw downto 2 do
- begin
- utf8:= char((Key or $80) and $BF) + utf8;
- Key:= Key shr 6
- end;
+ for i:= btw downto 2 do
+ begin
+ utf8:= char((Key or $80) and $BF) + utf8;
+ Key:= Key shr 6
+ end;
- utf8:= char(Key or firstByteMark[Pred(btw)]) + utf8;
+ utf8:= char(Key or firstByteMark[Pred(btw)]) + utf8;
- if byte(InputStr.s[0]) + btw > 240 then
- exit;
+ if byte(InputStr.s[0]) + btw > 240 then
+ exit;
- InputStrL[byte(InputStr.s[0]) + btw]:= InputStr.s[0];
- SetLine(InputStr, InputStr.s + utf8, true)
- end
+ InputStrL[byte(InputStr.s[0]) + btw]:= InputStr.s[0];
+ SetLine(InputStr, InputStr.s + utf8, true)
+ end
end;
procedure chChatMessage(var s: shortstring);
@@ -346,7 +393,11 @@ begin
if copy(s, 1, 4) = '/me ' then
s:= #2 + '* ' + UserNick + ' ' + copy(s, 5, Length(s) - 4)
else
+ begin
+ localLastStr:= (localLastStr + 1) mod MaxStrIndex;
+ LocalStrs[localLastStr]:= s;
s:= #1 + UserNick + ': ' + s;
+ end;
AddChatString(s)
end;
@@ -374,17 +425,7 @@ begin
if length(s) = 0 then
SetLine(InputStr, '', true)
else
- begin
- // err, does anyone have any documentation on this sequence?
- // ^^ isn't it obvious? 27 is esc, 32 is space, inbetween is "/team"
- KeyPressChat(27);
- KeyPressChat(47);
- KeyPressChat(116);
- KeyPressChat(101);
- KeyPressChat(97);
- KeyPressChat(109);
- KeyPressChat(32)
- end
+ SetLine(InputStr, '/team ', true)
end;
procedure initModule;
@@ -397,6 +438,8 @@ begin
RegisterVariable('chat', @chChat, true );
lastStr:= 0;
+ localLastStr:= 0;
+ history:= 0;
visibleCount:= 0;
showAll:= false;
ChatReady:= false;
diff --git a/hedgewars/uCollisions.pas b/hedgewars/uCollisions.pas
index 9717cf1..44ce0df 100644
--- a/hedgewars/uCollisions.pas
+++ b/hedgewars/uCollisions.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -83,7 +83,7 @@ with cinfos[Count] do
X:= hwRound(Gear^.X);
Y:= hwRound(Gear^.Y);
Radius:= Gear^.Radius;
- ChangeRoundInLand(X, Y, Radius - 1, true, (Gear = CurrentHedgehog^.Gear) or (Gear^.Kind = gtCase));
+ ChangeRoundInLand(X, Y, Radius - 1, true, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen <> 0)));
cGear:= Gear
end;
Gear^.CollisionIndex:= Count;
@@ -104,7 +104,7 @@ begin
if Gear^.CollisionIndex >= 0 then
begin
with cinfos[Gear^.CollisionIndex] do
- ChangeRoundInLand(X, Y, Radius - 1, false, (Gear = CurrentHedgehog^.Gear) or (Gear^.Kind = gtCase));
+ ChangeRoundInLand(X, Y, Radius - 1, false, (Gear = CurrentHedgehog^.Gear) or ((Gear^.Kind = gtCase) and (Gear^.State and gstFrozen <> 0)));
cinfos[Gear^.CollisionIndex]:= cinfos[Pred(Count)];
cinfos[Gear^.CollisionIndex].cGear^.CollisionIndex:= Gear^.CollisionIndex;
Gear^.CollisionIndex:= -1;
@@ -139,7 +139,7 @@ function TestCollisionXwithGear(Gear: PGear; Dir: LongInt): boolean;
var x, y, i: LongInt;
begin
// Special case to emulate the old intersect gear clearing, but with a bit of slop for pixel overlap
-if (Gear^.CollisionMask = $FF7F) and (Gear^.Kind <> gtHedgehog) and (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) and
+if (Gear^.CollisionMask = lfNotCurrentMask) and (Gear^.Kind <> gtHedgehog) and (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) and
((hwRound(Gear^.Hedgehog^.Gear^.X) + Gear^.Hedgehog^.Gear^.Radius + 16 < hwRound(Gear^.X) - Gear^.Radius) or
(hwRound(Gear^.Hedgehog^.Gear^.X) - Gear^.Hedgehog^.Gear^.Radius - 16 > hwRound(Gear^.X) + Gear^.Radius)) then
Gear^.CollisionMask:= $FFFF;
@@ -169,7 +169,7 @@ function TestCollisionYwithGear(Gear: PGear; Dir: LongInt): Word;
var x, y, i: LongInt;
begin
// Special case to emulate the old intersect gear clearing, but with a bit of slop for pixel overlap
-if (Gear^.CollisionMask = $FF7F) and (Gear^.Kind <> gtHedgehog) and (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) and
+if (Gear^.CollisionMask = lfNotCurrentMask) and (Gear^.Kind <> gtHedgehog) and (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Gear <> nil) and
((hwRound(Gear^.Hedgehog^.Gear^.Y) + Gear^.Hedgehog^.Gear^.Radius + 16 < hwRound(Gear^.Y) - Gear^.Radius) or
(hwRound(Gear^.Hedgehog^.Gear^.Y) - Gear^.Hedgehog^.Gear^.Radius - 16 > hwRound(Gear^.Y) + Gear^.Radius)) then
Gear^.CollisionMask:= $FFFF;
diff --git a/hedgewars/uCommandHandlers.pas b/hedgewars/uCommandHandlers.pas
index b76fea6..de3012d 100644
--- a/hedgewars/uCommandHandlers.pas
+++ b/hedgewars/uCommandHandlers.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,11 +30,13 @@ uses uCommands, uTypes, uVariables, uIO, uDebug, uConsts, uScript, uUtils, SDLh,
{$IFDEF USE_VIDEO_RECORDING}, uVideoRec {$ENDIF};
var prevGState: TGameState = gsConfirm;
+ cTagsMasks : array[0..15] of byte = (7, 0, 0, 0, 15, 6, 4, 5, 0, 0, 0, 0, 0, 14, 12, 13);
+ cTagsMasksNoHealth: array[0..15] of byte = (3, 2, 11, 1, 0, 0, 0, 0, 0, 10, 0, 9, 0, 0, 0, 0);
procedure chGenCmd(var s: shortstring);
begin
case s[1] of
- 'R': if ReadyTimeLeft > 1 then
+ 'R': if ReadyTimeLeft > 1 then
begin
ReadyTimeLeft:= 1;
if not isExternalSource then
@@ -87,11 +89,11 @@ begin
end;
procedure chCheckProto(var s: shortstring);
-var i, c: LongInt;
+var i: LongInt;
begin
if isDeveloperMode then
begin
- val(s, i, c);
+ i:= StrToInt(s);
TryDo(i <= cNetProtoVersion, 'Protocol version mismatch: engine is too old (got '+intToStr(i)+', expecting '+intToStr(cNetProtoVersion)+')', true);
TryDo(i >= cNetProtoVersion, 'Protocol version mismatch: engine is too new (got '+intToStr(i)+', expecting '+intToStr(cNetProtoVersion)+')', true);
end
@@ -478,7 +480,7 @@ bShowFinger:= false;
with CurrentHedgehog^.Gear^ do
begin
Message:= Message or (gmSlot and InputMask);
- MsgParam:= slot;
+ MsgParam:= slot;
ScriptCall('onSlot', MsgParam);
end
end;
@@ -515,7 +517,7 @@ if not isExternalSource then
with CurrentHedgehog^.Gear^ do
begin
Message:= Message or (gmAnimate and InputMask);
- MsgParam:= byte(s[1]) ;
+ MsgParam:= byte(s[1]) ;
ScriptCall('onTaunt', MsgParam);
end
end;
@@ -548,15 +550,9 @@ begin
if isDeveloperMode then
begin
if s = '' then
- begin
- UserPathz[ptMapCurrent]:= s;
- Pathz[ptMapCurrent]:= s;
- end
+ cPathz[ptMapCurrent]:= s
else
- begin
- UserPathz[ptMapCurrent]:= UserPathz[ptMaps] + '/' + s;
- Pathz[ptMapCurrent]:= Pathz[ptMaps] + '/' + s;
- end;
+ cPathz[ptMapCurrent]:= cPathz[ptMaps] + '/' + s;
InitStepsFlags:= InitStepsFlags or cifMap
end;
cMapName:= s;
@@ -567,8 +563,7 @@ procedure chSetTheme(var s: shortstring);
begin
if isDeveloperMode then
begin
- UserPathz[ptCurrTheme]:= UserPathz[ptThemes] + '/' + s;
- Pathz[ptCurrTheme]:= Pathz[ptThemes] + '/' + s;
+ cPathz[ptCurrTheme]:= cPathz[ptThemes] + '/' + s;
Theme:= s;
InitStepsFlags:= InitStepsFlags or cifTheme
end
@@ -578,7 +573,7 @@ procedure chSetSeed(var s: shortstring);
begin
if isDeveloperMode then
begin
- SetRandomSeed(s);
+ SetRandomSeed(s, true);
cSeed:= s;
InitStepsFlags:= InitStepsFlags or cifRandomize
end
@@ -598,9 +593,8 @@ else
if bShowAmmoMenu then
bShowAmmoMenu:= false
- else if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0)
- or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
- or ((Gear^.State and gstHHDriven) = 0) then
+ else if not(CurrentTeam^.Extdriven) and (((Gear^.State and (gstAttacking or gstAttacked)) <> 0)
+ or ((Gear^.State and gstHHDriven) = 0)) then
begin
end
else
diff --git a/hedgewars/uCommands.pas b/hedgewars/uCommands.pas
index 7fac4ae..e962651 100644
--- a/hedgewars/uCommands.pas
+++ b/hedgewars/uCommands.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -88,12 +88,14 @@ isExternalSource:= ExternalSource or ((CurrentTeam <> nil) and CurrentTeam^.ExtD
//WriteLnToConsole(CmdStr);
if CmdStr[0]=#0 then
exit;
+
+AddFileLog('[Cmd] ' + sanitizeForLog(CmdStr));
+
c:= CmdStr[1];
if (c = '/') or (c = '$') then
Delete(CmdStr, 1, 1);
s:= '';
SplitBySpace(CmdStr, s);
-AddFileLog('[Cmd] ' + CmdStr + ' (' + inttostr(length(s)) + ')');
t:= Variables;
while t <> nil do
diff --git a/hedgewars/uConsole.pas b/hedgewars/uConsole.pas
index ab828b7..866035c 100644
--- a/hedgewars/uConsole.pas
+++ b/hedgewars/uConsole.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,61 +21,26 @@
unit uConsole;
interface
-procedure initModule;
-procedure freeModule;
+
procedure WriteToConsole(s: shortstring);
procedure WriteLnToConsole(s: shortstring);
-function GetLastConsoleLine: shortstring;
function ShortStringAsPChar(s: shortstring): PChar;
-implementation
-uses Types, uVariables, uUtils {$IFDEF ANDROID}, log in 'log.pas'{$ENDIF};
-
-const cLinesCount = 8;
-var cLineWidth: LongInt;
+var lastConsoleline : shortstring;
-type
- TTextLine = record
- s: shortstring
- end;
-
-var ConsoleLines: array[byte] of TTextLine;
- CurrLine: LongInt;
+implementation
+uses Types, uUtils {$IFDEF ANDROID}, log in 'log.pas'{$ENDIF};
-procedure SetLine(var tl: TTextLine; str: shortstring);
-begin
-with tl do
- s:= str;
-end;
procedure WriteToConsole(s: shortstring);
-{$IFNDEF NOCONSOLE}
-var Len: LongInt;
- done: boolean;
-{$ENDIF}
begin
{$IFNDEF NOCONSOLE}
-AddFileLog('[Con] ' + s);
+ AddFileLog('[Con] ' + s);
{$IFDEF ANDROID}
+ //TODO integrate this function in the uMobile record
Log.__android_log_write(Log.Android_LOG_DEBUG, 'HW_Engine', ShortStringAsPChar('[Con]' + s));
{$ELSE}
-Write(stderr, s);
-done:= false;
-
-while not done do
- begin
- Len:= cLineWidth - Length(ConsoleLines[CurrLine].s);
- SetLine(ConsoleLines[CurrLine], ConsoleLines[CurrLine].s + copy(s, 1, Len));
- Delete(s, 1, Len);
- if byte(ConsoleLines[CurrLine].s[0]) = cLineWidth then
- begin
- inc(CurrLine);
- if CurrLine = cLinesCount then
- CurrLine:= 0;
- PByte(@ConsoleLines[CurrLine].s)^:= 0
- end;
- done:= (Length(s) = 0);
- end;
+ Write(stderr, s);
{$ENDIF}
{$ENDIF}
end;
@@ -83,13 +48,10 @@ end;
procedure WriteLnToConsole(s: shortstring);
begin
{$IFNDEF NOCONSOLE}
-WriteToConsole(s);
+ WriteToConsole(s);
+ lastConsoleline:= s;
{$IFNDEF ANDROID}
-WriteLn(stderr, '');
-inc(CurrLine);
-if CurrLine = cLinesCount then
- CurrLine:= 0;
-PByte(@ConsoleLines[CurrLine].s)^:= 0
+ WriteLn(stderr, '');
{$ENDIF}
{$ENDIF}
end;
@@ -102,37 +64,5 @@ begin
ShortStringAsPChar:= @s[1];
end;
-function GetLastConsoleLine: shortstring;
-var valueStr: shortstring;
- i: LongWord;
-begin
-i:= (CurrLine + cLinesCount - 2) mod cLinesCount;
-valueStr:= ConsoleLines[i].s;
-
-valueStr:= valueStr + #10;
-
-i:= (CurrLine + cLinesCount - 1) mod cLinesCount;
-valueStr:= valueStr + ConsoleLines[i].s;
-
-GetLastConsoleLine:= valueStr;
-end;
-
-procedure initModule;
-var i: LongInt;
-begin
- CurrLine:= 0;
-
- // initConsole
- cLineWidth:= cScreenWidth div 10;
- if cLineWidth > 255 then
- cLineWidth:= 255;
- for i:= 0 to Pred(cLinesCount) do
- PByte(@ConsoleLines[i])^:= 0;
-end;
-
-procedure freeModule;
-begin
-
-end;
end.
diff --git a/hedgewars/uConsts.pas b/hedgewars/uConsts.pas
index 44baada..48ff781 100644
--- a/hedgewars/uConsts.pas
+++ b/hedgewars/uConsts.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@ uses SDLh, uFloat, GLunit;
const
sfMax = 1000;
- cDefaultParamNum = 17;
- cVideorecParamNum = cDefaultParamNum + 7;
// message constants
errmsgCreateSurface = 'Error creating SDL surface';
@@ -45,6 +43,9 @@ const
msgFailedSize = 'failed due to size';
msgGettingConfig = 'Getting game config...';
+ // camera movement multipliers
+ cameraKeyboardSpeed : ShortInt = 10;
+
// color constants
cWhiteColorChannels : TSDL_Color = (r:$FF; g:$FF; b:$FF; unused:$FF);
cNearBlackColorChannels : TSDL_Color = (r:$00; g:$00; b:$10; unused:$FF);
@@ -96,6 +97,16 @@ const
lfDamaged = $1000; //
lfIce = $0800; // blue
lfBouncy = $0400; // green
+ lfLandMask = $FF00; // upper byte is used for terrain, not objects.
+
+ lfCurrentHog = $0080; // CurrentHog. It is also used to flag crates, for convenience of AI. Since an active hog would instantly collect the crate, this doesn't impact play
+ lfNotCurrentMask = $FF7F; // inverse of above. frequently used
+ lfObjMask = $007F; // lower 7 bits used for hogs
+ lfNotObjMask = $FF80; // inverse of above.
+ // lower byte is for objects.
+ // consists of 0-127 counted for object checkins and $80 as a bit flag for current hog.
+ lfAllObjMask = $00FF; // lfCurrentHog or lfObjMask
+
cMaxPower = 1500;
cMaxAngle = 2048;
@@ -104,17 +115,13 @@ const
MAXNAMELEN = 192;
MAXROPEPOINTS = 3840;
- {$IFNDEF PAS2C}
// some opengl headers do not have these macros
GL_BGR = $80E0;
GL_BGRA = $80E1;
GL_CLAMP_TO_EDGE = $812F;
GL_TEXTURE_PRIORITY = $8066;
- {$ENDIF}
- cSendCursorPosTime : LongWord = 50;
cVisibleWater : LongInt = 128;
- cCursorEdgesDist : LongInt = 100;
cTeamHealthWidth : LongInt = 128;
cifRandomize = $00000001;
@@ -122,8 +129,6 @@ const
cifMap = $00000002; // either theme or map (or map+theme)
cifAllInited = cifRandomize or cifTheme or cifMap;
- cTransparentColor: Longword = $00000000;
-
RGB_LUMINANCE_RED = 0.212671;
RGB_LUMINANCE_GREEN = 0.715160;
RGB_LUMINANCE_BLUE = 0.072169;
@@ -131,18 +136,14 @@ const
cMaxTeams = 8;
cMaxHHIndex = 7;
cMaxHHs = 48;
- cMaxSpawnPoints = 1024;
cMaxEdgePoints = 16384;
cHHRadius = 9;
cHHStepTicks = 29;
- cUsualZ = 500;
- cSmokeZ = 499;
cHHZ = 1000;
cCurrHHZ = Succ(cHHZ);
- cOnHHZ = 2000;
cBarrelHealth = 60;
cShotgunRadius = 22;
@@ -152,30 +153,12 @@ const
cKeyMaxIndex = 1023;
cKbdMaxIndex = 65536;//need more room for the modifier keys
- cHHFileName = 'Hedgehog';
- cCHFileName = 'Crosshair';
- cThemeCFGFilename = 'theme.cfg';
-
cFontBorder = 2;
// do not change this value
cDefaultZoomLevel = 2.0;
-{$IFDEF MOBILE}
- cMaxZoomLevel = 0.5;
- cMinZoomLevel = 3.5;
- cZoomDelta = 0.20;
-{$ELSE}
- cMaxZoomLevel = 1.0;
- cMinZoomLevel = 3.0;
- cZoomDelta = 0.25;
-{$ENDIF}
-
- cMinMaxZoomLevelDelta = cMaxZoomLevel - cMinZoomLevel;
-
- cSendEmptyPacketTime = 1000;
- trigTurns = $80000001;
-
+ // game flags
gfAny = $FFFFFFFF;
gfOneClanMode = $00000001; // used in trainings
gfMultiWeapon = $00000002; // used in trainings
@@ -208,6 +191,7 @@ const
// if a "game start notice" would be useful. If so,
// add one in uWorld.pas - look for "AddGoal".
+ // gear states
gstDrowning = $00000001;
gstHHDriven = $00000002;
gstMoving = $00000004;
@@ -228,7 +212,10 @@ const
gstLoser = $00080000;
gstHHGone = $00100000;
gstInvisible = $00200000;
+ gstSubmersible = $00400000;
+ gstFrozen = $00800000;
+ // gear messages
gmLeft = $00000001;
gmRight = $00000002;
gmUp = $00000004;
@@ -251,7 +238,12 @@ const
cMaxSlotIndex = 9;
cMaxSlotAmmoIndex = 5;
-
+
+ // ai hints
+ aihUsualProcessing = $00000000;
+ aihDoesntMatter = $00000001;
+
+ // ammo properties
ammoprop_Timerable = $00000001;
ammoprop_Power = $00000002;
ammoprop_NeedTarget = $00000004;
@@ -274,6 +266,7 @@ const
AMMO_INFINITE = 100;
+ // explosion flags
//EXPLAllDamageInRadius = $00000001; Completely unused for ages
EXPLAutoSound = $00000002;
EXPLNoDamage = $00000004;
@@ -293,40 +286,8 @@ const
NoPointX = Low(LongInt);
cTargetPointRef : TPoint = (X: NoPointX; Y: 0);
- // hog tag mask
- htNone = $00;
- htTeamName = $01;
- htName = $02;
- htHealth = $04;
- htTransparent = $08;
-
- AMAnimDuration = 200;
- AMHidden = 0;//AMState values
- AMShowingUp = 1;
- AMShowing = 2;
- AMHiding = 3;
-
- AMTypeMaskX = $00000001;
- AMTypeMaskY = $00000002;
- AMTypeMaskAlpha = $00000004;
- AMTypeMaskSlide = $00000008;
-
-{$IFDEF MOBILE}
- AMSlotSize = 48;
- AMTITLE = 30;
-{$ELSE}
- AMSlotSize = 32;
-{$ENDIF}
- AMSlotPadding = (AMSlotSize - 32) shr 1;
-
-{$IFDEF USE_TOUCH_INTERFACE}
- FADE_ANIM_TIME = 500;
- MOVE_ANIM_TIME = 500;
-{$ENDIF}
-
- cTagsMasks : array[0..15] of byte = (7, 0, 0, 0, 15, 6, 4, 5, 0, 0, 0, 0, 0, 14, 12, 13);
- cTagsMasksNoHealth: array[0..15] of byte = (3, 2, 11, 1, 0, 0, 0, 0, 0, 10, 0, 9, 0, 0, 0, 0);
-
+ kSystemSoundID_Vibrate = $00000FFF;
+
implementation
end.
diff --git a/hedgewars/uCursor.pas b/hedgewars/uCursor.pas
index a4c50fd..63c07a1 100644
--- a/hedgewars/uCursor.pas
+++ b/hedgewars/uCursor.pas
@@ -3,7 +3,9 @@ unit uCursor;
interface
procedure init;
+procedure resetPosition;
procedure updatePosition;
+procedure handlePositionUpdate(x, y: LongInt);
implementation
@@ -11,6 +13,11 @@ uses SDLh, uVariables;
procedure init;
begin
+ resetPosition();
+end;
+
+procedure resetPosition;
+begin
SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2);
end;
@@ -18,15 +25,20 @@ procedure updatePosition;
var x, y: LongInt;
begin
SDL_GetMouseState(@x, @y);
-
+
if(x <> cScreenWidth div 2) or (y <> cScreenHeight div 2) then
- begin
- CursorPoint.X:= CursorPoint.X + x - cScreenWidth div 2;
- CursorPoint.Y:= CursorPoint.Y - y + cScreenHeight div 2;
+ begin
+ handlePositionUpdate(x - cScreenWidth div 2, y - cScreenHeight div 2);
if cHasFocus then
SDL_WarpMouse(cScreenWidth div 2, cScreenHeight div 2);
- end
+ end
+end;
+
+procedure handlePositionUpdate(x, y: LongInt);
+begin
+ CursorPoint.X:= CursorPoint.X + x;
+ CursorPoint.Y:= CursorPoint.Y - y;
end;
end.
diff --git a/hedgewars/uDebug.pas b/hedgewars/uDebug.pas
index cf5c68c..f0dd60b 100644
--- a/hedgewars/uDebug.pas
+++ b/hedgewars/uDebug.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ begin
WriteLnToConsole(Msg);
if isFatalError then
begin
- ParseCommand('fatal ' + GetLastConsoleLine, true);
+ ParseCommand('fatal ' + lastConsoleline, true);
SDL_Quit;
halt(1)
end
diff --git a/hedgewars/uFloat.pas b/hedgewars/uFloat.pas
index d2c50e9..a37c121 100644
--- a/hedgewars/uFloat.pas
+++ b/hedgewars/uFloat.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -63,9 +63,7 @@ function hwFloat2Float (const i: hwFloat) : extended; inline;
// The implemented operators
operator = (const z1, z2: hwFloat) z : boolean; inline;
-{$IFDEF PAS2C}
-operator <> (const z1, z2: hwFloat) z : boolean; inline;
-{$ENDIF}
+
operator + (const z1, z2: hwFloat) z : hwFloat; inline;
operator - (const z1, z2: hwFloat) z : hwFloat; inline;
operator - (const z1: hwFloat) z : hwFloat; inline;
@@ -86,7 +84,8 @@ function hwRound(const t: hwFloat): LongInt; inline; // Does NOT really round bu
function hwAbs(const t: hwFloat): hwFloat; inline; // Returns the value of t with positive sign.
function hwSqr(const t: hwFloat): hwFloat; inline; // Returns the square value of parameter t.
function hwPow(const t: hwFloat; p: LongWord): hwFloat; inline; // Returns the power of the value
-function hwSqrt(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t.
+function hwSqrt1(const t: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t.
+function hwSqrt(const x: hwFloat): hwFloat; inline; // Returns the the positive square root of parameter t.
function Distance(const dx, dy: hwFloat): hwFloat; // Returns the distance between two points in 2-dimensional space, of which the parameters are the horizontal and vertical distance.
function DistanceI(const dx, dy: LongInt): hwFloat; // Same as above for integer parameters.
function AngleSin(const Angle: Longword): hwFloat;
@@ -221,19 +220,11 @@ if i.isNegative then
hwFloat2Float:= -hwFloat2Float;
end;
-{$IFNDEF WEB}
operator = (const z1, z2: hwFloat) z : boolean; inline;
begin
z:= (z1.isNegative = z2.isNegative) and (z1.QWordValue = z2.QWordValue);
end;
-{$IFDEF PAS2C}
-operator <> (const z1, z2: hwFloat) z : boolean; inline;
-begin
- z:= (z1.isNegative <> z2.isNegative) or (z1.QWordValue <> z2.QWordValue);
-end;
-{$ENDIF}
-
operator + (const z1, z2: hwFloat) z : hwFloat; inline;
begin
if z1.isNegative = z2.isNegative then
@@ -274,7 +265,7 @@ else
end
end;
-function isZero(const z: hwFloat): boolean; inline;
+function isZero(const z: hwFloat): boolean; inline;
begin
isZero := z.QWordValue = 0;
end;
@@ -287,7 +278,7 @@ else
if z1.QWordValue = z2.QWordValue then
b:= false
else
- b:= not((z1.QWordValue = z2.QWordValue) or ((z2.QWordValue < z1.QWordValue) <> z1.isNegative))
+ b:= (z2.QWordValue < z1.QWordValue) = z1.isNegative
end;
operator > (const z1, z2: hwFloat) b : boolean; inline;
@@ -300,102 +291,6 @@ else
else
b:= (z1.QWordValue > z2.QWordValue) <> z2.isNegative
end;
-{$ENDIF}
-{$IFDEF WEB}
-(*
- Mostly to be kind to JS as of 2012-08-27 where there is no int64/uint64. This may change though.
-*)
-operator = (const z1, z2: hwFloat) z : boolean; inline;
-begin
- z:= (z1.isNegative = z2.isNegative) and (z1.Frac = z2.Frac) and (z1.Round = z2.Round);
-end;
-
-operator <> (const z1, z2: hwFloat) z : boolean; inline;
-begin
- z:= (z1.isNegative <> z2.isNegative) or (z1.Frac <> z2.Frac) or (z1.Round <> z2.Round);
-end;
-
-operator + (const z1, z2: hwFloat) z : hwFloat; inline;
-begin
-if z1.isNegative = z2.isNegative then
- begin
- z:= z1;
- z.Frac:= z.Frac + z2.Frac;
- z.Round:= z.Round + z2.Round;
- if z.Frac<z1.Frac then inc(z.Round)
- end
-else
- if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then
- begin
- z.isNegative:= z1.isNegative;
- z.Round:= z1.Round - z2.Round;
- z.Frac:= z1.Frac - z2.Frac;
- if z2.Frac > z1.Frac then dec(z.Round)
- end
- else
- begin
- z.isNegative:= z2.isNegative;
- z.Round:= z2.Round - z1.Round;
- z.Frac:= z2.Frac-z1.Frac;
- if z2.Frac < z1.Frac then dec(z.Round)
- end
-end;
-
-operator - (const z1, z2: hwFloat) z : hwFloat; inline;
-begin
-if z1.isNegative = z2.isNegative then
- if (z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac)) then
- begin
- z.isNegative:= z1.isNegative;
- z.Round:= z1.Round - z2.Round;
- z.Frac:= z1.Frac-z2.Frac;
- if z2.Frac > z1.Frac then dec(z.Round)
- end
- else
- begin
- z.isNegative:= not z2.isNegative;
- z.Round:= z2.Round - z1.Round;
- z.Frac:= z2.Frac-z1.Frac;
- if z2.Frac < z1.Frac then dec(z.Round)
- end
-else
- begin
- z:= z1;
- z.Frac:= z.Frac + z2.Frac;
- z.Round:= z.Round + z2.Round;
- if z.Frac<z1.Frac then inc(z.Round)
- end
-end;
-
-operator < (const z1, z2: hwFloat) b : boolean; inline;
-begin
-if z1.isNegative xor z2.isNegative then
- b:= z1.isNegative
-else
-(* Not so sure this specialcase is a win w/ Round/Frac. have to do more tests anyway.
- if (z1.Round = z2.Round and (z1.Frac = z2.Frac)) then
- b:= false
- else *)
- b:= ((z1.Round < z2.Round) or ((z1.Round = z2.Round) and (z1.Frac < z2.Frac))) <> z1.isNegative
-end;
-
-operator > (const z1, z2: hwFloat) b : boolean; inline;
-begin
-if z1.isNegative xor z2.isNegative then
- b:= z2.isNegative
-else
-(*
- if z1.QWordValue = z2.QWordValue then
- b:= false
- else*)
- b:= ((z1.Round > z2.Round) or ((z1.Round = z2.Round) and (z1.Frac > z2.Frac))) <> z1.isNegative
-end;
-
-function isZero(const z: hwFloat): boolean; inline;
-begin
-isZero := (z.Round = 0) and (z.Frac = 0);
-end;
-{$ENDIF}
operator - (const z1: hwFloat) z : hwFloat; inline;
begin
@@ -418,24 +313,23 @@ z.QWordValue:= z1.QWordValue * abs(z2)
end;
operator / (const z1: hwFloat; z2: hwFloat) z : hwFloat; inline;
-var t: hwFloat;
+var t: QWord;
begin
z.isNegative:= z1.isNegative xor z2.isNegative;
z.Round:= z1.QWordValue div z2.QWordValue;
-t:= z1 - z2 * z.Round;
-if t.QWordValue = 0 then
- z.Frac:= 0
-else
+t:= z1.QWordValue - z2.QWordValue * z.Round;
+z.Frac:= 0;
+
+if t <> 0 then
begin
- while ((t.QWordValue and $8000000000000000) = 0) and ((z2.QWordValue and $8000000000000000) = 0) do
+ while ((t and $FF00000000000000) = 0) and ((z2.QWordValue and $FF00000000000000) = 0) do
begin
- t.QWordValue:= t.QWordValue shl 1;
- z2.QWordValue:= z2.QWordValue shl 1
+ t:= t shl 8;
+ z2.QWordValue:= z2.QWordValue shl 8
end;
+
if z2.Round > 0 then
- z.Frac:= (t.QWordValue) div (z2.Round)
- else
- z.Frac:= 0
+ inc(z.QWordValue, t div z2.Round);
end
end;
@@ -491,14 +385,14 @@ while p > 0 do
end
end;
-function hwSqrt(const t: hwFloat): hwFloat;
+function hwSqrt1(const t: hwFloat): hwFloat;
const pwr = 8; // even value, feel free to adjust
rThreshold = 1 shl (pwr + 32);
lThreshold = 1 shl (pwr div 2 + 32);
var l, r: QWord;
c: hwFloat;
begin
-hwSqrt.isNegative:= false;
+hwSqrt1.isNegative:= false;
if t.Round = 0 then
begin
@@ -531,12 +425,47 @@ repeat
l:= c.QWordValue
until r - l <= 1;
-hwSqrt.QWordValue:= l
+hwSqrt1.QWordValue:= l
end;
+function hwSqrt(const x: hwFloat): hwFloat;
+var r, t, s, q: QWord;
+ i: integer;
+begin
+hwSqrt.isNegative:= false;
+
+t:= $4000000000000000;
+r:= 0;
+q:= x.QWordValue;
+
+for i:= 0 to 31 do
+ begin
+ s:= r + t;
+ r:= r shr 1;
+ if s <= q then
+ begin
+ dec(q, s);
+ inc(r, t);
+ end;
+ t:= t shr 2;
+ end;
+
+hwSqrt.QWordValue:= r shl 16
+end;
+
+
+
function Distance(const dx, dy: hwFloat): hwFloat;
+var r: QWord;
begin
-Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy))
+r:= dx.QWordValue or dy.QWordValue;
+
+if r < $10000 then
+ begin
+ Distance.QWordValue:= r;
+ Distance.isNegative:= false
+ end else
+ Distance:= hwSqrt(hwSqr(dx) + hwSqr(dy))
end;
function DistanceI(const dx, dy: LongInt): hwFloat;
diff --git a/hedgewars/uGame.pas b/hedgewars/uGame.pas
index a71264a..03ecfc1 100644
--- a/hedgewars/uGame.pas
+++ b/hedgewars/uGame.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,21 +26,24 @@ procedure DoGameTick(Lag: LongInt);
////////////////////
implementation
////////////////////
-uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uMobile,
+uses uInputHandler, uTeams, uIO, uAI, uGears, uSound, uLocale, uCaptions,
uVisualGears, uTypes, uVariables, uCommands, uConsts
{$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
procedure DoGameTick(Lag: LongInt);
-var i: LongInt;
+var i,j : LongInt;
+ s: shortstring;
begin
if isPaused then
exit;
+
if (not CurrentTeam^.ExtDriven) then
begin
NetGetNextCmd; // its for the case of receiving "/say" message
isInLag:= false;
- SendKeepAliveMessage(Lag)
+ FlushMessages(Lag)
end;
+
if GameType <> gmtRecord then
begin
if Lag > 100 then
@@ -50,17 +53,33 @@ if GameType <> gmtRecord then
if (GameType = gmtDemo) then
if isSpeed then
- begin
+ begin
i:= RealTicks-SpeedStart;
if i < 2000 then Lag:= Lag*5
else if i < 4000 then Lag:= Lag*10
else if i < 6000 then Lag:= Lag*20
else if i < 8000 then Lag:= Lag*40
else Lag:= Lag*80;
- end
- else
- if cOnlyStats then
- Lag:= High(LongInt);
+ end
+ else if cOnlyStats then
+ Lag:= High(LongInt)
+ end;
+inc(SoundTimerTicks, Lag);
+if SoundTimerTicks >= 50 then
+ begin
+ SoundTimerTicks:= 0;
+ if cVolumeDelta <> 0 then
+ begin
+ j:= Volume;
+ i:= ChangeVolume(cVolumeDelta);
+ if isAudioMuted and (j<>i) then
+ AddCaption(trmsg[sidMute], cWhiteColor, capgrpVolume)
+ else if not isAudioMuted then
+ begin
+ str(i, s);
+ AddCaption(Format(trmsg[sidVolume], s), cWhiteColor, capgrpVolume)
+ end
+ end;
end;
PlayNextVoice;
i:= 1;
@@ -97,7 +116,9 @@ while (GameState <> gsExit) and (i <= Lag) do
AddVisualGear(0, 0, vgtTeamHealthSorter);
AddVisualGear(0, 0, vgtSmoothWindBar);
{$IFDEF IPHONEOS}InitIPC;{$ENDIF}
- uMobile.SaveLoadingEnded();
+ with mobileRecord do
+ if SaveLoadingEnded <> nil then
+ SaveLoadingEnded();
end;
end
else ProcessGears
diff --git a/hedgewars/uGears.pas b/hedgewars/uGears.pas
index 7cbc4e3..6d44ea9 100644
--- a/hedgewars/uGears.pas
+++ b/hedgewars/uGears.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,7 +46,8 @@ procedure RestoreHog(HH: PHedgehog);
procedure ProcessGears;
procedure EndTurnCleanup;
procedure SetAllToActive;
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+procedure SetAllHHToActive(Ice: boolean);
procedure DrawGears;
procedure FreeGearsList;
procedure AddMiscGears;
@@ -56,8 +57,8 @@ procedure doStepDrowningGear(Gear: PGear);
implementation
-uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics,
- uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uMobile, uVariables,
+uses uStore, uSound, uTeams, uRandom, uCollisions, uIO, uLandGraphics, {$IFDEF SDL13}uTouch,{$ENDIF}
+ uLocale, uAI, uAmmos, uStats, uVisualGears, uScript, GLunit, uVariables,
uCommands, uUtils, uTextures, uRenderUtils, uGearsRender, uCaptions, uDebug, uLandTexture,
uGearsHedgehog, uGearsUtils, uGearsList, uGearsHandlers, uGearsHandlersRope;
@@ -78,6 +79,7 @@ var delay: LongWord;
stSpawn, stNTurn);
upd: Longword;
snowLeft,snowRight: LongInt;
+ NewTurnTick: LongWord;
//SDMusic: shortstring;
// For better maintainability the step handlers of gears are stored in
@@ -189,6 +191,16 @@ var t: PGear;
i, AliveCount: LongInt;
s: shortstring;
begin
+ScriptCall('onGameTick');
+if GameTicks mod 20 = 0 then ScriptCall('onGameTick20');
+if GameTicks = NewTurnTick then
+ begin
+ ScriptCall('onNewTurn');
+{$IFDEF SDL13}
+ uTouch.NewTurnBeginning();
+{$ENDIF}
+ end;
+
PrvInactive:= AllInactive;
AllInactive:= true;
@@ -383,7 +395,8 @@ case step of
SwitchHedgehog;
AfterSwitchHedgehog;
- bBetweenTurns:= false
+ bBetweenTurns:= false;
+ NewTurnTick:= GameTicks + 1
end;
step:= Low(step)
end;
@@ -430,8 +443,8 @@ else if ((GameFlags and gfInfAttack) <> 0) then
if TurnTimeLeft > 0 then
if CurrentHedgehog^.Gear <> nil then
- if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0)
- and (not isInMultiShoot) then
+ if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) and
+ not(isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) then
begin
if (TurnTimeLeft = 5000)
and (cHedgehogTurnTime >= 10000)
@@ -470,8 +483,7 @@ if ((GameTicks and $FFFF) = $FFFF) then
inc(hiTicks) // we do not recieve a message for this
end;
AddRandomness(CheckSum);
-ScriptCall('onGameTick');
-if GameTicks mod 20 = 0 then ScriptCall('onGameTick20');
+
inc(GameTicks)
end;
@@ -551,7 +563,12 @@ while t <> nil do
end
end;
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+begin
+SetAllHHToActive(true)
+end;
+
+procedure SetAllHHToActive(Ice: boolean);
var t: PGear;
begin
AllInactive:= false;
@@ -559,12 +576,14 @@ t:= GearsList;
while t <> nil do
begin
if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then
- t^.Active:= true;
+ begin
+ if (t^.Kind = gtHedgehog) and Ice then CheckIce(t);
+ t^.Active:= true
+ end;
t:= t^.NextGear
end
end;
-
procedure DrawGears;
var Gear: PGear;
x, y: LongInt;
@@ -642,7 +661,7 @@ if (GameFlags and gfLaserSight) <> 0 then
if (GameFlags and gfArtillery) <> 0 then
cArtillery:= true;
-for i:= GetRandom(10)+30 downto 0 do
+for i:= (LAND_WIDTH*LAND_HEIGHT) div 524288+2 downto 0 do
begin
rx:= GetRandom(rightX-leftX)+leftX;
ry:= GetRandom(LAND_HEIGHT-topY)+topY;
@@ -656,7 +675,7 @@ snowLeft:= -(snowRight-LAND_WIDTH);
if (not hasBorder) and ((Theme = 'Snow') or (Theme = 'Christmas')) then
for i:= vobCount * Longword(max(LAND_WIDTH,4096)) div 2048 downto 1 do
- AddGear(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft, LongInt(LAND_HEIGHT + GetRandom(750)) - 1300, gtFlake, 0, _0, _0, 0);
+ AddGear(LongInt(GetRandom(snowRight - snowLeft)) + snowLeft, LAND_HEIGHT + LongInt(GetRandom(750)) - 1300, gtFlake, 0, _0, _0, 0);
end;
@@ -676,8 +695,8 @@ while t <> nil do
gtKnife,
gtCase,
gtTarget,
- gtExplosives,
- gtStructure: begin
+ gtExplosives: begin//,
+// gtStructure: begin
//addFileLog('ShotgunShot radius: ' + inttostr(Gear^.Radius) + ', t^.Radius = ' + inttostr(t^.Radius) + ', distance = ' + inttostr(dist) + ', dmg = ' + inttostr(dmg));
dmg:= 0;
r:= Gear^.Radius + t^.Radius;
@@ -755,6 +774,8 @@ while i > 0 do
begin
dec(i);
Gear:= t^.ar[i];
+ if (Ammo^.Kind = gtFlame) and (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
+ Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
tmpDmg:= ModifyDamage(Damage, Gear);
if (Gear^.State and gstNoDamage) = 0 then
begin
@@ -769,6 +790,7 @@ while i > 0 do
if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
Gear^.FlightTime:= 1;
+
case Gear^.Kind of
gtHedgehog,
gtMine,
@@ -776,8 +798,8 @@ while i > 0 do
gtKnife,
gtTarget,
gtCase,
- gtExplosives,
- gtStructure:
+ gtExplosives: //,
+ //gtStructure:
begin
if (Ammo^.Kind = gtDrill) then
begin
@@ -816,7 +838,7 @@ while i > 0 do
ApplyDamage(Gear, Ammo^.Hedgehog, tmpDmg * 100, dsUnknown); // crank up damage for explosives + blowtorch
end;
- if (Gear^.Kind = gtHedgehog) and Gear^.Hedgehog^.King then
+ if (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
begin
Gear^.dX:= Ammo^.dX * Power * _0_005;
Gear^.dY:= Ammo^.dY * Power * _0_005
@@ -905,10 +927,6 @@ if (GameFlags and gfDivideTeams) <> 0 then
inc(Count)
end;
end;
- // unC0Rr, while it is true user can watch value on map screen, IMO this (and check above) should be enforced in UI
- // - is there a good place to put values for the different widgets to check? Right now they are kind of disconnected.
- //it would be nice if divide teams, forts mode and hh per map could all be checked by the team widget, or maybe disable start button
- TryDo(Count <= MaxHedgehogs, 'Too many hedgehogs for this map! (max # is ' + inttostr(MaxHedgehogs) + ')', true);
while (Count > 0) do
begin
i:= GetRandom(Count);
@@ -1366,7 +1384,7 @@ const handlers: array[TGearType] of TGearStepProcedure = (
@doStepNapalmBomb,
@doStepSnowball,
@doStepSnowflake,
- @doStepStructure,
+ //@doStepStructure,
@doStepLandGun,
@doStepTardis,
@doStepIceGun,
@@ -1399,6 +1417,7 @@ begin
upd:= 0;
//SDMusic:= 'hell.ogg';
+ NewTurnTick:= $FFFFFFFF;
end;
procedure freeModule;
diff --git a/hedgewars/uGearsHandlers.pas b/hedgewars/uGearsHandlers.pas
index 9e9abc2..5d425c0 100644
--- a/hedgewars/uGearsHandlers.pas
+++ b/hedgewars/uGearsHandlers.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uGearsHandlersRope.pas b/hedgewars/uGearsHandlersRope.pas
index a207f8f..35b4eba 100644
--- a/hedgewars/uGearsHandlersRope.pas
+++ b/hedgewars/uGearsHandlersRope.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,6 +33,14 @@ var
HHGear: PGear;
begin
HHGear := Gear^.Hedgehog^.Gear;
+ if (HHGear^.Hedgehog^.CurAmmoType = amParachute) and (HHGear^.dY > _0_39) then
+ begin
+ DeleteGear(Gear);
+ ApplyAmmoChanges(HHGear^.Hedgehog^);
+ HHGear^.Message:= HHGear^.Message or gmLJump;
+ exit
+ end;
+
if ((HHGear^.State and gstHHDriven) = 0)
or (CheckGearDrowning(HHGear))
or (TestCollisionYwithGear(HHGear, 1) <> 0) then
@@ -102,7 +110,7 @@ var
lx, ly, cd: LongInt;
haveCollision,
haveDivided: boolean;
-
+ wrongSide: boolean;
begin
if GameTicks mod 4 <> 0 then exit;
@@ -165,12 +173,12 @@ begin
if ((Gear^.Message and gmDown) <> 0) and (Gear^.Elasticity < Gear^.Friction) then
if not (TestCollisionXwithGear(HHGear, hwSign(ropeDx))
- or (TestCollisionYwithGear(HHGear, hwSign(ropeDy)) <> 0)) then
+ or ((ropeDy.QWordValue <> 0) and TestCollisionYwithXYShift(HHGear, 0, 1, hwSign(ropeDy)))) then
Gear^.Elasticity := Gear^.Elasticity + _1_2;
if ((Gear^.Message and gmUp) <> 0) and (Gear^.Elasticity > _30) then
if not (TestCollisionXwithGear(HHGear, -hwSign(ropeDx))
- or (TestCollisionYwithGear(HHGear, -hwSign(ropeDy)) <> 0)) then
+ or ((ropeDy.QWordValue <> 0) and TestCollisionYwithXYShift(HHGear, 0, 1, -hwSign(ropeDy)))) then
Gear^.Elasticity := Gear^.Elasticity - _1_2;
HHGear^.X := Gear^.X + mdX * Gear^.Elasticity;
@@ -194,12 +202,12 @@ begin
begin
lx := hwRound(nx);
ly := hwRound(ny);
- if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and ((Land[ly, lx] and $FF00) <> 0) then
+ if ((ly and LAND_HEIGHT_MASK) = 0) and ((lx and LAND_WIDTH_MASK) = 0) and (Land[ly, lx] > lfAllObjMask) then
begin
- ny := _1 / Distance(ropeDx, ropeDy);
+ tx := _1 / Distance(ropeDx, ropeDy);
// old rope pos
- nx := ropeDx * ny;
- ny := ropeDy * ny;
+ nx := ropeDx * tx;
+ ny := ropeDy * tx;
with RopePoints.ar[RopePoints.Count] do
begin
@@ -208,9 +216,12 @@ begin
if RopePoints.Count = 0 then
RopePoints.HookAngle := DxDy2Angle(Gear^.dY, Gear^.dX);
b := (nx * HHGear^.dY) > (ny * HHGear^.dX);
+ sx:= Gear^.dX.isNegative;
+ sy:= Gear^.dY.isNegative;
+ sb:= Gear^.dX.QWordValue < Gear^.dY.QWordValue;
dLen := len
end;
-
+
with RopePoints.rounded[RopePoints.Count] do
begin
X := hwRound(Gear^.X);
@@ -240,21 +251,45 @@ begin
ty := RopePoints.ar[Pred(RopePoints.Count)].Y;
mdX := tx - Gear^.X;
mdY := ty - Gear^.Y;
- if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * (ty - HHGear^.Y) > (tx - HHGear^.X) * mdY) then
+ ropeDx:= tx - HHGear^.X;
+ ropeDy:= ty - HHGear^.Y;
+ if RopePoints.ar[Pred(RopePoints.Count)].b xor (mdX * ropeDy > ropeDx * mdY) then
begin
dec(RopePoints.Count);
- Gear^.X := RopePoints.ar[RopePoints.Count].X;
- Gear^.Y := RopePoints.ar[RopePoints.Count].Y;
- Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
- Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen;
-
- // restore hog position
- len := _1 / Distance(mdX, mdY);
- mdX := mdX * len;
- mdY := mdY * len;
-
- HHGear^.X := Gear^.X - mdX * Gear^.Elasticity;
- HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity;
+ Gear^.X := tx;
+ Gear^.Y := ty;
+
+ // oops, opposite quadrant, don't restore hog position in such case, just remove the point
+ wrongSide:= (ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx)
+ and (ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy);
+
+ // previous check could be inaccurate in vertical/horizontal rope positions,
+ // so perform this check also, even though odds are 1 to 415927 to hit this
+ if (not wrongSide)
+ and ((ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx)
+ <> (ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy)) then
+ if RopePoints.ar[RopePoints.Count].sb then
+ wrongSide:= ropeDy.isNegative = RopePoints.ar[RopePoints.Count].sy
+ else
+ wrongSide:= ropeDx.isNegative = RopePoints.ar[RopePoints.Count].sx;
+
+ if wrongSide then
+ begin
+ Gear^.Elasticity := Gear^.Elasticity - RopePoints.ar[RopePoints.Count].dLen;
+ Gear^.Friction := Gear^.Friction - RopePoints.ar[RopePoints.Count].dLen;
+ end else
+ begin
+ Gear^.Elasticity := Gear^.Elasticity + RopePoints.ar[RopePoints.Count].dLen;
+ Gear^.Friction := Gear^.Friction + RopePoints.ar[RopePoints.Count].dLen;
+
+ // restore hog position
+ len := _1 / Distance(mdX, mdY);
+ mdX := mdX * len;
+ mdY := mdY * len;
+
+ HHGear^.X := Gear^.X - mdX * Gear^.Elasticity;
+ HHGear^.Y := Gear^.Y - mdY * Gear^.Elasticity;
+ end;
end
end;
@@ -264,7 +299,7 @@ begin
HHGear^.dX := -_0_6 * HHGear^.dX;
haveCollision := true
end;
- if TestCollisionYwithGear(HHGear, hwSign(HHGear^.dY)) <> 0 then
+ if TestCollisionYwithXYShift(HHGear, 0, 1, hwSign(HHGear^.dY)) then
begin
HHGear^.dY := -_0_6 * HHGear^.dY;
haveCollision := true
@@ -390,7 +425,7 @@ begin
ty := _0;
while tt > _20 do
begin
- if ((hwRound(Gear^.Y+ty) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X+tx) and LAND_WIDTH_MASK) = 0) and ((Land[hwRound(Gear^.Y+ty), hwRound(Gear^.X+tx)] and $FF00) <> 0) then
+ if ((hwRound(Gear^.Y+ty) and LAND_HEIGHT_MASK) = 0) and ((hwRound(Gear^.X+tx) and LAND_WIDTH_MASK) = 0) and (Land[hwRound(Gear^.Y+ty), hwRound(Gear^.X+tx)] > lfAllObjMask) then
begin
Gear^.X := Gear^.X + tx;
Gear^.Y := Gear^.Y + ty;
@@ -414,8 +449,8 @@ begin
end;
end;
- if Gear^.Elasticity < _20 then Gear^.CollisionMask:= $FF00
- else Gear^.CollisionMask:= $FF7F;
+ if Gear^.Elasticity < _20 then Gear^.CollisionMask:= lfLandMask
+ else Gear^.CollisionMask:= lfNotCurrentMask;
CheckCollision(Gear);
if (Gear^.State and gstCollision) <> 0 then
diff --git a/hedgewars/uGearsHedgehog.pas b/hedgewars/uGearsHedgehog.pas
index a107747..6dc157f 100644
--- a/hedgewars/uGearsHedgehog.pas
+++ b/hedgewars/uGearsHedgehog.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,17 +23,18 @@ interface
uses uTypes;
procedure doStepHedgehog(Gear: PGear);
-procedure AfterAttack;
-procedure HedgehogStep(Gear: PGear);
-procedure doStepHedgehogMoving(Gear: PGear);
-procedure HedgehogChAngle(HHGear: PGear);
+procedure AfterAttack;
+procedure HedgehogStep(Gear: PGear);
+procedure doStepHedgehogMoving(Gear: PGear);
+procedure HedgehogChAngle(HHGear: PGear);
procedure PickUp(HH, Gear: PGear);
procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
+procedure CheckIce(Gear: PGear); inline;
implementation
-uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
+uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions,
uCommands, uLocale, uUtils, uVisualGears, uStats, uIO, uScript,
- uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
+ uGearsList, uGears, uCollisions, uRandom, uStore, uTeams,
uGearsUtils;
var GHStepTicks: LongWord = 0;
@@ -53,7 +54,6 @@ with HHGear^.Hedgehog^ do
prevAmmo:= CurAmmoType;
ammoidx:= 0;
if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
- or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
or ((HHGear^.State and gstHHDriven) = 0) then
exit;
ChangeAmmo:= true;
@@ -61,12 +61,21 @@ with HHGear^.Hedgehog^ do
while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
inc(ammoidx);
- if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
- OnUsedAmmo(HHGear^.Hedgehog^);
+ if (MultiShootAttacks > 0) then
+ begin
+ if (CurAmmoType = amSniperRifle) and ((GameFlags and gfArtillery) = 0) then
+ cArtillery := false;
+ if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0 then
+ begin
+ MultiShootAttacks:= Ammoz[CurAmmoType].Ammo.NumPerTurn;
+ AfterAttack
+ end
+ else OnUsedAmmo(HHGear^.Hedgehog^)
+ end;
MultiShootAttacks:= 0;
HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
-
+
if Ammoz[CurAmmoType].Slot = slot then
begin
i:= 0;
@@ -81,8 +90,8 @@ with HHGear^.Hedgehog^ do
end;
until (i = 1) or ((Ammo^[slot, ammoidx].Count > 0)
and (Team^.Clan^.TurnNumber > Ammoz[Ammo^[slot, ammoidx].AmmoType].SkipTurns))
-
- end
+
+ end
else
begin
i:= 0;
@@ -103,6 +112,13 @@ with HHGear^.Hedgehog^ do
LoadHedgehogHat(HHGear^.Hedgehog^, 'Reserved/chef')
else if prevAmmo = amKnife then
LoadHedgehogHat(HHGear^.Hedgehog^, Hat);
+ end;
+ // Try again in the next slot
+ if CurAmmoType = prevAmmo then
+ begin
+ if slot >= cMaxSlotIndex then slot:= 0 else inc(slot);
+ HHGear^.MsgParam:= slot;
+ ChangeAmmo(HHGear)
end
end
end;
@@ -197,16 +213,14 @@ with Gear^,
if ((State and gstHHDriven) <> 0) and ((State and (gstAttacked or gstHHChooseTarget)) = 0) and (((State and gstMoving) = 0)
or (Power > 0)
or (CurAmmoType = amTeleport)
- or
+ or
// Allow attacks while moving on ammo with AltAttack
((CurAmmoGear <> nil) and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0))
or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackInMove) <> 0))
and ((TargetPoint.X <> NoPointX) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget) = 0)) then
begin
State:= State or gstAttacking;
- if Power = cMaxPower then
- Message:= Message and (not gmAttack)
- else if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0 then
+ if (Power = cMaxPower) or ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) = 0) then
Message:= Message and (not gmAttack)
else
begin
@@ -217,44 +231,52 @@ with Gear^,
end;
inc(Power)
end;
- if ((Message and gmAttack) <> 0) then
- exit;
+ if ((Message and gmAttack) <> 0) then
+ exit;
- if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
- begin
- StopSound(sndThrowPowerUp);
- PlaySound(sndThrowRelease);
- end;
+ if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0 then
+ begin
+ StopSound(sndThrowPowerUp);
+ PlaySound(sndThrowRelease);
+ end;
- xx:= SignAs(AngleSin(Angle), dX);
- yy:= -AngleCos(Angle);
+ xx:= SignAs(AngleSin(Angle), dX);
+ yy:= -AngleCos(Angle);
- lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
- ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
+ lx:= X + int2hwfloat(round(GetLaunchX(CurAmmoType, hwSign(dX), Angle)));
+ ly:= Y + int2hwfloat(round(GetLaunchY(CurAmmoType, Angle)));
- if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
- xx:= - xx;
- if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
- AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
+ if ((Gear^.State and gstHHHJump) <> 0) and (not cArtillery) then
+ xx:= - xx;
+ if Ammoz[CurAmmoType].Ammo.AttackVoice <> sndNone then
+ AddVoice(Ammoz[CurAmmoType].Ammo.AttackVoice, CurrentTeam^.voicepack);
// Initiating alt attack
- if (CurAmmoGear <> nil)
- and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
- and ((Gear^.Message and gmLJump) <> 0)
- and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
- begin
- newDx:= dX;
- newDy:= dY;
- altUse:= true
- end
- else
- begin
- newDx:= xx*Power/cPowerDivisor;
- newDy:= yy*Power/cPowerDivisor;
- altUse:= false
- end;
+ if (CurAmmoGear <> nil)
+ and ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
+ and ((Gear^.Message and gmLJump) <> 0)
+ and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) <> 0) then
+ begin
+ if (CurAmmoGear^.AmmoType = amJetpack) and (Gear^.Message and gmPrecise <> 0) then
+ begin
+ newDx:= xx*cMaxPower/cPowerDivisor;
+ newDy:= yy*cMaxPower/cPowerDivisor
+ end
+ else
+ begin
+ newDx:= dX;
+ newDy:= dY
+ end;
+ altUse:= true
+ end
+ else
+ begin
+ newDx:= xx*Power/cPowerDivisor;
+ newDy:= yy*Power/cPowerDivisor;
+ altUse:= false
+ end;
- case CurAmmoType of
+ case CurAmmoType of
amGrenade: newGear:= AddGear(hwRound(lx), hwRound(ly), gtGrenade, 0, newDx, newDy, CurWeapon^.Timer);
amMolotov: newGear:= AddGear(hwRound(lx), hwRound(ly), gtMolotov, 0, newDx, newDy, 0);
amClusterBomb: newGear:= AddGear(hwRound(lx), hwRound(ly), gtClusterBomb, 0, newDx, newDy, CurWeapon^.Timer);
@@ -271,15 +293,15 @@ with Gear^,
amRope: newGear:= AddGear(hwRound(lx), hwRound(ly), gtRope, 0, xx, yy, 0);
amMine: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
amSMine: newGear:= AddGear(hwRound(lx), hwRound(ly), gtSMine, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
- amKnife: begin
+ amKnife: begin
newGear:= AddGear(hwRound(lx), hwRound(ly), gtKnife, 0, xx*Power/cPowerDivisor, yy*Power/cPowerDivisor, 0);
- newGear^.State:= newGear^.State or gstMoving;
- newGear^.Radius:= 6 // temporarily shrink so it doesn't instantly embed in the ground
+ newGear^.State:= newGear^.State or gstMoving;
+ newGear^.Radius:= 4 // temporarily shrink so it doesn't instantly embed in the ground
end;
amDEagle: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
amSineGun: newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
amPortalGun: begin
- newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6,
+ newGear:= AddGear(hwRound(lx + xx * cHHRadius), hwRound(ly + yy * cHHRadius), gtPortal, 0, xx * _0_6, yy * _0_6,
// set selected color
CurWeapon^.Pos);
end;
@@ -339,7 +361,7 @@ with Gear^,
cGravity:= cMaxWindSpeed;
cGravityf:= 0.00025
end;
- amExtraDamage: begin
+ amExtraDamage: begin
PlaySound(sndHellishImpact4);
cDamageModifier:= _1_5
end;
@@ -358,7 +380,7 @@ with Gear^,
Unplaced:= true;
X:= _0;
Y:= _0;
- newGear:= AddGear(TargetPoint.X, 0, gtPiano, 0, _0, _0, 0);
+ newGear:= AddGear(TargetPoint.X, -1024, gtPiano, 0, _0, _0, 0);
PauseMusic
end;
amFlamethrower: newGear:= AddGear(hwRound(X), hwRound(Y), gtFlamethrower, 0, xx * _0_5, yy * _0_5, 0);
@@ -367,102 +389,106 @@ with Gear^,
newGear:= AddGear(hwRound(lx), hwRound(ly), gtResurrector, 0, _0, _0, 0);
newGear^.SoundChannel := LoopSound(sndResurrector);
end;
- amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
+ //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
- end;
- if altUse and (newGear <> nil) then
- begin
- newGear^.dX:= newDx / newGear^.Density;
- newGear^.dY:= newDY / newGear^.Density
- end;
-
- case CurAmmoType of
- amGrenade, amMolotov,
- amClusterBomb, amGasBomb,
- amBazooka, amSnowball,
- amBee, amSMine,
- amMortar, amWatermelon,
- amHellishBomb, amDrill: FollowGear:= newGear;
-
- amShotgun, amPickHammer,
- amRope, amDEagle,
- amSineGun, amSniperRifle,
- amFirePunch, amWhip,
- amHammer, amBaseballBat,
- amParachute, amBlowTorch,
- amGirder, amTeleport,
- amSwitch, amRCPlane,
- amKamikaze, amCake,
- amSeduction, amBallgun,
- amJetpack, amBirdy,
- amFlamethrower, amLandGun,
- amResurrector, amStructure,
- amTardis, amPiano,
- amIceGun: CurAmmoGear:= newGear;
- end;
-
+ end;
+ if altUse and (newGear <> nil) and
+ ((CurAmmoGear = nil) or (CurAmmoGear^.AmmoType <> amJetpack) or (Gear^.Message and gmPrecise = 0)) then
+ begin
+ newGear^.dX:= newDx / newGear^.Density;
+ newGear^.dY:= newDY / newGear^.Density
+ end;
+ if (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack) and
+ (Gear^.Message and gmPrecise <> 0) and (hwRound(Y) > cWaterLine) then
+ newGear^.State:= newGear^.State or gstSubmersible;
+
+ case CurAmmoType of
+ amGrenade, amMolotov,
+ amClusterBomb, amGasBomb,
+ amBazooka, amSnowball,
+ amBee, amSMine,
+ amMortar, amWatermelon,
+ amHellishBomb, amDrill: FollowGear:= newGear;
+
+ amShotgun, amPickHammer,
+ amRope, amDEagle,
+ amSineGun, amSniperRifle,
+ amFirePunch, amWhip,
+ amHammer, amBaseballBat,
+ amParachute, amBlowTorch,
+ amGirder, amTeleport,
+ amSwitch, amRCPlane,
+ amKamikaze, amCake,
+ amSeduction, amBallgun,
+ amJetpack, amBirdy,
+ amFlamethrower, amLandGun,
+ amResurrector, //amStructure,
+ amTardis, amPiano,
+ amIceGun: CurAmmoGear:= newGear;
+ end;
+
if ((CurAmmoType = amMine) or (CurAmmoType = amSMine)) and (GameFlags and gfInfAttack <> 0) then
newGear^.FlightTime:= GameTicks + 1000
else if CurAmmoType = amDrill then
newGear^.FlightTime:= GameTicks + 250;
- if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
- begin
- newGear^.Target.X:= TargetPoint.X;
- newGear^.Target.Y:= TargetPoint.Y
- end;
- if (newGear <> nil) and (newGear^.CollisionMask and $80 <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not $80);
+ if Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0 then
+ begin
+ newGear^.Target.X:= TargetPoint.X;
+ newGear^.Target.Y:= TargetPoint.Y
+ end;
+ if (newGear <> nil) and (newGear^.CollisionMask and lfCurrentHog <> 0) then newGear^.CollisionMask:= newGear^.CollisionMask and (not lfCurrentHog);
- // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
- if altUse then
- FollowGear:= nil;
+ // Clear FollowGear if using on a rope/parachute/saucer etc so focus stays with the hog's movement
+ if altUse then
+ FollowGear:= nil;
- if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
- begin
- elastic:= int2hwfloat(CurWeapon^.Bounciness) / _1000;
-
- if elastic < _1 then
- newGear^.Elasticity:= newGear^.Elasticity * elastic
- else if elastic > _1 then
- newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
-(* Experimented with friction modifier. Didn't seem helpful
- fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
- if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
- else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
- end;
+ if (newGear <> nil) and ((Ammoz[newGear^.AmmoType].Ammo.Propz and ammoprop_SetBounce) <> 0) then
+ begin
+ elastic:= int2hwfloat(CurWeapon^.Bounciness) / _1000;
+
+ if elastic < _1 then
+ newGear^.Elasticity:= newGear^.Elasticity * elastic
+ else if elastic > _1 then
+ newGear^.Elasticity:= _1 - ((_1-newGear^.Elasticity) / elastic);
+ (* Experimented with friction modifier. Didn't seem helpful
+ fric:= int2hwfloat(CurWeapon^.Bounciness) / _250;
+ if fric < _1 then newGear^.Friction:= newGear^.Friction * fric
+ else if fric > _1 then newGear^.Friction:= _1 - ((_1-newGear^.Friction) / fric)*)
+ end;
- uStats.AmmoUsed(CurAmmoType);
+ uStats.AmmoUsed(CurAmmoType);
- if not (SpeechText = '') then
- begin
- speech:= AddVisualGear(0, 0, vgtSpeechBubble);
- if speech <> nil then
+ if not (SpeechText = '') then
begin
- speech^.Text:= SpeechText;
- speech^.Hedgehog:= Gear^.Hedgehog;
- speech^.FrameTicks:= SpeechType;
+ speech:= AddVisualGear(0, 0, vgtSpeechBubble);
+ if speech <> nil then
+ begin
+ speech^.Text:= SpeechText;
+ speech^.Hedgehog:= Gear^.Hedgehog;
+ speech^.FrameTicks:= SpeechType;
+ end;
+ SpeechText:= ''
end;
- SpeechText:= ''
- end;
- Power:= 0;
- if (CurAmmoGear <> nil)
- and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
- begin
- Message:= Message or gmAttack;
- CurAmmoGear^.Message:= Message
+ Power:= 0;
+ if (CurAmmoGear <> nil)
+ and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
+ begin
+ if CurAmmoType in [amRope,amResurrector] then Message:= Message or gmAttack;
+ CurAmmoGear^.Message:= Message
+ end
+ else
+ begin
+ if not CurrentTeam^.ExtDriven
+ and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
+ SendIPC(_S'a');
+ AfterAttack;
+ end
end
else
- begin
- if not CurrentTeam^.ExtDriven
- and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_Power) <> 0) then
- SendIPC(_S'a');
- AfterAttack;
- end
- end
- else
- Message:= Message and (not gmAttack);
+ Message:= Message and (not gmAttack);
end;
TargetPoint.X := NoPointX;
ScriptCall('onHogAttack');
@@ -481,13 +507,13 @@ with CurrentHedgehog^ do
if (Ammoz[a].Ammo.Propz and ammoprop_Effect) = 0 then
begin
Inc(MultiShootAttacks);
-
+
if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks) then
begin
s:= inttostr(Ammoz[a].Ammo.NumPerTurn - MultiShootAttacks + 1);
AddCaption(format(trmsg[sidRemaining], s), cWhiteColor, capgrpAmmostate);
end;
-
+
if (Ammoz[a].Ammo.NumPerTurn >= MultiShootAttacks)
or ((GameFlags and gfMultiWeapon) <> 0) then
begin
@@ -500,9 +526,11 @@ with CurrentHedgehog^ do
begin
if TagTurnTimeLeft = 0 then
TagTurnTimeLeft:= TurnTimeLeft;
- TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
+ if (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0) and (hwRound(CurAmmoGear^.Y) > cWaterLine) then
+ TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 25
+ else TurnTimeLeft:=(Ammoz[a].TimeAfterTurn * cGetAwayTime) div 100;
end;
- if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then
+ if ((Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) = 0) and (HHGear <> nil) then
HHGear^.State:= HHGear^.State or gstAttacked;
if (Ammoz[a].Ammo.Propz and ammoprop_NoRoundEnd) <> 0 then
ApplyAmmoChanges(CurrentHedgehog^)
@@ -530,15 +558,16 @@ if Gear^.Timer > 1 then
dec(Gear^.Timer);
if (Gear^.Timer mod frametime) = 0 then
inc(Gear^.Pos)
- end
+ end
else if Gear^.Timer = 1 then
begin
+ Gear^.Hedgehog^.Effects[heFrozen]:= 0;
Gear^.State:= Gear^.State or gstNoDamage;
doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, CurrentHedgehog, EXPLAutoSound);
AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtGrave, 0, _0, _0, 0)^.Hedgehog:= Gear^.Hedgehog;
DeleteGear(Gear);
SetAllToActive
- end
+ end
else // Gear^.Timer = 0
begin
AllInactive:= false;
@@ -591,7 +620,7 @@ begin
if cnt <> 0 then AddAmmo(HH, ammo, cnt)
else AddAmmo(HH, ammo);
- if (not (HH.Team^.ExtDriven
+ if (not (HH.Team^.ExtDriven
or (HH.BotLevel > 0)))
or (HH.Team^.Clan^.ClanIndex = LocalClan)
or (GameType = gmtDemo) then
@@ -629,7 +658,7 @@ case Gear^.Pos of
posCaseUtility,
posCaseAmmo: begin
PlaySound(sndShotgunReload);
- if Gear^.AmmoType <> amNothing then
+ if Gear^.AmmoType <> amNothing then
begin
AddPickup(HH^.Hedgehog^, Gear^.AmmoType, Gear^.Power, hwRound(Gear^.X), hwRound(Gear^.Y));
end
@@ -637,13 +666,14 @@ case Gear^.Pos of
begin
// Add spawning here...
AddRandomness(GameTicks);
-
+
gi := GearsList;
while gi <> nil do
begin
- if gi^.Kind = gtGenericFaller then
+ if (gi^.Kind = gtGenericFaller) and (gi^.State and gstInvisible <> 0) then
begin
gi^.Active:= true;
+ gi^.State:= gi^.State or gstTmpFlag;
gi^.X:= int2hwFloat(GetRandom(rightX-leftX)+leftX);
gi^.Y:= int2hwFloat(GetRandom(LAND_HEIGHT-topY)+topY);
gi^.dX:= _90-(GetRandomf*_360);
@@ -751,7 +781,7 @@ if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
if (Gear^.Message and gmLeft )<>0 then
Gear^.dX:= -cLittle else
if (Gear^.Message and gmRight )<>0 then
- Gear^.dX:= cLittle
+ Gear^.dX:= cLittle
else exit;
StepSoundTimer:= cHHStepTicks;
@@ -769,7 +799,7 @@ if ((Gear^.State and (gstAttacking or gstMoving)) = 0) then
if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) then
MakeHedgehogsStep(Gear);
- SetAllHHToActive;
+ SetAllHHToActive(false);
AddGearCI(Gear)
end
end;
@@ -778,12 +808,12 @@ procedure HedgehogChAngle(HHGear: PGear);
var da: LongWord;
begin
with HHGear^.Hedgehog^ do
- if ((CurAmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
+ if ((CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amRope) and ((HHGear^.State and (gstMoving or gstHHJumping)) = gstMoving))
or ((CurAmmoType = amPortalGun) and ((HHGear^.State and gstMoving) <> 0)) then
da:= 2
else da:= 1;
-if (((HHGear^.Message and gmPrecise) = 0) or ((GameTicks mod 5) = 1)) then
+if ((HHGear^.Message and gmPrecise = 0) or ((CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack))) or (GameTicks mod 5 = 1) then
if ((HHGear^.Message and gmUp) <> 0) and (HHGear^.Angle >= CurMinAngle + da) then
dec(HHGear^.Angle, da)
else
@@ -818,7 +848,7 @@ if isFalling then
Gear^.dY:= _0;
Gear^.State:= Gear^.State or gstMoving;
if (CurrentHedgehog^.Gear = Gear)
- and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
+ and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
begin
// TODO: why so aggressive at setting FollowGear when falling?
FollowGear:= Gear;
@@ -834,7 +864,7 @@ if isFalling then
or ((Gear^.dY.QWordValue + Gear^.dX.QWordValue) > _0_55.QWordValue))) then
Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
end
- end
+ end
else
begin
land:= TestCollisionYwithGear(Gear, 1);
@@ -879,35 +909,40 @@ if (Gear^.State and gstMoving) <> 0 then
if TestCollisionXKick(Gear, hwSign(Gear^.dX)) then
if not isFalling then
if hwAbs(Gear^.dX) > _0_01 then
- if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) then
+ if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -1, hwSign(Gear^.dX)) or
+ (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.dX:= Gear^.dX * _0_96;
Gear^.Y:= Gear^.Y - _1
end
else
- if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) then
+ if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -2, hwSign(Gear^.dX)) or
+ (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.dX:= Gear^.dX * _0_93;
Gear^.Y:= Gear^.Y - _2
- end
+ end
else
- if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) then
+ if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -3, hwSign(Gear^.dX)) or
+ (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.dX:= Gear^.dX * _0_9 ;
Gear^.Y:= Gear^.Y - _3
end
else
- if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) then
+ if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -4, hwSign(Gear^.dX)) or
+ (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.dX:= Gear^.dX * _0_87;
Gear^.Y:= Gear^.Y - _4
end
else
- if not TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) then
+ if not (TestCollisionXwithXYShift(Gear, int2hwFloat(hwSign(Gear^.dX)) - Gear^.dX, -5, hwSign(Gear^.dX)) or
+ (TestCollisionYwithXYShift(Gear, hwSign(Gear^.dX) - hwRound(Gear^.dX), -1, -1))) then
begin
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.dX:= Gear^.dX * _0_84;
@@ -941,8 +976,11 @@ if (not isFalling)
begin
Gear^.State:= Gear^.State and (not gstWinner);
Gear^.State:= Gear^.State and (not gstMoving);
- while (TestCollisionYWithGear(Gear,1) = 0) and (not CheckGearDrowning(Gear)) do
- Gear^.Y:= Gear^.Y+_1;
+ while (TestCollisionYWithGear(Gear,1) = 0) and (not CheckGearDrowning(Gear)) and (Gear <> nil) do
+ Gear^.Y:= Gear^.Y + _1;
+
+ // could become nil in CheckGearDrowning if ai's hog fails to respawn in ai survival
+ if Gear = nil then exit;
SetLittle(Gear^.dX);
Gear^.dY:= _0
end
@@ -955,14 +993,17 @@ if (Gear^.State and gstMoving) <> 0 then
// ARTILLERY but not being moved by explosions
Gear^.X:= Gear^.X + Gear^.dX;
Gear^.Y:= Gear^.Y + Gear^.dY;
- if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
+ if (not Gear^.dY.isNegative) and (not TestCollisionYKick(Gear, 1))
and TestCollisionYwithXYShift(Gear, 0, 1, 1) then
begin
CheckHHDamage(Gear);
Gear^.dY:= _0;
Gear^.Y:= Gear^.Y + _1
end;
+
CheckGearDrowning(Gear);
+ // could become nil if ai's hog fails to respawn in ai survival
+ if Gear = nil then exit;
// hide target cursor if current hog is drowning
if (Gear^.State and gstDrowning) <> 0 then
if (CurrentHedgehog^.Gear = Gear) then
@@ -971,7 +1012,7 @@ if (Gear^.State and gstMoving) <> 0 then
if (not isZero(Gear^.dY)) and (Gear^.FlightTime > 0) and ((GameFlags and gfLowGravity) = 0) then
begin
inc(Gear^.FlightTime);
- if (Gear^.FlightTime > 1500) and ((hwRound(Gear^.X) < leftX-250) or (hwRound(Gear^.X) > rightX+250)) then
+ if (Gear^.FlightTime > 1500) and ((hwRound(Gear^.X) < LongInt(leftX)-250) or (hwRound(Gear^.X) > LongInt(rightX)+250)) then
begin
Gear^.FlightTime:= 0;
AddCaption(GetEventString(eidHomerun), cWhiteColor, capgrpMessage);
@@ -992,16 +1033,15 @@ var t: PGear;
Hedgehog: PHedgehog;
begin
Hedgehog:= HHGear^.Hedgehog;
-if isInMultiShoot then
+if not isInMultiShoot then
+ AllInactive:= false
+else if Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle] then
HHGear^.Message:= 0;
-if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then
- AllInactive:= true
-else if not isInMultiShoot then
- AllInactive:= false;
-
if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
begin
+ if (Hedgehog^.CurAmmoType = amKnife) then
+ LoadHedgehogHat(Hedgehog^, Hedgehog^.Hat);
if TagTurnTimeLeft = 0 then
TagTurnTimeLeft:= TurnTimeLeft;
TurnTimeLeft:= 0;
@@ -1040,7 +1080,7 @@ or (CurAmmoGear <> nil) then // we are moving
HHGear^.Message:= HHGear^.Message or gmAttack;
// check for case with ammo
t:= CheckGearNear(HHGear, gtCase, 36, 36);
- if t <> nil then
+ if (t <> nil) and (t^.State and gstFrozen = 0) then
PickUp(HHGear, t)
end;
@@ -1049,7 +1089,7 @@ if (CurAmmoGear = nil) then
or ((HHGear^.State and gstAttacking) <> 0)) then
Attack(HHGear) // should be before others to avoid desync with '/put' msg and changing weapon msgs
else
-else
+else
with Hedgehog^ do
if ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
and ((HHGear^.Message and gmLJump) <> 0)
@@ -1060,8 +1100,7 @@ else
end;
if (CurAmmoGear = nil)
-or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0)
-or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) then
+or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) <> 0) then
begin
if ((HHGear^.Message and gmSlot) <> 0) then
if ChangeAmmo(HHGear) then ApplyAmmoChanges(Hedgehog^);
@@ -1079,7 +1118,6 @@ if CurAmmoGear <> nil then
exit
end;
-if not isInMultiShoot then
HedgehogChAngle(HHGear);
if (HHGear^.State and gstMoving) <> 0 then
@@ -1115,7 +1153,7 @@ if (HHGear^.State and gstMoving) <> 0 then
exit
end;
- if not isInMultiShoot and (Hedgehog^.Gear <> nil) then
+ if not(isInMultiShoot and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) and (Hedgehog^.Gear <> nil) then
begin
if GHStepTicks > 0 then
dec(GHStepTicks);
@@ -1156,7 +1194,7 @@ if (Gear^.Health = 0) then
begin
ResurrectHedgehog(Gear);
end
- else
+ else
begin
Gear^.State:= (Gear^.State or gstHHDeath) and (not gstAnimation);
Gear^.doStep:= @doStepHedgehogDead;
@@ -1187,7 +1225,7 @@ else
if Gear^.Timer = 0 then
begin
Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
- Gear^.Active:= false;
+ if Gear^.Hedgehog^.Effects[heFrozen] = 0 then Gear^.Active:= false;
AddGearCI(Gear);
exit
end
@@ -1197,13 +1235,43 @@ else
AllInactive:= false
end;
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehog(Gear: PGear);
+procedure CheckIce(Gear: PGear); inline;
(*
var x,y,tx,ty: LongInt;
- tdX, tdY, slope: hwFloat;
+ tdX, tdY, slope: hwFloat;
land: Word; *)
-var slope: hwFloat;
+var slope: hwFloat;
+begin
+ if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
+ and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
+ and ((Gear^.Hedgehog = nil) or ((Gear^.Hedgehog^.Effects[heFrozen] = 0) or (Gear^.Hedgehog^.Effects[heFrozen] > 255)))
+ and (not Gear^.dY.isNegative) and (TurnTimeLeft > 0) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
+ begin
+ slope:= CalcSlopeBelowGear(Gear);
+ if slope.QWordValue > 730144440 then // ignore mild slopes
+ begin
+ Gear^.dX:=Gear^.dX+slope*cGravity*_256;
+ Gear^.State:= Gear^.State or gstMoving
+ end
+ end;
+(*
+ x:= hwRound(Gear^.X);
+ y:= hwRound(Gear^.Y);
+ AddVisualGear(x, y, vgtSmokeTrace);
+ AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
+ AddVisualGear(x + hwRound(_5*slope), y - hwRound(_5*slope), vgtSmokeTrace);
+ AddVisualGear(x - hwRound(_20 * slope), y + hwRound(_20 * slope), vgtSmokeTrace);
+ AddVisualGear(x + hwRound(_20 * slope), y - hwRound(_20 * slope), vgtSmokeTrace);
+ AddVisualGear(x - hwRound(_30 * slope), y + hwRound(_30 * slope), vgtSmokeTrace);
+ AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
+ AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
+ AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
+ AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
+ AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehog(Gear: PGear);
begin
CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
if (Gear^.Message and gmDestroy) <> 0 then
@@ -1211,7 +1279,18 @@ if (Gear^.Message and gmDestroy) <> 0 then
DeleteGear(Gear);
exit
end;
-
+if GameTicks mod 100 = 0 then CheckIce(Gear);
+(*
+if Gear^.Hedgehog^.Effects[heFrozen] > 0 then
+ begin
+ if (Gear^.Hedgehog^.Effects[heFrozen] > 256) and (CurrentHedgehog^.Team^.Clan <> Gear^.Hedgehog^.Team^.Clan) then
+ dec(Gear^.Hedgehog^.Effects[heFrozen])
+ else if GameTicks mod 10 = 0 then
+ dec(Gear^.Hedgehog^.Effects[heFrozen])
+ end;
+*)
+if (GameTicks mod 10 = 0) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) and (Gear^.Hedgehog^.Effects[heFrozen] < 256) then
+ dec(Gear^.Hedgehog^.Effects[heFrozen]);
if (Gear^.State and gstHHDriven) = 0 then
doStepHedgehogFree(Gear)
else
@@ -1222,30 +1301,6 @@ else
else
doStepHedgehogDriven(Gear)
end;
-if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
-and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
-and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
-and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
- begin
- slope:= CalcSlopeBelowGear(Gear);
- Gear^.dX:=Gear^.dX+slope*_0_07;
- if slope.QWordValue <> 0 then
- Gear^.State:= Gear^.State or gstMoving;
-(*
- x:= hwRound(Gear^.X);
- y:= hwRound(Gear^.Y);
- AddVisualGear(x, y, vgtSmokeTrace);
- AddVisualGear(x - hwRound(_5*slope), y + hwRound(_5*slope), vgtSmokeTrace);
- AddVisualGear(x + hwRound(_5*slope), y - hwRound(_5*slope), vgtSmokeTrace);
- AddVisualGear(x - hwRound(_20 * slope), y + hwRound(_20 * slope), vgtSmokeTrace);
- AddVisualGear(x + hwRound(_20 * slope), y - hwRound(_20 * slope), vgtSmokeTrace);
- AddVisualGear(x - hwRound(_30 * slope), y + hwRound(_30 * slope), vgtSmokeTrace);
- AddVisualGear(x + hwRound(_30 * slope), y - hwRound(_30 * slope), vgtSmokeTrace);
- AddVisualGear(x - hwRound(_40 * slope), y + hwRound(_40 * slope), vgtSmokeTrace);
- AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
- AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
- AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
- end
end;
end.
diff --git a/hedgewars/uGearsList.pas b/hedgewars/uGearsList.pas
index 2a0cf6d..8cb5aea 100644
--- a/hedgewars/uGearsList.pas
+++ b/hedgewars/uGearsList.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,8 +35,83 @@ uses uRandom, uUtils, uConsts, uVariables, uAmmos, uTeams, uStats,
uTextures, uScript, uRenderUtils, uAI, uCollisions,
uGearsRender, uGearsUtils, uDebug;
+const
+ GearKindAmmoTypeMap : array [TGearType] of TAmmoType = (
+(* gtFlame *) amNothing
+(* gtHedgehog *) , amNothing
+(* gtMine *) , amMine
+(* gtCase *) , amNothing
+(* gtExplosives *) , amNothing
+(* gtGrenade *) , amGrenade
+(* gtShell *) , amBazooka
+(* gtGrave *) , amNothing
+(* gtBee *) , amBee
+(* gtShotgunShot *) , amShotgun
+(* gtPickHammer *) , amPickHammer
+(* gtRope *) , amRope
+(* gtDEagleShot *) , amDEagle
+(* gtDynamite *) , amDynamite
+(* gtClusterBomb *) , amClusterBomb
+(* gtCluster *) , amClusterBomb
+(* gtShover *) , amBaseballBat // Shover is only used for baseball bat right now
+(* gtFirePunch *) , amFirePunch
+(* gtATStartGame *) , amNothing
+(* gtATFinishGame *) , amNothing
+(* gtParachute *) , amParachute
+(* gtAirAttack *) , amAirAttack
+(* gtAirBomb *) , amAirAttack
+(* gtBlowTorch *) , amBlowTorch
+(* gtGirder *) , amGirder
+(* gtTeleport *) , amTeleport
+(* gtSwitcher *) , amSwitch
+(* gtTarget *) , amNothing
+(* gtMortar *) , amMortar
+(* gtWhip *) , amWhip
+(* gtKamikaze *) , amKamikaze
+(* gtCake *) , amCake
+(* gtSeduction *) , amSeduction
+(* gtWatermelon *) , amWatermelon
+(* gtMelonPiece *) , amWatermelon
+(* gtHellishBomb *) , amHellishBomb
+(* gtWaterUp *) , amNothing
+(* gtDrill *) , amDrill
+(* gtBallGun *) , amBallgun
+(* gtBall *) , amBallgun
+(* gtRCPlane *) , amRCPlane
+(*gtSniperRifleShot *) , amSniperRifle
+(* gtJetpack *) , amJetpack
+(* gtMolotov *) , amMolotov
+(* gtBirdy *) , amBirdy
+(* gtEgg *) , amBirdy
+(* gtPortal *) , amPortalGun
+(* gtPiano *) , amPiano
+(* gtGasBomb *) , amGasBomb
+(* gtSineGunShot *) , amSineGun
+(* gtFlamethrower *) , amFlamethrower
+(* gtSMine *) , amSMine
+(* gtPoisonCloud *) , amNothing
+(* gtHammer *) , amHammer
+(* gtHammerHit *) , amHammer
+(* gtResurrector *) , amResurrector
+(* gtPoisonCloud *) , amNothing
+(* gtSnowball *) , amSnowball
+(* gtFlake *) , amNothing
+//(* gtStructure *) , amStructure // TODO - This will undoubtedly change once there is more than one structure
+(* gtLandGun *) , amLandGun
+(* gtTardis *) , amTardis
+(* gtIceGun *) , amIceGun
+(* gtAddAmmo *) , amNothing
+(* gtGenericFaller *) , amNothing
+(* gtKnife *) , amKnife
+ );
+
+
var GCounter: LongWord = 0; // this does not get re-initialized, but should be harmless
+const
+ cUsualZ = 500;
+ cOnHHZ = 2000;
+
procedure InsertGearToList(Gear: PGear);
var tmp, ptmp: PGear;
begin
@@ -106,18 +181,18 @@ gear^.Density:= _1;
gear^.AmmoType:= GearKindAmmoTypeMap[Kind];
gear^.CollisionMask:= $FFFF;
-if CurrentHedgehog <> nil then
+if CurrentHedgehog <> nil then
begin
gear^.Hedgehog:= CurrentHedgehog;
if (CurrentHedgehog^.Gear <> nil) and (hwRound(CurrentHedgehog^.Gear^.X) = X) and (hwRound(CurrentHedgehog^.Gear^.Y) = Y) then
- gear^.CollisionMask:= $FF7F
+ gear^.CollisionMask:= lfNotCurrentMask
end;
if (Ammoz[Gear^.AmmoType].Ammo.Propz and ammoprop_NeedTarget <> 0) then
gear^.Z:= cHHZ+1
else gear^.Z:= cUsualZ;
-
+
case Kind of
gtGrenade,
gtClusterBomb,
@@ -252,7 +327,7 @@ case Kind of
end;
gtKnife: begin
gear^.Density:= _4;
- gear^.Radius:= 16
+ gear^.Radius:= 7
end;
gtCase: begin
gear^.ImpactSound:= sndGraveImpact;
@@ -394,7 +469,8 @@ case Kind of
end;
gtJetpack: begin
gear^.Health:= 2000;
- gear^.Damage:= 100
+ gear^.Damage:= 100;
+ gear^.State:= gstSubmersible
end;
gtMolotov: begin
gear^.Radius:= 6;
@@ -461,6 +537,7 @@ gtFlamethrower: begin
gear^.Radius:= 5;
gear^.Density:= _1_5;
end;
+{
gtStructure: begin
gear^.Elasticity:= _0_55;
gear^.Friction:= _0_995;
@@ -471,7 +548,11 @@ gtFlamethrower: begin
gear^.Tag:= TotalRounds + 3;
gear^.Pos:= 1;
end;
- gtIceGun: gear^.Health:= 1000;
+}
+ gtIceGun: begin
+ gear^.Health:= 1000;
+ gear^.Radius:= 8;
+ end;
gtGenericFaller:begin
gear^.AdvBounce:= 1;
gear^.Radius:= 1;
@@ -568,7 +649,7 @@ else if Gear^.Kind = gtHedgehog then
if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Effects[heResurrectable] <> 0) and
//(Gear^.Hedgehog^.Effects[heResurrectable] = 0) then
(Gear^.Hedgehog^.Team^.Clan <> CurrentHedgehog^.Team^.Clan) then
- with CurrentHedgehog^ do
+ with CurrentHedgehog^ do
begin
inc(Team^.stats.AIKills);
FreeTexture(Team^.AIKillsTex);
diff --git a/hedgewars/uGearsRender.pas b/hedgewars/uGearsRender.pas
index a9c28b4..4a46e97 100644
--- a/hedgewars/uGearsRender.pas
+++ b/hedgewars/uGearsRender.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@ var RopePoints: record
X, Y: hwFloat;
dLen: hwFloat;
b: boolean;
+ sx, sy, sb: boolean;
end;
rounded: array[0..MAXROPEPOINTS + 2] of TVertex2f;
end;
@@ -39,6 +40,14 @@ var RopePoints: record
implementation
uses uRender, uUtils, uVariables, uAmmos, Math, uVisualGears;
+const
+ // hog tag mask
+ //htNone = $00;
+ htTeamName = $01;
+ htName = $02;
+ htHealth = $04;
+ htTransparent = $08;
+
procedure DrawRopeLinesRQ(Gear: PGear);
begin
with RopePoints do
@@ -99,7 +108,7 @@ begin
end
else sX:= dX;
- if (dY > 0) then
+ if (dY > 0) then
sY:= 1
else
if (dY < 0) then
@@ -107,7 +116,7 @@ begin
sY:= -1;
dY:= -dY
end
- else
+ else
sY:= dY;
if (dX > dY) then
@@ -203,6 +212,8 @@ var i, t: LongInt;
defaultPos, HatVisible: boolean;
HH: PHedgehog;
CurWeapon: PAmmo;
+ iceOffset:Longint;
+ r:TSDL_Rect;
begin
HH:= Gear^.Hedgehog;
if HH^.Unplaced then
@@ -231,6 +242,30 @@ begin
defaultPos:= true;
HatVisible:= false;
+ if HH^.Effects[heFrozen] > 0 then
+ if HH^.Effects[heFrozen] < 150000 then
+ begin
+ DrawHedgehog(sx, sy,
+ sign,
+ 0,
+ 0,
+ 0);
+ defaultPos:= false;
+ if HH^.Effects[heFrozen] < 256 then
+ HatVisible:= true
+ else HatVisible:= false
+ end
+ else
+ begin
+ DrawHedgehog(sx, sy,
+ sign,
+ 2,
+ 4,
+ 0);
+ defaultPos:= false;
+ HatVisible:= false
+ end;
+
if HH^.Effects[hePoisoned] <> 0 then
begin
@@ -239,6 +274,7 @@ begin
Tint($FF, $FF, $FF, $FF)
end;
+
if ((Gear^.State and gstWinner) <> 0) and
((CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtPickHammer)) then
begin
@@ -316,13 +352,7 @@ begin
lx:= lx + ax;
ly:= ly + ay;
tx:= round(lx);
- ty:= round(ly);
- if (abs(tx-hx) > 1000) or (abs(hy-ty) > 1000) then
- begin
- DrawLine(hx, hy, tx, ty, 1.0, $FF, $00, $00, $C0);
- hx:= tx;
- hy:= ty
- end
+ ty:= round(ly)
end;
// reached edge of land. assume infinite beam. Extend it way out past camera
if ((ty and LAND_HEIGHT_MASK) <> 0) or ((tx and LAND_WIDTH_MASK) <> 0) then
@@ -332,7 +362,6 @@ begin
end;
//if (abs(lx-tx)>8) or (abs(ly-ty)>8) then
- if (tx <> hx) or (ty <> hy) then
begin
DrawLine(hx, hy, tx, ty, 1.0, $FF, $00, $00, $C0);
end;
@@ -340,8 +369,8 @@ begin
// draw crosshair
CrosshairX := Round(hwRound(Gear^.X) + dx * 80 + GetLaunchX(HH^.CurAmmoType, sign * m, Gear^.Angle));
CrosshairY := Round(hwRound(Gear^.Y) + dy * 80 + GetLaunchY(HH^.CurAmmoType, Gear^.Angle));
-
-
+
+
DrawTextureRotated(HH^.Team^.CrosshairTex,
12, 12, CrosshairX + WorldDx, CrosshairY + WorldDy, 0,
sign * (Gear^.Angle * 180.0) / cMaxAngle);
@@ -530,7 +559,7 @@ begin
DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
end;
gtIceGun:
- begin DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+ begin DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
if CurAmmoGear^.Tex <> nil then
DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
end;
@@ -616,13 +645,13 @@ begin
amShotgun: DrawSpriteRotated(sprHandShotgun, hx, hy, sign, aangle);
amDEagle: DrawSpriteRotated(sprHandDEagle, hx, hy, sign, aangle);
amSineGun: DrawSpriteRotatedF(sprHandSinegun, hx, hy, 73 + (sign * LongInt(RealTicks div 73)) mod 8, sign, aangle);
-
+
amPortalGun:
if (CurWeapon^.Timer and 2) <> 0 then // Add a new Hedgehog value instead of abusing timer?
DrawSpriteRotatedF(sprPortalGun, hx, hy, 0, sign, aangle)
else
DrawSpriteRotatedF(sprPortalGun, hx, hy, 1+CurWeapon^.Pos, sign, aangle);
-
+
amSniperRifle: DrawSpriteRotatedF(sprSniperRifle, hx, hy, 0, sign, aangle);
amBlowTorch: DrawSpriteRotated(sprHandBlowTorch, hx, hy, sign, aangle);
amCake: DrawSpriteRotated(sprHandCake, hx, hy, sign, aangle);
@@ -638,7 +667,7 @@ begin
amKnife: DrawSpriteRotatedF(sprHandKnife, hx, hy, 0, sign, aangle);
amSeduction: begin
DrawSpriteRotated(sprHandSeduction, hx, hy, sign, aangle);
- DrawCircle(ox, oy, 248, 4, $FF, $00, $00, $AA);
+ DrawCircle(ox, oy, 248, 4, $FF, $00, $00, $AA);
//Tint($FF, $0, $0, $AA);
//DrawTexture(ox - 240, oy - 240, SpritesData[sprVampiric].Texture, 10);
//Tint($FF, $FF, $FF, $FF);
@@ -661,7 +690,7 @@ begin
amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
amLandGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
- amIceGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+ amIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
amResurrector: DrawCircle(ox, oy, 98, 4, $F5, $DB, $35, $AA); // I'd rather not like to hardcode 100 here
end;
@@ -724,7 +753,7 @@ begin
end else // not gstHHDriven
begin
- if (Gear^.Damage > 0)
+ if (Gear^.Damage > 0) and (HH^.Effects[heFrozen] = 0)
and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then
begin
DrawHedgehog(sx, sy,
@@ -750,6 +779,7 @@ begin
begin
if defaultPos then
begin
+ if HH^.Team^.hasGone then Tint($FF, $FF, $FF, $80);
DrawSpriteRotatedF(sprHHIdle,
sx,
sy,
@@ -791,7 +821,8 @@ begin
32,
32);
Tint($FF, $FF, $FF, $FF)
- end
+ end;
+ if HH^.Team^.hasGone then Tint($FF, $FF, $FF, $FF)
end
else
begin
@@ -907,6 +938,28 @@ begin
Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - ((RealTicks div 2 + Gear^.uid * 491) mod 1500) / 750))));
DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
end;
+
+ if HH^.Effects[heFrozen] < 150000 then
+ begin
+ if HH^.Effects[heFrozen] < 150000 then
+ Tint($FF, $FF, $FF, min(255,127+HH^.Effects[heFrozen] div 800));
+
+ iceOffset:= min(32, HH^.Effects[heFrozen] div 8);
+ r.x := 128;
+ r.y := 96 - iceOffset;
+ r.w := 32;
+ r.h := iceOffset;
+ if sign = -1 then
+ DrawTextureFromRectDir(sx + sign*2, sy+16-iceoffset, r.w, r.h, @r, HHTexture, sign)
+ else
+ DrawTextureFromRectDir(sx-16 + sign*2, sy+16-iceoffset, r.w, r.h, @r, HHTexture, sign);
+
+
+ if HH^.Effects[heFrozen] < 150000 then
+ Tint($FF, $FF, $FF, $FF);
+ end;
+
+
if cVampiric and
(CurrentHedgehog^.Gear <> nil) and
(CurrentHedgehog^.Gear = Gear) then
@@ -926,11 +979,13 @@ var
aAngle: real;
startX, endX, startY, endY: LongInt;
begin
+ if Gear^.State and gstFrozen <> 0 then Tint($A0, $A0, $FF, $FF);
+ //if Gear^.State and gstFrozen <> 0 then Tint(IceColor or $FF);
if Gear^.Target.X <> NoPointX then
if Gear^.AmmoType = amBee then
DrawSpriteRotatedF(sprTargetBee, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, 0, 0, (RealTicks shr 3) mod 360)
- else if Gear^.AmmoType = amIceGun then
- //DrawSprite(sprSnowDust, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8)
+ else if Gear^.AmmoType = amIceGun then
+ //DrawSprite(sprSnowDust, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8)
//DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8, 1, 22, 22, (RealTicks shr 3) mod 360)
DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1/(1+(RealTicks shr 8) mod 5), 0, 0, Gear^.Target.X + WorldDx, Gear^.Target.Y + WorldDy, (RealTicks shr 2) mod 8, 1, 22, 22, (RealTicks shr 3) mod 360)
else
@@ -940,7 +995,7 @@ begin
gtGrenade: DrawSpriteRotated(sprBomb, x, y, 0, Gear^.DirAngle);
gtSnowball: DrawSpriteRotated(sprSnowball, x, y, 0, Gear^.DirAngle);
gtGasBomb: DrawSpriteRotated(sprCheese, x, y, 0, Gear^.DirAngle);
-
+
gtMolotov: if (Gear^.State and gstDrowning) = 0 then
DrawSpriteRotatedF(sprMolotov, x, y, (RealTicks div 125) mod 8, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX))
else DrawSprite(sprMolotov, x, y, 8);
@@ -984,45 +1039,59 @@ begin
gtBee: DrawSpriteRotatedF(sprBee, x, y, (GameTicks shr 5) mod 2, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
gtPickHammer: DrawSprite(sprPHammer, x - 16, y - 50 + LongInt(((GameTicks shr 5) and 1) * 2), 0);
gtRope: DrawRope(Gear);
-
- gtMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then
+
+ gtMine: begin
+ if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then
DrawSpriteRotated(sprMineOff, x, y, 0, Gear^.DirAngle)
- else if Gear^.Health <> 0 then
- DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle)
- else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
-
+ else if Gear^.Health <> 0 then
+ DrawSpriteRotated(sprMineOn, x, y, 0, Gear^.DirAngle)
+ else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
+ end;
+
gtSMine: if (((Gear^.State and gstAttacking) = 0)or((Gear^.Timer and $3FF) < 420)) and (Gear^.Health <> 0) then
DrawSpriteRotated(sprSMineOff, x, y, 0, Gear^.DirAngle)
else if Gear^.Health <> 0 then
DrawSpriteRotated(sprSMineOn, x, y, 0, Gear^.DirAngle)
else DrawSpriteRotated(sprMineDead, x, y, 0, Gear^.DirAngle);
gtKnife: DrawSpriteRotatedF(sprKnife, x, y, 0, hwSign(Gear^.dX), Gear^.DirAngle);
-
+
gtCase: begin
if Gear^.Timer > 1000 then
begin
if ((Gear^.Pos and posCaseAmmo) <> 0) then
begin
- i:= (GameTicks shr 6) mod 64;
- if i > 18 then
- i:= 0;
- DrawSprite(sprCase, x - 24, y - 24, i);
+ if Gear^.State and gstFrozen <> 0 then
+ DrawSprite(sprCase, x - 24, y - 28, 0)
+ else
+ begin
+ i:= (GameTicks shr 6) mod 64;
+ if i > 18 then i:= 0;
+ DrawSprite(sprCase, x - 24, y - 24, i)
+ end
end
else if ((Gear^.Pos and posCaseHealth) <> 0) then
begin
- i:= ((GameTicks shr 6) + 38) mod 64;
- if i > 13 then
- i:= 0;
- DrawSprite(sprFAid, x - 24, y - 24, i);
+ if Gear^.State and gstFrozen <> 0 then
+ DrawSprite(sprFAid, x - 24, y - 28, 0)
+ else
+ begin
+ i:= ((GameTicks shr 6) + 38) mod 64;
+ if i > 13 then i:= 0;
+ DrawSprite(sprFAid, x - 24, y - 24, i)
+ end
end
else if ((Gear^.Pos and posCaseUtility) <> 0) then
begin
- i:= (GameTicks shr 6) mod 70;
- if i > 23 then
- i:= 0;
- i:= i mod 12;
- DrawSprite(sprUtility, x - 24, y - 24, i);
- end;
+ if Gear^.State and gstFrozen <> 0 then
+ DrawSprite(sprUtility, x - 24, y - 28, 0)
+ else
+ begin
+ i:= (GameTicks shr 6) mod 70;
+ if i > 23 then i:= 0;
+ i:= i mod 12;
+ DrawSprite(sprUtility, x - 24, y - 24, i)
+ end
+ end
end;
if Gear^.Timer < 1833 then
begin
@@ -1043,7 +1112,7 @@ begin
else if Gear^.State and gsttmpFlag = 0 then
DrawSpriteRotatedF(sprExplosivesRoll, x, y + 4, 0, 0, Gear^.DirAngle)
else
- DrawSpriteRotatedF(sprExplosivesRoll, x, y + 4, 1, 0, Gear^.DirAngle);
+ DrawSpriteRotatedF(sprExplosivesRoll, x, y + 4, 1, 0, Gear^.DirAngle)
end;
gtDynamite: DrawSprite(sprDynamite, x - 16, y - 25, Gear^.Tag and 1, Gear^.Tag shr 1);
gtClusterBomb: DrawSpriteRotated(sprClusterBomb, x, y, 0, Gear^.DirAngle);
@@ -1081,7 +1150,7 @@ begin
DrawSpriteRotatedF(sprCakeDown, x, y, 5 - Gear^.Pos, hwSign(Gear^.dX), Gear^.DirAngle * hwSign(Gear^.dX) + 90);
gtSeduction: if Gear^.Pos >= 14 then
DrawSprite(sprSeduction, x - 16, y - 16, 0);
-
+
gtWatermelon: DrawSpriteRotatedF(sprWatermelon, x, y, 0, 0, Gear^.DirAngle);
gtMelonPiece: DrawSpriteRotatedF(sprWatermelon, x, y, 1, 0, Gear^.DirAngle);
gtHellishBomb: DrawSpriteRotated(sprHellishBomb, x, y, 0, Gear^.DirAngle);
@@ -1096,8 +1165,8 @@ begin
startX:= max(max(LAND_WIDTH,4096) + 1024, endX + 2048)
else
startX:= max(-max(LAND_WIDTH,4096) - 1024, endX - 2048);
- startY:= endY - 256;
- DrawTextureF(SpritesData[sprBirdy].Texture, 1, startX + WorldDx + LongInt(round((endX - startX) * (-power(2, -10 * LongInt(Gear^.Timer)/2000) + 1))), startY + WorldDy + LongInt(round((endY - startY) * sqrt(1 - power((LongInt(Gear^.Timer)/2000)-1, 2)))), ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75);
+ startY:= endY - 1024;
+ DrawTextureF(SpritesData[sprBirdy].Texture, min(Gear^.Timer/750,1), startX + WorldDx + LongInt(round((endX - startX) * (-power(2, -10 * LongInt(Gear^.Timer)/2000) + 1))), startY + WorldDy + LongInt(round((endY - startY) * sqrt(1 - power((LongInt(Gear^.Timer)/2000)-1, 2)))), ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75);
end
else // Disappearing
begin
@@ -1107,8 +1176,8 @@ begin
endX:= max(max(LAND_WIDTH,4096) + 1024, startX + 2048)
else
endX:= max(-max(LAND_WIDTH,4096) - 1024, startX - 2048);
- endY:= startY + 256;
- DrawTextureF(SpritesData[sprBirdy].Texture, 1, startX + WorldDx + LongInt(round((endX - startX) * power(2, 10 * (LongInt(Gear^.Timer)/2000 - 1)))) + hwRound(Gear^.dX * Gear^.Timer), startY + WorldDy + LongInt(round((endY - startY) * cos(LongInt(Gear^.Timer)/2000 * (Pi/2)) - (endY - startY))) + hwRound(Gear^.dY * Gear^.Timer), ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75);
+ endY:= startY + 1024;
+ DrawTextureF(SpritesData[sprBirdy].Texture, min((2000-Gear^.Timer)/750,1), startX + WorldDx + LongInt(round((endX - startX) * power(2, 10 * (LongInt(Gear^.Timer)/2000 - 1)))) + hwRound(Gear^.dX * Gear^.Timer), startY + WorldDy + LongInt(round((endY - startY) * cos(LongInt(Gear^.Timer)/2000 * (Pi/2)) - (endY - startY))) + hwRound(Gear^.dY * Gear^.Timer), ((Gear^.Pos shr 6) or (RealTicks shr 8)) mod 2, Gear^.Tag, 75, 75);
end;
end
else
@@ -1149,9 +1218,9 @@ begin
gtNapalmBomb: DrawSpriteRotated(sprNapalmBomb, x, y, 0, DxDy2Angle(Gear^.dY, Gear^.dX));
gtFlake: if Gear^.State and (gstDrowning or gstTmpFlag) <> 0 then
begin
- Tint((ExplosionBorderColor shr RShift) and $FF,
- (ExplosionBorderColor shr GShift) and $FF,
- (ExplosionBorderColor shr BShift) and $FF,
+ Tint((ExplosionBorderColor shr RShift) and $FF,
+ (ExplosionBorderColor shr GShift) and $FF,
+ (ExplosionBorderColor shr BShift) and $FF,
$FF);
// Needs a nicer white texture to tint
DrawTextureRotatedF(SpritesData[sprSnowDust].Texture, 1, 0, 0, x, y, 0, 1, 8, 8, Gear^.DirAngle);
@@ -1176,12 +1245,12 @@ begin
if Gear^.FlightTime > 0 then
Tint($FF, $FF, $FF, $FF);
end;
- gtStructure: DrawSprite(sprTarget, x - 16, y - 16, 0);
+ //gtStructure: DrawSprite(sprTarget, x - 16, y - 16, 0);
gtTardis: if Gear^.Pos <> 4 then
begin
if Gear^.Pos = 2 then
Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or $FF)
- else
+ else
Tint(Gear^.Hedgehog^.Team^.Clan^.Color shl 8 or max($00, round(Gear^.Power * (1-abs(0.5 - (GameTicks mod 2000) / 2000)))));
DrawSprite(sprTardis, x-24, y-63,0);
if Gear^.Pos = 2 then
@@ -1218,8 +1287,13 @@ begin
begin
i:= random(100)+100;
if Gear^.Target.X <> NoPointX then
- DrawLine(Gear^.Target.X, Gear^.Target.Y, hwRound(HHGear^.X), hwRound(HHGear^.Y), 4.0, i, i, $FF, $40)
- else DrawLine(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, i, i, $FF, $40);
+ begin
+ DrawLine(Gear^.Target.X, Gear^.Target.Y, hwRound(HHGear^.X), hwRound(HHGear^.Y), 4.0, i, i, $FF, $40);
+ end
+ else
+ begin
+ DrawLine(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, i, i, $FF, $40);
+ end;
end
end
end;
@@ -1227,6 +1301,7 @@ begin
end;
if Gear^.RenderTimer and (Gear^.Tex <> nil) then
DrawTextureCentered(x + 8, y + 8, Gear^.Tex);
+ if Gear^.State and gstFrozen <> 0 then Tint($FF, $FF, $FF, $FF)
end;
end.
diff --git a/hedgewars/uGearsUtils.pas b/hedgewars/uGearsUtils.pas
index 2c23467..e38bee6 100644
--- a/hedgewars/uGearsUtils.pas
+++ b/hedgewars/uGearsUtils.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,13 +31,13 @@ procedure spawnHealthTagForHH(HHGear: PGear; dmg: Longword);
procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
procedure CheckHHDamage(Gear: PGear);
procedure CalcRotationDirAngle(Gear: PGear);
-procedure ResurrectHedgehog(gear: PGear);
+procedure ResurrectHedgehog(var gear: PGear);
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt); inline;
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
function CheckGearNear(Gear: PGear; Kind: TGearType; rX, rY: LongInt): PGear;
-function CheckGearDrowning(Gear: PGear): boolean;
+function CheckGearDrowning(var Gear: PGear): boolean;
procedure CheckCollision(Gear: PGear); inline;
procedure CheckCollisionWithLand(Gear: PGear); inline;
@@ -106,8 +106,8 @@ while Gear <> nil do
gtTarget,
gtFlame,
gtKnife,
- gtExplosives,
- gtStructure: begin
+ gtExplosives: begin //,
+ //gtStructure: begin
// Run the calcs only once we know we have a type that will need damage
tdX:= Gear^.X-fX;
tdY:= Gear^.Y-fY;
@@ -137,7 +137,7 @@ while Gear <> nil do
Gear^.Active:= true;
if Gear^.Kind <> gtFlame then FollowGear:= Gear
end;
- if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) then
+ if ((Mask and EXPLPoisoned) <> 0) and (Gear^.Kind = gtHedgehog) and (not Gear^.Invulnerable) and ((Gear^.State and gstHHDeath) = 0) then
Gear^.Hedgehog^.Effects[hePoisoned] := 1;
end;
@@ -182,7 +182,7 @@ begin
i:= _1;
if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then
i:= _1_5;
-if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then
+if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King or (Gear^.Hedgehog^.Effects[heFrozen] > 0)) then
ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5)
else
ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent)
@@ -243,8 +243,8 @@ begin
end;
uStats.HedgehogDamaged(Gear, AttackerHog, Damage, false);
end;
- end
- else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure
+ end else
+ //else if Gear^.Kind <> gtStructure then // not gtHedgehog nor gtStructure
Gear^.Hedgehog:= AttackerHog;
inc(Gear^.Damage, Damage);
@@ -263,6 +263,7 @@ end;
procedure HHHurt(Hedgehog: PHedgehog; Source: TDamageSource);
begin
+if Hedgehog^.Effects[heFrozen] <> 0 then exit;
if (Source = dsFall) or (Source = dsExplosion) then
case random(3) of
0: PlaySoundV(sndOoff1, Hedgehog^.Team^.voicepack);
@@ -286,35 +287,37 @@ end;
procedure CheckHHDamage(Gear: PGear);
var
dmg: Longword;
- i: LongInt;
+ i: LongWord;
particle: PVisualGear;
begin
- if _0_4 < Gear^.dY then
+if _0_4 < Gear^.dY then
+ begin
+ dmg := ModifyDamage(1 + hwRound((Gear^.dY - _0_4) * 70), Gear);
+ if Gear^.Hedgehog^.Effects[heFrozen] = 0 then
+ PlaySound(sndBump)
+ else PlaySound(sndFrozenHogImpact);
+ if dmg < 1 then
+ exit;
+
+ for i:= min(12, (3 + dmg div 10)) downto 0 do
begin
- dmg := ModifyDamage(1 + hwRound((hwAbs(Gear^.dY) - _0_4) * 70), Gear);
- PlaySound(sndBump);
- if dmg < 1 then
- exit;
-
- for i:= min(12, (3 + dmg div 10)) downto 0 do
- begin
- particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
- if particle <> nil then
- particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
- end;
+ particle := AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
+ if particle <> nil then
+ particle^.dX := particle^.dX + (Gear^.dX.QWordValue / 21474836480);
+ end;
- if (Gear^.Invulnerable) then
- exit;
+ if (Gear^.Invulnerable) then
+ exit;
- //if _0_6 < Gear^.dY then
- // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack)
- //else
- // PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack);
+ //if _0_6 < Gear^.dY then
+ // PlaySound(sndOw4, Gear^.Hedgehog^.Team^.voicepack)
+ //else
+ // PlaySound(sndOw1, Gear^.Hedgehog^.Team^.voicepack);
- if Gear^.LastDamage <> nil then
- ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall)
- else
- ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall);
+ if Gear^.LastDamage <> nil then
+ ApplyDamage(Gear, Gear^.LastDamage, dmg, dsFall)
+ else
+ ApplyDamage(Gear, CurrentHedgehog, dmg, dsFall);
end
end;
@@ -337,7 +340,7 @@ begin
Gear^.DirAngle := Gear^.DirAngle - 360
end;
-function CheckGearDrowning(Gear: PGear): boolean;
+function CheckGearDrowning(var Gear: PGear): boolean;
var
skipSpeed, skipAngle, skipDecay: hwFloat;
i, maxDrops, X, Y: LongInt;
@@ -361,7 +364,7 @@ begin
else DeleteGear(Gear);
exit
end;
- isSubmersible:= (Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.AmmoType = amJetpack);
+ isSubmersible:= ((Gear = CurrentHedgehog^.Gear) and (CurAmmoGear <> nil) and (CurAmmoGear^.State and gstSubmersible <> 0)) or (Gear^.State and gstSubmersible <> 0);
skipSpeed := _0_25;
skipAngle := _1_9;
skipDecay := _0_87;
@@ -369,7 +372,7 @@ begin
vdX:= hwFloat2Float(Gear^.dX);
vdY:= hwFloat2Float(Gear^.dY);
// this could perhaps be a tiny bit higher.
- if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
+ if (cWaterLine + 64 + Gear^.Radius > Y) and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > skipSpeed)
and (hwAbs(Gear^.dX) > skipAngle * hwAbs(Gear^.dY)) then
begin
Gear^.dY.isNegative := true;
@@ -390,7 +393,11 @@ begin
if Gear^.Kind = gtHedgehog then
begin
if Gear^.Hedgehog^.Effects[heResurrectable] <> 0 then
- ResurrectHedgehog(Gear)
+ begin
+ // Gear could become nil after this, just exit to skip splashes
+ ResurrectHedgehog(Gear);
+ exit
+ end
else
begin
Gear^.doStep := @doStepDrowningGear;
@@ -402,9 +409,12 @@ begin
Gear^.doStep := @doStepDrowningGear;
if Gear^.Kind = gtFlake then
exit // skip splashes
- end;
+ end
+ else if (Y > cWaterLine + cVisibleWater*4) and
+ ((Gear <> CurrentHedgehog^.Gear) or (CurAmmoGear = nil) or (CurAmmoGear^.State and gstSubmersible = 0)) then
+ Gear^.doStep:= @doStepDrowningGear;
if ((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius))
- or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0)
+ or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0)
and (CurAmmoGear^.dY < _0_01))) then
if Gear^.Density * Gear^.dY > _1 then
PlaySound(sndSplash)
@@ -416,7 +426,7 @@ begin
if ((cReducedQuality and rqPlainSplash) = 0)
and (((not isSubmersible) and (Y < cWaterLine + 64 + Gear^.Radius))
- or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and ((CurAmmoGear^.Pos = 0)
+ or (isSubmersible and (Y < cWaterLine + 2 + Gear^.Radius) and (Gear = CurAmmoGear) and ((CurAmmoGear^.Pos = 0)
and (CurAmmoGear^.dY < _0_01)))) then
begin
splash:= AddVisualGear(X, cWaterLine, vgtSplash);
@@ -457,7 +467,7 @@ begin
end
end
end;
- if isSubmersible and (CurAmmoGear^.Pos = 0) then
+ if isSubmersible and (Gear = CurAmmoGear) and (CurAmmoGear^.Pos = 0) then
CurAmmoGear^.Pos := 1000
end
else
@@ -465,7 +475,7 @@ begin
end;
-procedure ResurrectHedgehog(gear: PGear);
+procedure ResurrectHedgehog(var gear: PGear);
var tempTeam : PTeam;
sparkles: PVisualGear;
gX, gY: LongInt;
@@ -507,7 +517,7 @@ begin
RenderHealth(gear^.Hedgehog^);
ScriptCall('onGearResurrect', gear^.uid);
gear^.State := gstWait;
- end;
+ end;
RecountTeamHealth(tempTeam);
end;
@@ -555,8 +565,8 @@ end;
procedure FindPlace(var Gear: PGear; withFall: boolean; Left, Right: LongInt; skipProximity: boolean);
var x: LongInt;
y, sy: LongInt;
- ar: array[0..511] of TPoint;
- ar2: array[0..1023] of TPoint;
+ ar: array[0..1023] of TPoint;
+ ar2: array[0..2047] of TPoint;
cnt, cnt2: Longword;
delta: LongInt;
ignoreNearObjects, ignoreOverlap, tryAgain: boolean;
@@ -566,10 +576,10 @@ ignoreOverlap:= false; // this not only skips proximity, but allows overlapping
tryAgain:= true;
while tryAgain do
begin
- delta:= 250;
+ delta:= LAND_WIDTH div 16;
cnt2:= 0;
repeat
- x:= Left + LongInt(GetRandom(Delta));
+ x:= Left + max(LAND_WIDTH div 2048, LongInt(GetRandom(Delta)));
repeat
inc(x, Delta);
cnt:= 0;
@@ -580,7 +590,7 @@ while tryAgain do
inc(y, 2);
until (y >= cWaterLine) or
(not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or
- (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) = 0));
+ (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) = 0));
sy:= y;
@@ -588,7 +598,7 @@ while tryAgain do
inc(y);
until (y >= cWaterLine) or
(not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or
- (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) <> 0));
+ (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, lfLandMask) <> 0));
if (y - sy > Gear^.Radius * 2)
and (((Gear^.Kind = gtExplosives)
diff --git a/hedgewars/uIO.pas b/hedgewars/uIO.pas
index b704553..0ce98e3 100644
--- a/hedgewars/uIO.pas
+++ b/hedgewars/uIO.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,10 +27,10 @@ procedure freeModule;
procedure InitIPC;
procedure SendIPC(s: shortstring);
-procedure SendIPCXY(cmd: char; X, Y: SmallInt);
+procedure SendIPCXY(cmd: char; X, Y: LongInt);
procedure SendIPCRaw(p: pointer; len: Longword);
procedure SendIPCAndWaitReply(s: shortstring);
-procedure SendKeepAliveMessage(Lag: Longword);
+procedure FlushMessages(Lag: Longword);
procedure LoadRecordFromFile(fileName: shortstring);
procedure SendStat(sit: TStatInfoType; s: shortstring);
procedure IPCWaitPongEvent;
@@ -41,6 +41,10 @@ procedure doPut(putX, putY: LongInt; fromAI: boolean);
implementation
uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug;
+const
+ cSendEmptyPacketTime = 1000;
+ cSendBufferSize = 1024;
+
type PCmd = ^TCmd;
TCmd = packed record
Next: PCmd;
@@ -48,7 +52,7 @@ type PCmd = ^TCmd;
case byte of
1: (len: byte;
cmd: Char;
- X, Y: SmallInt);
+ X, Y: LongInt);
2: (str: shortstring);
end;
@@ -60,7 +64,11 @@ var IPCSock: PTCPSocket;
headcmd: PCmd;
lastcmd: PCmd;
- SendEmptyPacketTicks: LongWord;
+ flushDelayTicks: LongWord;
+ sendBuffer: record
+ buf: array[0..Pred(cSendBufferSize)] of byte;
+ count: Word;
+ end;
function AddCmd(Time: Word; str: shortstring): PCmd;
var command: PCmd;
@@ -121,6 +129,7 @@ case s[1] of
'E': OutError(copy(s, 2, Length(s) - 1), true);
'W': OutError(copy(s, 2, Length(s) - 1), false);
'M': ParseCommand('landcheck ' + s, true);
+ 'o': if fastUntilLag then ParseCommand('forcequit', true);
'T': case s[2] of
'L': GameType:= gmtLocal;
'D': GameType:= gmtDemo;
@@ -135,7 +144,7 @@ case s[1] of
else
loTicks:= SDLNet_Read16(@s[byte(s[0]) - 1]);
AddCmd(loTicks, s);
- AddFileLog('[IPC in] '+s[1]+' ticks '+IntToStr(lastcmd^.loTime));
+ AddFileLog('[IPC in] ' + sanitizeCharForLog(s[1]) + ' ticks ' + IntToStr(lastcmd^.loTime));
end
end;
@@ -210,19 +219,45 @@ buf:= 'i' + stc[sit] + s;
SendIPCRaw(@buf[0], length(buf) + 1)
end;
+function isSyncedCommand(c: char): boolean;
+begin
+ isSyncedCommand:= (c in ['+', '#', 'L', 'l', 'R', 'r', 'U', 'u', 'D', 'd', 'Z', 'z', 'A', 'a', 'S', 'j', 'J', ',', 'c', 'N', 'p', 'P', 'w', 't', '1', '2', '3', '4', '5']) or ((c >= #128) and (c <= char(128 + cMaxSlotIndex)))
+end;
+
+procedure flushBuffer();
+begin
+ if IPCSock <> nil then
+ begin
+ SDLNet_TCP_Send(IPCSock, @sendBuffer.buf, sendBuffer.count);
+ flushDelayTicks:= 0;
+ sendBuffer.count:= 0
+ end
+end;
procedure SendIPC(s: shortstring);
begin
if IPCSock <> nil then
begin
- SendEmptyPacketTicks:= 0;
- if s[0]>#251 then
+ if s[0] > #251 then
s[0]:= #251;
SDLNet_Write16(GameTicks, @s[Succ(byte(s[0]))]);
- AddFileLog('[IPC out] '+ s[1]);
+
+ AddFileLog('[IPC out] '+ sanitizeCharForLog(s[1]));
inc(s[0], 2);
- SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0])))
+
+ if isSyncedCommand(s[1]) then
+ begin
+ if sendBuffer.count + byte(s[0]) >= cSendBufferSize then
+ flushBuffer();
+
+ Move(s, sendBuffer.buf[sendBuffer.count], byte(s[0]) + 1);
+ inc(sendBuffer.count, byte(s[0]) + 1);
+
+ if (s[1] = 'N') or (s[1] = '#') then
+ flushBuffer();
+ end else
+ SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0])))
end
end;
@@ -234,13 +269,13 @@ if IPCSock <> nil then
end
end;
-procedure SendIPCXY(cmd: char; X, Y: SmallInt);
+procedure SendIPCXY(cmd: char; X, Y: LongInt);
var s: shortstring;
begin
-s[0]:= #5;
+s[0]:= #9;
s[1]:= cmd;
-SDLNet_Write16(X, @s[2]);
-SDLNet_Write16(Y, @s[4]);
+SDLNet_Write32(X, @s[2]);
+SDLNet_Write32(Y, @s[6]);
SendIPC(s)
end;
@@ -260,17 +295,22 @@ SendIPC(_S'?');
IPCWaitPongEvent
end;
-procedure SendKeepAliveMessage(Lag: Longword);
+procedure FlushMessages(Lag: Longword);
begin
-inc(SendEmptyPacketTicks, Lag);
-if (SendEmptyPacketTicks >= cSendEmptyPacketTime) then
- SendIPC(_S'+')
+inc(flushDelayTicks, Lag);
+if (flushDelayTicks >= cSendEmptyPacketTime) then
+ begin
+ if sendBuffer.count = 0 then
+ SendIPC(_S'+');
+
+ flushBuffer()
+ end
end;
procedure NetGetNextCmd;
var tmpflag: boolean;
s: shortstring;
- x16, y16: SmallInt;
+ x32, y32: LongInt;
begin
tmpflag:= true;
@@ -327,18 +367,20 @@ while (headcmd <> nil)
AddFileLog('got cmd "N": time '+IntToStr(hiTicks shl 16 + headcmd^.loTime))
end;
'p': begin
- x16:= SDLNet_Read16(@(headcmd^.X));
- y16:= SDLNet_Read16(@(headcmd^.Y));
- doPut(x16, y16, false)
+ x32:= SDLNet_Read32(@(headcmd^.X));
+ y32:= SDLNet_Read32(@(headcmd^.Y));
+ doPut(x32, y32, false)
end;
'P': begin
// these are equations solved for CursorPoint
// SDLNet_Read16(@(headcmd^.X)) == CursorPoint.X - WorldDx;
// SDLNet_Read16(@(headcmd^.Y)) == cScreenHeight - CursorPoint.Y - WorldDy;
- if not (CurrentTeam^.ExtDriven and bShowAmmoMenu) then
+ if CurrentTeam^.ExtDriven then
begin
- CursorPoint.X:= SmallInt(SDLNet_Read16(@(headcmd^.X))) + WorldDx;
- CursorPoint.Y:= cScreenHeight - SmallInt(SDLNet_Read16(@(headcmd^.Y))) - WorldDy
+ TargetCursorPoint.X:= LongInt(SDLNet_Read32(@(headcmd^.X))) + WorldDx;
+ TargetCursorPoint.Y:= cScreenHeight - LongInt(SDLNet_Read32(@(headcmd^.Y))) - WorldDy;
+ if not bShowAmmoMenu and autoCameraOn then
+ CursorPoint:= TargetCursorPoint
end
end;
'w': ParseCommand('setweap ' + headcmd^.str[2], true);
@@ -428,7 +470,8 @@ begin
SocketString:= '';
hiTicks:= 0;
- SendEmptyPacketTicks:= 0;
+ flushDelayTicks:= 0;
+ sendBuffer.count:= 0;
end;
procedure freeModule;
diff --git a/hedgewars/uInputHandler.pas b/hedgewars/uInputHandler.pas
index ea1a85b..1b43020 100644
--- a/hedgewars/uInputHandler.pas
+++ b/hedgewars/uInputHandler.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,6 +39,7 @@ procedure InitKbdKeyTable;
procedure SetBinds(var binds: TBinds);
procedure SetDefaultBinds;
+procedure chDefaultBind(var id: shortstring);
procedure ControllerInit;
procedure ControllerAxisEvent(joy, axis: Byte; value: Integer);
@@ -57,9 +58,19 @@ const
RCTRL = $4000;
var tkbd: array[0..cKbdMaxIndex] of boolean;
- quitKeyCode, closeKeyCode: Byte;
KeyNames: array [0..cKeyMaxIndex] of string[15];
CurrentBinds: TBinds;
+ ControllerNumControllers: Integer;
+ ControllerEnabled: Integer;
+ ControllerNumAxes: array[0..5] of Integer;
+ //ControllerNumBalls: array[0..5] of Integer;
+ ControllerNumHats: array[0..5] of Integer;
+ ControllerNumButtons: array[0..5] of Integer;
+ //ControllerAxes: array[0..5] of array[0..19] of Integer;
+ //ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
+ //ControllerHats: array[0..5] of array[0..19] of Byte;
+ //ControllerButtons: array[0..5] of array[0..19] of Byte;
+ usingDBinds: boolean;
function KeyNameToCode(name: shortstring): LongInt; inline;
begin
@@ -121,13 +132,12 @@ begin
if not(tkbd[code] xor KeyDown) then exit;
tkbd[code]:= KeyDown;
-hideAmmoMenu:= false;
Trusted:= (CurrentTeam <> nil)
and (not CurrentTeam^.ExtDriven)
and (CurrentHedgehog^.BotLevel = 0);
// ctrl/cmd + q to close engine and frontend
-if(KeyDown and (code = quitKeyCode)) then
+if(KeyDown and (code = SDLK_q)) then
begin
{$IFDEF DARWIN}
if tkbd[KeyNameToCode('left_meta')] or tkbd[KeyNameToCode('right_meta')] then
@@ -138,7 +148,7 @@ if(KeyDown and (code = quitKeyCode)) then
end;
// ctrl/cmd + w to close engine
-if(KeyDown and (code = closeKeyCode)) then
+if(KeyDown and (code = SDLK_w)) then
begin
{$IFDEF DARWIN}
// on OS X it this is expected behaviour
@@ -148,14 +158,14 @@ if(KeyDown and (code = closeKeyCode)) then
if tkbd[KeyNameToCode('left_ctrl')] or tkbd[KeyNameToCode('right_ctrl')] then
if ((CurrentBinds[KeyNameToCode('left_ctrl')] = '') or
(CurrentBinds[KeyNameToCode('right_ctrl')] = '')) and
- (CurrentBinds[closeKeyCode] = '') then
+ (CurrentBinds[SDLK_w] = '') then
{$ENDIF}
ParseCommand('forcequit', true);
end;
if CurrentBinds[code][0] <> #0 then
begin
- if (code > 3) and KeyDown and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true;
+ if (code > 3) and KeyDown and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) and (CurrentTeam <> nil) and (not CurrentTeam^.ExtDriven) then bShowAmmoMenu:= false;
if KeyDown then
begin
@@ -231,8 +241,6 @@ for i:= 6 to cKeyMaxIndex do
end;
end;
-quitKeyCode:= KeyNameToCode(_S'q');
-closeKeyCode:= KeyNameToCode(_S'w');
// get the size of keyboard array
SDL_GetKeyState(@k);
@@ -320,9 +328,9 @@ begin
binds:= binds; // avoid hint
CurrentBinds:= DefaultBinds;
{$ELSE}
-for t:= 0 to cKbdMaxIndex do
- if (CurrentBinds[t] <> binds[t]) and tkbd[t] then
- ProcessKey(t, False);
+ for t:= 0 to cKbdMaxIndex do
+ if (CurrentBinds[t] <> binds[t]) and tkbd[t] then
+ ProcessKey(t, False);
CurrentBinds:= binds;
{$ENDIF}
@@ -344,7 +352,7 @@ end;
var Controller: array [0..5] of PSDL_Joystick;
procedure ControllerInit;
-var i, j: Integer;
+var j: Integer;
begin
ControllerEnabled:= 0;
{$IFDEF IPHONE}
@@ -389,18 +397,18 @@ if ControllerNumControllers > 0 then
if ControllerNumButtons[j] > 20 then
ControllerNumButtons[j]:= 20;
- // reset all buttons/axes
+ (*// reset all buttons/axes
for i:= 0 to pred(ControllerNumAxes[j]) do
ControllerAxes[j][i]:= 0;
- (*for i:= 0 to pred(ControllerNumBalls[j]) do
+ for i:= 0 to pred(ControllerNumBalls[j]) do
begin
ControllerBalls[j][i][0]:= 0;
ControllerBalls[j][i][1]:= 0;
- end;*)
+ end;
for i:= 0 to pred(ControllerNumHats[j]) do
ControllerHats[j][i]:= SDL_HAT_CENTERED;
for i:= 0 to pred(ControllerNumButtons[j]) do
- ControllerButtons[j][i]:= 0;
+ ControllerButtons[j][i]:= 0;*)
end;
end;
// enable event generation/controller updating
@@ -441,8 +449,45 @@ begin
ProcessKey(k + ControllerNumAxes[joy]*2 + ControllerNumHats[joy]*4 + button, pressed);
end;
+// Bind that isn't a team bind, but overrides defaultbinds.
+// When first called, DefaultBinds is cleared, because we assume we are getting a full list of dbinds.
+procedure chDefaultBind(var id: shortstring);
+var KeyName, Modifier, tmp: shortstring;
+ b: LongInt;
+begin
+KeyName:= '';
+Modifier:= '';
+
+if (not usingDBinds) then
+ begin
+ usingDBinds:= true;
+ FillByte(DefaultBinds, SizeOf(DefaultBinds), 0);
+ end;
+
+if (Pos('mod:', id) <> 0) then
+ begin
+ tmp:= '';
+ SplitBySpace(id, tmp);
+ Modifier:= id;
+ id:= tmp;
+ end;
+
+SplitBySpace(id, KeyName);
+if KeyName[1]='"' then
+ Delete(KeyName, 1, 1);
+if KeyName[byte(KeyName[0])]='"' then
+ Delete(KeyName, byte(KeyName[0]), 1);
+b:= KeyNameToCode(id, Modifier);
+if b = 0 then
+ OutError(errmsgUnknownVariable + ' "' + id + '"', false)
+else
+ DefaultBinds[b]:= KeyName;
+end;
+
procedure initModule;
begin
+ usingDBinds:= false;
+ RegisterVariable('dbind', @chDefaultBind, true );
end;
procedure freeModule;
diff --git a/hedgewars/uLand.pas b/hedgewars/uLand.pas
index cad6cd0..50dc77a 100644
--- a/hedgewars/uLand.pas
+++ b/hedgewars/uLand.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,12 +31,12 @@ procedure GenPreview(out Preview: TPreview);
implementation
uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, SysUtils,
uVariables, uUtils, uCommands, adler32, uDebug, uLandPainted, uTextures,
- uLandGenMaze, uLandOutline;
+ uLandGenMaze, uLandOutline, uPhysFSLayer;
var digest: shortstring;
procedure ResizeLand(width, height: LongWord);
-var potW, potH: LongWord;
+var potW, potH: LongInt;
begin
potW:= toPowerOf2(width);
potH:= toPowerOf2(height);
@@ -54,6 +54,9 @@ if (potW <> LAND_WIDTH) or (potH <> LAND_HEIGHT) then
SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
+ // 0.5 is already approaching on unplayable
+ if (width div 4096 >= 2) or (height div 2048 >= 2) then cMaxZoomLevel:= 0.5;
+ cMinMaxZoomLevelDelta:= cMaxZoomLevel - cMinZoomLevel
end;
end;
@@ -124,7 +127,7 @@ begin
SDL_FreeSurface(tmpsurf);
end;
-procedure SetPoints(var Template: TEdgeTemplate; var pa: TPixAr);
+procedure SetPoints(var Template: TEdgeTemplate; var pa: TPixAr; fps: PPointArray);
var i: LongInt;
begin
with Template do
@@ -145,7 +148,7 @@ with Template do
if pa.ar[i].x <> NTPX then
pa.ar[i].x:= LAND_WIDTH - 1 - pa.ar[i].x;
for i:= 0 to pred(FillPointsCount) do
- FillPoints^[i].x:= LAND_WIDTH - 1 - FillPoints^[i].x;
+ fps^[i].x:= LAND_WIDTH - 1 - fps^[i].x;
end;
(* Experiment in making this option more useful
@@ -178,9 +181,9 @@ with Template do
end;
for i:= 0 to pred(FillPointsCount) do
begin
- dec(FillPoints^[i].y, 100);
- if FillPoints^[i].y < 0 then
- FillPoints^[i].y:= 0;
+ dec(fps^[i].y, 100);
+ if fps^[i].y < 0 then
+ fps^[i].y:= 0;
end;
end;
@@ -189,7 +192,7 @@ with Template do
for i:= 0 to pred(BasePointsCount) do
pa.ar[i].y:= LAND_HEIGHT - 1 - pa.ar[i].y;
for i:= 0 to pred(FillPointsCount) do
- FillPoints^[i].y:= LAND_HEIGHT - 1 - FillPoints^[i].y;
+ fps^[i].y:= LAND_HEIGHT - 1 - fps^[i].y;
end;
end
end;
@@ -199,13 +202,15 @@ procedure GenBlank(var Template: TEdgeTemplate);
var pa: TPixAr;
i: Longword;
y, x: Longword;
+ fps: TPointArray;
begin
+ fps:=Template.FillPoints^;
ResizeLand(Template.TemplateWidth, Template.TemplateHeight);
for y:= 0 to LAND_HEIGHT - 1 do
for x:= 0 to LAND_WIDTH - 1 do
Land[y, x]:= lfBasic;
{$HINTS OFF}
- SetPoints(Template, pa);
+ SetPoints(Template, pa, @fps);
{$HINTS ON}
for i:= 1 to Template.BezierizeCount do
begin
@@ -222,7 +227,7 @@ begin
with Template do
for i:= 0 to pred(FillPointsCount) do
- with FillPoints^[i] do
+ with fps[i] do
FillLand(x, y);
DrawEdge(pa, lfBasic);
@@ -322,14 +327,6 @@ procedure GenLandSurface;
var tmpsurf: PSDL_Surface;
x,y: Longword;
begin
- WriteLnToConsole('Generating land...');
- case cMapGen of
- 0: GenBlank(EdgeTemplates[SelectTemplate]);
- 1: begin ResizeLand(4096,2048); GenMaze; end;
- 2: GenDrawnMap;
- else
- OutError('Unknown mapgen', true);
- end;
AddProgress();
tmpsurf:= SDL_CreateRGBSurface(SDL_SWSURFACE, LAND_WIDTH, LAND_HEIGHT, 32, RMask, GMask, BMask, 0);
@@ -425,22 +422,58 @@ BlitImageAndGenerateCollisionInfo(rightX - 150 - tmpsurf^.w, LAND_HEIGHT - tmpsu
SDL_FreeSurface(tmpsurf);
end;
+procedure LoadMapConfig;
+var f: PFSFile;
+ s: shortstring;
+begin
+s:= cPathz[ptMapCurrent] + '/map.cfg';
+
+WriteLnToConsole('Fetching map HH limit');
+
+f:= pfsOpenRead(s);
+if f <> nil then
+ begin
+ pfsReadLn(f, s);
+ if not pfsEof(f) then
+ begin
+ pfsReadLn(f, s);
+ val(s, MaxHedgehogs)
+ end;
+
+ pfsClose(f)
+ end;
+
+if (MaxHedgehogs = 0) then
+ MaxHedgehogs:= 18;
+end;
+
// Loads Land[] from an image, allowing overriding standard collision
-procedure LoadMask(mapName: shortstring);
+procedure LoadMask;
var tmpsurf: PSDL_Surface;
p: PLongwordArray;
x, y, cpX, cpY: Longword;
+ mapName: shortstring;
begin
tmpsurf:= LoadDataImage(ptMapCurrent, 'mask', ifAlpha or ifTransparent or ifIgnoreCaps);
if tmpsurf = nil then
begin
- mapName:= ExtractFileName(Pathz[ptMapCurrent]);
+ mapName:= ExtractFileName(cPathz[ptMapCurrent]);
tmpsurf:= LoadDataImage(ptMissionMaps, mapName + '/mask', ifAlpha or ifTransparent or ifIgnoreCaps);
end;
-if (tmpsurf <> nil) and (tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT) and (tmpsurf^.format^.BytesPerPixel = 4) then
+if (tmpsurf <> nil) and (tmpsurf^.format^.BytesPerPixel = 4) then
begin
+ if LAND_WIDTH = 0 then
+ begin
+ LoadMapConfig;
+ ResizeLand(tmpsurf^.w, tmpsurf^.h);
+ playHeight:= tmpsurf^.h;
+ playWidth:= tmpsurf^.w;
+ leftX:= (LAND_WIDTH - playWidth) div 2;
+ rightX:= (playWidth + ((LAND_WIDTH - playWidth) div 2)) - 1;
+ topY:= LAND_HEIGHT - playHeight;
+ end;
disableLandBack:= true;
cpX:= (LAND_WIDTH - tmpsurf^.w) div 2;
@@ -450,28 +483,11 @@ if (tmpsurf <> nil) and (tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGH
p:= tmpsurf^.pixels;
for y:= 0 to Pred(tmpsurf^.h) do
- begin
- for x:= 0 to Pred(tmpsurf^.w) do
begin
- // this an if instead of masking colours to avoid confusing map creators
- if ((AMask and p^[x]) = 0) then
- Land[cpY + y, cpX + x]:= 0
- else if p^[x] = $FFFFFFFF then // white
- Land[cpY + y, cpX + x]:= lfObject
- else if p^[x] = AMask then // black
- begin
- Land[cpY + y, cpX + x]:= lfBasic;
- disableLandBack:= false
- end
- else if p^[x] = (AMask or RMask) then // red
- Land[cpY + y, cpX + x]:= lfIndestructible
- else if p^[x] = (AMask or BMask) then // blue
- Land[cpY + y, cpX + x]:= lfObject or lfIce
- else if p^[x] = (AMask or GMask) then // green
- Land[cpY + y, cpX + x]:= lfObject or lfBouncy
- end;
+ for x:= 0 to Pred(tmpsurf^.w) do
+ SetLand(Land[cpY + y, cpX + x], p^[x]);
p:= @(p^[tmpsurf^.pitch div 4]);
- end;
+ end;
if SDL_MustLock(tmpsurf) then
SDL_UnlockSurface(tmpsurf);
@@ -490,8 +506,6 @@ end;
procedure LoadMap;
var tmpsurf: PSDL_Surface;
- s: shortstring;
- f: textfile;
mapName: shortstring = '';
begin
WriteLnToConsole('Loading land from file...');
@@ -499,35 +513,14 @@ AddProgress;
tmpsurf:= LoadDataImage(ptMapCurrent, 'map', ifAlpha or ifTransparent or ifIgnoreCaps);
if tmpsurf = nil then
begin
- mapName:= ExtractFileName(Pathz[ptMapCurrent]);
+ mapName:= ExtractFileName(cPathz[ptMapCurrent]);
tmpsurf:= LoadDataImage(ptMissionMaps, mapName + '/map', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps);
end;
// (bare) Sanity check. Considering possible LongInt comparisons as well as just how much system memoery it would take
TryDo((tmpsurf^.w < $40000000) and (tmpsurf^.h < $40000000) and (tmpsurf^.w * tmpsurf^.h < 6*1024*1024*1024), 'Map dimensions too big!', true);
ResizeLand(tmpsurf^.w, tmpsurf^.h);
-
-// unC0Rr - should this be passed from the GUI? I am not sure which layer does what
-s:= UserPathz[ptMapCurrent] + '/map.cfg';
-if not FileExists(s) then
- s:= Pathz[ptMapCurrent] + '/map.cfg';
-WriteLnToConsole('Fetching map HH limit');
-{$I-}
-Assign(f, s);
-filemode:= 0; // readonly
-Reset(f);
-if IOResult <> 0 then
- begin
- s:= Pathz[ptMissionMaps] + '/' + mapName + '/map.cfg';
- Assign(f, s);
- Reset(f);
- end;
-Readln(f);
-if not eof(f) then
- Readln(f, MaxHedgehogs);
-{$I+}
-if (MaxHedgehogs = 0) then
- MaxHedgehogs:= 18;
+LoadMapConfig;
playHeight:= tmpsurf^.h;
playWidth:= tmpsurf^.w;
@@ -544,7 +537,7 @@ BlitImageAndGenerateCollisionInfo(
tmpsurf);
SDL_FreeSurface(tmpsurf);
-LoadMask(mapname);
+LoadMask;
end;
procedure DrawBottomBorder; // broken out from other borders for doing a floor-only map, or possibly updating bottom during SD
@@ -568,8 +561,11 @@ end;
procedure GenMap;
var x, y, w, c: Longword;
+ map, mask: shortstring;
+ maskOnly: boolean;
begin
hasBorder:= false;
+ maskOnly:= false;
LoadThemeConfig;
@@ -578,10 +574,30 @@ begin
// FillChar(Land,SizeOf(TCollisionArray),0);*)
if (GameFlags and gfForts) = 0 then
- if Pathz[ptMapCurrent] <> '' then
- LoadMap
+ if cPathz[ptMapCurrent] <> '' then
+ begin
+ map:= cPathz[ptMapCurrent] + '/map.png';
+ mask:= cPathz[ptMapCurrent] + '/mask.png';
+ if (not(pfsExists(map)) and pfsExists(mask)) then
+ begin
+ maskOnly:= true;
+ LoadMask;
+ GenLandSurface
+ end
+ else LoadMap;
+ end
else
+ begin
+ WriteLnToConsole('Generating land...');
+ case cMapGen of
+ 0: GenBlank(EdgeTemplates[SelectTemplate]);
+ 1: begin ResizeLand(4096,2048); GenMaze; end;
+ 2: GenDrawnMap;
+ else
+ OutError('Unknown mapgen', true);
+ end;
GenLandSurface
+ end
else
MakeFortsMap;
@@ -597,7 +613,7 @@ else
if Land[y, x] <> 0 then
begin
inc(c);
- if c > 1000 then // avoid accidental triggering
+ if c > LongWord((LAND_WIDTH div 2)) then // avoid accidental triggering
begin
hasBorder:= true;
break;
@@ -657,7 +673,7 @@ if (GameFlags and gfBottomBorder) <> 0 then
if (GameFlags and gfDisableGirders) <> 0 then
hasGirders:= false;
-if ((GameFlags and gfForts) = 0) and (Pathz[ptMapCurrent] = '') then
+if (GameFlags and gfForts = 0) and (maskOnly or (cPathz[ptMapCurrent] = '')) then
AddObjects
else
diff --git a/hedgewars/uLandGenMaze.pas b/hedgewars/uLandGenMaze.pas
index 3cd92be..3112b16 100644
--- a/hedgewars/uLandGenMaze.pas
+++ b/hedgewars/uLandGenMaze.pas
@@ -1,3 +1,5 @@
+{$INCLUDE "options.inc"}
+
unit uLandGenMaze;
interface
diff --git a/hedgewars/uLandGraphics.pas b/hedgewars/uLandGraphics.pas
index 566040a..1eeb3c5 100644
--- a/hedgewars/uLandGraphics.pas
+++ b/hedgewars/uLandGraphics.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,10 +22,14 @@ unit uLandGraphics;
interface
uses uFloat, uConsts, uTypes;
+type
+ fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent);
+
type TRangeArray = array[0..31] of record
Left, Right: LongInt;
end;
PRangeArray = ^TRangeArray;
+TLandCircleProcedure = procedure (landX, landY, pixelX, pixelY: Longint);
function addBgColor(OldColor, NewColor: LongWord): LongWord;
function SweepDirty: boolean;
@@ -36,17 +40,230 @@ function DrawExplosion(X, Y, Radius: LongInt): Longword;
procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt);
procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
+function FillRoundInLand(X, Y, Radius: LongInt; fill: fillType): LongWord;
procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
function LandBackPixel(x, y: LongInt): LongWord;
procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
procedure DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword);
procedure DumpLandToLog(x, y, r: LongInt);
-
+procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; indestructible: boolean): boolean;
implementation
uses SDLh, uLandTexture, uVariables, uUtils, uDebug;
+
+procedure calculatePixelsCoordinates(landX, landY: Longint; var pixelX, pixelY: Longint); inline;
+begin
+if (cReducedQuality and rqBlurryLand) = 0 then
+ begin
+ pixelX := landX;
+ pixelY := landY;
+ end
+else
+ begin
+ pixelX := LandX div 2;
+ pixelY := LandY div 2;
+ end;
+end;
+
+function drawPixelBG(landX, landY, pixelX, pixelY: Longint): Longword; inline;
+begin
+drawPixelBG := 0;
+if (Land[LandY, landX] and lfIndestructible) = 0 then
+ begin
+ if ((Land[landY, landX] and lfBasic) <> 0) and (((LandPixels[pixelY, pixelX] and AMask) shr AShift) = 255) and (not disableLandBack) then
+ begin
+ LandPixels[pixelY, pixelX]:= LandBackPixel(landX, landY);
+ inc(drawPixelBG);
+ end
+ else if ((Land[landY, landX] and lfObject) <> 0) or (((LandPixels[pixelY, pixelX] and AMask) shr AShift) < 255) then
+ LandPixels[pixelY, pixelX]:= 0
+ end;
+end;
+
+procedure drawPixelEBC(landX, landY, pixelX, pixelY: Longint); inline;
+begin
+if ((Land[landY, landX] and lfBasic) <> 0) or ((Land[landY, landX] and lfObject) <> 0) then
+ begin
+ LandPixels[pixelY, pixelX]:= ExplosionBorderColor;
+ Land[landY, landX]:= (Land[landY, landX] or lfDamaged) and not lfIce;
+ LandDirty[landY div 32, landX div 32]:= 1;
+ end;
+end;
+
+function isLandscapeEdge(weight:Longint):boolean; inline;
+begin
+result := (weight < 8) and (weight >= 2);
+end;
+
+function getPixelWeight(x, y:Longint): Longint;
+var
+ i, j:Longint;
+begin
+result := 0;
+for i := x - 1 to x + 1 do
+ for j := y - 1 to y + 1 do
+ begin
+ if (i < 0) or
+ (i > LAND_WIDTH - 1) or
+ (j < 0) or
+ (j > LAND_HEIGHT -1) then
+ begin
+ result := 9;
+ exit;
+ end;
+ if Land[j, i] and lfLandMask and not lfIce = 0 then
+ result := result + 1;
+ end;
+end;
+
+
+procedure fillPixelFromIceSprite(pixelX, pixelY:Longint); inline;
+var
+ iceSurface: PSDL_Surface;
+ icePixels: PLongwordArray;
+ w: LongWord;
+begin
+ // So. 3 parameters here. Ice colour, Ice opacity, and a bias on the greyscaled pixel towards lightness
+ iceSurface:= SpritesData[sprIceTexture].Surface;
+ icePixels := iceSurface^.pixels;
+ w:= LandPixels[pixelY, pixelX];
+ if w > 0 then
+ begin
+ w:= round(((w shr RShift and $FF) * RGB_LUMINANCE_RED +
+ (w shr BShift and $FF) * RGB_LUMINANCE_GREEN +
+ (w shr GShift and $FF) * RGB_LUMINANCE_BLUE));
+ if w < 128 then w:= w+128;
+ if w > 255 then w:= 255;
+ w:= (w shl RShift) or (w shl BShift) or (w shl GShift) or (LandPixels[pixelY, pixelX] and AMask);
+ LandPixels[pixelY, pixelX]:= addBgColor(w, IceColor);
+ LandPixels[pixelY, pixelX]:= addBgColor(LandPixels[pixelY, pixelX], icePixels^[iceSurface^.w * (pixelY mod iceSurface^.h) + (pixelX mod iceSurface^.w)])
+ end
+ else
+ begin
+ LandPixels[pixelY, pixelX]:= IceColor and not AMask or $E8 shl AShift;
+ LandPixels[pixelY, pixelX]:= addBgColor(LandPixels[pixelY, pixelX], icePixels^[iceSurface^.w * (pixelY mod iceSurface^.h) + (pixelX mod iceSurface^.w)]);
+ // silly workaround to avoid having to make background erasure a tadb it smarter about sea ice
+ if LandPixels[pixelY, pixelX] and AMask shr AShift = 255 then
+ LandPixels[pixelY, pixelX]:= LandPixels[pixelY, pixelX] and not AMask or 254 shl AShift;
+ end;
+end;
+
+
+procedure DrawPixelIce(landX, landY, pixelX, pixelY: Longint); inline;
+begin
+if ((Land[landY, landX] and lfIce) <> 0) then exit;
+if isLandscapeEdge(getPixelWeight(landX, landY)) then
+ begin
+ if (LandPixels[pixelY, pixelX] and AMask < 255) and (LandPixels[pixelY, pixelX] and AMask > 0) then
+ LandPixels[pixelY, pixelX] := (IceEdgeColor and not AMask) or (LandPixels[pixelY, pixelX] and AMask)
+ else if (LandPixels[pixelY, pixelX] and AMask < 255) or (Land[landY, landX] > 255) then
+ LandPixels[pixelY, pixelX] := IceEdgeColor
+ end
+else if Land[landY, landX] > 255 then
+ begin
+ fillPixelFromIceSprite(pixelX, pixelY);
+ end;
+if Land[landY, landX] > 255 then Land[landY, landX] := Land[landY, landX] or lfIce and not lfDamaged;
+end;
+
+
+function FillLandCircleLine(y, fromPix, toPix: LongInt; fill : fillType): Longword;
+var px, py, i: LongInt;
+begin
+//get rid of compiler warning
+ px := 0;
+ py := 0;
+ FillLandCircleLine := 0;
+ case fill of
+ backgroundPixel:
+ for i:= fromPix to toPix do
+ begin
+ calculatePixelsCoordinates(i, y, px, py);
+ inc(FillLandCircleLine, drawPixelBG(i, y, px, py));
+ end;
+ ebcPixel:
+ for i:= fromPix to toPix do
+ begin
+ calculatePixelsCoordinates(i, y, px, py);
+ drawPixelEBC(i, y, px, py);
+ end;
+ nullPixel:
+ for i:= fromPix to toPix do
+ begin
+ calculatePixelsCoordinates(i, y, px, py);
+ if ((Land[y, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[y, i] > 255)) then
+ LandPixels[py, px]:= 0
+ end;
+ icePixel:
+ for i:= fromPix to toPix do
+ begin
+ calculatePixelsCoordinates(i, y, px, py);
+ DrawPixelIce(i, y, px, py);
+ end;
+ setNotCurrentMask:
+ for i:= fromPix to toPix do
+ begin
+ Land[y, i]:= Land[y, i] and lfNotCurrentMask;
+ end;
+ changePixelSetNotCurrent:
+ for i:= fromPix to toPix do
+ begin
+ if Land[y, i] and lfObjMask > 0 then
+ Land[y, i]:= (Land[y, i] and lfNotObjMask) or ((Land[y, i] and lfObjMask) - 1);
+ end;
+ setCurrentHog:
+ for i:= fromPix to toPix do
+ begin
+ Land[y, i]:= Land[y, i] or lfCurrentHog
+ end;
+ changePixelNotSetNotCurrent:
+ for i:= fromPix to toPix do
+ begin
+ if Land[y, i] and lfObjMask < lfObjMask then
+ Land[y, i]:= (Land[y, i] and lfNotObjMask) or ((Land[y, i] and lfObjMask) + 1)
+ end;
+ end;
+end;
+
+function FillLandCircleSegment(x, y, dx, dy: LongInt; fill : fillType): Longword; inline;
+begin
+ FillLandCircleSegment := 0;
+if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
+ inc(FillLandCircleSegment, FillLandCircleLine(y + dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill));
+if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
+ inc(FillLandCircleSegment, FillLandCircleLine(y - dy, Max(x - dx, 0), Min(x + dx, LAND_WIDTH - 1), fill));
+if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
+ inc(FillLandCircleSegment, FillLandCircleLine(y + dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill));
+if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
+ inc(FillLandCircleSegment, FillLandCircleLine(y - dx, Max(x - dy, 0), Min(x + dy, LAND_WIDTH - 1), fill));
+end;
+
+function FillRoundInLand(X, Y, Radius: LongInt; fill: fillType): Longword; inline;
+var dx, dy, d: LongInt;
+begin
+dx:= 0;
+dy:= Radius;
+d:= 3 - 2 * Radius;
+FillRoundInLand := 0;
+while (dx < dy) do
+ begin
+ inc(FillRoundInLand, FillLandCircleSegment(x, y, dx, dy, fill));
+ if (d < 0) then
+ d:= d + 4 * dx + 6
+ else
+ begin
+ d:= d + 4 * (dx - dy) + 10;
+ dec(dy)
+ end;
+ inc(dx)
+ end;
+if (dx = dy) then
+ inc (FillRoundInLand, FillLandCircleSegment(x, y, dx, dy, fill));
+end;
+
+
function addBgColor(OldColor, NewColor: LongWord): LongWord;
// Factor ranges from 0 to 100% NewColor
var
@@ -99,65 +316,6 @@ if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
Land[y - dx, i]:= Value;
end;
-procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet, isCurrent: boolean);
-var i: LongInt;
-begin
-if not doSet then
- begin
- if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y + dy, i]:= Land[y + dy, i] and $FF7F
- else if Land[y + dy, i] and $007F > 0 then
- Land[y + dy, i]:= (Land[y + dy, i] and $FF80) or ((Land[y + dy, i] and $7F) - 1);
- if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y - dy, i]:= Land[y - dy, i] and $FF7F
- else if Land[y - dy, i] and $007F > 0 then
- Land[y - dy, i]:= (Land[y - dy, i] and $FF80) or ((Land[y - dy, i] and $7F) - 1);
- if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y + dx, i]:= Land[y + dx, i] and $FF7F
- else if Land[y + dx, i] and $007F > 0 then
- Land[y + dx, i]:= (Land[y + dx, i] and $FF80) or ((Land[y + dx, i] and $7F) - 1);
- if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y - dx, i]:= Land[y - dx, i] and $FF7F
- else if Land[y - dx, i] and $007F > 0 then
- Land[y - dx, i]:= (Land[y - dx, i] and $FF80) or ((Land[y - dx, i] and $7F) - 1)
- end
-else
- begin
- if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y + dy, i]:= Land[y + dy, i] or $80
- else if Land[y + dy, i] and $007F < 127 then
- Land[y + dy, i]:= (Land[y + dy, i] and $FF80) or ((Land[y + dy, i] and $7F) + 1);
- if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y - dy, i]:= Land[y - dy, i] or $80
- else if Land[y - dy, i] and $007F < 127 then
- Land[y - dy, i]:= (Land[y - dy, i] and $FF80) or ((Land[y - dy, i] and $7F) + 1);
- if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y + dx, i]:= Land[y + dx, i] or $80
- else if Land[y + dx, i] and $007F < 127 then
- Land[y + dx, i]:= (Land[y + dx, i] and $FF80) or ((Land[y + dx, i] and $7F) + 1);
- if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if isCurrent then
- Land[y - dx, i]:= Land[y - dx, i] or $80
- else if Land[y - dx, i] and $007F < 127 then
- Land[y - dx, i]:= (Land[y - dx, i] and $FF80) or ((Land[y - dx, i] and $7F) + 1)
- end
-end;
-
procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
var dx, dy, d: LongInt;
begin
@@ -181,307 +339,54 @@ if (dx = dy) then
end;
procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
-var dx, dy, d: LongInt;
-begin
-dx:= 0;
-dy:= Radius;
-d:= 3 - 2 * Radius;
-while (dx < dy) do
- begin
- ChangeCircleLines(x, y, dx, dy, doSet, isCurrent);
- if (d < 0) then
- d:= d + 4 * dx + 6
- else
- begin
- d:= d + 4 * (dx - dy) + 10;
- dec(dy)
- end;
- inc(dx)
- end;
-if (dx = dy) then
- ChangeCircleLines(x, y, dx, dy, doSet, isCurrent)
-end;
-
-procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
-var i, t: LongInt;
-begin
-t:= y + dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[t, i] > 255)) then
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= 0
- else
- LandPixels[t div 2, i div 2]:= 0;
-
-t:= y - dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[t, i] > 255)) then
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= 0
- else
- LandPixels[t div 2, i div 2]:= 0;
-
-t:= y + dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[t, i] > 255)) then
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= 0
- else
- LandPixels[t div 2, i div 2]:= 0;
-
-t:= y - dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfIndestructible) = 0) and (not disableLandBack or (Land[t, i] > 255)) then
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= 0
- else
- LandPixels[t div 2, i div 2]:= 0;
-
-end;
-
-function FillLandCircleLinesBG(x, y, dx, dy: LongInt): Longword;
-var i, t, by, bx: LongInt;
- cnt: Longword;
-begin
-cnt:= 0;
-t:= y + dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if (Land[t, i] and lfIndestructible) = 0 then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- begin
- by:= t; bx:= i;
- end
- else
- begin
- by:= t div 2; bx:= i div 2;
- end;
- if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
- begin
- inc(cnt);
- LandPixels[by, bx]:= LandBackPixel(i, t)
- end
- else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
- LandPixels[by, bx]:= 0
- end;
-
-t:= y - dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if (Land[t, i] and lfIndestructible) = 0 then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- begin
- by:= t; bx:= i;
- end
- else
- begin
- by:= t div 2; bx:= i div 2;
- end;
- if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
- begin
- inc(cnt);
- LandPixels[by, bx]:= LandBackPixel(i, t)
- end
- else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
- LandPixels[by, bx]:= 0
- end;
-
-t:= y + dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if (Land[t, i] and lfIndestructible) = 0 then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- begin
- by:= t; bx:= i;
- end
- else
- begin
- by:= t div 2; bx:= i div 2;
- end;
- if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
- begin
- inc(cnt);
- LandPixels[by, bx]:= LandBackPixel(i, t)
- end
- else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
- LandPixels[by, bx]:= 0
- end;
-t:= y - dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if (Land[t, i] and lfIndestructible) = 0 then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- begin
- by:= t; bx:= i;
- end
- else
- begin
- by:= t div 2; bx:= i div 2;
- end;
- if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
- begin
- inc(cnt);
- LandPixels[by, bx]:= LandBackPixel(i, t)
- end
- else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then
- LandPixels[by, bx]:= 0
- end;
-FillLandCircleLinesBG:= cnt;
-end;
-
-procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
-var i, t: LongInt;
begin
-t:= y + dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= ExplosionBorderColor
- else
- LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
-
- Land[t, i]:= Land[t, i] or lfDamaged;
- //Despeckle(i, t);
- LandDirty[t div 32, i div 32]:= 1;
- end;
-
-t:= y - dy;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= ExplosionBorderColor
- else
- LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
- Land[t, i]:= Land[t, i] or lfDamaged;
- //Despeckle(i, t);
- LandDirty[t div 32, i div 32]:= 1;
- end;
-
-t:= y + dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= ExplosionBorderColor
- else
- LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
-
- Land[t, i]:= Land[t, i] or lfDamaged;
- //Despeckle(i, t);
- LandDirty[t div 32, i div 32]:= 1;
- end;
-
-t:= y - dx;
-if (t and LAND_HEIGHT_MASK) = 0 then
- for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
- if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
- begin
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[t, i]:= ExplosionBorderColor
- else
- LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
-
- Land[t, i]:= Land[t, i] or lfDamaged;
- //Despeckle(i, y - dy);
- LandDirty[t div 32, i div 32]:= 1;
- end;
+if not doSet and isCurrent then
+ FillRoundInLand(X, Y, Radius, setNotCurrentMask)
+else if not doSet and not IsCurrent then
+ FillRoundInLand(X, Y, Radius, changePixelSetNotCurrent)
+else if doSet and IsCurrent then
+ FillRoundInLand(X, Y, Radius, setCurrentHog)
+else if doSet and not IsCurrent then
+ FillRoundInLand(X, Y, Radius, changePixelNotSetNotCurrent);
end;
-function DrawExplosion(X, Y, Radius: LongInt): Longword;
-var dx, dy, ty, tx, d: LongInt;
- cnt: Longword;
+procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
+var
+ i, j: integer;
+ landRect: TSDL_Rect;
begin
-
-// draw background land texture
+for i := min(max(x - iceRadius, 0), LAND_WIDTH - 1) to min(max(x + iceRadius, 0), LAND_WIDTH - 1) do
begin
- cnt:= 0;
- dx:= 0;
- dy:= Radius;
- d:= 3 - 2 * Radius;
-
- while (dx < dy) do
+ for j := min(max(y, 0), LAND_HEIGHT - 1) to min(max(y + iceHeight, 0), LAND_HEIGHT - 1) do
begin
- inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
- if (d < 0) then
- d:= d + 4 * dx + 6
- else
+ if Land[j, i] = 0 then
begin
- d:= d + 4 * (dx - dy) + 10;
- dec(dy)
+ Land[j, i] := lfIce;
+ fillPixelFromIceSprite(i, j);
end;
- inc(dx)
end;
- if (dx = dy) then
- inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
- end;
-
-// draw a hole in land
-if Radius > 20 then
- begin
- dx:= 0;
- dy:= Radius - 15;
- d:= 3 - 2 * dy;
-
- while (dx < dy) do
- begin
- FillLandCircleLines0(x, y, dx, dy);
- if (d < 0) then
- d:= d + 4 * dx + 6
- else
- begin
- d:= d + 4 * (dx - dy) + 10;
- dec(dy)
- end;
- inc(dx)
- end;
- if (dx = dy) then
- FillLandCircleLines0(x, y, dx, dy);
end;
+landRect.x := min(max(x - iceRadius, 0), LAND_WIDTH - 1);
+landRect.y := min(max(y, 0), LAND_HEIGHT - 1);
+landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
+landRect.h := min(iceHeight, LAND_HEIGHT - landRect.y - 1);
+UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
+end;
- // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
+function DrawExplosion(X, Y, Radius: LongInt): Longword;
+var
+ tx, ty, dx, dy: Longint;
+begin
+ DrawExplosion := FillRoundInLand(x, y, Radius, backgroundPixel);
+ if Radius > 20 then
+ FillRoundInLand(x, y, Radius - 15, nullPixel);
FillRoundInLand(X, Y, Radius, 0);
-
-// draw explosion border
- begin
- inc(Radius, 4);
- dx:= 0;
- dy:= Radius;
- d:= 3 - 2 * Radius;
- while (dx < dy) do
- begin
- FillLandCircleLinesEBC(x, y, dx, dy);
- if (d < 0) then
- d:= d + 4 * dx + 6
- else
- begin
- d:= d + 4 * (dx - dy) + 10;
- dec(dy)
- end;
- inc(dx)
- end;
- if (dx = dy) then
- FillLandCircleLinesEBC(x, y, dx, dy);
- end;
-
-tx:= Max(X - Radius - 1, 0);
-dx:= Min(X + Radius + 1, LAND_WIDTH) - tx;
-ty:= Max(Y - Radius - 1, 0);
-dy:= Min(Y + Radius + 1, LAND_HEIGHT) - ty;
-UpdateLandTexture(tx, dx, ty, dy, false);
-DrawExplosion:= cnt
+ FillRoundInLand(x, y, Radius + 4, ebcPixel);
+ tx:= Max(X - Radius - 5, 0);
+ dx:= Min(X + Radius + 5, LAND_WIDTH) - tx;
+ ty:= Max(Y - Radius - 5, 0);
+ dy:= Min(Y + Radius + 5, LAND_HEIGHT) - ty;
+ UpdateLandTexture(tx, dx, ty, dy, false);
end;
procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
@@ -525,7 +430,7 @@ for i:= 0 to Pred(Count) do
else
LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor;
- Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
LandDirty[ty div 32, tx div 32]:= 1;
end;
inc(y, dY)
@@ -535,6 +440,33 @@ for i:= 0 to Pred(Count) do
UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false)
end;
+
+
+procedure DrawExplosionBorder(X, Y, dx, dy:hwFloat; despeckle : Boolean);
+var
+ t, tx, ty :Longint;
+begin
+for t:= 0 to 7 do
+ begin
+ X:= X + dX;
+ Y:= Y + dY;
+ tx:= hwRound(X);
+ ty:= hwRound(Y);
+ if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
+ or ((Land[ty, tx] and lfObject) <> 0)) then
+ begin
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
+ if despeckle then
+ LandDirty[ty div 32, tx div 32]:= 1;
+ if (cReducedQuality and rqBlurryLand) = 0 then
+ LandPixels[ty, tx]:= ExplosionBorderColor
+ else
+ LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
+ end
+ end;
+end;
+
+
//
// - (dX, dY) - direction, vector of length = 0.5
//
@@ -567,6 +499,7 @@ for i:= 0 to 7 do
and ((tx and LAND_WIDTH_MASK) = 0)
and (((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0)) then
begin
+ Land[ty, tx]:= Land[ty, tx] and not lfIce;
if despeckle then
begin
Land[ty, tx]:= Land[ty, tx] or lfDamaged;
@@ -586,24 +519,7 @@ for i:= -HalfWidth to HalfWidth do
begin
X:= nx - dX8;
Y:= ny - dY8;
- for t:= 0 to 7 do
- begin
- X:= X + dX;
- Y:= Y + dY;
- tx:= hwRound(X);
- ty:= hwRound(Y);
- if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
- or ((Land[ty, tx] and lfObject) <> 0)) then
- begin
- Land[ty, tx]:= Land[ty, tx] or lfDamaged;
- if despeckle then
- LandDirty[ty div 32, tx div 32]:= 1;
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[ty, tx]:= ExplosionBorderColor
- else
- LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
- end
- end;
+ DrawExplosionBorder(X, Y, dx, dy, despeckle);
X:= nx;
Y:= ny;
for t:= 0 to ticks do
@@ -629,24 +545,7 @@ for i:= -HalfWidth to HalfWidth do
Land[ty, tx]:= 0;
end
end;
- for t:= 0 to 7 do
- begin
- X:= X + dX;
- Y:= Y + dY;
- tx:= hwRound(X);
- ty:= hwRound(Y);
- if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
- or ((Land[ty, tx] and lfObject) <> 0)) then
- begin
- Land[ty, tx]:= Land[ty, tx] or lfDamaged;
- if despeckle then
- LandDirty[ty div 32, tx div 32]:= 1;
- if (cReducedQuality and rqBlurryLand) = 0 then
- LandPixels[ty, tx]:= ExplosionBorderColor
- else
- LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
- end
- end;
+ DrawExplosionBorder(X, Y, dx, dy, despeckle);
nx:= nx - dY;
ny:= ny + dX;
end;
@@ -664,7 +563,7 @@ for i:= 0 to 7 do
if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
or ((Land[ty, tx] and lfObject) <> 0)) then
begin
- Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+ Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
if despeckle then
LandDirty[ty div 32, tx div 32]:= 1;
if (cReducedQuality and rqBlurryLand) = 0 then
@@ -790,7 +689,7 @@ begin
yy:= Y div 2;
end;
- pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
+ pixelsweep:= (Land[Y, X] <= lfAllObjMask) and (LandPixels[yy, xx] <> 0);
if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
begin
c:= 0;
@@ -891,7 +790,7 @@ if (Land[Y, X] = 0) and (Y > LongInt(topY) + 1) and
end
end
else if ((cReducedQuality and rqBlurryLand) = 0) and (LandPixels[Y, X] and AMask = 255)
-and ((Land[Y, X] and (lfDamaged or lfBasic) = lfBasic) or (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic))
+and (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic)
and (Y > LongInt(topY) + 1) and (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
begin
if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0))
diff --git a/hedgewars/uLandObjects.pas b/hedgewars/uLandObjects.pas
index aa59bfd..dd0cdf3 100644
--- a/hedgewars/uLandObjects.pas
+++ b/hedgewars/uLandObjects.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,20 +27,24 @@ procedure FreeLandObjects();
procedure LoadThemeConfig;
procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word);
+procedure BlitImageUsingMask(cpX, cpY: Longword; Image, Mask: PSDL_Surface);
procedure AddOnLandObjects(Surface: PSDL_Surface);
+procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
implementation
-uses uStore, uConsts, uConsole, uRandom, uSound, GLunit,
- uTypes, uVariables, uUtils, uDebug, SysUtils;
+uses uStore, uConsts, uConsole, uRandom, uSound, GLunit
+ , uTypes, uVariables, uUtils, uDebug, SysUtils
+ , uPhysFSLayer;
const MaxRects = 512;
MAXOBJECTRECTS = 16;
MAXTHEMEOBJECTS = 32;
+ cThemeCFGFilename = 'theme.cfg';
type TRectsArray = array[0..MaxRects] of TSDL_Rect;
PRectArray = ^TRectsArray;
TThemeObject = record
- Surf: PSDL_Surface;
+ Surf, Mask: PSDL_Surface;
inland: TSDL_Rect;
outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect;
rectcnt: Longword;
@@ -66,6 +70,26 @@ var Rects: PRectArray;
ThemeObjects: TThemeObjects;
SprayObjects: TSprayObjects;
+procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
+begin
+ // this an if instead of masking colours to avoid confusing map creators
+ if ((AMask and Pixel) = 0) then
+ LandWord:= 0
+ else if Pixel = $FFFFFFFF then // white
+ LandWord:= lfObject
+ else if Pixel = AMask then // black
+ begin
+ LandWord:= lfBasic;
+ disableLandBack:= false
+ end
+ else if Pixel = (AMask or RMask) then // red
+ LandWord:= lfIndestructible
+ else if Pixel = (AMask or BMask) then // blue
+ LandWord:= lfObject or lfIce
+ else if Pixel = (AMask or GMask) then // green
+ LandWord:= lfObject or lfBouncy
+end;
+
procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
begin
BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
@@ -103,7 +127,7 @@ for y:= 0 to Pred(Image^.h) do
if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then
LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
- if ((Land[cpY + y, cpX + x] and $FF00) = 0) and ((p^[x] and AMask) <> 0) then
+ if (Land[cpY + y, cpX + x] <= lfAllObjMask) and ((p^[x] and AMask) <> 0) then
begin
Land[cpY + y, cpX + x]:= lfObject;
Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags
@@ -117,6 +141,47 @@ if SDL_MustLock(Image) then
WriteLnToConsole(msgOK)
end;
+procedure BlitImageUsingMask(cpX, cpY: Longword; Image, Mask: PSDL_Surface);
+var p, mp: PLongwordArray;
+ x, y: Longword;
+ bpp: LongInt;
+begin
+WriteToConsole('Generating collision info... ');
+
+if SDL_MustLock(Image) then
+ SDLTry(SDL_LockSurface(Image) >= 0, true);
+
+bpp:= Image^.format^.BytesPerPixel;
+TryDo(bpp = 4, 'Land object should be 32bit', true);
+
+p:= Image^.pixels;
+mp:= Mask^.pixels;
+for y:= 0 to Pred(Image^.h) do
+ begin
+ for x:= 0 to Pred(Image^.w) do
+ begin
+ if (cReducedQuality and rqBlurryLand) = 0 then
+ begin
+ if (LandPixels[cpY + y, cpX + x] = 0)
+ or (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then
+ LandPixels[cpY + y, cpX + x]:= p^[x];
+ end
+ else
+ if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then
+ LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
+
+ if (Land[cpY + y, cpX + x] <= lfAllObjMask) or (Land[cpY + y, cpX + x] and lfObject <> 0) then
+ SetLand(Land[cpY + y, cpX + x], mp^[x]);
+ end;
+ p:= @(p^[Image^.pitch shr 2]);
+ mp:= @(mp^[Mask^.pitch shr 2])
+ end;
+
+if SDL_MustLock(Image) then
+ SDL_UnlockSurface(Image);
+WriteLnToConsole(msgOK)
+end;
+
procedure AddRect(x1, y1, w1, h1: LongInt);
begin
with Rects^[RectCount] do
@@ -324,7 +389,9 @@ with Obj do
if bRes then
begin
i:= getrandom(cnt);
- BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
+ if Obj.Mask <> nil then
+ BlitImageUsingMask(ar[i].x, ar[i].y, Obj.Surf, Obj.Mask)
+ else BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
AddRect(ar[i].x, ar[i].y, Width, Height);
dec(Maxcnt)
end
@@ -399,7 +466,7 @@ end;
procedure ReadThemeInfo(var ThemeObjects: TThemeObjects; var SprayObjects: TSprayObjects);
var s, key: shortstring;
- f: textfile;
+ f: PFSFile;
i: LongInt;
ii, t: Longword;
c2: TSDL_Color;
@@ -429,21 +496,17 @@ if GrayScale then
end
end;
-s:= UserPathz[ptCurrTheme] + '/' + cThemeCFGFilename;
-if not FileExists(s) then
- s:= Pathz[ptCurrTheme] + '/' + cThemeCFGFilename;
+s:= cPathz[ptCurrTheme] + '/' + cThemeCFGFilename;
WriteLnToConsole('Reading objects info...');
-Assign(f, s);
-{$I-}
-filemode:= 0; // readonly
-Reset(f);
+f:= pfsOpenRead(s);
+TryDo(f <> nil, 'Bad data or cannot access file ' + cThemeCFGFilename, true);
ThemeObjects.Count:= 0;
SprayObjects.Count:= 0;
-while not eof(f) do
+while not pfsEOF(f) do
begin
- Readln(f, s);
+ pfsReadLn(f, s);
if Length(s) = 0 then
continue;
if s[1] = ';' then
@@ -557,9 +620,10 @@ while not eof(f) do
with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
begin
i:= Pos(',', s);
- Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps);
+ Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps or ifCritical);
Width:= Surf^.w;
Height:= Surf^.h;
+ Mask:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i)))+'_mask', ifTransparent or ifIgnoreCaps);
Delete(s, 1, i);
i:= Pos(',', s);
Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
@@ -738,9 +802,7 @@ while not eof(f) do
end
end;
-Close(f);
-{$I+}
-TryDo(IOResult = 0, 'Bad data or cannot access file ' + cThemeCFGFilename, true);
+pfsClose(f);
AddProgress;
end;
diff --git a/hedgewars/uLandOutline.pas b/hedgewars/uLandOutline.pas
index 3bc58b8..60bef6f 100644
--- a/hedgewars/uLandOutline.pas
+++ b/hedgewars/uLandOutline.pas
@@ -27,6 +27,9 @@ var Stack: record
end
end;
+const
+ cMaxEdgePoints = 16384;
+
procedure Push(_xl, _xr, _y, _dir: LongInt);
begin
TryDo(Stack.Count <= 8192, 'FillLand: stack overflow', true);
diff --git a/hedgewars/uLandPainted.pas b/hedgewars/uLandPainted.pas
index d472e08..2ca0d87 100644
--- a/hedgewars/uLandPainted.pas
+++ b/hedgewars/uLandPainted.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uLandTemplates.pas b/hedgewars/uLandTemplates.pas
index aaa625d..ef912ee 100644
--- a/hedgewars/uLandTemplates.pas
+++ b/hedgewars/uLandTemplates.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1815,7 +1815,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template0FPoints));
BezierizeCount: 3;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1826,7 +1826,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template1FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1837,7 +1837,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template2FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1848,7 +1848,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template3FPoints));
BezierizeCount: 3;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1859,7 +1859,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template4FPoints));
BezierizeCount: 3;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1870,7 +1870,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template5FPoints));
BezierizeCount: 2;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1881,7 +1881,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template6FPoints));
BezierizeCount: 2;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1892,7 +1892,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template7FPoints));
BezierizeCount: 4;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1903,7 +1903,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template8FPoints));
BezierizeCount: 2;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1914,7 +1914,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template9FPoints));
BezierizeCount: 1;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1925,7 +1925,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template10FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1936,7 +1936,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template11FPoints));
BezierizeCount: 1;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1947,7 +1947,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template12FPoints));
BezierizeCount: 3;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1958,7 +1958,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template13FPoints));
BezierizeCount: 3;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1969,7 +1969,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template14FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1980,7 +1980,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template15FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -1991,7 +1991,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template16FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -2002,7 +2002,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template17FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 2848;
+ TemplateHeight: 1424; TemplateWidth: 3072;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 18;
@@ -2013,7 +2013,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template18FPoints));
BezierizeCount: 3;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2024,7 +2024,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template19FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2035,7 +2035,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template20FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2046,7 +2046,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template21FPoints));
BezierizeCount: 3;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2057,7 +2057,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template22FPoints));
BezierizeCount: 3;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2068,7 +2068,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template23FPoints));
BezierizeCount: 2;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2079,7 +2079,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template24FPoints));
BezierizeCount: 2;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2090,7 +2090,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template25FPoints));
BezierizeCount: 4;
RandPassesCount: 4;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2101,7 +2101,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template26FPoints));
BezierizeCount: 2;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2112,7 +2112,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template27FPoints));
BezierizeCount: 1;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2123,7 +2123,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template28FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2134,7 +2134,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template29FPoints));
BezierizeCount: 1;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2145,7 +2145,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template30FPoints));
BezierizeCount: 3;
RandPassesCount: 8;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2156,7 +2156,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template31FPoints));
BezierizeCount: 3;
RandPassesCount: 5;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2167,7 +2167,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template32FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2178,7 +2178,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template33FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2189,7 +2189,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template34FPoints));
BezierizeCount: 2;
RandPassesCount: 6;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
@@ -2200,7 +2200,7 @@ var EdgeTemplates: array[0..45] of TEdgeTemplate =
FillPointsCount: Succ(High(Template35FPoints));
BezierizeCount: 3;
RandPassesCount: 7;
- TemplateHeight: 1424; TemplateWidth: 3900;
+ TemplateHeight: 1424; TemplateWidth: 4096;
canMirror: true; canFlip: false; isNegative: false; canInvert: false;
hasGirders: true;
MaxHedgeHogs: 36;
diff --git a/hedgewars/uLandTexture.pas b/hedgewars/uLandTexture.pas
index d5c713d..a006204 100644
--- a/hedgewars/uLandTexture.pas
+++ b/hedgewars/uLandTexture.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -66,6 +66,7 @@ end;
procedure UpdateLandTexture(X, Width, Y, Height: LongInt; landAdded: boolean);
var tx, ty: Longword;
begin
+ if cOnlyStats then exit;
if (Width <= 0) or (Height <= 0) then
exit;
TryDo((X >= 0) and (X < LAND_WIDTH), 'UpdateLandTexture: wrong X parameter', true);
@@ -93,6 +94,7 @@ procedure RealLandTexUpdate;
var x, y, ty, tx, lx, ly : LongWord;
isEmpty: boolean;
begin
+ if cOnlyStats then exit;
(*
if LandTextures[0, 0].tex = nil then
for x:= 0 to LANDTEXARW -1 do
diff --git a/hedgewars/uLocale.pas b/hedgewars/uLocale.pas
index e04aa50..cf74bfc 100644
--- a/hedgewars/uLocale.pas
+++ b/hedgewars/uLocale.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,35 +34,29 @@ procedure LoadLocaleWrapper(str: pchar); cdecl; export;
{$ENDIF}
implementation
-uses uRandom, uUtils, uVariables, uDebug;
+uses uRandom, uUtils, uVariables, uDebug, uPhysFSLayer;
var trevt: array[TEventId] of array [0..Pred(MAX_EVENT_STRINGS)] of ansistring;
trevt_n: array[TEventId] of integer;
procedure LoadLocale(FileName: shortstring);
-var s: ansistring;
- f: textfile;
+var s: ansistring = '';
+ f: pfsFile;
a, b, c: LongInt;
first: array[TEventId] of boolean;
e: TEventId;
- loaded: boolean;
begin
-loaded:= false;
for e:= Low(TEventId) to High(TEventId) do
first[e]:= true;
-{$I-} // iochecks off
-Assign(f, FileName);
-filemode:= 0; // readonly
-Reset(f);
-if IOResult = 0 then
- loaded:= true;
-TryDo(loaded, 'Cannot load locale "' + FileName + '"', false);
-if loaded then
+f:= pfsOpenRead(FileName);
+TryDo(f <> nil, 'Cannot load locale "' + FileName + '"', false);
+
+if f <> nil then
begin
- while not eof(f) do
+ while not pfsEof(f) do
begin
- readln(f, s);
+ pfsReadLnA(f, s);
if Length(s) = 0 then
continue;
if (s[1] < '0') or (s[1] > '9') then
@@ -99,9 +93,8 @@ if loaded then
trgoal[TGoalStrId(b)]:= s;
end;
end;
- Close(f);
+ pfsClose(f);
end;
-{$I+}
end;
function GetEventString(e: TEventId): ansistring;
diff --git a/hedgewars/uMisc.pas b/hedgewars/uMisc.pas
index 3b76379..fd45562 100644
--- a/hedgewars/uMisc.pas
+++ b/hedgewars/uMisc.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,8 +38,7 @@ function SDL_RectMake(x, y: SmallInt; width, height: Word): TSDL_Rect; inline;
implementation
uses SysUtils, uVariables, uUtils
- {$IFDEF PNG_SCREENSHOTS}, PNGh, png {$ENDIF}
- {$IFNDEF USE_SDLTHREADS} {$IFDEF UNIX}, cthreads{$ENDIF} {$ENDIF};
+ {$IFDEF PNG_SCREENSHOTS}, PNGh, png {$ENDIF};
type PScreenshot = ^TScreenshot;
TScreenshot = record
@@ -64,7 +63,7 @@ end;
{$IFDEF PNG_SCREENSHOTS}
// this funtion will be executed in separate thread
-function SaveScreenshot(screenshot: pointer): PtrInt;
+function SaveScreenshot(screenshot: pointer): LongInt; cdecl; export;
var i: LongInt;
png_ptr: ^png_struct;
info_ptr: ^png_info;
@@ -119,7 +118,7 @@ end;
{$ELSE} // no PNG_SCREENSHOTS
// this funtion will be executed in separate thread
-function SaveScreenshot(screenshot: pointer): PtrInt;
+function SaveScreenshot(screenshot: pointer): LongInt; cdecl; export;
var f: file;
// Windows Bitmap Header
head: array[0..53] of Byte = (
@@ -262,11 +261,7 @@ image^.height:= cScreenHeight div k;
image^.size:= size;
image^.buffer:= p;
-{$IFDEF USE_SDLTHREADS}
-SDL_CreateThread(@SaveScreenshot{$IFDEF SDL13}, nil{$ENDIF}, image);
-{$ELSE}
-BeginThread(@SaveScreenshot, image);
-{$ENDIF}
+SDL_CreateThread(@SaveScreenshot{$IFDEF SDL13}, 'snapshot'{$ENDIF}, image);
MakeScreenshot:= true; // possibly it is not true but we will not wait for thread to terminate
end;
diff --git a/hedgewars/uMobile.pas b/hedgewars/uMobile.pas
deleted file mode 100644
index 23cab7a..0000000
--- a/hedgewars/uMobile.pas
+++ /dev/null
@@ -1,110 +0,0 @@
-(*
- * Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *)
-
-{$INCLUDE "options.inc"}
-
-(*
- * This unit contains a lot of useful functions when hw is running on mobile
- * Unlike HwLibrary when you declare functions that you will call from your code,
- * here you need to provide functions that Pascall code will call.
- *)
-
-unit uMobile;
-interface
-
-function isPhone: Boolean; inline;
-function getScreenDPI: Double; inline;
-procedure performRumble; inline;
-
-procedure GameLoading; inline;
-procedure GameLoaded; inline;
-procedure SaveLoadingEnded; inline;
-
-implementation
-uses uVariables, uConsole, SDLh;
-
-// add here any external call that you need
-{$IFDEF IPHONEOS}
-(* iOS calls written in ObjcExports.m *)
-procedure startLoadingIndicator; cdecl; external;
-procedure stopLoadingIndicator; cdecl; external;
-procedure saveFinishedSynching; cdecl; external;
-function isApplePhone: Boolean; cdecl; external;
-procedure AudioServicesPlaySystemSound(num: LongInt); cdecl; external;
-{$ENDIF}
-
-// this function is just to determine whether we are running on a limited screen device
-function isPhone: Boolean; inline;
-begin
- isPhone:= false;
-{$IFDEF IPHONEOS}
- isPhone:= isApplePhone();
-{$ENDIF}
-{$IFDEF ANDROID}
- //nasty nasty hack. TODO: implement callback to java to have a unified way of determining if it is a tablet
- if (cScreenWidth < 1000) and (cScreenHeight < 500) then
- isPhone:= true;
-{$ENDIF}
-end;
-
-function getScreenDPI: Double; inline;
-begin
-{$IFDEF ANDROID}
-// getScreenDPI:= Android_JNI_getDensity();
- getScreenDPI:= 1;
-{$ELSE}
- getScreenDPI:= 1;
-{$ENDIF}
-end;
-
-// this function should make the device vibrate in some way
-procedure PerformRumble; inline;
-{$IFDEF IPHONEOS}const kSystemSoundID_Vibrate = $00000FFF;{$ENDIF}
-begin
- // do not vibrate while synchronising a demo/save
- if not fastUntilLag then
- begin
-{$IFDEF IPHONEOS}
- AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
-{$ENDIF}
- end;
-end;
-
-procedure GameLoading; inline;
-begin
-{$IFDEF IPHONEOS}
- startLoadingIndicator();
-{$ENDIF}
-end;
-
-procedure GameLoaded; inline;
-begin
-{$IFDEF IPHONEOS}
- stopLoadingIndicator();
-{$ENDIF}
-end;
-
-procedure SaveLoadingEnded; inline;
-begin
-{$IFDEF IPHONEOS}
- saveFinishedSynching();
-{$ENDIF}
-end;
-
-
-end.
diff --git a/hedgewars/uPhysFSLayer.pas b/hedgewars/uPhysFSLayer.pas
new file mode 100644
index 0000000..286afbd
--- /dev/null
+++ b/hedgewars/uPhysFSLayer.pas
@@ -0,0 +1,172 @@
+unit uPhysFSLayer;
+
+interface
+uses SDLh, LuaPas;
+
+const PhysfsLibName = {$IFDEF PHYSFS_INTERNAL}'libhw_physfs'{$ELSE}'libphysfs'{$ENDIF};
+const PhyslayerLibName = 'libphyslayer';
+
+{$IFNDEF WIN32}
+ {$linklib physfs}
+ {$linklib physlayer}
+
+ {statically linking physfs brings IOKit dependency on OSX}
+ {divdi3 is found in stdc++ on linux x86 and in gcc_s.1 on osx ppc32}
+ {$IFDEF PHYSFS_INTERNAL}
+ {$IFDEF DARWIN}
+ {$linkframework IOKit}
+ {$IFDEF CPU32}
+ {$linklib gcc_s.1}
+ {$ENDIF}
+ {$ELSE}
+ {$IFDEF CPU32}
+ {$linklib stdc++}
+ {$ENDIF}
+ {$ENDIF}
+ {$ENDIF}
+{$ENDIF}
+
+procedure initModule;
+procedure freeModule;
+
+type PFSFile = pointer;
+
+function rwopsOpenRead(fname: shortstring): PSDL_RWops;
+function rwopsOpenWrite(fname: shortstring): PSDL_RWops;
+
+function pfsOpenRead(fname: shortstring): PFSFile;
+function pfsClose(f: PFSFile): boolean;
+
+procedure pfsReadLn(f: PFSFile; var s: shortstring);
+procedure pfsReadLnA(f: PFSFile; var s: ansistring);
+function pfsBlockRead(f: PFSFile; buf: pointer; size: Int64): Int64;
+function pfsEOF(f: PFSFile): boolean;
+
+function pfsExists(fname: shortstring): boolean;
+
+function physfsReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; cdecl; external PhyslayerLibName;
+procedure physfsReaderSetBuffer(buf: pointer); cdecl; external PhyslayerLibName;
+procedure hedgewarsMountPackage(filename: PChar); cdecl; external PhyslayerLibName;
+
+implementation
+uses uUtils, uVariables, sysutils;
+
+function PHYSFS_init(argv0: PChar) : LongInt; cdecl; external PhysfsLibName;
+function PHYSFS_deinit() : LongInt; cdecl; external PhysfsLibName;
+function PHYSFSRWOPS_openRead(fname: PChar): PSDL_RWops; cdecl ; external PhyslayerLibName;
+function PHYSFSRWOPS_openWrite(fname: PChar): PSDL_RWops; cdecl; external PhyslayerLibName;
+
+function PHYSFS_mount(newDir, mountPoint: PChar; appendToPath: LongBool) : LongInt; cdecl; external PhysfsLibName;
+function PHYSFS_openRead(fname: PChar): PFSFile; cdecl; external PhysfsLibName;
+function PHYSFS_eof(f: PFSFile): LongBool; cdecl; external PhysfsLibName;
+function PHYSFS_readBytes(f: PFSFile; buffer: pointer; len: Int64): Int64; cdecl; external PhysfsLibName;
+function PHYSFS_close(f: PFSFile): LongBool; cdecl; external PhysfsLibName;
+function PHYSFS_exists(fname: PChar): LongBool; cdecl; external PhysfsLibName;
+
+procedure hedgewarsMountPackages(); cdecl; external PhyslayerLibName;
+
+function rwopsOpenRead(fname: shortstring): PSDL_RWops;
+begin
+ exit(PHYSFSRWOPS_openRead(Str2PChar(fname)));
+end;
+
+function rwopsOpenWrite(fname: shortstring): PSDL_RWops;
+begin
+ exit(PHYSFSRWOPS_openWrite(Str2PChar(fname)));
+end;
+
+function pfsOpenRead(fname: shortstring): PFSFile;
+begin
+ exit(PHYSFS_openRead(Str2PChar(fname)));
+end;
+
+function pfsEOF(f: PFSFile): boolean;
+begin
+ exit(PHYSFS_eof(f))
+end;
+
+function pfsClose(f: PFSFile): boolean;
+begin
+ exit(PHYSFS_close(f))
+end;
+
+function pfsExists(fname: shortstring): boolean;
+begin
+ exit(PHYSFS_exists(Str2PChar(fname)))
+end;
+
+
+procedure pfsReadLn(f: PFSFile; var s: shortstring);
+var c: char;
+begin
+s[0]:= #0;
+
+while (PHYSFS_readBytes(f, @c, 1) = 1) and (c <> #10) do
+ if (c <> #13) and (s[0] < #255) then
+ begin
+ inc(s[0]);
+ s[byte(s[0])]:= c
+ end
+end;
+
+procedure pfsReadLnA(f: PFSFile; var s: ansistring);
+var c: char;
+ b: shortstring;
+begin
+s:= '';
+b[0]:= #0;
+
+while (PHYSFS_readBytes(f, @c, 1) = 1) and (c <> #10) do
+ if (c <> #13) then
+ begin
+ inc(b[0]);
+ b[byte(b[0])]:= c;
+ if b[0] = #255 then
+ begin
+ s:= s + b;
+ b[0]:= #0
+ end
+ end;
+
+s:= s + b
+end;
+
+function pfsBlockRead(f: PFSFile; buf: pointer; size: Int64): Int64;
+var r: Int64;
+begin
+ r:= PHYSFS_readBytes(f, buf, size);
+
+ if r <= 0 then
+ pfsBlockRead:= 0
+ else
+ pfsBlockRead:= r
+end;
+
+procedure initModule;
+var i: LongInt;
+ cPhysfsId: shortstring;
+begin
+{$IFDEF HWLIBRARY}
+ //TODO: http://icculus.org/pipermail/physfs/2011-August/001006.html
+ cPhysfsId:= GetCurrentDir() + {$IFDEF DARWIN}'/Hedgewars.app/Contents/MacOS/' + {$ENDIF} ' hedgewars';
+{$ELSE}
+ cPhysfsId:= ParamStr(0);
+{$ENDIF}
+
+ i:= PHYSFS_init(Str2PChar(cPhysfsId));
+ AddFileLog('[PhysFS] init: ' + inttostr(i));
+
+ i:= PHYSFS_mount(Str2PChar(PathPrefix), nil, false);
+ AddFileLog('[PhysFS] mount ' + PathPrefix + ': ' + inttostr(i));
+ i:= PHYSFS_mount(Str2PChar(UserPathPrefix + '/Data'), nil, false);
+ AddFileLog('[PhysFS] mount ' + UserPathPrefix + '/Data: ' + inttostr(i));
+
+ hedgewarsMountPackages;
+end;
+
+procedure freeModule;
+begin
+ PHYSFS_deinit;
+end;
+
+end.
diff --git a/hedgewars/uRandom.pas b/hedgewars/uRandom.pas
index 32c79ca..d3ff100 100644
--- a/hedgewars/uRandom.pas
+++ b/hedgewars/uRandom.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ unit uRandom;
interface
uses uFloat;
-procedure SetRandomSeed(Seed: shortstring); // Sets the seed that should be used for generating pseudo-random values.
+procedure SetRandomSeed(Seed: shortstring; dropAdditionalPart: boolean); // Sets the seed that should be used for generating pseudo-random values.
function GetRandomf: hwFloat; overload; // Returns a pseudo-random hwFloat.
function GetRandom(m: LongWord): LongWord; overload; inline; // Returns a positive pseudo-random integer smaller than m.
procedure AddRandomness(r: LongWord); inline;
@@ -59,18 +59,24 @@ cirbuf[n]:=
GetNext:= cirbuf[n]
end;
-procedure SetRandomSeed(Seed: shortstring);
-var i: Longword;
+procedure SetRandomSeed(Seed: shortstring; dropAdditionalPart: boolean);
+var i, t, l: Longword;
begin
n:= 54;
if Length(Seed) > 54 then
Seed:= copy(Seed, 1, 54); // not 55 to ensure we have odd numbers in cirbuf
-for i:= 0 to Pred(Length(Seed)) do
- cirbuf[i]:= byte(Seed[i + 1]);
+t:= 0;
+l:= Length(Seed);
-for i:= Length(Seed) to 54 do
+while (t < l) and ((not dropAdditionalPart) or (Seed[t + 1] <> '|')) do
+ begin
+ cirbuf[t]:= byte(Seed[t + 1]);
+ inc(t)
+ end;
+
+for i:= t to 54 do
cirbuf[i]:= $A98765 + 68; // odd number
for i:= 0 to 1023 do
diff --git a/hedgewars/uRender.pas b/hedgewars/uRender.pas
index f978358..646e20c 100644
--- a/hedgewars/uRender.pas
+++ b/hedgewars/uRender.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,15 +26,16 @@ uses SDLh, uTypes, GLunit, uConsts;
procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt);
procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
-procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
procedure DrawTexture (X, Y: LongInt; Texture: PTexture); inline;
procedure DrawTexture (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
-procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
-procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
procedure DrawTextureCentered (X, Top: LongInt; Source: PTexture);
procedure DrawTextureF (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -55,21 +56,31 @@ procedure Tint (c: Longword); inline;
implementation
uses uVariables;
+{$IFDEF USE_TOUCH_INTERFACE}
+const
+ FADE_ANIM_TIME = 500;
+ MOVE_ANIM_TIME = 500;
+{$ENDIF}
+
var LastTint: LongWord = 0;
-procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
begin
r.y:= r.y + Height * Position;
r.h:= Height;
DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture)
end;
-procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
begin
-DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
+DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1)
+end;
+procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+begin
+DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
end;
-procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
var rr: TSDL_Rect;
_l, _r, _t, _b: real;
VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
@@ -95,14 +106,28 @@ _b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry;
glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
-VertexBuffer[0].X:= X;
-VertexBuffer[0].Y:= Y;
-VertexBuffer[1].X:= rr.w + X;
-VertexBuffer[1].Y:= Y;
-VertexBuffer[2].X:= rr.w + X;
-VertexBuffer[2].Y:= rr.h + Y;
-VertexBuffer[3].X:= X;
-VertexBuffer[3].Y:= rr.h + Y;
+if Dir < 0 then
+ begin
+ VertexBuffer[0].X:= X + rr.w/2;
+ VertexBuffer[0].Y:= Y;
+ VertexBuffer[1].X:= X - rr.w/2;
+ VertexBuffer[1].Y:= Y;
+ VertexBuffer[2].X:= X - rr.w/2;
+ VertexBuffer[2].Y:= rr.h + Y;
+ VertexBuffer[3].X:= X + rr.w/2;
+ VertexBuffer[3].Y:= rr.h + Y;
+ end
+else
+ begin
+ VertexBuffer[0].X:= X;
+ VertexBuffer[0].Y:= Y;
+ VertexBuffer[1].X:= rr.w + X;
+ VertexBuffer[1].Y:= Y;
+ VertexBuffer[2].X:= rr.w + X;
+ VertexBuffer[2].Y:= rr.h + Y;
+ VertexBuffer[3].X:= X;
+ VertexBuffer[3].Y:= rr.h + Y;
+ end;
TextureBuffer[0].X:= _l;
TextureBuffer[0].Y:= _t;
@@ -324,7 +349,7 @@ begin
end;
procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
-var VertexBuffer: array [0..3] of TVertex2f;
+var VertexBuffer: array [0..1] of TVertex2f;
begin
glDisable(GL_TEXTURE_2D);
glEnable(GL_LINE_SMOOTH);
diff --git a/hedgewars/uRenderUtils.pas b/hedgewars/uRenderUtils.pas
index 3e5282a..6bf5c0f 100644
--- a/hedgewars/uRenderUtils.pas
+++ b/hedgewars/uRenderUtils.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uScript.pas b/hedgewars/uScript.pas
index 1888fe8..5f3895b 100644
--- a/hedgewars/uScript.pas
+++ b/hedgewars/uScript.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,7 @@ procedure ScriptClearStack;
procedure ScriptLoad(name : shortstring);
procedure ScriptOnGameInit;
procedure ScriptOnScreenResize;
+procedure ScriptSetInteger(name : shortstring; value : LongInt);
procedure ScriptCall(fname : shortstring);
function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
@@ -81,7 +82,9 @@ uses LuaPas,
uLandGraphics,
SDLh,
SysUtils,
- uIO;
+ uIO,
+ uPhysFSLayer
+ ;
var luaState : Plua_State;
ScriptAmmoLoadout : shortstring;
@@ -222,6 +225,35 @@ begin
lc_hidemission:= 0;
end;
+function lc_enablegameflags(L : Plua_State) : LongInt; Cdecl;
+var i : integer;
+begin
+ for i:= 1 to lua_gettop(L) do
+ if (GameFlags and lua_tointeger(L, i)) = 0 then
+ GameFlags := GameFlags + LongWord(lua_tointeger(L, i));
+ ScriptSetInteger('GameFlags', GameFlags);
+ lc_enablegameflags:= 0;
+end;
+
+function lc_disablegameflags(L : Plua_State) : LongInt; Cdecl;
+var i : integer;
+begin
+ for i:= 1 to lua_gettop(L) do
+ if (GameFlags and lua_tointeger(L, i)) <> 0 then
+ GameFlags := GameFlags - LongWord(lua_tointeger(L, i));
+ ScriptSetInteger('GameFlags', GameFlags);
+ lc_disablegameflags:= 0;
+end;
+
+function lc_cleargameflags(L : Plua_State) : LongInt; Cdecl;
+begin
+ // Silence hint
+ L:= L;
+ GameFlags:= 0;
+ ScriptSetInteger('GameFlags', GameFlags);
+ lc_cleargameflags:= 0;
+end;
+
function lc_addcaption(L : Plua_State) : LongInt; Cdecl;
begin
if lua_gettop(L) = 1 then
@@ -688,7 +720,7 @@ begin
else
begin
gear := GearByUID(lua_tointeger(L, 1));
- if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+ if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
lua_pushinteger(L, gear^.Hedgehog^.BotLevel)
else
lua_pushnil(L);
@@ -721,7 +753,7 @@ begin
else
begin
gear:= GearByUID(lua_tointeger(L, 1));
- if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+ if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
begin
lua_pushinteger(L, gear^.Hedgehog^.Team^.Clan^.ClanIndex)
end
@@ -803,7 +835,7 @@ begin
else
begin
gear:= GearByUID(lua_tointeger(L, 1));
- if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+ if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
begin
lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.TeamName))
end
@@ -824,7 +856,7 @@ begin
else
begin
gear:= GearByUID(lua_tointeger(L, 1));
- if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+ if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
begin
lua_pushstring(L, str2pchar(gear^.Hedgehog^.Name))
end
@@ -1249,7 +1281,7 @@ end;
function lc_endgame(L : Plua_State) : LongInt; Cdecl;
begin
L:= L; // avoid compiler hint
- GameState:= gsExit;
+ AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
lc_endgame:= 0
end;
@@ -1592,7 +1624,7 @@ begin
lua_pushnil(L);
end
else
- lua_pushstring(L, str2pchar(Pathz[ptData]));
+ lua_pushstring(L, str2pchar(cPathz[ptData]));
lc_getdatapath:= 1
end;
@@ -1604,7 +1636,7 @@ begin
lua_pushnil(L);
end
else
- lua_pushstring(L, str2pchar(UserPathz[ptData]));
+ lua_pushstring(L, str2pchar(cPathz[ptData]));
lc_getuserdatapath:= 1
end;
@@ -1646,7 +1678,7 @@ begin
LuaError('Lua: Wrong number of parameters passed to GetHogHat!')
else begin
gear := GearByUID(lua_tointeger(L, 1));
- if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
+ if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
lua_pushstring(L, str2pchar(gear^.Hedgehog^.Hat))
else
lua_pushnil(L);
@@ -1727,36 +1759,28 @@ begin
else
begin
gear:= GearByUID(lua_tointeger(L, 1));
- hiddenHedgehogs[hiddenHedgehogsNumber]:=gear^.hedgehog;
- inc(hiddenHedgehogsNumber);
- HideHog(gear^.hedgehog);
+ HideHog(gear^.hedgehog)
end;
lc_hidehog := 0;
end;
function lc_restorehog(L: Plua_State): LongInt; Cdecl;
-var hog: PHedgehog;
- i, j: LongInt;
+var i, h: LongInt;
+ uid: LongWord;
begin
if lua_gettop(L) <> 1 then
LuaError('Lua: Wrong number of parameters passed to RestoreHog!')
else
begin
- i := 0;
- while (i < hiddenHedgehogsNumber) do
- begin
- if hiddenHedgehogs[i]^.gearHidden^.uid = LongWord(lua_tointeger(L, 1)) then
- begin
- hog := hiddenHedgehogs[i];
- RestoreHog(hog);
- dec(hiddenHedgehogsNumber);
- for j := i to hiddenHedgehogsNumber - 1 do
- hiddenHedgehogs[j] := hiddenHedgehogs[j + 1];
- lc_restorehog := 0;
- exit;
- end;
- inc(i);
- end;
+ uid:= LongWord(lua_tointeger(L, 1));
+ if TeamsCount > 0 then
+ for i:= 0 to Pred(TeamsCount) do
+ for h:= 0 to cMaxHHIndex do
+ if (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil) and (TeamsArray[i]^.Hedgehogs[h].GearHidden^.uid = uid) then
+ begin
+ RestoreHog(@TeamsArray[i]^.Hedgehogs[h]);
+ exit(0)
+ end
end;
lc_restorehog := 0;
end;
@@ -1783,6 +1807,34 @@ begin
end;
lc_testrectforobstacle:= 1
end;
+
+
+function lc_setaihintsongear(L : Plua_State) : LongInt; Cdecl;
+var gear: PGear;
+begin
+ if lua_gettop(L) <> 2 then
+ LuaError('Lua: Wrong number of parameters passed to SetAIHintOnGear!')
+ else
+ begin
+ gear:= GearByUID(lua_tointeger(L, 1));
+ if gear <> nil then
+ gear^.aihints:= lua_tointeger(L, 2);
+ end;
+ lc_setaihintsongear:= 0
+end;
+
+
+function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl;
+begin
+ if lua_gettop(L) <> 1 then
+ begin
+ LuaError('Lua: Wrong number of parameters passed to HedgewarsScriptLoad!');
+ lua_pushnil(L)
+ end
+ else
+ ScriptLoad(lua_tostring(L, 1));
+ lc_hedgewarsscriptload:= 0;
+end;
///////////////////
procedure ScriptPrintStack;
@@ -1955,18 +2007,27 @@ ScriptSetInteger('ScreenWidth', cScreenWidth);
ScriptCall('onScreenResize');
end;
+// custom script loader via physfs, passed to lua_load
+const BUFSIZE = 1024;
procedure ScriptLoad(name : shortstring);
var ret : LongInt;
s : shortstring;
+ f : PFSFile;
+ buf : array[0..Pred(BUFSIZE)] of byte;
begin
-s:= UserPathz[ptData] + '/' + name;
-if not FileExists(s) then
- s:= Pathz[ptData] + '/' + name;
-if not FileExists(s) then
+s:= cPathz[ptData] + name;
+if not pfsExists(s) then
+ exit;
+
+f:= pfsOpenRead(s);
+if f = nil then
exit;
-ret:= luaL_loadfile(luaState, Str2PChar(s));
+physfsReaderSetBuffer(@buf);
+ret:= lua_load(luaState, @physfsReader, f, Str2PChar(s));
+pfsClose(f);
+
if ret <> 0 then
begin
LuaError('Lua: Failed to load ' + name + '(error ' + IntToStr(ret) + ')');
@@ -1978,14 +2039,14 @@ else
// call the script file
lua_pcall(luaState, 0, 0, 0);
ScriptLoaded:= true
- end
+ end;
+ hedgewarsMountPackage(Str2PChar(copy(s, 1, length(s)-4)+'.hwp'));
end;
procedure SetGlobals;
begin
ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
ScriptSetInteger('GameTime', GameTicks);
-ScriptSetInteger('RealTime', RealTicks);
ScriptSetInteger('TotalRounds', TotalRounds);
ScriptSetInteger('WaterLine', cWaterLine);
if GameTicks = 0 then
@@ -2201,6 +2262,7 @@ ScriptSetInteger('gfForts', gfForts);
ScriptSetInteger('gfMultiWeapon', gfMultiWeapon);
ScriptSetInteger('gfSolidLand', gfSolidLand);
ScriptSetInteger('gfBorder', gfBorder);
+ScriptSetInteger('gfBottomBorder', gfBottomBorder);
ScriptSetInteger('gfDivideTeams', gfDivideTeams);
ScriptSetInteger('gfLowGravity', gfLowGravity);
ScriptSetInteger('gfLaserSight', gfLaserSight);
@@ -2287,6 +2349,10 @@ ScriptSetInteger('gstLoser' ,$00080000);
ScriptSetInteger('gstHHGone' ,$00100000);
ScriptSetInteger('gstInvisible' ,$00200000);
+// ai hints
+ScriptSetInteger('aihUsualProcessing' ,$00000000);
+ScriptSetInteger('aihDoesntMatter' ,$00000001);
+
// register functions
lua_register(luaState, _P'HideHog', @lc_hidehog);
lua_register(luaState, _P'RestoreHog', @lc_restorehog);
@@ -2299,6 +2365,9 @@ lua_register(luaState, _P'div', @lc_div);
lua_register(luaState, _P'GetInputMask', @lc_getinputmask);
lua_register(luaState, _P'SetInputMask', @lc_setinputmask);
lua_register(luaState, _P'AddGear', @lc_addgear);
+lua_register(luaState, _P'EnableGameFlags', @lc_enablegameflags);
+lua_register(luaState, _P'DisableGameFlags', @lc_disablegameflags);
+lua_register(luaState, _P'ClearGameFlags', @lc_cleargameflags);
lua_register(luaState, _P'DeleteGear', @lc_deletegear);
lua_register(luaState, _P'AddVisualGear', @lc_addvisualgear);
lua_register(luaState, _P'DeleteVisualGear', @lc_deletevisualgear);
@@ -2380,6 +2449,9 @@ lua_register(luaState, _P'PlaceGirder', @lc_placegirder);
lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype);
lua_register(luaState, _P'TestRectForObstacle', @lc_testrectforobstacle);
+lua_register(luaState, _P'SetGearAIHints', @lc_setaihintsongear);
+lua_register(luaState, _P'HedgewarsScriptLoad', @lc_hedgewarsscriptload);
+
ScriptClearStack; // just to be sure stack is empty
ScriptLoaded:= false;
diff --git a/hedgewars/uSinTable.pas b/hedgewars/uSinTable.pas
index 449651b..eb6f97d 100644
--- a/hedgewars/uSinTable.pas
+++ b/hedgewars/uSinTable.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/hedgewars/uSound.pas b/hedgewars/uSound.pas
index 3c601af..f2171ac 100644
--- a/hedgewars/uSound.pas
+++ b/hedgewars/uSound.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
unit uSound;
(*
* This unit controls the sounds and music of the game.
- * Doesn't really do anything if isSoundEnabled = false.
+ * Doesn't really do anything if isSoundEnabled = false and isMusicEnabled = false
*
* There are three basic types of sound controls:
* Music - The background music of the game:
@@ -105,12 +105,13 @@ function ChangeVolume(voldelta: LongInt): LongInt;
function AskForVoicepack(name: shortstring): Pointer;
+var Volume: LongInt;
+ SoundTimerTicks: Longword;
implementation
-uses uVariables, uConsole, uUtils, uCommands, uDebug;
+uses uVariables, uConsole, uCommands, uDebug, uPhysFSLayer;
const chanTPU = 32;
-var Volume: LongInt;
- cInitVolume: LongInt;
+var cInitVolume: LongInt;
previousVolume: LongInt; // cached volume value
lastChan: array [TSound] of LongInt;
voicepacks: array[0..cMaxTeams] of TVoicepack;
@@ -120,6 +121,139 @@ var Volume: LongInt;
isMusicEnabled: boolean;
isSoundEnabled: boolean;
isSEBackup: boolean;
+ VoiceList : array[0..7] of TVoice = (
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil),
+ ( snd: sndNone; voicepack: nil));
+ Soundz: array[TSound] of record
+ FileName: string[31];
+ Path : TPathType;
+ end = (
+ (FileName: ''; Path: ptNone ),// sndNone
+ (FileName: 'grenadeimpact.ogg'; Path: ptSounds),// sndGrenadeImpact
+ (FileName: 'explosion.ogg'; Path: ptSounds),// sndExplosion
+ (FileName: 'throwpowerup.ogg'; Path: ptSounds),// sndThrowPowerUp
+ (FileName: 'throwrelease.ogg'; Path: ptSounds),// sndThrowRelease
+ (FileName: 'splash.ogg'; Path: ptSounds),// sndSplash
+ (FileName: 'shotgunreload.ogg'; Path: ptSounds),// sndShotgunReload
+ (FileName: 'shotgunfire.ogg'; Path: ptSounds),// sndShotgunFire
+ (FileName: 'graveimpact.ogg'; Path: ptSounds),// sndGraveImpact
+ (FileName: 'mineimpact.ogg'; Path: ptSounds),// sndMineImpact
+ (FileName: 'minetick.ogg'; Path: ptSounds),// sndMineTicks
+ (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndMudballImpact
+ (FileName: 'pickhammer.ogg'; Path: ptSounds),// sndPickhammer
+ (FileName: 'gun.ogg'; Path: ptSounds),// sndGun
+ (FileName: 'bee.ogg'; Path: ptSounds),// sndBee
+ (FileName: 'Jump1.ogg'; Path: ptVoices),// sndJump1
+ (FileName: 'Jump2.ogg'; Path: ptVoices),// sndJump2
+ (FileName: 'Jump3.ogg'; Path: ptVoices),// sndJump3
+ (FileName: 'Yessir.ogg'; Path: ptVoices),// sndYesSir
+ (FileName: 'Laugh.ogg'; Path: ptVoices),// sndLaugh
+ (FileName: 'Illgetyou.ogg'; Path: ptVoices),// sndIllGetYou
+ (FileName: 'Justyouwait.ogg'; Path: ptVoices),// sndJustyouwait
+ (FileName: 'Incoming.ogg'; Path: ptVoices),// sndIncoming
+ (FileName: 'Missed.ogg'; Path: ptVoices),// sndMissed
+ (FileName: 'Stupid.ogg'; Path: ptVoices),// sndStupid
+ (FileName: 'Firstblood.ogg'; Path: ptVoices),// sndFirstBlood
+ (FileName: 'Boring.ogg'; Path: ptVoices),// sndBoring
+ (FileName: 'Byebye.ogg'; Path: ptVoices),// sndByeBye
+ (FileName: 'Sameteam.ogg'; Path: ptVoices),// sndSameTeam
+ (FileName: 'Nutter.ogg'; Path: ptVoices),// sndNutter
+ (FileName: 'Reinforcements.ogg'; Path: ptVoices),// sndReinforce
+ (FileName: 'Traitor.ogg'; Path: ptVoices),// sndTraitor
+ (FileName: 'Youllregretthat.ogg'; Path: ptVoices),// sndRegret
+ (FileName: 'Enemydown.ogg'; Path: ptVoices),// sndEnemyDown
+ (FileName: 'Coward.ogg'; Path: ptVoices),// sndCoward
+ (FileName: 'Hurry.ogg'; Path: ptVoices),// sndHurry
+ (FileName: 'Watchit.ogg'; Path: ptVoices),// sndWatchIt
+ (FileName: 'Kamikaze.ogg'; Path: ptVoices),// sndKamikaze
+ (FileName: 'cake2.ogg'; Path: ptSounds),// sndCake
+ (FileName: 'Ow1.ogg'; Path: ptVoices),// sndOw1
+ (FileName: 'Ow2.ogg'; Path: ptVoices),// sndOw2
+ (FileName: 'Ow3.ogg'; Path: ptVoices),// sndOw3
+ (FileName: 'Ow4.ogg'; Path: ptVoices),// sndOw4
+ (FileName: 'Firepunch1.ogg'; Path: ptVoices),// sndFirepunch1
+ (FileName: 'Firepunch2.ogg'; Path: ptVoices),// sndFirepunch2
+ (FileName: 'Firepunch3.ogg'; Path: ptVoices),// sndFirepunch3
+ (FileName: 'Firepunch4.ogg'; Path: ptVoices),// sndFirepunch4
+ (FileName: 'Firepunch5.ogg'; Path: ptVoices),// sndFirepunch5
+ (FileName: 'Firepunch6.ogg'; Path: ptVoices),// sndFirepunch6
+ (FileName: 'Melon.ogg'; Path: ptVoices),// sndMelon
+ (FileName: 'Hellish.ogg'; Path: ptSounds),// sndHellish
+ (FileName: 'Yoohoo.ogg'; Path: ptSounds),// sndYoohoo
+ (FileName: 'rcplane.ogg'; Path: ptSounds),// sndRCPlane
+ (FileName: 'whipcrack.ogg'; Path: ptSounds),// sndWhipCrack
+ (FileName:'ride_of_the_valkyries.ogg'; Path: ptSounds),// sndRideOfTheValkyries
+ (FileName: 'denied.ogg'; Path: ptSounds),// sndDenied
+ (FileName: 'placed.ogg'; Path: ptSounds),// sndPlaced
+ (FileName: 'baseballbat.ogg'; Path: ptSounds),// sndBaseballBat
+ (FileName: 'steam.ogg'; Path: ptSounds),// sndVaporize
+ (FileName: 'warp.ogg'; Path: ptSounds),// sndWarp
+ (FileName: 'suddendeath.ogg'; Path: ptSounds),// sndSuddenDeath
+ (FileName: 'mortar.ogg'; Path: ptSounds),// sndMortar
+ (FileName: 'shutterclick.ogg'; Path: ptSounds),// sndShutter
+ (FileName: 'homerun.ogg'; Path: ptSounds),// sndHomerun
+ (FileName: 'molotov.ogg'; Path: ptSounds),// sndMolotov
+ (FileName: 'Takecover.ogg'; Path: ptVoices),// sndCover
+ (FileName: 'Uh-oh.ogg'; Path: ptVoices),// sndUhOh
+ (FileName: 'Oops.ogg'; Path: ptVoices),// sndOops
+ (FileName: 'Nooo.ogg'; Path: ptVoices),// sndNooo
+ (FileName: 'Hello.ogg'; Path: ptVoices),// sndHello
+ (FileName: 'ropeshot.ogg'; Path: ptSounds),// sndRopeShot
+ (FileName: 'ropeattach.ogg'; Path: ptSounds),// sndRopeAttach
+ (FileName: 'roperelease.ogg'; Path: ptSounds),// sndRopeRelease
+ (FileName: 'switchhog.ogg'; Path: ptSounds),// sndSwitchHog
+ (FileName: 'Victory.ogg'; Path: ptVoices),// sndVictory
+ (FileName: 'Flawless.ogg'; Path: ptVoices),// sndFlawless
+ (FileName: 'sniperreload.ogg'; Path: ptSounds),// sndSniperReload
+ (FileName: 'steps.ogg'; Path: ptSounds),// sndSteps
+ (FileName: 'lowgravity.ogg'; Path: ptSounds),// sndLowGravity
+ (FileName: 'hell_growl.ogg'; Path: ptSounds),// sndHellishImpact1
+ (FileName: 'hell_ooff.ogg'; Path: ptSounds),// sndHellishImpact2
+ (FileName: 'hell_ow.ogg'; Path: ptSounds),// sndHellishImpact3
+ (FileName: 'hell_ugh.ogg'; Path: ptSounds),// sndHellishImpact4
+ (FileName: 'melonimpact.ogg'; Path: ptSounds),// sndMelonImpact
+ (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndDroplet1
+ (FileName: 'Droplet2.ogg'; Path: ptSounds),// sndDroplet2
+ (FileName: 'Droplet3.ogg'; Path: ptSounds),// sndDroplet3
+ (FileName: 'egg.ogg'; Path: ptSounds),// sndEggBreak
+ (FileName: 'drillgun.ogg'; Path: ptSounds),// sndDrillRocket
+ (FileName: 'PoisonCough.ogg'; Path: ptVoices),// sndPoisonCough
+ (FileName: 'PoisonMoan.ogg'; Path: ptVoices),// sndPoisonMoan
+ (FileName: 'BirdyLay.ogg'; Path: ptSounds),// sndBirdyLay
+ (FileName: 'Whistle.ogg'; Path: ptSounds),// sndWhistle
+ (FileName: 'beewater.ogg'; Path: ptSounds),// sndBeeWater
+ (FileName: '1C.ogg'; Path: ptSounds),// sndPiano0
+ (FileName: '2D.ogg'; Path: ptSounds),// sndPiano1
+ (FileName: '3E.ogg'; Path: ptSounds),// sndPiano2
+ (FileName: '4F.ogg'; Path: ptSounds),// sndPiano3
+ (FileName: '5G.ogg'; Path: ptSounds),// sndPiano4
+ (FileName: '6A.ogg'; Path: ptSounds),// sndPiano5
+ (FileName: '7B.ogg'; Path: ptSounds),// sndPiano6
+ (FileName: '8C.ogg'; Path: ptSounds),// sndPiano7
+ (FileName: '9D.ogg'; Path: ptSounds),// sndPiano8
+ (FileName: 'skip.ogg'; Path: ptSounds),// sndSkip
+ (FileName: 'sinegun.ogg'; Path: ptSounds),// sndSineGun
+ (FileName: 'Ooff1.ogg'; Path: ptVoices),// sndOoff1
+ (FileName: 'Ooff2.ogg'; Path: ptVoices),// sndOoff2
+ (FileName: 'Ooff3.ogg'; Path: ptVoices),// sndOoff3
+ (FileName: 'hammer.ogg'; Path: ptSounds),// sndWhack
+ (FileName: 'Comeonthen.ogg'; Path: ptVoices),// sndComeonthen
+ (FileName: 'parachute.ogg'; Path: ptSounds),// sndParachute
+ (FileName: 'bump.ogg'; Path: ptSounds),// sndBump
+ (FileName: 'hogchant3.ogg'; Path: ptSounds),// sndResurrector
+ (FileName: 'plane.ogg'; Path: ptSounds),// sndPlane
+ (FileName: 'TARDIS.ogg'; Path: ptSounds),// sndTardis
+ (FileName: 'frozen_hog_impact.ogg'; Path: ptSounds),// sndFrozenHogImpact
+ (FileName: 'ice_beam.ogg'; Path: ptSounds),// sndIceBeam
+ (FileName: 'hog_freeze.ogg'; Path: ptSounds) // sndHogFreeze
+ );
+
function AskForVoicepack(name: shortstring): Pointer;
@@ -131,29 +265,17 @@ i:= 0;
if cLocale <> 'en' then
begin
locName:= name+'_'+cLocale;
- path:= UserPathz[ptVoices] + '/' + locName;
- if DirectoryExists(path) then
+ path:= cPathz[ptVoices] + '/' + locName;
+ if pfsExists(path) then
name:= locName
else
- begin
- path:= Pathz[ptVoices] + '/' + locName;
- if DirectoryExists(path) then
- name:= locName
- else if Length(cLocale) > 2
- then
+ if Length(cLocale) > 3 then
begin
locName:= name+'_'+Copy(cLocale,1,2);
- path:= UserPathz[ptVoices] + '/' + locName;
- if DirectoryExists(path) then
+ path:= cPathz[ptVoices] + '/' + locName;
+ if pfsExists(path) then
name:= locName
- else
- begin
- path:= Pathz[ptVoices] + '/' + locName;
- if DirectoryExists(path) then
- name:= locName
- end
end
- end
end;
// If that fails, use the unmodified one
@@ -169,19 +291,24 @@ end;
procedure InitSound;
const channels: LongInt = {$IFDEF MOBILE}1{$ELSE}2{$ENDIF};
+var success: boolean;
begin
- if not isSoundEnabled then
+ if not (isSoundEnabled or isMusicEnabled) then
exit;
WriteToConsole('Init sound...');
- isSoundEnabled:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
+ success:= SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0;
- if isSoundEnabled then
- isSoundEnabled:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0;
+ if success then
+ success:= Mix_OpenAudio(44100, $8010, channels, 1024) = 0;
- if isSoundEnabled then
+ if success then
WriteLnToConsole(msgOK)
else
+ begin
WriteLnToConsole(msgFailed);
+ isSoundEnabled:= false;
+ isMusicEnabled:= false;
+ end;
WriteToConsole('Init SDL_mixer... ');
SDLTry(Mix_Init(MIX_INIT_OGG) <> 0, true);
@@ -267,11 +394,11 @@ begin
begin
if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
begin
- s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
- if not FileExists(s) then
- s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
+ s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
+ if (not pfsExists(s)) and (snd in [sndFirePunch2, sndFirePunch3, sndFirePunch4, sndFirePunch5, sndFirePunch6]) then
+ s:= cPathz[Soundz[sndFirePunch1].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
WriteToConsole(msgLoading + s + ' ');
- voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1);
+ voicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
if voicepack^.chunks[snd] = nil then
WriteLnToConsole(msgFailed)
else
@@ -283,11 +410,9 @@ begin
begin
if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
begin
- s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
- if not FileExists(s) then
- s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
+ s:= cPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
WriteToConsole(msgLoading + s + ' ');
- defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1);
+ defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
SDLTry(defVoicepack^.chunks[snd] <> nil, true);
WriteLnToConsole(msgOK);
end;
@@ -303,7 +428,7 @@ begin
if (snd = sndVictory) or (snd = sndFlawless) then
begin
Mix_FadeOutChannel(-1, 800);
- for i:= 0 to 7 do
+ for i:= 0 to High(VoiceList) do
VoiceList[i].snd:= sndNone;
LastVoice.snd:= sndNone;
end;
@@ -325,7 +450,7 @@ begin
if (not isSoundEnabled) or fastUntilLag or ((LastVoice.snd <> sndNone) and (lastChan[LastVoice.snd] <> -1) and (Mix_Playing(lastChan[LastVoice.snd]) <> 0)) then
exit;
i:= 0;
- while (i<8) and (VoiceList[i].snd = sndNone) do
+ while (i<High(VoiceList)) and (VoiceList[i].snd = sndNone) do
inc(i);
if (VoiceList[i].snd <> sndNone) then
@@ -367,11 +492,9 @@ begin
begin
if (voicepack^.chunks[snd] = nil) and (Soundz[snd].Path = ptVoices) and (Soundz[snd].FileName <> '') then
begin
- s:= UserPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
- if not FileExists(s) then
- s:= Pathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
+ s:= cPathz[Soundz[snd].Path] + '/' + voicepack^.name + '/' + Soundz[snd].FileName;
WriteToConsole(msgLoading + s + ' ');
- voicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1);
+ voicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
if voicepack^.chunks[snd] = nil then
WriteLnToConsole(msgFailed)
else
@@ -383,11 +506,9 @@ begin
begin
if (defVoicepack^.chunks[snd] = nil) and (Soundz[snd].Path <> ptVoices) and (Soundz[snd].FileName <> '') then
begin
- s:= UserPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
- if not FileExists(s) then
- s:= Pathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
+ s:= cPathz[Soundz[snd].Path] + '/' + Soundz[snd].FileName;
WriteToConsole(msgLoading + s + ' ');
- defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(SDL_RWFromFile(Str2PChar(s), _P'rb'), 1);
+ defVoicepack^.chunks[snd]:= Mix_LoadWAV_RW(rwopsOpenRead(s), 1);
SDLTry(defVoicepack^.chunks[snd] <> nil, true);
WriteLnToConsole(msgOK);
end;
@@ -431,15 +552,13 @@ end;
procedure PlayMusic;
var s: shortstring;
begin
- if (not isSoundEnabled) or (MusicFN = '') or (not isMusicEnabled) then
+ if (MusicFN = '') or (not isMusicEnabled) then
exit;
- s:= UserPathPrefix + '/Data/Music/' + MusicFN;
- if not FileExists(s) then
- s:= PathPrefix + '/Music/' + MusicFN;
+ s:= '/Music/' + MusicFN;
WriteToConsole(msgLoading + s + ' ');
- Mus:= Mix_LoadMUS(Str2PChar(s));
+ Mus:= Mix_LoadMUS_RW(rwopsOpenRead(s));
SDLTry(Mus <> nil, false);
WriteLnToConsole(msgOK);
@@ -454,7 +573,7 @@ end;
function ChangeVolume(voldelta: LongInt): LongInt;
begin
ChangeVolume:= 0;
- if (not isSoundEnabled) or ((voldelta = 0) and not (cInitVolume = 0)) then
+ if not (isSoundEnabled or isMusicEnabled) or ((voldelta = 0) and (not (cInitVolume = 0))) then
exit;
inc(Volume, voldelta);
@@ -494,7 +613,7 @@ end;
procedure MuteAudio;
begin
- if (not isSoundEnabled) then
+ if not (isSoundEnabled or isMusicEnabled) then
exit;
if (isAudioMuted) then
@@ -597,6 +716,7 @@ begin
isAudioMuted:= false;
isSEBackup:= isSoundEnabled;
Volume:= 0;
+ SoundTimerTicks:= 0;
defVoicepack:= AskForVoicepack('Default');
for i:= Low(TSound) to High(TSound) do
@@ -609,7 +729,7 @@ begin
voicepacks[t].chunks[i]:= nil;
(* on MOBILE SDL_mixer has to be compiled against Tremor (USE_OGG_TREMOR)
- or sound files bigger than 32k will lockup the game *)
+ or sound files bigger than 32k will lockup the game on slow cpu *)
for i:= Low(TSound) to High(TSound) do
defVoicepack^.chunks[i]:= nil;
@@ -617,7 +737,7 @@ end;
procedure freeModule;
begin
- if isSoundEnabled then
+ if isSoundEnabled or isMusicEnabled then
ReleaseSound(true);
end;
diff --git a/hedgewars/uStats.pas b/hedgewars/uStats.pas
index 9cc51b9..3e27439 100644
--- a/hedgewars/uStats.pas
+++ b/hedgewars/uStats.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,10 +36,11 @@ procedure SendStats;
procedure hedgehogFlight(Gear: PGear; time: Longword);
implementation
-uses uSound, uLocale, uVariables, uUtils, uIO, uCaptions, uDebug, uMisc;
+uses uSound, uLocale, uVariables, uUtils, uIO, uCaptions, uDebug, uMisc, uConsole;
var DamageClan : Longword = 0;
DamageTotal : Longword = 0;
+ DamageTurn : Longword = 0;
KillsClan : LongWord = 0;
Kills : LongWord = 0;
KillsTotal : LongWord = 0;
@@ -82,7 +83,8 @@ if killed then
inc(KillsClan);
end;
-inc(DamageTotal, Damage)
+inc(DamageTotal, Damage);
+inc(DamageTurn, Damage)
end;
procedure Skipped;
@@ -112,7 +114,7 @@ if FinishedTurnsTotal <> 0 then
end
else if DamageClan <> 0 then
- if DamageTotal > DamageClan then
+ if DamageTurn > DamageClan then
if random(2) = 0 then
AddVoice(sndNutter, CurrentTeam^.voicepack)
else
@@ -170,6 +172,7 @@ for t:= 0 to Pred(ClansCount) do
Kills:= 0;
KillsClan:= 0;
DamageClan:= 0;
+DamageTurn:= 0;
AmmoUsedCount:= 0;
AmmoDamagingUsed:= false;
isTurnSkipped:= false
@@ -185,10 +188,10 @@ procedure hedgehogFlight(Gear: PGear; time: Longword);
begin
if time > 4000 then
begin
- writeln(stdout, 'FLIGHT');
- writeln(stdout, Gear^.Hedgehog^.Team^.TeamName);
- writeln(stdout, inttostr(time));
- writeln(stdout, '');
+ WriteLnToConsole('FLIGHT');
+ WriteLnToConsole(Gear^.Hedgehog^.Team^.TeamName);
+ WriteLnToConsole(inttostr(time));
+ WriteLnToConsole( '');
end
end;
@@ -293,14 +296,14 @@ if KilledHHs > 0 then
// now to console
if winnersClan <> nil then
begin
- writeln(stdout, 'WINNERS');
+ WriteLnToConsole('WINNERS');
for t:= 0 to winnersClan^.TeamsNumber - 1 do
- writeln(stdout, winnersClan^.Teams[t]^.TeamName);
+ WriteLnToConsole(winnersClan^.Teams[t]^.TeamName);
end
else
- writeln(stdout, 'DRAW');
+ WriteLnToConsole('DRAW');
-writeln(stdout, '');
+WriteLnToConsole('');
end;
procedure initModule;
diff --git a/hedgewars/uStore.pas b/hedgewars/uStore.pas
index 0b9f27c..bb3a385 100644
--- a/hedgewars/uStore.pas
+++ b/hedgewars/uStore.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
unit uStore;
interface
-uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
+uses StrUtils, SysUtils, uConsts, SDLh, GLunit, uTypes, uLandTexture, uCaptions, uChat;
procedure initModule;
procedure freeModule;
@@ -33,7 +33,7 @@ procedure AddProgress;
procedure FinishProgress;
function LoadImage(const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
-// loads an image from the game's data files
+// loads an image from the games data files
function LoadDataImage(const path: TPathType; const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
// like LoadDataImage but uses altPath as fallback-path if file not found/loadable in path
function LoadDataImageAltPath(const path, altPath: TPathType; const filename: shortstring; imageFlags: LongInt): PSDL_Surface;
@@ -56,9 +56,11 @@ procedure WarpMouse(x, y: Word); inline;
procedure SwapBuffers; {$IFDEF USE_VIDEO_RECORDING}cdecl{$ELSE}inline{$ENDIF};
implementation
-uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands,
- uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}
- {$IF NOT DEFINED(SDL13) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF};
+uses uMisc, uConsole, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands
+ , uPhysFSLayer
+ , uDebug
+ {$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}
+ {$IF NOT DEFINED(SDL13) AND DEFINED(USE_VIDEO_RECORDING)}, glut {$ENDIF};
//type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
@@ -69,6 +71,13 @@ var MaxTextureSize: LongInt;
{$ELSE}
SDLPrimSurface: PSDL_Surface;
{$ENDIF}
+ squaresize : LongInt;
+ numsquares : LongInt;
+ ProgrTex: PTexture;
+
+const
+ cHHFileName = 'Hedgehog';
+ cCHFileName = 'Crosshair';
function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect;
var w, h: LongInt;
@@ -146,6 +155,7 @@ var t: LongInt;
texsurf, flagsurf, iconsurf: PSDL_Surface;
foundBot: boolean;
begin
+ if cOnlyStats then exit;
r.x:= 0;
r.y:= 0;
drY:= - 4;
@@ -308,11 +318,9 @@ if not reload then
for fi:= Low(THWFont) to High(THWFont) do
with Fontz[fi] do
begin
- s:= UserPathz[ptFonts] + '/' + Name;
- if not FileExists(s) then
- s:= Pathz[ptFonts] + '/' + Name;
+ s:= cPathz[ptFonts] + '/' + Name;
WriteToConsole(msgLoading + s + ' (' + inttostr(Height) + 'pt)... ');
- Handle:= TTF_OpenFont(Str2PChar(s), Height);
+ Handle:= TTF_OpenFontRW(rwopsOpenRead(s), true, Height);
SDLTry(Handle <> nil, true);
TTF_SetFontStyle(Handle, style);
WriteLnToConsole(msgOK)
@@ -436,7 +444,7 @@ if not reload then
IMG_Quit();
end;
-{$IF NOT DEFINED(S3D_DISABLED) OR DEFINED(USE_VIDEO_RECORDING)}
+{$IF DEFINED(USE_S3D_RENDERING) OR DEFINED(USE_VIDEO_RECORDING)}
procedure CreateFramebuffer(var frame, depth, tex: GLuint);
begin
glGenFramebuffersEXT(1, @frame);
@@ -538,8 +546,8 @@ for i:= Low(CountTexz) to High(CountTexz) do
if defaultFrame <> 0 then
DeleteFramebuffer(defaultFrame, depthv, texv);
{$ENDIF}
-{$IFNDEF S3D_DISABLED}
- if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
+{$IFDEF USE_S3D_RENDERING}
+ if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
begin
DeleteFramebuffer(framel, depthl, texl);
DeleteFramebuffer(framer, depthr, texr);
@@ -564,22 +572,22 @@ begin
WriteToConsole(msgLoading + filename + '.png [flags: ' + inttostr(imageFlags) + '] ');
s:= filename + '.png';
- tmpsurf:= IMG_Load(Str2PChar(s));
+ tmpsurf:= IMG_Load_RW(rwopsOpenRead(s), true);
if tmpsurf = nil then
- begin
+ begin
OutError(msgFailed, (imageFlags and ifCritical) <> 0);
exit;
- end;
+ end;
if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then
- begin
+ begin
SDL_FreeSurface(tmpsurf);
- OutError(msgFailedSize, (imageFlags and ifCritical) <> 0);
+ OutError(msgFailedSize, ((not cOnlyStats) and ((imageFlags and ifCritical) <> 0)));
// dummy surface to replace non-critical textures that failed to load due to their size
LoadImage:= SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask);
exit;
- end;
+ end;
tmpsurf:= doSurfaceConversion(tmpsurf);
@@ -596,12 +604,8 @@ function LoadDataImage(const path: TPathType; const filename: shortstring; image
var tmpsurf: PSDL_Surface;
begin
// check for file in user dir (never critical)
- tmpsurf:= LoadImage(UserPathz[path] + '/' + filename, imageFlags and (not ifCritical));
-
- // if unsuccessful check data dir
- if (tmpsurf = nil) then
- tmpsurf:= LoadImage(Pathz[path] + '/' + filename, imageFlags);
-
+ tmpsurf:= LoadImage(cPathz[path] + '/' + filename, imageFlags);
+
LoadDataImage:= tmpsurf;
end;
@@ -761,7 +765,7 @@ begin
AddFileLog(' |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum));
{$ENDIF}
AddFileLog(' \----- Extensions: ');
-{$IFNDEF PAS2C}
+
// fetch extentions and store them in string
tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS)));
tmpn := WordCount(tmpstr, [' ']);
@@ -779,10 +783,6 @@ begin
tmpint := tmpint + 3;
end;
until (tmpint > tmpn);
-{$ELSE}
- // doesn't seem to print >256 chars
- AddFileLogRaw(PChar(glGetString(GL_EXTENSIONS)));
-{$ENDIF}
AddFileLog('');
defaultFrame:= 0;
@@ -810,8 +810,8 @@ begin
end;
{$ENDIF}
-{$IFNDEF S3D_DISABLED}
- if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then
+{$IFDEF USE_S3D_RENDERING}
+ if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
begin
// prepare left and right frame buffers and associated textures
if glLoadExtension('GL_EXT_framebuffer_object') then
@@ -873,6 +873,7 @@ procedure AddProgress;
var r: TSDL_Rect;
texsurf: PSDL_Surface;
begin
+ if cOnlyStats then exit;
if Step = 0 then
begin
WriteToConsole(msgLoading + 'progress sprite: ');
@@ -883,8 +884,10 @@ begin
squaresize:= texsurf^.w shr 1;
numsquares:= texsurf^.h div squaresize;
SDL_FreeSurface(texsurf);
-
- uMobile.GameLoading();
+ with mobileRecord do
+ if GameLoading <> nil then
+ GameLoading();
+
end;
TryDo(ProgrTex <> nil, 'Error - Progress Texure is nil!', true);
@@ -907,7 +910,9 @@ end;
procedure FinishProgress;
begin
- uMobile.GameLoaded();
+ with mobileRecord do
+ if GameLoaded <> nil then
+ GameLoaded();
WriteLnToConsole('Freeing progress surface... ');
FreeTexture(ProgrTex);
ProgrTex:= nil;
@@ -1127,10 +1132,25 @@ var flags: Longword = 0;
{$IFNDEF DARWIN}ico: PSDL_Surface;{$ENDIF}
{$IFDEF SDL13}x, y: LongInt;{$ENDIF}
begin
+ if cOnlyStats then
+ begin
+ MaxTextureSize:= 1024;
+ exit
+ end;
if Length(s) = 0 then
- cFullScreen:= (not cFullScreen)
+ cFullScreen:= (not cFullScreen)
+ else cFullScreen:= s = '1';
+
+ if cFullScreen then
+ begin
+ cScreenWidth:= cFullscreenWidth;
+ cScreenHeight:= cFullscreenHeight;
+ end
else
- cFullScreen:= s = '1';
+ begin
+ cScreenWidth:= cWindowedWidth;
+ cScreenHeight:= cWindowedHeight;
+ end;
AddFileLog('Preparing to change video parameters...');
{$IFDEF SDL13}
@@ -1208,22 +1228,25 @@ begin
if SDLwindow = nil then
if cFullScreen then
- SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cOrigScreenWidth, cOrigScreenHeight, flags or SDL_WINDOW_FULLSCREEN)
+ SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags or SDL_WINDOW_FULLSCREEN)
else
+ begin
SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags);
+ end;
SDLTry(SDLwindow <> nil, true);
{$ELSE}
flags:= SDL_OPENGL or SDL_RESIZABLE;
if cFullScreen then
+ begin
flags:= flags or SDL_FULLSCREEN;
-
+ end;
if not cOnlyStats then
begin
{$IFDEF WIN32}
s:= SDL_getenv('SDL_VIDEO_CENTERED');
SDL_putenv('SDL_VIDEO_CENTERED=1');
{$ENDIF}
- SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
+ SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, 0, flags);
SDLTry(SDLPrimSurface <> nil, true);
{$IFDEF WIN32}SDL_putenv(str2pchar('SDL_VIDEO_CENTERED=' + s));{$ENDIF}
end;
diff --git a/hedgewars/uTeams.pas b/hedgewars/uTeams.pas
index 223734f..0d9e28b 100644
--- a/hedgewars/uTeams.pas
+++ b/hedgewars/uTeams.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,12 +40,13 @@ procedure TeamGoneEffect(var Team: TTeam);
procedure SwitchCurrentHedgehog(newHog: PHedgehog);
implementation
-uses uLocale, uAmmos, uChat, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug, uScript,
+uses uLocale, uAmmos, uChat, uVariables, uUtils, uIO, uCaptions, uCommands, uDebug,
uGearsUtils, uGearsList
{$IFDEF USE_TOUCH_INTERFACE}, uTouch{$ENDIF};
var MaxTeamHealth: LongInt;
GameOver: boolean;
+ NextClan: boolean;
function CheckForWin: boolean;
var AliveClan: PClan;
@@ -109,7 +110,7 @@ GameOver:= true
end;
procedure SwitchHedgehog;
-var c: LongWord;
+var c, i, t, j: LongWord;
PrevHH, PrevTeam : LongWord;
begin
TargetPoint.X:= NoPointX;
@@ -187,11 +188,22 @@ repeat
PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
repeat
CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
- until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
+ until ((Hedgehogs[CurrHedgehog].Gear <> nil) and (Hedgehogs[CurrHedgehog].Effects[heFrozen] < 256)) or (CurrHedgehog = PrevHH)
end
- until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0));
- end
-until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
+ until ((CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 50256)) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0))
+ end;
+ if (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = nil) or (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] > 255) then
+ begin
+ inc(CurrentTeam^.Clan^.TurnNumber);
+ with CurrentTeam^.Clan^ do
+ for t:= 0 to Pred(TeamsNumber) do
+ with Teams[t]^ do
+ for i:= 0 to Pred(HedgehogsNumber) do
+ with Hedgehogs[i] do
+ if Effects[heFrozen] > 255 then
+ Effects[heFrozen]:= max(255,Effects[heFrozen]-50000)
+ end
+until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] < 256);
SwitchCurrentHedgehog(@(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]));
{$IFDEF USE_TOUCH_INTERFACE}
@@ -238,6 +250,13 @@ if PlacingHogs then
end;
inc(CurrentTeam^.Clan^.TurnNumber);
+with CurrentTeam^.Clan^ do
+ for t:= 0 to Pred(TeamsNumber) do
+ with Teams[t]^ do
+ for i:= 0 to Pred(HedgehogsNumber) do
+ with Hedgehogs[i] do
+ if Effects[heFrozen] > 255 then
+ Effects[heFrozen]:= max(255,Effects[heFrozen]-50000);
CurWeapon:= GetCurAmmoEntry(CurrentHedgehog^);
if CurWeapon^.Count = 0 then
@@ -292,12 +311,20 @@ else
TagTurnTimeLeft:= 0;
NextClan:= false;
end;
+
if (TurnTimeLeft > 0) and (CurrentHedgehog^.BotLevel = 0) then
begin
if CurrentTeam^.ExtDriven then
- AddVoice(sndIllGetYou, CurrentTeam^.voicepack)
+ begin
+ if GetRandom(2) = 0 then
+ AddVoice(sndIllGetYou, CurrentTeam^.voicepack)
+ else AddVoice(sndJustYouWait, CurrentTeam^.voicepack)
+ end
else
+ begin
+ GetRandom(2); // needed to avoid extdriven desync
AddVoice(sndYesSir, CurrentTeam^.voicepack);
+ end;
if cHedgehogTurnTime < 1000000 then
ReadyTimeLeft:= cReadyDelay;
AddCaption(Format(shortstring(trmsg[sidReady]), CurrentTeam^.TeamName), cWhiteColor, capgrpGameState)
@@ -305,19 +332,18 @@ if (TurnTimeLeft > 0) and (CurrentHedgehog^.BotLevel = 0) then
else
begin
if TurnTimeLeft > 0 then
- AddVoice(sndIllGetYou, CurrentTeam^.voicepack);
+ begin
+ if GetRandom(2) = 0 then
+ AddVoice(sndIllGetYou, CurrentTeam^.voicepack)
+ else AddVoice(sndJustYouWait, CurrentTeam^.voicepack)
+ end;
ReadyTimeLeft:= 0
end;
-
-{$IFDEF SDL13}
-uTouch.NewTurnBeginning();
-{$ENDIF}
-ScriptCall('onNewTurn');
end;
function AddTeam(TeamColor: Longword): PTeam;
var team: PTeam;
- c: LongInt;
+ c, t: LongInt;
begin
TryDo(TeamsCount < cMaxTeams, 'Too many teams', true);
New(team);
@@ -330,6 +356,9 @@ team^.Flag:= 'hedgewars';
TeamsArray[TeamsCount]:= team;
inc(TeamsCount);
+for t:= 0 to cKbdMaxIndex do
+ team^.Binds[t]:= '';
+
c:= Pred(ClansCount);
while (c >= 0) and (ClansArray[c]^.Color <> TeamColor) do dec(c);
if c < 0 then
@@ -438,16 +467,18 @@ var i: LongInt;
begin
with team^ do
begin
- NewTeamHealthBarWidth:= 0;
+ TeamHealth:= 0;
+ for i:= 0 to cMaxHHIndex do
+ if Hedgehogs[i].Gear <> nil then
+ inc(TeamHealth, Hedgehogs[i].Gear^.Health)
+ else if Hedgehogs[i].GearHidden <> nil then
+ inc(TeamHealth, Hedgehogs[i].GearHidden^.Health);
if not hasGone then
- for i:= 0 to cMaxHHIndex do
- if Hedgehogs[i].Gear <> nil then
- inc(NewTeamHealthBarWidth, Hedgehogs[i].Gear^.Health)
- else if Hedgehogs[i].GearHidden <> nil then
- inc(NewTeamHealthBarWidth, Hedgehogs[i].GearHidden^.Health);
+ NewTeamHealthBarWidth:= TeamHealth
+ else
+ NewTeamHealthBarWidth:= 0;
- TeamHealth:= NewTeamHealthBarWidth;
if NewTeamHealthBarWidth > MaxTeamHealth then
begin
MaxTeamHealth:= NewTeamHealthBarWidth;
@@ -490,7 +521,6 @@ end;
procedure chAddHH(var id: shortstring);
var s: shortstring;
Gear: PGear;
- c: LongInt;
begin
s:= '';
if (not isDeveloperMode) or (CurrentTeam = nil) then
@@ -499,10 +529,10 @@ with CurrentTeam^ do
begin
SplitBySpace(id, s);
SwitchCurrentHedgehog(@Hedgehogs[HedgehogsNumber]);
- val(id, CurrentHedgehog^.BotLevel, c);
+ CurrentHedgehog^.BotLevel:= StrToInt(id);
Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0);
SplitBySpace(s, id);
- val(s, Gear^.Health, c);
+ Gear^.Health:= StrToInt(s);
TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true);
Gear^.Hedgehog^.Team:= CurrentTeam;
if (GameFlags and gfSharedAmmo) <> 0 then
@@ -523,7 +553,6 @@ end;
procedure chAddTeam(var s: shortstring);
var Color: Longword;
- c: LongInt;
ts, cs: shortstring;
begin
cs:= '';
@@ -532,7 +561,7 @@ if isDeveloperMode then
begin
SplitBySpace(s, cs);
SplitBySpace(cs, ts);
- val(cs, Color, c);
+ Color:= StrToInt(cs);
TryDo(Color <> 0, 'Error: black team color', true);
// color is always little endian so the mask must be constant also in big endian archs
@@ -549,16 +578,16 @@ end;
procedure chSetHHCoords(var x: shortstring);
var y: shortstring;
- t, c: Longint;
+ t: Longint;
begin
-y:= '';
-if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then
- exit;
-SplitBySpace(x, y);
-val(x, t, c);
-CurrentHedgehog^.Gear^.X:= int2hwFloat(t);
-val(y, t, c);
-CurrentHedgehog^.Gear^.Y:= int2hwFloat(t)
+ y:= '';
+ if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then
+ exit;
+ SplitBySpace(x, y);
+ t:= StrToInt(x);
+ CurrentHedgehog^.Gear^.X:= int2hwFloat(t);
+ t:= StrToInt(y);
+ CurrentHedgehog^.Gear^.Y:= int2hwFloat(t)
end;
procedure chBind(var id: shortstring);
diff --git a/hedgewars/uTextures.pas b/hedgewars/uTextures.pas
index dcdb4dd..8992ccf 100644
--- a/hedgewars/uTextures.pas
+++ b/hedgewars/uTextures.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -126,6 +126,7 @@ var tw, th, x, y: Longword;
tmpp: pointer;
fromP4, toP4: PLongWordArray;
begin
+if cOnlyStats then exit(nil);
new(Surface2Tex);
Surface2Tex^.PrevTexture:= nil;
Surface2Tex^.NextTexture:= nil;
diff --git a/hedgewars/uTouch.pas b/hedgewars/uTouch.pas
index 09faeef..38a14d2 100644
--- a/hedgewars/uTouch.pas
+++ b/hedgewars/uTouch.pas
@@ -22,7 +22,7 @@ unit uTouch;
interface
-uses SysUtils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, GLUnit, uTypes, uCaptions, uAmmos, uWorld, uMobile;
+uses SysUtils, uConsole, uVariables, SDLh, uFloat, uConsts, uCommands, GLUnit, uTypes, uCaptions, uAmmos, uWorld;
procedure initModule;
@@ -558,7 +558,7 @@ begin
isOnCrosshair:= isOnRect((x-HalfRectSize), (y-HalfRectSize), RectSize, RectSize, finger);
printFinger(finger);
WriteLnToConsole(inttostr(finger.x) + ' ' + inttostr(x));
- WriteLnToConsole(inttostr(x) + ' ' + inttostr(y) + ' ' + inttostr(round(uMobile.getScreenDPI * 10)));
+ WriteLnToConsole(inttostr(x) + ' ' + inttostr(y) + ' ' + inttostr(round(mobileRecord.getScreenDPI() * 10)));
end;
function isOnCurrentHog(finger: TTouch_Data): boolean;
@@ -640,7 +640,7 @@ begin
for index := 0 to High(fingers) do
fingers[index].id := nilFingerId;
- rectSize:= round(baseRectSize * uMobile.getScreenDPI);
+ rectSize:= round(baseRectSize * mobileRecord.getScreenDPI());
halfRectSize:= rectSize shl 1;
end;
diff --git a/hedgewars/uTypes.pas b/hedgewars/uTypes.pas
index 87e2415..b72bdd0 100644
--- a/hedgewars/uTypes.pas
+++ b/hedgewars/uTypes.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -86,7 +86,7 @@ type
sprHandResurrector, sprCross, sprAirDrill, sprNapalmBomb,
sprBulletHit, sprSnowball, sprHandSnowball, sprSnow,
sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis,
- sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar
+ sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog
);
// Gears that interact with other Gears and/or Land
@@ -102,7 +102,7 @@ type
gtSniperRifleShot, gtJetpack, gtMolotov, gtBirdy, // 44
gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 50
gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 55
- gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis, // 61
+ gtNapalmBomb, gtSnowball, gtFlake, {gtStructure,} gtLandGun, gtTardis, // 61
gtIceGun, gtAddAmmo, gtGenericFaller, gtKnife); // 65
// Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
@@ -123,7 +123,7 @@ type
sndSplash, sndShotgunReload, sndShotgunFire, sndGraveImpact,
sndMineImpact, sndMineTick, sndMudballImpact,
sndPickhammer, sndGun, sndBee, sndJump1, sndJump2,
- sndJump3, sndYesSir, sndLaugh, sndIllGetYou, sndIncoming,
+ sndJump3, sndYesSir, sndLaugh, sndIllGetYou, sndJustYouWait, sndIncoming,
sndMissed, sndStupid, sndFirstBlood, sndBoring, sndByeBye,
sndSameTeam, sndNutter, sndReinforce, sndTraitor, sndRegret,
sndEnemyDown, sndCoward, sndHurry, sndWatchIt, sndKamikaze,
@@ -140,7 +140,8 @@ type
sndPoisonCough, sndPoisonMoan, sndBirdyLay, sndWhistle, sndBeeWater,
sndPiano0, sndPiano1, sndPiano2, sndPiano3, sndPiano4, sndPiano5, sndPiano6, sndPiano7, sndPiano8,
sndSkip, sndSineGun, sndOoff1, sndOoff2, sndOoff3, sndWhack,
- sndComeonthen, sndParachute, sndBump, sndResurrector, sndPlane, sndTardis);
+ sndComeonthen, sndParachute, sndBump, sndResurrector, sndPlane, sndTardis, sndFrozenHogImpact, sndIceBeam, sndHogFreeze
+ );
// Available ammo types to be used by hedgehogs
TAmmoType = (amNothing, amGrenade, amClusterBomb, amBazooka, amBee, amShotgun, amPickHammer, // 6
@@ -151,7 +152,7 @@ type
amRCPlane, amLowGravity, amExtraDamage, amInvulnerable, amExtraTime, // 35
amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun, // 42
amPiano, amGasBomb, amSineGun, amFlamethrower, amSMine, amHammer, // 48
- amResurrector, amDrillStrike, amSnowball, amTardis, amStructure, amLandGun, amIceGun, amKnife); // 54
+ amResurrector, amDrillStrike, amSnowball, amTardis, {amStructure,} amLandGun, amIceGun, amKnife); // 54
// Different kind of crates that e.g. hedgehogs can pick up
TCrateType = (HealthCrate, AmmoCrate, UtilityCrate);
@@ -169,7 +170,7 @@ type
TWave = (waveRollup, waveSad, waveWave, waveHurrah, waveLemonade, waveShrug, waveJuggle);
TRenderMode = (rmDefault, rmLeftEye, rmRightEye);
- TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical, smAFR);
+ TStereoMode = (smNone, smRedCyan, smCyanRed, smRedBlue, smBlueRed, smRedGreen, smGreenRed, smHorizontal, smVertical);
THHFont = record
Handle: PTTF_Font;
@@ -220,45 +221,56 @@ For example, say, a mode where the weaponset is reset each turn, or on sudden de
PClan = ^TClan;
TGearStepProcedure = procedure (Gear: PGear);
+// So, you're here looking for variables you can (ab)use to store some gear state?
+// Not all members of this structure are created equal. Comments below are my take on what can be used for what in the gear structure.
TGear = record
- NextGear, PrevGear: PGear;
- Active: Boolean;
- AdvBounce: Longword;
- Invulnerable: Boolean;
- RenderTimer: Boolean;
- AmmoType : TAmmoType;
- State : Longword;
- X : hwFloat;
+// Don't ever override these.
+ NextGear, PrevGear: PGear; // Linked list
+ Z: Longword; // Z index. For rendering. Sets order in list
+ Active: Boolean; // Is gear Active (running step code)
+ Kind: TGearType;
+ doStep: TGearStepProcedure; // Code the gear is running
+ AmmoType : TAmmoType; // Ammo type associated with this kind of gear
+ RenderTimer: Boolean; // Will visually display Timer if true
+ Target : TPoint; // Gear target. Will render in uGearsRender unless a special case is added
+ AIHints: LongWord; // hints for ai.
+ LastDamage: PHedgehog; // Used to track damage source for stats
+ CollisionIndex: LongInt; // Position in collision array
+ Message: LongWord; // Game messages are stored here. See gm bitmasks in uConsts
+ uid: Longword; // Lua use this to reference gears
+// Strongly recommended not to override these. Will mess up generic operations like portaling
+ X : hwFloat; // X/Y/dX/dY are position/velocity. People count on these having semi-normal values
Y : hwFloat;
dX: hwFloat;
dY: hwFloat;
- Target : TPoint;
- Kind: TGearType;
- Pos: Longword;
- doStep: TGearStepProcedure;
- Radius: LongInt;
- Angle, Power : Longword;
- DirAngle: real;
- Timer : LongWord;
+ State : Longword; // See gst bitmask values in uConsts
+ PortalCounter: LongWord; // Necessary to interrupt portal loops. Not possible to avoid infinite loops without it.
+// Don't use these if you're using generic movement like doStepFallingGear and explosion shoves. Generally recommended not to use.
+ Radius: LongInt; // Radius. If not using uCollisions, is usually used to indicate area of effect
+ CollisionMask: Word; // Masking off Land impact FF7F for example ignores current hog and crates
+ AdvBounce: Longword; // Triggers 45° bounces. Is a counter to avoid edge cases
Elasticity: hwFloat;
Friction : hwFloat;
- Density : hwFloat;
- Message, MsgParam : Longword;
- Hedgehog: PHedgehog;
- Health, Damage, Karma: LongInt;
- CollisionIndex: LongInt;
- Tag: LongInt;
- Tex: PTexture;
- Z: Longword;
- CollisionMask: Word;
- LinkedGear: PGear;
- FlightTime: Longword;
- uid: Longword;
+ Density : hwFloat; // Density is kind of a mix of size and density. Impacts distance thrown, wind.
ImpactSound: TSound; // first sound, others have to be after it in the sounds def.
- nImpactSounds: Word; // count of ImpactSounds
- SoundChannel: LongInt;
- PortalCounter: LongWord; // Hopefully temporary, but avoids infinite portal loops in a guaranteed fashion.
- LastDamage: PHedgehog;
+ nImpactSounds: Word; // count of ImpactSounds.
+// Don't use these if you want to take damage normally, otherwise health/damage are commonly used for other purposes
+ Invulnerable: Boolean;
+ Health, Damage, Karma: LongInt;
+// DirAngle is a "real" - if you don't need it for rotation of sprite in uGearsRender, you can use it for any visual-only value
+ DirAngle: real;
+// These are frequently overridden to serve some other purpose
+ Pos: Longword; // Commonly overridden. Example use is posCase values in uConsts.
+ Angle, Power : Longword; // Used for hog aiming/firing. Angle is rarely used as an Angle otherwise.
+ Timer : LongWord; // Typically used for some sort of gear timer. Time to explosion, remaining fuel...
+ Tag: LongInt; // Quite generic. Variety of uses.
+ FlightTime: Longword; // Initially added for batting of hogs to determine homerun. Used for some firing delays
+ MsgParam: LongWord; // Initially stored a set of messages. So usually gm values like Message. Frequently overriden
+// These are not used generically, but should probably be used for purpose intended. Definitely shouldn't override pointer type
+ Tex: PTexture; // A texture created by the gear. Shouldn't use for anything but textures
+ LinkedGear: PGear; // Used to track a related gear. Portal pairs for example.
+ Hedgehog: PHedgehog; // set to CurrentHedgehog on gear creation
+ SoundChannel: LongInt; // Used to track a sound the gear started
end;
TPGearArray = array of PGear;
PGearArrayS = record
@@ -398,6 +410,18 @@ For example, say, a mode where the weaponset is reset each turn, or on sudden de
Flawless: boolean;
end;
+ cdeclPtr = procedure; cdecl;
+ cdeclIntPtr = procedure(num: LongInt); cdecl;
+ functionDoublePtr = function: Double;
+
+ TMobileRecord = record
+ getScreenDPI: functionDoublePtr;
+ PerformRumble: cdeclIntPtr;
+ GameLoading: cdeclPtr;
+ GameLoaded: cdeclPtr;
+ SaveLoadingEnded: cdeclPtr;
+ end;
+
TAmmoStrId = (sidGrenade, sidClusterBomb, sidBazooka, sidBee, sidShotgun,
sidPickHammer, sidSkip, sidRope, sidMine, sidDEagle,
sidDynamite, sidBaseballBat, sidFirePunch, sidSeconds,
@@ -410,11 +434,11 @@ For example, say, a mode where the weaponset is reset each turn, or on sudden de
sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb,
sidSineGun, sidFlamethrower,sidSMine, sidHammer, sidResurrector,
sidDrillStrike, sidSnowball, sidNothing, sidTardis,
- sidStructure, sidLandGun, sidIceGun, sidKnife);
+ {sidStructure,} sidLandGun, sidIceGun, sidKnife);
TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused,
sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync,
- sidNoEndTurn, sidNotYetAvailable, sidRoundSD, sidRoundsSD, sidReady,
+ sidNoEndTurn, sidNotYetAvailable, sidRoundSD, sidRoundsSD, sidReady,
sidBounce1, sidBounce2, sidBounce3, sidBounce4, sidBounce5, sidBounce,
sidMute);
@@ -425,8 +449,8 @@ For example, say, a mode where the weaponset is reset each turn, or on sudden de
TGoalStrId = (gidCaption, gidSubCaption, gidForts, gidLowGravity, gidInvulnerable,
gidVampiric, gidKarma, gidKing, gidPlaceHog, gidArtillery,
- gidSolidLand, gidSharedAmmo, gidMineTimer, gidNoMineTimer,
- gidRandomMineTimer, gidDamageModifier, gidResetHealth, gidAISurvival,
+ gidSolidLand, gidSharedAmmo, gidMineTimer, gidNoMineTimer,
+ gidRandomMineTimer, gidDamageModifier, gidResetHealth, gidAISurvival,
gidInfAttack, gidResetWeps, gidPerHogAmmo, gidTagTeam);
TLandArray = packed array of array of LongWord;
diff --git a/hedgewars/uUtils.pas b/hedgewars/uUtils.pas
index a1c7787..ddb9868 100644
--- a/hedgewars/uUtils.pas
+++ b/hedgewars/uUtils.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,14 +27,12 @@ procedure SplitBySpace(var a, b: shortstring);
procedure SplitByChar(var a, b: shortstring; c: char);
procedure SplitByChar(var a, b: ansistring; c: char);
-{$IFNDEF PAS2C}
function EnumToStr(const en : TGearType) : shortstring; overload;
function EnumToStr(const en : TVisualGearType) : shortstring; overload;
function EnumToStr(const en : TSound) : shortstring; overload;
function EnumToStr(const en : TAmmoType) : shortstring; overload;
function EnumToStr(const en : THogEffect) : shortstring; overload;
function EnumToStr(const en : TCapGroup) : shortstring; overload;
-{$ENDIF}
function Min(a, b: LongInt): LongInt; inline;
function Max(a, b: LongInt): LongInt; inline;
@@ -68,17 +66,29 @@ function CheckNoTeamOrHH: boolean; inline;
function GetLaunchX(at: TAmmoType; dir: LongInt; angle: LongInt): LongInt;
function GetLaunchY(at: TAmmoType; angle: LongInt): LongInt;
-{$IFNDEF PAS2C}
procedure Write(var f: textfile; s: shortstring);
procedure WriteLn(var f: textfile; s: shortstring);
+
+function isPhone: Boolean; inline;
+function getScreenDPI: Double; inline; //cdecl; external;
+
+{$IFDEF IPHONEOS}
+procedure startLoadingIndicator; cdecl; external;
+procedure stopLoadingIndicator; cdecl; external;
+procedure saveFinishedSynching; cdecl; external;
+function isApplePhone: Boolean; cdecl; external;
+procedure AudioServicesPlaySystemSound(num: LongInt); cdecl; external;
{$ENDIF}
+function sanitizeForLog(s: shortstring): shortstring;
+function sanitizeCharForLog(c: char): shortstring;
+
procedure initModule(isNotPreview: boolean);
procedure freeModule;
implementation
-uses {$IFNDEF PAS2C}typinfo, {$ENDIF}Math, uConsts, uVariables, SysUtils;
+uses typinfo, Math, uConsts, uVariables, SysUtils;
{$IFDEF DEBUGFILE}
var f: textfile;
@@ -121,11 +131,11 @@ if i > 0 then
end else b:= '';
end;
-{$IFNDEF PAS2C}
function EnumToStr(const en : TGearType) : shortstring; overload;
begin
EnumToStr:= GetEnumName(TypeInfo(TGearType), ord(en))
end;
+
function EnumToStr(const en : TVisualGearType) : shortstring; overload;
begin
EnumToStr:= GetEnumName(TypeInfo(TVisualGearType), ord(en))
@@ -150,7 +160,7 @@ function EnumToStr(const en: TCapGroup) : shortstring; overload;
begin
EnumToStr := GetEnumName(TypeInfo(TCapGroup), ord(en))
end;
-{$ENDIF}
+
function Min(a, b: LongInt): LongInt;
begin
@@ -177,7 +187,11 @@ end;
function StrToInt(s: shortstring): LongInt;
var c: LongInt;
begin
-val(s, StrToInt, c)
+val(s, StrToInt, c);
+{$IFDEF DEBUGFILE}
+if c <> 0 then
+ writeln(f, 'Error at position ' + IntToStr(c) + ' : ' + s[c])
+{$ENDIF}
end;
function FloatToStr(n: hwFloat): shortstring;
@@ -343,14 +357,14 @@ while i < l do
if (#$1100 <= u) and (
(u <= #$11FF ) or // Hangul Jamo
((#$2E80 <= u) and (u <= #$2FDF)) or // CJK Radicals Supplement / Kangxi Radicals
- ((#$2FF0 <= u) and (u <= #$303F)) or // Ideographic Description Characters / CJK Radicals Supplement
- ((#$3130 <= u) and (u <= #$318F)) or // Hangul Compatibility Jamo
+ ((#$2FF0 <= u) and (u <= #$31FF)) or // Ideographic Description Characters / CJK Radicals Supplement / Hiragana / Hangul Compatibility Jamo / Katakana
((#$31C0 <= u) and (u <= #$31EF)) or // CJK Strokes
- ((#$3200 <= u) and (u <= #$4DBF)) or // Enclosed CJK Letters and Months / CJK Compatibility / CJK Unified Ideographs Extension A
+ ((#$3200 <= u) and (u <= #$4DBF)) or // Enclosed CJK Letters and Months / CJK Compatibility / CJK Unified Ideographs Extension A / Circled Katakana
((#$4E00 <= u) and (u <= #$9FFF)) or // CJK Unified Ideographs
((#$AC00 <= u) and (u <= #$D7AF)) or // Hangul Syllables
((#$F900 <= u) and (u <= #$FAFF)) or // CJK Compatibility Ideographs
- ((#$FE30 <= u) and (u <= #$FE4F))) // CJK Compatibility Forms
+ ((#$FE30 <= u) and (u <= #$FE4F)) or // CJK Compatibility Forms
+ ((#$FF66 <= u) and (u <= #$FF9D))) // halfwidth katakana
then
begin
CheckCJKFont:= THWFont( ord(font) + ((ord(High(THWFont))+1) div 2) );
@@ -389,7 +403,6 @@ begin
CheckNoTeamOrHH:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil);
end;
-{$IFNDEF PAS2C}
procedure Write(var f: textfile; s: shortstring);
begin
system.write(f, s)
@@ -399,12 +412,62 @@ procedure WriteLn(var f: textfile; s: shortstring);
begin
system.writeln(f, s)
end;
+
+
+// this function is just to determine whether we are running on a limited screen device
+function isPhone: Boolean; inline;
+begin
+ isPhone:= false;
+{$IFDEF IPHONEOS}
+ isPhone:= isApplePhone();
+{$ENDIF}
+{$IFDEF ANDROID}
+ //nasty nasty hack. TODO: implement callback to java to have a unified way of determining if it is a tablet
+ if (cScreenWidth < 1000) and (cScreenHeight < 500) then
+ isPhone:= true;
{$ENDIF}
+end;
+
+//This dummy function should be reimplemented (externally).
+function getScreenDPI: Double; inline;
+begin
+{$IFDEF ANDROID}
+// getScreenDPI:= Android_JNI_getDensity();
+ getScreenDPI:= 1;
+{$ELSE}
+ getScreenDPI:= 1;
+{$ENDIF}
+end;
+
+function sanitizeForLog(s: shortstring): shortstring;
+var i: byte;
+ r: shortstring;
+begin
+ r[0]:= s[0];
+ for i:= 1 to length(s) do
+ if (s[i] < #32) or (s[i] > #127) then
+ r[i]:= '?'
+ else
+ r[i]:= s[i];
+
+ sanitizeForLog:= r
+end;
+
+function sanitizeCharForLog(c: char): shortstring;
+var r: shortstring;
+begin
+ if (c < #32) or (c > #127) then
+ r:= '#' + inttostr(byte(c))
+ else
+ r:= c;
+
+ sanitizeCharForLog:= r
+end;
procedure initModule(isNotPreview: boolean);
{$IFDEF DEBUGFILE}
var logfileBase: shortstring;
-{$IFNDEF MOBILE}var i: LongInt;{$ENDIF}
+ i: LongInt;
{$ENDIF}
begin
{$IFDEF DEBUGFILE}
@@ -421,28 +484,24 @@ begin
InitCriticalSection(logMutex);
{$ENDIF}
{$I-}
-{$IFDEF MOBILE}
- {$IFDEF IPHONEOS} Assign(f, UserPathPrefix + '/hw-' + logfileBase + '.log'); {$ENDIF}
- {$IFDEF ANDROID} Assign(f,pathPrefix + '/' + logfileBase + '.log'); {$ENDIF}
- Rewrite(f);
-{$ELSE}
+ f:= stderr; // if everything fails, write to stderr
if (UserPathPrefix <> '') then
begin
- i:= 0;
- while(i < 7) do
+ // create directory if it doesn't exist
+ if not FileExists(UserPathPrefix + '/Logs/') then
+ CreateDir(UserPathPrefix + '/Logs/');
+
+ // if log is locked, write to the next one
+ i:= 0;
+ while(i < 7) do
begin
- assign(f, UserPathPrefix + '/Logs/' + logfileBase + inttostr(i) + '.log');
- rewrite(f);
- if IOResult = 0 then
- break;
- inc(i)
+ assign(f, UserPathPrefix + '/Logs/' + logfileBase + inttostr(i) + '.log');
+ if IOResult = 0 then
+ break;
+ inc(i)
end;
- if i = 7 then
- f:= stderr; // if everything fails, write to stderr
- end
- else
- f:= stderr;
-{$ENDIF}
+ end;
+ Rewrite(f);
{$I+}
{$ENDIF}
diff --git a/hedgewars/uVariables.pas b/hedgewars/uVariables.pas
index 9ce625e..26b52c0 100644
--- a/hedgewars/uVariables.pas
+++ b/hedgewars/uVariables.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,20 +21,21 @@
unit uVariables;
interface
-uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uMobile;
+uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uUtils;
var
/////// init flags ///////
cMinScreenWidth : LongInt;
cMinScreenHeight : LongInt;
+ cFullscreenWidth : LongInt;
+ cFullscreenHeight : LongInt;
+ cWindowedWidth : LongInt;
+ cWindowedHeight : LongInt;
cScreenWidth : LongInt;
cScreenHeight : LongInt;
- cOrigScreenWidth : LongInt;
- cOrigScreenHeight : LongInt;
cNewScreenWidth : LongInt;
cNewScreenHeight : LongInt;
cScreenResizeDelay : LongWord;
- cBits : LongInt;
ipcPort : Word;
cFullScreen : boolean;
cLocaleFName : shortstring;
@@ -108,22 +109,21 @@ var
zoom : GLfloat;
ZoomValue : GLfloat;
- cWaterLine : Word;
+ cWaterLine : LongInt;
cGearScrEdgesDist: LongInt;
isAudioMuted : boolean;
// originally typed consts
ExplosionBorderColor: LongWord;
+ IceColor : LongWord;
+ IceEdgeColor : LongWord;
WaterOpacity: byte;
SDWaterOpacity: byte;
GrayScale: Boolean;
- // originally from uConsts
- Pathz: array[TPathType] of shortstring;
- UserPathz: array[TPathType] of shortstring;
CountTexz: array[0..Pred(AMMO_INFINITE)] of PTexture;
- LAND_WIDTH : Word;
- LAND_HEIGHT : Word;
+ LAND_WIDTH : LongInt;
+ LAND_HEIGHT : LongInt;
LAND_WIDTH_MASK : LongWord;
LAND_HEIGHT_MASK : LongWord;
@@ -160,10 +160,13 @@ var
cVampiric : boolean;
cArtillery : boolean;
WeaponTooltipTex: PTexture;
- AmmoMenuTex : PTexture;
AmmoMenuInvalidated: boolean;
AmmoRect : TSDL_Rect;
HHTexture : PTexture;
+ cMaxZoomLevel : real;
+ cMinZoomLevel : real;
+ cZoomDelta : real;
+ cMinMaxZoomLevelDelta : real;
flagMakeCapture : boolean;
@@ -176,8 +179,9 @@ var
SDWaterColorArray : array[0..3] of HwColor4f;
SDTint : LongInt;
- CursorPoint : TPoint;
- TargetPoint : TPoint;
+ TargetCursorPoint : TPoint;
+ CursorPoint : TPoint;
+ TargetPoint : TPoint;
ScreenFade : TScreenFade;
ScreenFadeValue : LongInt;
@@ -192,22 +196,13 @@ var
hiTicks: Word;
LuaGoals : shortstring;
- hiddenHedgehogs : array [0..cMaxHHs] of PHedgehog;
- hiddenHedgehogsNumber : longint;
LuaTemplateNumber : LongWord;
- VoiceList : array[0..7] of TVoice = (
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil),
- ( snd: sndNone; voicepack: nil));
LastVoice : TVoice = ( snd: sndNone; voicepack: nil );
+ mobileRecord: TMobileRecord;
+
/////////////////////////////////////
//Buttons
{$IFDEF USE_TOUCH_INTERFACE}
@@ -223,27 +218,27 @@ var
// these consts are here because they would cause circular dependencies in uConsts/uTypes
cPathz: array[TPathType] of shortstring = (
'', // ptNone
- '', // ptData
- 'Graphics', // ptGraphics
- 'Themes', // ptThemes
- 'Themes/Bamboo', // ptCurrTheme
- 'Teams', // ptTeams
- 'Maps', // ptMaps
+ '/', // ptData
+ '/Graphics', // ptGraphics
+ '/Themes', // ptThemes
+ '/Themes/Bamboo', // ptCurrTheme
+ '/Teams', // ptTeams
+ '/Maps', // ptMaps
'', // ptMapCurrent
- 'Demos', // ptDemos
- 'Sounds', // ptSounds
- 'Graphics/Graves', // ptGraves
- 'Fonts', // ptFonts
- 'Forts', // ptForts
- 'Locale', // ptLocale
- 'Graphics/AmmoMenu', // ptAmmoMenu
- 'Graphics/Hedgehog', // ptHedgehog
- 'Sounds/voices', // ptVoices
- 'Graphics/Hats', // ptHats
- 'Graphics/Flags', // ptFlags
- 'Missions/Maps', // ptMissionMaps
- 'Graphics/SuddenDeath', // ptSuddenDeath
- 'Graphics/Buttons' // ptButton
+ '/Demos', // ptDemos
+ '/Sounds', // ptSounds
+ '/Graphics/Graves', // ptGraves
+ '/Fonts', // ptFonts
+ '/Forts', // ptForts
+ '/Locale', // ptLocale
+ '/Graphics/AmmoMenu', // ptAmmoMenu
+ '/Graphics/Hedgehog', // ptHedgehog
+ '/Sounds/voices', // ptVoices
+ '/Graphics/Hats', // ptHats
+ '/Graphics/Flags', // ptFlags
+ '/Missions/Maps', // ptMissionMaps
+ '/Graphics/SuddenDeath', // ptSuddenDeath
+ '/Graphics/Buttons' // ptButton
);
Fontz: array[THWFont] of THHFont = (
@@ -661,16 +656,18 @@ var
Width: 3; Height: 17; imageWidth: 3; imageHeight: 17; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprSlider
(FileName: 'botlevels'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 22; Height: 15; imageWidth: 22; imageHeight: 15; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprBotlevels
- (* (FileName: 'amKnife'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandKnife*)
(FileName: 'amCleaver'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: false),// sprHandKnife
- (*(FileName: 'knife'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 29; Height: 14; imageWidth: 64; imageHeight: 64; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprKnife*)
(FileName: 'cleaver'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
Width: 64; Height: 64; imageWidth: 64; imageHeight: 128; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprKnife
(FileName: 'star'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
- Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprStar
+ Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprStar
+ (FileName: 'icetexture'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 128; Height: 128; imageWidth: 128; imageHeight: 128; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: true), // sprIceTexture
+ (FileName: 'amIceGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 32; Height: 32; imageWidth: 32; imageHeight: 32; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprIceGun
+ (FileName: 'amFrozenHog'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+ Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprFrozenHog
);
const
@@ -691,125 +688,6 @@ const
(Sprite: sprJuggle; FramesCount: 49; Interval: 38; cmd: '/juggle'; Voice: sndNone; VoiceDelay: 0)
);
- Soundz: array[TSound] of record
- FileName: string[31];
- Path : TPathType;
- end = (
- (FileName: ''; Path: ptNone ),// sndNone
- (FileName: 'grenadeimpact.ogg'; Path: ptSounds),// sndGrenadeImpact
- (FileName: 'explosion.ogg'; Path: ptSounds),// sndExplosion
- (FileName: 'throwpowerup.ogg'; Path: ptSounds),// sndThrowPowerUp
- (FileName: 'throwrelease.ogg'; Path: ptSounds),// sndThrowRelease
- (FileName: 'splash.ogg'; Path: ptSounds),// sndSplash
- (FileName: 'shotgunreload.ogg'; Path: ptSounds),// sndShotgunReload
- (FileName: 'shotgunfire.ogg'; Path: ptSounds),// sndShotgunFire
- (FileName: 'graveimpact.ogg'; Path: ptSounds),// sndGraveImpact
- (FileName: 'mineimpact.ogg'; Path: ptSounds),// sndMineImpact
- (FileName: 'minetick.ogg'; Path: ptSounds),// sndMineTicks
- (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndMudballImpact
- (FileName: 'pickhammer.ogg'; Path: ptSounds),// sndPickhammer
- (FileName: 'gun.ogg'; Path: ptSounds),// sndGun
- (FileName: 'bee.ogg'; Path: ptSounds),// sndBee
- (FileName: 'Jump1.ogg'; Path: ptVoices),// sndJump1
- (FileName: 'Jump2.ogg'; Path: ptVoices),// sndJump2
- (FileName: 'Jump3.ogg'; Path: ptVoices),// sndJump3
- (FileName: 'Yessir.ogg'; Path: ptVoices),// sndYesSir
- (FileName: 'Laugh.ogg'; Path: ptVoices),// sndLaugh
- (FileName: 'Illgetyou.ogg'; Path: ptVoices),// sndIllGetYou
- (FileName: 'Incoming.ogg'; Path: ptVoices),// sndIncoming
- (FileName: 'Missed.ogg'; Path: ptVoices),// sndMissed
- (FileName: 'Stupid.ogg'; Path: ptVoices),// sndStupid
- (FileName: 'Firstblood.ogg'; Path: ptVoices),// sndFirstBlood
- (FileName: 'Boring.ogg'; Path: ptVoices),// sndBoring
- (FileName: 'Byebye.ogg'; Path: ptVoices),// sndByeBye
- (FileName: 'Sameteam.ogg'; Path: ptVoices),// sndSameTeam
- (FileName: 'Nutter.ogg'; Path: ptVoices),// sndNutter
- (FileName: 'Reinforcements.ogg'; Path: ptVoices),// sndReinforce
- (FileName: 'Traitor.ogg'; Path: ptVoices),// sndTraitor
- (FileName: 'Youllregretthat.ogg'; Path: ptVoices),// sndRegret
- (FileName: 'Enemydown.ogg'; Path: ptVoices),// sndEnemyDown
- (FileName: 'Coward.ogg'; Path: ptVoices),// sndCoward
- (FileName: 'Hurry.ogg'; Path: ptVoices),// sndHurry
- (FileName: 'Watchit.ogg'; Path: ptVoices),// sndWatchIt
- (FileName: 'Kamikaze.ogg'; Path: ptVoices),// sndKamikaze
- (FileName: 'cake2.ogg'; Path: ptSounds),// sndCake
- (FileName: 'Ow1.ogg'; Path: ptVoices),// sndOw1
- (FileName: 'Ow2.ogg'; Path: ptVoices),// sndOw2
- (FileName: 'Ow3.ogg'; Path: ptVoices),// sndOw3
- (FileName: 'Ow4.ogg'; Path: ptVoices),// sndOw4
- (FileName: 'Firepunch1.ogg'; Path: ptVoices),// sndFirepunch1
- (FileName: 'Firepunch2.ogg'; Path: ptVoices),// sndFirepunch2
- (FileName: 'Firepunch3.ogg'; Path: ptVoices),// sndFirepunch3
- (FileName: 'Firepunch4.ogg'; Path: ptVoices),// sndFirepunch4
- (FileName: 'Firepunch5.ogg'; Path: ptVoices),// sndFirepunch5
- (FileName: 'Firepunch6.ogg'; Path: ptVoices),// sndFirepunch6
- (FileName: 'Melon.ogg'; Path: ptVoices),// sndMelon
- (FileName: 'Hellish.ogg'; Path: ptSounds),// sndHellish
- (FileName: 'Yoohoo.ogg'; Path: ptSounds),// sndYoohoo
- (FileName: 'rcplane.ogg'; Path: ptSounds),// sndRCPlane
- (FileName: 'whipcrack.ogg'; Path: ptSounds),// sndWhipCrack
- (FileName:'ride_of_the_valkyries.ogg'; Path: ptSounds),// sndRideOfTheValkyries
- (FileName: 'denied.ogg'; Path: ptSounds),// sndDenied
- (FileName: 'placed.ogg'; Path: ptSounds),// sndPlaced
- (FileName: 'baseballbat.ogg'; Path: ptSounds),// sndBaseballBat
- (FileName: 'steam.ogg'; Path: ptSounds),// sndVaporize
- (FileName: 'warp.ogg'; Path: ptSounds),// sndWarp
- (FileName: 'suddendeath.ogg'; Path: ptSounds),// sndSuddenDeath
- (FileName: 'mortar.ogg'; Path: ptSounds),// sndMortar
- (FileName: 'shutterclick.ogg'; Path: ptSounds),// sndShutter
- (FileName: 'homerun.ogg'; Path: ptSounds),// sndHomerun
- (FileName: 'molotov.ogg'; Path: ptSounds),// sndMolotov
- (FileName: 'Takecover.ogg'; Path: ptVoices),// sndCover
- (FileName: 'Uh-oh.ogg'; Path: ptVoices),// sndUhOh
- (FileName: 'Oops.ogg'; Path: ptVoices),// sndOops
- (FileName: 'Nooo.ogg'; Path: ptVoices),// sndNooo
- (FileName: 'Hello.ogg'; Path: ptVoices),// sndHello
- (FileName: 'ropeshot.ogg'; Path: ptSounds),// sndRopeShot
- (FileName: 'ropeattach.ogg'; Path: ptSounds),// sndRopeAttach
- (FileName: 'roperelease.ogg'; Path: ptSounds),// sndRopeRelease
- (FileName: 'switchhog.ogg'; Path: ptSounds),// sndSwitchHog
- (FileName: 'Victory.ogg'; Path: ptVoices),// sndVictory
- (FileName: 'Flawless.ogg'; Path: ptVoices),// sndFlawless
- (FileName: 'sniperreload.ogg'; Path: ptSounds),// sndSniperReload
- (FileName: 'steps.ogg'; Path: ptSounds),// sndSteps
- (FileName: 'lowgravity.ogg'; Path: ptSounds),// sndLowGravity
- (FileName: 'hell_growl.ogg'; Path: ptSounds),// sndHellishImpact1
- (FileName: 'hell_ooff.ogg'; Path: ptSounds),// sndHellishImpact2
- (FileName: 'hell_ow.ogg'; Path: ptSounds),// sndHellishImpact3
- (FileName: 'hell_ugh.ogg'; Path: ptSounds),// sndHellishImpact4
- (FileName: 'melonimpact.ogg'; Path: ptSounds),// sndMelonImpact
- (FileName: 'Droplet1.ogg'; Path: ptSounds),// sndDroplet1
- (FileName: 'Droplet2.ogg'; Path: ptSounds),// sndDroplet2
- (FileName: 'Droplet3.ogg'; Path: ptSounds),// sndDroplet3
- (FileName: 'egg.ogg'; Path: ptSounds),// sndEggBreak
- (FileName: 'drillgun.ogg'; Path: ptSounds),// sndDrillRocket
- (FileName: 'PoisonCough.ogg'; Path: ptVoices),// sndPoisonCough
- (FileName: 'PoisonMoan.ogg'; Path: ptVoices),// sndPoisonMoan
- (FileName: 'BirdyLay.ogg'; Path: ptSounds),// sndBirdyLay
- (FileName: 'Whistle.ogg'; Path: ptSounds),// sndWhistle
- (FileName: 'beewater.ogg'; Path: ptSounds),// sndBeeWater
- (FileName: '1C.ogg'; Path: ptSounds),// sndPiano0
- (FileName: '2D.ogg'; Path: ptSounds),// sndPiano1
- (FileName: '3E.ogg'; Path: ptSounds),// sndPiano2
- (FileName: '4F.ogg'; Path: ptSounds),// sndPiano3
- (FileName: '5G.ogg'; Path: ptSounds),// sndPiano4
- (FileName: '6A.ogg'; Path: ptSounds),// sndPiano5
- (FileName: '7B.ogg'; Path: ptSounds),// sndPiano6
- (FileName: '8C.ogg'; Path: ptSounds),// sndPiano7
- (FileName: '9D.ogg'; Path: ptSounds),// sndPiano8
- (FileName: 'skip.ogg'; Path: ptSounds),// sndSkip
- (FileName: 'sinegun.ogg'; Path: ptSounds),// sndSineGun
- (FileName: 'Ooff1.ogg'; Path: ptVoices),// sndOoff1
- (FileName: 'Ooff2.ogg'; Path: ptVoices),// sndOoff2
- (FileName: 'Ooff3.ogg'; Path: ptVoices),// sndOoff3
- (FileName: 'hammer.ogg'; Path: ptSounds),// sndWhack
- (FileName: 'Comeonthen.ogg'; Path: ptVoices),// sndComeonthen
- (FileName: 'parachute.ogg'; Path: ptSounds),// sndParachute
- (FileName: 'bump.ogg'; Path: ptSounds),// sndBump
- (FileName: 'hogchant3.ogg'; Path: ptSounds),// sndResurrector
- (FileName: 'plane.ogg'; Path: ptSounds),// sndPlane
- (FileName: 'TARDIS.ogg'; Path: ptSounds) // sndTardis
- );
var
Ammoz: array [TAmmoType] of record
NameId: TAmmoStrId;
@@ -1320,8 +1198,8 @@ var
Bounciness: 1000);
Slot: 6;
TimeAfterTurn: 3000;
- minAngle: 768;
- maxAngle: 1280;
+ minAngle: 804;
+ maxAngle: 1327;
isDamaging: false;
SkipTurns: 0;
PosCount: 1;
@@ -1887,7 +1765,6 @@ var
Ammo: (Propz: ammoprop_NoRoundEnd or
ammoprop_ForwMsgs or
ammoprop_AttackInMove or
- ammoprop_NoCrosshair or
ammoprop_DontHold or
ammoprop_Utility or
ammoprop_NeedUpDown or
@@ -2222,7 +2099,7 @@ var
TimeAfterTurn: 3000;
minAngle: 0;
maxAngle: 0;
- isDamaging: true;
+ isDamaging: false;
SkipTurns: 0;
PosCount: 1;
PosSprite: sprWater;
@@ -2257,6 +2134,7 @@ var
ejectY: 0),
// Structure
+{
(NameId: sidStructure;
NameTex: nil;
Probability: 0;
@@ -2282,6 +2160,7 @@ var
PosSprite: sprWater;
ejectX: 0;
ejectY: 0),
+}
// Land Gun
(NameId: sidLandGun;
@@ -2297,7 +2176,7 @@ var
AmmoType: amLandGun;
AttackVoice: sndNone;
Bounciness: 1000);
- Slot: 2;
+ Slot: 6;
TimeAfterTurn: 0;
minAngle: 0;
maxAngle: 0;
@@ -2322,11 +2201,11 @@ var
AmmoType: amIceGun;
AttackVoice: sndNone;
Bounciness: 1000);
- Slot: 9;
+ Slot: 2;
TimeAfterTurn: 0;
minAngle: 0;
maxAngle: 0;
- isDamaging: true;
+ isDamaging: false;
SkipTurns: 0;
PosCount: 1;
PosSprite: sprWater;
@@ -2359,76 +2238,6 @@ var
ejectY: 0)
);
-const
- GearKindAmmoTypeMap : array [TGearType] of TAmmoType = (
-(* gtFlame *) amNothing
-(* gtHedgehog *) , amNothing
-(* gtMine *) , amMine
-(* gtCase *) , amNothing
-(* gtExplosives *) , amNothing
-(* gtGrenade *) , amGrenade
-(* gtShell *) , amBazooka
-(* gtGrave *) , amNothing
-(* gtBee *) , amBee
-(* gtShotgunShot *) , amShotgun
-(* gtPickHammer *) , amPickHammer
-(* gtRope *) , amRope
-(* gtDEagleShot *) , amDEagle
-(* gtDynamite *) , amDynamite
-(* gtClusterBomb *) , amClusterBomb
-(* gtCluster *) , amClusterBomb
-(* gtShover *) , amBaseballBat // Shover is only used for baseball bat right now
-(* gtFirePunch *) , amFirePunch
-(* gtATStartGame *) , amNothing
-(* gtATFinishGame *) , amNothing
-(* gtParachute *) , amParachute
-(* gtAirAttack *) , amAirAttack
-(* gtAirBomb *) , amAirAttack
-(* gtBlowTorch *) , amBlowTorch
-(* gtGirder *) , amGirder
-(* gtTeleport *) , amTeleport
-(* gtSwitcher *) , amSwitch
-(* gtTarget *) , amNothing
-(* gtMortar *) , amMortar
-(* gtWhip *) , amWhip
-(* gtKamikaze *) , amKamikaze
-(* gtCake *) , amCake
-(* gtSeduction *) , amSeduction
-(* gtWatermelon *) , amWatermelon
-(* gtMelonPiece *) , amWatermelon
-(* gtHellishBomb *) , amHellishBomb
-(* gtWaterUp *) , amNothing
-(* gtDrill *) , amDrill
-(* gtBallGun *) , amBallgun
-(* gtBall *) , amBallgun
-(* gtRCPlane *) , amRCPlane
-(*gtSniperRifleShot *) , amSniperRifle
-(* gtJetpack *) , amJetpack
-(* gtMolotov *) , amMolotov
-(* gtBirdy *) , amBirdy
-(* gtEgg *) , amBirdy
-(* gtPortal *) , amPortalGun
-(* gtPiano *) , amPiano
-(* gtGasBomb *) , amGasBomb
-(* gtSineGunShot *) , amSineGun
-(* gtFlamethrower *) , amFlamethrower
-(* gtSMine *) , amSMine
-(* gtPoisonCloud *) , amNothing
-(* gtHammer *) , amHammer
-(* gtHammerHit *) , amHammer
-(* gtResurrector *) , amResurrector
-(* gtPoisonCloud *) , amNothing
-(* gtSnowball *) , amSnowball
-(* gtFlake *) , amNothing
-(* gtStructure *) , amStructure // TODO - This will undoubtedly change once there is more than one structure
-(* gtLandGun *) , amLandGun
-(* gtTardis *) , amTardis
-(* gtIceGun *) , amIceGun
-(* gtAddAmmo *) , amNothing
-(* gtGenericFaller *) , amNothing
-(* gtKnife *) , amKnife
- );
-
var
Land: TCollisionArray;
LandPixels: TLandArray;
@@ -2462,7 +2271,6 @@ var
LocalTeam: LongInt; // last non-bot, non-extdriven clan first team
LocalAmmo: LongInt; // last non-bot, non-extdriven clan's first team's ammo index, updated to next upcoming hog for per-hog-ammo
CurMinAngle, CurMaxAngle: Longword;
- NextClan: boolean;
FollowGear: PGear;
WindBarWidth: LongInt;
@@ -2473,13 +2281,9 @@ var
WaterColor, DeepWaterColor: TSDL_Color;
SkyColor, RQSkyColor, SDSkyColor: TSDL_Color;
SkyOffset: LongInt;
- HorizontOffset: LongInt;
{$IFDEF COUNTTICKS}
cntTicks: LongWord;
{$ENDIF}
- cOffsetY: LongInt;
- AFRToggle: Boolean;
- bAFRRight: Boolean;
PauseTexture,
@@ -2488,9 +2292,6 @@ var
cScaleFactor: GLfloat;
SupportNPOTT: Boolean;
Step: LongInt;
- squaresize : LongInt;
- numsquares : LongInt;
- ProgrTex: PTexture;
MissionIcons: PSDL_Surface;
ropeIconTex: PTexture;
@@ -2502,26 +2303,12 @@ var
defaultFrame, depthv: GLuint;
texv: GLuint;
- VisualGearLayers: array[0..6] of PVisualGear;
lastVisualGearByUID: PVisualGear;
vobFrameTicks, vobFramesCount, vobCount: Longword;
vobVelocity, vobFallSpeed: LongInt;
vobSDFrameTicks, vobSDFramesCount, vobSDCount: Longword;
vobSDVelocity, vobSDFallSpeed: LongInt;
- hideAmmoMenu: boolean;
-
- ControllerNumControllers: Integer;
- ControllerEnabled: Integer;
- ControllerNumAxes: array[0..5] of Integer;
- //ControllerNumBalls: array[0..5] of Integer;
- ControllerNumHats: array[0..5] of Integer;
- ControllerNumButtons: array[0..5] of Integer;
- ControllerAxes: array[0..5] of array[0..19] of Integer;
- //ControllerBalls: array[0..5] of array[0..19] of array[0..1] of Integer;
- ControllerHats: array[0..5] of array[0..19] of Byte;
- ControllerButtons: array[0..5] of array[0..19] of Byte;
-
DefaultBinds : TBinds;
lastTurnChecksum : Longword;
@@ -2543,9 +2330,13 @@ procedure preInitModule;
begin
// initialisation flags - they are going to be overwritten by program args
- cScreenWidth := 1024;
- cScreenHeight := 768;
- cBits := 32;
+ cFullscreenWidth := 0;
+ cFullscreenHeight := 0;
+ cWindowedWidth := 1024;
+ cWindowedHeight := 768;
+ cScreenWidth := cWindowedWidth;
+ cScreenHeight := cWindowedHeight;
+
cShowFPS := false;
cAltDamage := true;
cTimerInterval := 8;
@@ -2555,11 +2346,13 @@ begin
UserPathPrefix := '';
ipcPort := 0;
+ recordFileName := '';
UserNick := '';
cStereoMode := smNone;
GrayScale := false;
PathPrefix := './';
GameType := gmtLocal;
+ cOnlyStats := False;
{$IFDEF USE_VIDEO_RECORDING}
RecPrefix := '';
@@ -2573,21 +2366,16 @@ begin
end;
procedure initModule;
+var s: ShortString;
begin
-
- if (Length(cLocaleFName) > 6) then
- cLocale := Copy(cLocaleFName,1,5)
- else
- cLocale := Copy(cLocaleFName,1,2);
+ cLocale:= cLocaleFName;
+ SplitByChar(cLocale, s, '.');
cFlattenFlakes := false;
cFlattenClouds := false;
- cOnlyStats := False;
lastVisualGearByUID := nil;
lastGearByUID := nil;
- recordFileName := '';
cReadyDelay := 5000;
- Pathz := cPathz;
{* REFERENCE
4096 -> $FFFFF000
@@ -2622,6 +2410,9 @@ begin
SDWaterOpacity:= $80;
SDTint:= $80;
ExplosionBorderColor:= $FF808080;
+ IceColor:= ($44 shl RShift) or ($97 shl GShift) or ($A9 shl BShift) or ($A0 shl AShift);
+ IceEdgeColor:= ($8A shl RShift) or ($AF shl GShift) or ($B2 shl BShift) or ($FF shl AShift);
+
WaterOpacity:= $80;
cDrownSpeed.QWordValue := 257698038; // 0.06
@@ -2634,6 +2425,18 @@ begin
cDamageModifier := _1;
TargetPoint := cTargetPointRef;
+{$IFDEF MOBILE}
+ cMaxZoomLevel:= 0.5;
+ cMinZoomLevel:= 3.5;
+ cZoomDelta:= 0.20;
+{$ELSE}
+ cMaxZoomLevel:= 1.0;
+ cMinZoomLevel:= 3.0;
+ cZoomDelta:= 0.25;
+{$ENDIF}
+
+ cMinMaxZoomLevelDelta:= cMaxZoomLevel - cMinZoomLevel;
+
// int, longint longword and byte
CursorMovementX := 0;
CursorMovementY := 0;
@@ -2717,20 +2520,37 @@ begin
vobSDVelocity:= 15;
vobSDFallSpeed:= 250;
- cMinScreenWidth:= min(cScreenWidth, 640);
- cMinScreenHeight:= min(cScreenHeight, 480);
- cOrigScreenWidth:= cScreenWidth;
- cOrigScreenHeight:= cScreenHeight;
+ cMinScreenWidth := min(cScreenWidth, 640);
+ cMinScreenHeight := min(cScreenHeight, 480);
cNewScreenWidth := cScreenWidth;
cNewScreenHeight := cScreenHeight;
cScreenResizeDelay := 0;
+ // make sure fullscreen resolution is always initialised somehow
+ if cFullscreenWidth = 0 then
+ cFullscreenWidth:= min(cWindowedWidth, 640);
+ if cFullscreenHeight = 0 then
+ cFullscreenHeight:= min(cWindowedHeight, 480);
+
+
LuaGoals:= '';
cMapName:= '';
LuaTemplateNumber:= 0;
- hiddenHedgehogsNumber:=0;
+
+ mobileRecord.getScreenDPI:= @getScreenDPI; //TODO: define external function.
+ {$IFDEF IPHONEOS}
+ mobileRecord.PerformRumble:= @AudioServicesPlaySystemSound;
+ mobileRecord.GameLoading:= @startLoadingIndicator;
+ mobileRecord.GameLoaded:= @stopLoadingIndicator;
+ mobileRecord.SaveLoadingEnded:= @saveFinishedSynching;
+ {$ELSE}
+ mobileRecord.PerformRumble:= nil;
+ mobileRecord.GameLoading:= nil;
+ mobileRecord.GameLoaded:= nil;
+ mobileRecord.SaveLoadingEnded:= nil;
+ {$ENDIF}
end;
procedure freeModule;
diff --git a/hedgewars/uVideoRec.pas b/hedgewars/uVideoRec.pas
index 1f27973..a7c9d00 100644
--- a/hedgewars/uVideoRec.pas
+++ b/hedgewars/uVideoRec.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,12 +28,10 @@ end.
{$ELSE}
{$IFNDEF WIN32}
- {$LINKLIB ../bin/libavwrapper.a}
-{$ENDIF}
-{$IFDEF DARWIN}
- {$LINKLIB bz2}
- {$LINKFRAMEWORK CoreVideo}
- {$LINKFRAMEWORK VideoDecodeAcceleration}
+ {$linklib avcodec}
+ {$linklib avformat}
+ {$linklib avutil}
+ {$linklib avwrapper}
{$ENDIF}
interface
@@ -53,17 +51,17 @@ procedure initModule;
procedure freeModule;
implementation
-
uses uVariables, uUtils, GLunit, SDLh, SysUtils, uIO, uMisc, uTypes;
type TAddFileLogRaw = procedure (s: pchar); cdecl;
+const AvwrapperLibName = 'libavwrapper';
procedure AVWrapper_Init(
AddLog: TAddFileLogRaw;
filename, desc, soundFile, format, vcodec, acodec: PChar;
- width, height, framerateNum, framerateDen, vquality: LongInt); cdecl; external {$IFDEF WIN32}'libavwrapper.dll'{$ENDIF};
-procedure AVWrapper_Close; cdecl; external {$IFDEF WIN32}'libavwrapper.dll'{$ENDIF};
-procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external {$IFDEF WIN32}'libavwrapper.dll'{$ENDIF};
+ width, height, framerateNum, framerateDen, vquality: LongInt); cdecl; external AvwrapperLibName;
+procedure AVWrapper_Close; cdecl; external AvwrapperLibName;
+procedure AVWrapper_WriteFrame( pY, pCb, pCr: PByte ); cdecl; external AvwrapperLibName;
type TFrame = record
realTicks: LongWord;
@@ -201,7 +199,7 @@ begin
end;
function LoadNextCameraPosition(out newRealTicks, newGameTicks: LongInt): Boolean;
-var frame: TFrame;
+var frame: TFrame = (realTicks: 0; gameTicks: 0; CamX: 0; CamY: 0; zoom: 0);
begin
// we need to skip or duplicate frames to match target framerate
while Int64(curTime)*cVideoFramerateNum <= Int64(numFrames)*cVideoFramerateDen*1000 do
@@ -249,9 +247,12 @@ procedure CopyFile(src, dest: shortstring);
var inF, outF: file;
buffer: array[0..1023] of byte;
result: LongInt;
+ i: integer;
begin
{$IOCHECKS OFF}
- result:= 0; // avoid compiler hint
+ result:= 0; // avoid compiler hint and warning
+ for i:= 0 to 1023 do
+ buffer[i]:= 0;
Assign(inF, src);
Reset(inF, 1);
diff --git a/hedgewars/uVisualGears.pas b/hedgewars/uVisualGears.pas
index 15f559a..366849e 100644
--- a/hedgewars/uVisualGears.pas
+++ b/hedgewars/uVisualGears.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -53,10 +53,13 @@ procedure ChangeToSDFlakes;
procedure KickFlakes(Radius, X, Y: LongInt);
implementation
-uses uSound, uMobile, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils;
+uses uSound, uVariables, uTextures, uRender, Math, uRenderUtils, uStore, uUtils;
-const cExplFrameTicks = 110;
+const
+ cExplFrameTicks = 110;
+ //cSmokeZ = 499;
var VGCounter: LongWord;
+ VisualGearLayers: array[0..6] of PVisualGear;
// For better maintainability the step handlers of visual gears are stored
// in a separate file.
diff --git a/hedgewars/uWorld.pas b/hedgewars/uWorld.pas
index e21fe47..9ca33f8 100644
--- a/hedgewars/uWorld.pas
+++ b/hedgewars/uWorld.pas
@@ -1,6 +1,6 @@
(*
* Hedgewars, a free turn based strategy game
- * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr at gmail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -60,7 +60,6 @@ uses
, uCaptions
, uCursor
, uCommands
- , uMobile
{$IFDEF USE_VIDEO_RECORDING}
, uVideoRec
{$ENDIF}
@@ -75,8 +74,7 @@ var cWaveWidth, cWaveHeight: LongInt;
timeTexture: PTexture;
FPS: Longword;
CountTicks: Longword;
- SoundTimerTicks: Longword;
- prevPoint: TPoint;
+ prevPoint{, prevTargetPoint}: TPoint;
amSel: TAmmoType = amNothing;
missionTex: PTexture;
missionTimer: LongInt;
@@ -84,6 +82,9 @@ var cWaveWidth, cWaveHeight: LongInt;
isFirstFrame: boolean;
AMAnimType: LongInt;
recTexture: PTexture;
+ AmmoMenuTex : PTexture;
+ HorizontOffset: LongInt;
+ cOffsetY: LongInt;
const cStereo_Sky = 0.0500;
cStereo_Horizon = 0.0250;
@@ -93,6 +94,27 @@ const cStereo_Sky = 0.0500;
cStereo_Water_near = 0.0025;
cStereo_Outside = -0.0400;
+ AMAnimDuration = 200;
+ AMHidden = 0;//AMState values
+ AMShowingUp = 1;
+ AMShowing = 2;
+ AMHiding = 3;
+
+ AMTypeMaskX = $00000001;
+ AMTypeMaskY = $00000002;
+ AMTypeMaskAlpha = $00000004;
+ //AMTypeMaskSlide = $00000008;
+
+{$IFDEF MOBILE}
+ AMSlotSize = 48;
+{$ELSE}
+ AMSlotSize = 32;
+{$ENDIF}
+ AMSlotPadding = (AMSlotSize - 32) shr 1;
+
+ cSendCursorPosTime = 50;
+ cCursorEdgesDist = 100;
+
// helper functions to create the goal/game mode string
function AddGoal(s: ansistring; gf: longword; si: TGoalStrId; i: LongInt): ansistring;
var t: ansistring;
@@ -199,6 +221,8 @@ InitCameraBorders();
uCursor.init();
prevPoint.X:= 0;
prevPoint.Y:= cScreenHeight div 2;
+//prevTargetPoint.X:= 0;
+//prevTargetPoint.Y:= 0;
WorldDx:= -(LAND_WIDTH div 2) + cScreenWidth div 2;
WorldDy:= -(LAND_HEIGHT - (playHeight div 2)) + (cScreenHeight div 2);
@@ -220,7 +244,7 @@ begin
{$IFDEF USE_TOUCH_INTERFACE}
//positioning of the buttons
-buttonScale:= uMobile.getScreenDPI/cDefaultZoomLevel;
+buttonScale:= mobileRecord.getScreenDPI()/cDefaultZoomLevel;
with JumpWidget do
@@ -511,9 +535,7 @@ var Slot, Pos: LongInt;
Ammo: PHHAmmo;
c,i,g,t,STurns: LongInt;
begin
-if (TurnTimeLeft = 0) or (not CurrentTeam^.ExtDriven and (((CurAmmoGear = nil)
-or ((Ammoz[CurAmmoGear^.AmmoType].Ammo.Propz and ammoprop_AltAttack) = 0)) and hideAmmoMenu)) then
- bShowAmmoMenu:= false;
+if TurnTimeLeft = 0 then bShowAmmoMenu:= false;
// give the assigned ammo to hedgehog
Ammo:= nil;
@@ -552,16 +574,19 @@ if(AmmoMenuInvalidated) then
AmmoRect.x:= (cScreenWidth shr 1) - AmmoRect.w - AMSlotSize;
AmmoRect.y:= cScreenHeight - (AmmoRect.h + AMSlotSize);
{$ENDIF}
- AMShiftTargetX:= (cScreenWidth shr 1) - AmmoRect.x;
- AMShiftTargetY:= cScreenHeight - AmmoRect.y;
+ if AMState <> AMShowing then
+ begin
+ AMShiftTargetX:= (cScreenWidth shr 1) - AmmoRect.x;
+ AMShiftTargetY:= cScreenHeight - AmmoRect.y;
- if (AMAnimType and AMTypeMaskX) <> 0 then AMShiftTargetX:= (cScreenWidth shr 1) - AmmoRect.x
- else AMShiftTargetX:= 0;
- if (AMAnimType and AMTypeMaskY) <> 0 then AMShiftTargetY:= cScreenHeight - AmmoRect.y
- else AMShiftTargetY:= 0;
+ if (AMAnimType and AMTypeMaskX) <> 0 then AMShiftTargetX:= (cScreenWidth shr 1) - AmmoRect.x
+ else AMShiftTargetX:= 0;
+ if (AMAnimType and AMTypeMaskY) <> 0 then AMShiftTargetY:= cScreenHeight - AmmoRect.y
+ else AMShiftTargetY:= 0;
- AMShiftX:= AMShiftTargetX;
- AMShiftY:= AMShiftTargetY;
+ AMShiftX:= AMShiftTargetX;
+ AMShiftY:= AMShiftTargetY
+ end
end;
AMAnimState:= (RealTicks - AMAnimStartTime) / AMAnimDuration;
@@ -617,6 +642,7 @@ if AMState = AMHiding then // hide ammo menu
AMShiftX:= AMShiftTargetX;
AMShiftY:= AMShiftTargetY;
prevPoint:= CursorPoint;
+ //prevTargetPoint:= TargetCursorPoint;
AMState:= AMHidden;
end;
end;
@@ -960,16 +986,7 @@ begin
glClear(GL_COLOR_BUFFER_BIT);
DrawWorldStereo(Lag, rmDefault)
end
-{$IFNDEF S3D_DISABLED}
- else if (cStereoMode = smAFR) then
- begin
- AFRToggle:= not AFRToggle;
- glClear(GL_COLOR_BUFFER_BIT);
- if AFRToggle then
- DrawWorldStereo(Lag, rmLeftEye)
- else
- DrawWorldStereo(Lag, rmRightEye)
- end
+{$IFDEF USE_S3D_RENDERING}
else if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
begin
// create left fb
@@ -1073,7 +1090,7 @@ end;
procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
begin
-{$IFDEF S3D_DISABLED}
+{$IFNDEF USE_S3D_RENDERING}
rm:= rm; d:= d; // avoid hint
exit;
{$ELSE}
@@ -1091,7 +1108,7 @@ end;
procedure ResetDepth(rm: TRenderMode);
begin
-{$IFDEF S3D_DISABLED}
+{$IFNDEF USE_S3D_RENDERING}
rm:= rm; // avoid hint
exit;
{$ELSE}
@@ -1303,7 +1320,7 @@ for t:= 0 to Pred(TeamsCount) do
// draw health bars right border
inc(r.x, cTeamHealthWidth + 2);
r.w:= 3;
- DrawTextureFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
+ DrawTextureFromRect(TeamHealthBarWidth + 15, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex);
if not highlight and (not hasGone) then
for i:= 0 to cMaxHHIndex do
@@ -1340,7 +1357,7 @@ for t:= 0 to Pred(TeamsCount) do
// draw health bar
r.w:= TeamHealthBarWidth + 1;
r.h:= HealthTex^.h - 4;
- DrawTextureFromRect(16, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex);
+ DrawTextureFromRect(15, cScreenHeight + DrawHealthY + smallScreenOffset + 2, @r, HealthTex);
if not hasGone and (TeamHealth > 1) then
begin
Tint(Clan^.Color shl 8 or $FF);
@@ -1496,25 +1513,11 @@ if (RM = rmDefault) or (RM = rmRightEye) then
if fpsTexture <> nil then
DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
end;
-
- // lag warning (?)
- inc(SoundTimerTicks, Lag);
end;
-if SoundTimerTicks >= 50 then
-begin
- SoundTimerTicks:= 0;
- if cVolumeDelta <> 0 then
- begin
- str(ChangeVolume(cVolumeDelta), s);
- AddCaption(Format(trmsg[sidVolume], s), cWhiteColor, capgrpVolume);
- end;
- if isAudioMuted then
- AddCaption(trmsg[sidMute], cWhiteColor, capgrpVolume)
-end;
if GameState = gsConfirm then
- DrawTextureCentered(0, (cScreenHeight shr 1), ConfirmTexture);
+ DrawTextureCentered(0, (cScreenHeight shr 1)-40, ConfirmTexture);
if ScreenFade <> sfNone then
begin
@@ -1614,6 +1617,7 @@ if isCursorVisible then
begin
if not bShowAmmoMenu then
begin
+ if not CurrentTeam^.ExtDriven then TargetCursorPoint:= CursorPoint;
with CurrentHedgehog^ do
if (Gear <> nil) and ((Gear^.State and gstHHChooseTarget) <> 0) then
begin
@@ -1622,9 +1626,9 @@ if isCursorVisible then
i:= GetCurAmmoEntry(CurrentHedgehog^)^.Pos;
with Ammoz[CurAmmoType] do
if PosCount > 1 then
- DrawSprite(PosSprite, CursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - CursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i);
+ DrawSprite(PosSprite, TargetCursorPoint.X - (SpritesData[PosSprite].Width shr 1), cScreenHeight - TargetCursorPoint.Y - (SpritesData[PosSprite].Height shr 1),i);
end;
- DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8)
+ DrawSprite(sprArrow, TargetCursorPoint.X, cScreenHeight - TargetCursorPoint.Y, (RealTicks shr 6) mod 8)
end
end;
isFirstFrame:= false
@@ -1636,7 +1640,7 @@ procedure MoveCamera;
var EdgesDist, wdy, shs,z, amNumOffsetX, amNumOffsetY: LongInt;
begin
{$IFNDEF MOBILE}
-if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu))) and cHasFocus and (GameState <> gsConfirm) then
+if (not (CurrentTeam^.ExtDriven and isCursorVisible and (not bShowAmmoMenu) and autoCameraOn)) and cHasFocus and (GameState <> gsConfirm) then
uCursor.updatePosition();
{$ENDIF}
z:= round(200/zoom);
@@ -1707,7 +1711,8 @@ else
EdgesDist:= cGearScrEdgesDist;
// this generates the border around the screen that moves the camera when cursor is near it
-if isCursorVisible or ((FollowGear <> nil) and autoCameraOn) then
+if (CurrentTeam^.ExtDriven and isCursorVisible and autoCameraOn) or
+ (not CurrentTeam^.ExtDriven and isCursorVisible) or ((FollowGear <> nil) and autoCameraOn) then
begin
if CursorPoint.X < - cScreenWidth div 2 + EdgesDist then
begin
diff --git a/misc/Android.mk b/misc/Android.mk
index 295f430..e820fa8 100644
--- a/misc/Android.mk
+++ b/misc/Android.mk
@@ -4,3 +4,6 @@ LOCAL_PATH := MISC_DIR
include $(MISC_DIR)/libfreetype/Android.mk
include $(MISC_DIR)/liblua/Android.mk
include $(MISC_DIR)/libtremor/Android.mk
+include $(MISC_DIR)/libphysfs/Android.mk
+include $(MISC_DIR)/libphyslayer/Android.mk
+
diff --git a/misc/hedgewars.desktop b/misc/hedgewars.desktop
deleted file mode 100644
index 6403c00..0000000
--- a/misc/hedgewars.desktop
+++ /dev/null
@@ -1,23 +0,0 @@
-[Desktop Entry]
-Type=Application
-Version=1.0
-Encoding=UTF-8
-Name=Hedgewars
-GenericName=Fighting Hedgehogs
-GenericName[de]=Kämpfende Igel
-GenericName[es]=Batallas entre erizos
-GenericName[fr]=Bataille de hérissons
-GenericName[ko]=ê³ ì´ëì¹ ì¸ì°ê¸°
-GenericName[ja]=ãã¡ã¤ãã³ã°ããªããºã
-GenericName[it]=Ricci combattenti
-GenericName[pl]=WalczÄ
ce jeże
-GenericName[pt]=Batalhas entre ouriços
-GenericName[ru]=ÐиÑÐ²Ñ ÐµÐ¶ÐµÐ¹
-GenericName[sk]=Bojujúci ježkovia
-GenericName[cs]=BojujÃcà ježci
-GenericName[sv]=Stridande igelkottar
-Icon=hedgewars.png
-Exec=hedgewars
-Terminal=false
-StartupNotify=false
-Categories=Application;Game;StrategyGame;
diff --git a/misc/libfreetype/builds/amiga/src/base/ftdebug.c b/misc/libfreetype/builds/amiga/src/base/ftdebug.c
new file mode 100644
index 0000000..5284e69
--- /dev/null
+++ b/misc/libfreetype/builds/amiga/src/base/ftdebug.c
@@ -0,0 +1,279 @@
+/***************************************************************************/
+/* */
+/* ftdebug.c */
+/* */
+/* Debugging and logging component (body). */
+/* */
+/* Copyright 1996-2001, 2002, 2004, 2005 by */
+/* David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This component contains various macros and functions used to ease the */
+ /* debugging of the FreeType engine. Its main purpose is in assertion */
+ /* checking, tracing, and error detection. */
+ /* */
+ /* There are now three debugging modes: */
+ /* */
+ /* - trace mode */
+ /* */
+ /* Error and trace messages are sent to the log file (which can be the */
+ /* standard error output). */
+ /* */
+ /* - error mode */
+ /* */
+ /* Only error messages are generated. */
+ /* */
+ /* - release mode: */
+ /* */
+ /* No error message is sent or generated. The code is free from any */
+ /* debugging parts. */
+ /* */
+ /*************************************************************************/
+
+
+/*
+ * Based on the default ftdebug.c,
+ * replaced vprintf() with KVPrintF(),
+ * commented out exit(),
+ * replaced getenv() with GetVar().
+ */
+
+#include <exec/types.h>
+#include <utility/tagitem.h>
+#include <dos/exall.h>
+#include <dos/var.h>
+#define __NOLIBBASE__
+#define __NOLOBALIFACE__
+#define __USE_INLINE__
+#include <proto/dos.h>
+#include <clib/debug_protos.h>
+
+#ifndef __amigaos4__
+extern struct Library *DOSBase;
+#else
+extern struct DOSIFace *IDOS;
+#endif
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
+
+
+#if defined( FT_DEBUG_LEVEL_ERROR )
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( void )
+ FT_Message( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+/* vprintf( fmt, ap ); */
+ KVPrintF( fmt, ap );
+ va_end( ap );
+ }
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( void )
+ FT_Panic( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+/* vprintf( fmt, ap ); */
+ KVPrintF( fmt, ap );
+ va_end( ap );
+
+/* exit( EXIT_FAILURE ); */
+ }
+
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ /* array of trace levels, initialized to 0 */
+ int ft_trace_levels[trace_count];
+
+
+ /* define array of trace toggle names */
+#define FT_TRACE_DEF( x ) #x ,
+
+ static const char* ft_trace_toggles[trace_count + 1] =
+ {
+#include FT_INTERNAL_TRACE_H
+ NULL
+ };
+
+#undef FT_TRACE_DEF
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( FT_Int )
+ FT_Trace_Get_Count( void )
+ {
+ return trace_count;
+ }
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( const char * )
+ FT_Trace_Get_Name( FT_Int idx )
+ {
+ int max = FT_Trace_Get_Count();
+
+
+ if ( idx < max )
+ return ft_trace_toggles[idx];
+ else
+ return NULL;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Initialize the tracing sub-system. This is done by retrieving the */
+ /* value of the `FT2_DEBUG' environment variable. It must be a list of */
+ /* toggles, separated by spaces, `;', or `,'. Example: */
+ /* */
+ /* export FT2_DEBUG="any:3 memory:7 stream:5" */
+ /* */
+ /* This requests that all levels be set to 3, except the trace level for */
+ /* the memory and stream components which are set to 7 and 5, */
+ /* respectively. */
+ /* */
+ /* See the file <include/freetype/internal/fttrace.h> for details of the */
+ /* available toggle names. */
+ /* */
+ /* The level must be between 0 and 7; 0 means quiet (except for serious */
+ /* runtime errors), and 7 means _very_ verbose. */
+ /* */
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+/* const char* ft2_debug = getenv( "FT2_DEBUG" ); */
+ char buf[256];
+ const char* ft2_debug = &buf[0];
+
+
+/* if ( ft2_debug ) */
+ if ( GetVar( "FT2_DEBUG", (STRPTR)ft2_debug, 256, LV_VAR ) > 0 )
+ {
+ const char* p = ft2_debug;
+ const char* q;
+
+
+ for ( ; *p; p++ )
+ {
+ /* skip leading whitespace and separators */
+ if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
+ continue;
+
+ /* read toggle name, followed by ':' */
+ q = p;
+ while ( *p && *p != ':' )
+ p++;
+
+ if ( *p == ':' && p > q )
+ {
+ FT_Int n, i, len = (FT_Int)( p - q );
+ FT_Int level = -1, found = -1;
+
+
+ for ( n = 0; n < trace_count; n++ )
+ {
+ const char* toggle = ft_trace_toggles[n];
+
+
+ for ( i = 0; i < len; i++ )
+ {
+ if ( toggle[i] != q[i] )
+ break;
+ }
+
+ if ( i == len && toggle[i] == 0 )
+ {
+ found = n;
+ break;
+ }
+ }
+
+ /* read level */
+ p++;
+ if ( *p )
+ {
+ level = *p++ - '0';
+ if ( level < 0 || level > 7 )
+ level = -1;
+ }
+
+ if ( found >= 0 && level >= 0 )
+ {
+ if ( found == trace_any )
+ {
+ /* special case for `any' */
+ for ( n = 0; n < trace_count; n++ )
+ ft_trace_levels[n] = level;
+ }
+ else
+ ft_trace_levels[found] = level;
+ }
+ }
+ }
+ }
+ }
+
+
+#else /* !FT_DEBUG_LEVEL_TRACE */
+
+
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ /* nothing */
+ }
+
+
+ FT_BASE_DEF( FT_Int )
+ FT_Trace_Get_Count( void )
+ {
+ return 0;
+ }
+
+
+ FT_BASE_DEF( const char * )
+ FT_Trace_Get_Name( FT_Int idx )
+ {
+ FT_UNUSED( idx );
+
+ return NULL;
+ }
+
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
+
+/*
+Local Variables:
+coding: latin-1
+End:
+*/
+/* END */
diff --git a/misc/libfreetype/builds/win32/ftdebug.c b/misc/libfreetype/builds/win32/ftdebug.c
new file mode 100644
index 0000000..d1ca15a
--- /dev/null
+++ b/misc/libfreetype/builds/win32/ftdebug.c
@@ -0,0 +1,214 @@
+/***************************************************************************/
+/* */
+/* ftdebug.c */
+/* */
+/* Debugging and logging component for Win32 (body). */
+/* */
+/* Copyright 1996-2001, 2002, 2005, 2008, 2009 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This component contains various macros and functions used to ease the */
+ /* debugging of the FreeType engine. Its main purpose is in assertion */
+ /* checking, tracing, and error detection. */
+ /* */
+ /* There are now three debugging modes: */
+ /* */
+ /* - trace mode */
+ /* */
+ /* Error and trace messages are sent to the log file (which can be the */
+ /* standard error output). */
+ /* */
+ /* - error mode */
+ /* */
+ /* Only error messages are generated. */
+ /* */
+ /* - release mode: */
+ /* */
+ /* No error message is sent or generated. The code is free from any */
+ /* debugging parts. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <windows.h>
+
+
+ FT_BASE_DEF( void )
+ FT_Message( const char* fmt, ... )
+ {
+ static char buf[8192];
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ /* send the string to the debugger as well */
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringA( buf );
+ va_end( ap );
+ }
+
+
+ FT_BASE_DEF( void )
+ FT_Panic( const char* fmt, ... )
+ {
+ static char buf[8192];
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringA( buf );
+ va_end( ap );
+
+ exit( EXIT_FAILURE );
+ }
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+
+ /* array of trace levels, initialized to 0 */
+ int ft_trace_levels[trace_count];
+
+ /* define array of trace toggle names */
+#define FT_TRACE_DEF( x ) #x ,
+
+ static const char* ft_trace_toggles[trace_count + 1] =
+ {
+#include FT_INTERNAL_TRACE_H
+ NULL
+ };
+
+#undef FT_TRACE_DEF
+
+
+ /*************************************************************************/
+ /* */
+ /* Initialize the tracing sub-system. This is done by retrieving the */
+ /* value of the "FT2_DEBUG" environment variable. It must be a list of */
+ /* toggles, separated by spaces, `;' or `,'. Example: */
+ /* */
+ /* "any:3 memory:6 stream:5" */
+ /* */
+ /* This will request that all levels be set to 3, except the trace level */
+ /* for the memory and stream components which are set to 6 and 5, */
+ /* respectively. */
+ /* */
+ /* See the file <freetype/internal/fttrace.h> for details of the */
+ /* available toggle names. */
+ /* */
+ /* The level must be between 0 and 6; 0 means quiet (except for serious */
+ /* runtime errors), and 6 means _very_ verbose. */
+ /* */
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ const char* ft2_debug = getenv( "FT2_DEBUG" );
+
+
+ if ( ft2_debug )
+ {
+ const char* p = ft2_debug;
+ const char* q;
+
+
+ for ( ; *p; p++ )
+ {
+ /* skip leading whitespace and separators */
+ if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
+ continue;
+
+ /* read toggle name, followed by ':' */
+ q = p;
+ while ( *p && *p != ':' )
+ p++;
+
+ if ( *p == ':' && p > q )
+ {
+ int n, i, len = p - q;
+ int level = -1, found = -1;
+
+
+ for ( n = 0; n < trace_count; n++ )
+ {
+ const char* toggle = ft_trace_toggles[n];
+
+
+ for ( i = 0; i < len; i++ )
+ {
+ if ( toggle[i] != q[i] )
+ break;
+ }
+
+ if ( i == len && toggle[i] == 0 )
+ {
+ found = n;
+ break;
+ }
+ }
+
+ /* read level */
+ p++;
+ if ( *p )
+ {
+ level = *p++ - '0';
+ if ( level < 0 || level > 7 )
+ level = -1;
+ }
+
+ if ( found >= 0 && level >= 0 )
+ {
+ if ( found == trace_any )
+ {
+ /* special case for "any" */
+ for ( n = 0; n < trace_count; n++ )
+ ft_trace_levels[n] = level;
+ }
+ else
+ ft_trace_levels[found] = level;
+ }
+ }
+ }
+ }
+ }
+
+
+#else /* !FT_DEBUG_LEVEL_TRACE */
+
+
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ /* nothing */
+ }
+
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
+
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
+/* END */
diff --git a/misc/libfreetype/builds/wince/ftdebug.c b/misc/libfreetype/builds/wince/ftdebug.c
new file mode 100644
index 0000000..272415d
--- /dev/null
+++ b/misc/libfreetype/builds/wince/ftdebug.c
@@ -0,0 +1,236 @@
+/***************************************************************************/
+/* */
+/* ftdebug.c */
+/* */
+/* Debugging and logging component for WinCE (body). */
+/* */
+/* Copyright 1996-2001, 2002, 2005, 2008, 2009 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This component contains various macros and functions used to ease the */
+ /* debugging of the FreeType engine. Its main purpose is in assertion */
+ /* checking, tracing, and error detection. */
+ /* */
+ /* There are now three debugging modes: */
+ /* */
+ /* - trace mode */
+ /* */
+ /* Error and trace messages are sent to the log file (which can be the */
+ /* standard error output). */
+ /* */
+ /* - error mode */
+ /* */
+ /* Only error messages are generated. */
+ /* */
+ /* - release mode: */
+ /* */
+ /* No error message is sent or generated. The code is free from any */
+ /* debugging parts. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <windows.h>
+
+
+ void
+ OutputDebugStringEx( const char* str )
+ {
+ static WCHAR buf[8192];
+
+
+ int sz = MultiByteToWideChar( CP_ACP, 0, str, -1, buf,
+ sizeof ( buf ) / sizeof ( *buf ) );
+ if ( !sz )
+ lstrcpyW( buf, L"OutputDebugStringEx: MultiByteToWideChar failed" );
+
+ OutputDebugStringW( buf );
+ }
+
+
+ FT_BASE_DEF( void )
+ FT_Message( const char* fmt, ... )
+ {
+ static char buf[8192];
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vprintf( fmt, ap );
+ /* send the string to the debugger as well */
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringEx( buf );
+ va_end( ap );
+ }
+
+
+ FT_BASE_DEF( void )
+ FT_Panic( const char* fmt, ... )
+ {
+ static char buf[8192];
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vsprintf( buf, fmt, ap );
+ OutputDebugStringEx( buf );
+ va_end( ap );
+
+ exit( EXIT_FAILURE );
+ }
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+
+ /* array of trace levels, initialized to 0 */
+ int ft_trace_levels[trace_count];
+
+ /* define array of trace toggle names */
+#define FT_TRACE_DEF( x ) #x ,
+
+ static const char* ft_trace_toggles[trace_count + 1] =
+ {
+#include FT_INTERNAL_TRACE_H
+ NULL
+ };
+
+#undef FT_TRACE_DEF
+
+
+ /*************************************************************************/
+ /* */
+ /* Initialize the tracing sub-system. This is done by retrieving the */
+ /* value of the "FT2_DEBUG" environment variable. It must be a list of */
+ /* toggles, separated by spaces, `;' or `,'. Example: */
+ /* */
+ /* "any:3 memory:6 stream:5" */
+ /* */
+ /* This will request that all levels be set to 3, except the trace level */
+ /* for the memory and stream components which are set to 6 and 5, */
+ /* respectively. */
+ /* */
+ /* See the file <freetype/internal/fttrace.h> for details of the */
+ /* available toggle names. */
+ /* */
+ /* The level must be between 0 and 6; 0 means quiet (except for serious */
+ /* runtime errors), and 6 means _very_ verbose. */
+ /* */
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ /* Windows Mobile doesn't have environment API: */
+ /* GetEnvironmentStrings, GetEnvironmentVariable, getenv. */
+ /* */
+ /* FIXME!!! How to set debug mode? */
+
+ /* const char* ft2_debug = getenv( "FT2_DEBUG" ); */
+
+ const char* ft2_debug = 0;
+
+
+ if ( ft2_debug )
+ {
+ const char* p = ft2_debug;
+ const char* q;
+
+
+ for ( ; *p; p++ )
+ {
+ /* skip leading whitespace and separators */
+ if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
+ continue;
+
+ /* read toggle name, followed by ':' */
+ q = p;
+ while ( *p && *p != ':' )
+ p++;
+
+ if ( *p == ':' && p > q )
+ {
+ int n, i, len = p - q;
+ int level = -1, found = -1;
+
+
+ for ( n = 0; n < trace_count; n++ )
+ {
+ const char* toggle = ft_trace_toggles[n];
+
+
+ for ( i = 0; i < len; i++ )
+ {
+ if ( toggle[i] != q[i] )
+ break;
+ }
+
+ if ( i == len && toggle[i] == 0 )
+ {
+ found = n;
+ break;
+ }
+ }
+
+ /* read level */
+ p++;
+ if ( *p )
+ {
+ level = *p++ - '0';
+ if ( level < 0 || level > 7 )
+ level = -1;
+ }
+
+ if ( found >= 0 && level >= 0 )
+ {
+ if ( found == trace_any )
+ {
+ /* special case for "any" */
+ for ( n = 0; n < trace_count; n++ )
+ ft_trace_levels[n] = level;
+ }
+ else
+ ft_trace_levels[found] = level;
+ }
+ }
+ }
+ }
+ }
+
+
+#else /* !FT_DEBUG_LEVEL_TRACE */
+
+
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ /* nothing */
+ }
+
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
+
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
+/* END */
diff --git a/misc/libfreetype/include/freetype/internal/ftdebug.h b/misc/libfreetype/include/freetype/internal/ftdebug.h
new file mode 100644
index 0000000..7baae35
--- /dev/null
+++ b/misc/libfreetype/include/freetype/internal/ftdebug.h
@@ -0,0 +1,250 @@
+/***************************************************************************/
+/* */
+/* ftdebug.h */
+/* */
+/* Debugging and logging component (specification). */
+/* */
+/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008, 2009 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/* */
+/* IMPORTANT: A description of FreeType's debugging support can be */
+/* found in `docs/DEBUG.TXT'. Read it if you need to use or */
+/* understand this code. */
+/* */
+/***************************************************************************/
+
+
+#ifndef __FTDEBUG_H__
+#define __FTDEBUG_H__
+
+
+#include <ft2build.h>
+#include FT_CONFIG_CONFIG_H
+#include FT_FREETYPE_H
+
+
+FT_BEGIN_HEADER
+
+
+ /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */
+ /* is already defined; this simplifies the following #ifdefs */
+ /* */
+#ifdef FT_DEBUG_LEVEL_TRACE
+#undef FT_DEBUG_LEVEL_ERROR
+#define FT_DEBUG_LEVEL_ERROR
+#endif
+
+
+ /*************************************************************************/
+ /* */
+ /* Define the trace enums as well as the trace levels array when they */
+ /* are needed. */
+ /* */
+ /*************************************************************************/
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#define FT_TRACE_DEF( x ) trace_ ## x ,
+
+ /* defining the enumeration */
+ typedef enum FT_Trace_
+ {
+#include FT_INTERNAL_TRACE_H
+ trace_count
+
+ } FT_Trace;
+
+
+ /* defining the array of trace levels, provided by `src/base/ftdebug.c' */
+ extern int ft_trace_levels[trace_count];
+
+#undef FT_TRACE_DEF
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+
+ /*************************************************************************/
+ /* */
+ /* Define the FT_TRACE macro */
+ /* */
+ /* IMPORTANT! */
+ /* */
+ /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */
+ /* value before using any TRACE macro. */
+ /* */
+ /*************************************************************************/
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+#define FT_TRACE( level, varformat ) \
+ do \
+ { \
+ if ( ft_trace_levels[FT_COMPONENT] >= level ) \
+ FT_Message varformat; \
+ } while ( 0 )
+
+#else /* !FT_DEBUG_LEVEL_TRACE */
+
+#define FT_TRACE( level, varformat ) do { } while ( 0 ) /* nothing */
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Trace_Get_Count */
+ /* */
+ /* <Description> */
+ /* Return the number of available trace components. */
+ /* */
+ /* <Return> */
+ /* The number of trace components. 0 if FreeType 2 is not built with */
+ /* FT_DEBUG_LEVEL_TRACE definition. */
+ /* */
+ /* <Note> */
+ /* This function may be useful if you want to access elements of */
+ /* the internal `ft_trace_levels' array by an index. */
+ /* */
+ FT_BASE( FT_Int )
+ FT_Trace_Get_Count( void );
+
+
+ /*************************************************************************/
+ /* */
+ /* <Function> */
+ /* FT_Trace_Get_Name */
+ /* */
+ /* <Description> */
+ /* Return the name of a trace component. */
+ /* */
+ /* <Input> */
+ /* The index of the trace component. */
+ /* */
+ /* <Return> */
+ /* The name of the trace component. This is a statically allocated */
+ /* C string, so do not free it after use. NULL if FreeType 2 is not */
+ /* built with FT_DEBUG_LEVEL_TRACE definition. */
+ /* */
+ /* <Note> */
+ /* Use @FT_Trace_Get_Count to get the number of available trace */
+ /* components. */
+ /* */
+ /* This function may be useful if you want to control FreeType 2's */
+ /* debug level in your application. */
+ /* */
+ FT_BASE( const char * )
+ FT_Trace_Get_Name( FT_Int idx );
+
+
+ /*************************************************************************/
+ /* */
+ /* You need two opening and closing parentheses! */
+ /* */
+ /* Example: FT_TRACE0(( "Value is %i", foo )) */
+ /* */
+ /* Output of the FT_TRACEX macros is sent to stderr. */
+ /* */
+ /*************************************************************************/
+
+#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat )
+#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat )
+#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat )
+#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat )
+#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat )
+#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat )
+#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat )
+#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat )
+
+
+ /*************************************************************************/
+ /* */
+ /* Define the FT_ERROR macro. */
+ /* */
+ /* Output of this macro is sent to stderr. */
+ /* */
+ /*************************************************************************/
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+#define FT_ERROR( varformat ) FT_Message varformat
+
+#else /* !FT_DEBUG_LEVEL_ERROR */
+
+#define FT_ERROR( varformat ) do { } while ( 0 ) /* nothing */
+
+#endif /* !FT_DEBUG_LEVEL_ERROR */
+
+
+ /*************************************************************************/
+ /* */
+ /* Define the FT_ASSERT macro. */
+ /* */
+ /*************************************************************************/
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+#define FT_ASSERT( condition ) \
+ do \
+ { \
+ if ( !( condition ) ) \
+ FT_Panic( "assertion failed on line %d of file %s\n", \
+ __LINE__, __FILE__ ); \
+ } while ( 0 )
+
+#else /* !FT_DEBUG_LEVEL_ERROR */
+
+#define FT_ASSERT( condition ) do { } while ( 0 )
+
+#endif /* !FT_DEBUG_LEVEL_ERROR */
+
+
+ /*************************************************************************/
+ /* */
+ /* Define `FT_Message' and `FT_Panic' when needed. */
+ /* */
+ /*************************************************************************/
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+#include "stdio.h" /* for vfprintf() */
+
+ /* print a message */
+ FT_BASE( void )
+ FT_Message( const char* fmt,
+ ... );
+
+ /* print a message and exit */
+ FT_BASE( void )
+ FT_Panic( const char* fmt,
+ ... );
+
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
+ FT_BASE( void )
+ ft_debug_init( void );
+
+
+#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
+
+ /* We disable the warning `conditional expression is constant' here */
+ /* in order to compile cleanly with the maximum level of warnings. */
+#pragma warning( disable : 4127 )
+
+#endif /* _MSC_VER */
+
+
+FT_END_HEADER
+
+#endif /* __FTDEBUG_H__ */
+
+
+/* END */
diff --git a/misc/libfreetype/src/base/ftdebug.c b/misc/libfreetype/src/base/ftdebug.c
new file mode 100644
index 0000000..2adbeab
--- /dev/null
+++ b/misc/libfreetype/src/base/ftdebug.c
@@ -0,0 +1,246 @@
+/***************************************************************************/
+/* */
+/* ftdebug.c */
+/* */
+/* Debugging and logging component (body). */
+/* */
+/* Copyright 1996-2001, 2002, 2004, 2008 by */
+/* David Turner, Robert Wilhelm, and Werner Lemberg. */
+/* */
+/* This file is part of the FreeType project, and may only be used, */
+/* modified, and distributed under the terms of the FreeType project */
+/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
+/* this file you indicate that you have read the license and */
+/* understand and accept it fully. */
+/* */
+/***************************************************************************/
+
+
+ /*************************************************************************/
+ /* */
+ /* This component contains various macros and functions used to ease the */
+ /* debugging of the FreeType engine. Its main purpose is in assertion */
+ /* checking, tracing, and error detection. */
+ /* */
+ /* There are now three debugging modes: */
+ /* */
+ /* - trace mode */
+ /* */
+ /* Error and trace messages are sent to the log file (which can be the */
+ /* standard error output). */
+ /* */
+ /* - error mode */
+ /* */
+ /* Only error messages are generated. */
+ /* */
+ /* - release mode: */
+ /* */
+ /* No error message is sent or generated. The code is free from any */
+ /* debugging parts. */
+ /* */
+ /*************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
+
+
+#ifdef FT_DEBUG_LEVEL_ERROR
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( void )
+ FT_Message( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vfprintf( stderr, fmt, ap );
+ va_end( ap );
+ }
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( void )
+ FT_Panic( const char* fmt, ... )
+ {
+ va_list ap;
+
+
+ va_start( ap, fmt );
+ vfprintf( stderr, fmt, ap );
+ va_end( ap );
+
+ exit( EXIT_FAILURE );
+ }
+
+#endif /* FT_DEBUG_LEVEL_ERROR */
+
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+ /* array of trace levels, initialized to 0 */
+ int ft_trace_levels[trace_count];
+
+
+ /* define array of trace toggle names */
+#define FT_TRACE_DEF( x ) #x ,
+
+ static const char* ft_trace_toggles[trace_count + 1] =
+ {
+#include FT_INTERNAL_TRACE_H
+ NULL
+ };
+
+#undef FT_TRACE_DEF
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( FT_Int )
+ FT_Trace_Get_Count( void )
+ {
+ return trace_count;
+ }
+
+
+ /* documentation is in ftdebug.h */
+
+ FT_BASE_DEF( const char * )
+ FT_Trace_Get_Name( FT_Int idx )
+ {
+ int max = FT_Trace_Get_Count();
+
+
+ if ( idx < max )
+ return ft_trace_toggles[idx];
+ else
+ return NULL;
+ }
+
+
+ /*************************************************************************/
+ /* */
+ /* Initialize the tracing sub-system. This is done by retrieving the */
+ /* value of the `FT2_DEBUG' environment variable. It must be a list of */
+ /* toggles, separated by spaces, `;', or `,'. Example: */
+ /* */
+ /* export FT2_DEBUG="any:3 memory:7 stream:5" */
+ /* */
+ /* This requests that all levels be set to 3, except the trace level for */
+ /* the memory and stream components which are set to 7 and 5, */
+ /* respectively. */
+ /* */
+ /* See the file <include/freetype/internal/fttrace.h> for details of the */
+ /* available toggle names. */
+ /* */
+ /* The level must be between 0 and 7; 0 means quiet (except for serious */
+ /* runtime errors), and 7 means _very_ verbose. */
+ /* */
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ const char* ft2_debug = getenv( "FT2_DEBUG" );
+
+
+ if ( ft2_debug )
+ {
+ const char* p = ft2_debug;
+ const char* q;
+
+
+ for ( ; *p; p++ )
+ {
+ /* skip leading whitespace and separators */
+ if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' )
+ continue;
+
+ /* read toggle name, followed by ':' */
+ q = p;
+ while ( *p && *p != ':' )
+ p++;
+
+ if ( *p == ':' && p > q )
+ {
+ FT_Int n, i, len = (FT_Int)( p - q );
+ FT_Int level = -1, found = -1;
+
+
+ for ( n = 0; n < trace_count; n++ )
+ {
+ const char* toggle = ft_trace_toggles[n];
+
+
+ for ( i = 0; i < len; i++ )
+ {
+ if ( toggle[i] != q[i] )
+ break;
+ }
+
+ if ( i == len && toggle[i] == 0 )
+ {
+ found = n;
+ break;
+ }
+ }
+
+ /* read level */
+ p++;
+ if ( *p )
+ {
+ level = *p++ - '0';
+ if ( level < 0 || level > 7 )
+ level = -1;
+ }
+
+ if ( found >= 0 && level >= 0 )
+ {
+ if ( found == trace_any )
+ {
+ /* special case for `any' */
+ for ( n = 0; n < trace_count; n++ )
+ ft_trace_levels[n] = level;
+ }
+ else
+ ft_trace_levels[found] = level;
+ }
+ }
+ }
+ }
+ }
+
+
+#else /* !FT_DEBUG_LEVEL_TRACE */
+
+
+ FT_BASE_DEF( void )
+ ft_debug_init( void )
+ {
+ /* nothing */
+ }
+
+
+ FT_BASE_DEF( FT_Int )
+ FT_Trace_Get_Count( void )
+ {
+ return 0;
+ }
+
+
+ FT_BASE_DEF( const char * )
+ FT_Trace_Get_Name( FT_Int idx )
+ {
+ FT_UNUSED( idx );
+
+ return NULL;
+ }
+
+
+#endif /* !FT_DEBUG_LEVEL_TRACE */
+
+
+/* END */
diff --git a/misc/liblua/Android.mk b/misc/liblua/Android.mk
new file mode 100644
index 0000000..de74aff
--- /dev/null
+++ b/misc/liblua/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := lua5.1
+
+LOCAL_CFLAGS := -DANDROID
+
+LOCAL_SRC_FILES := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c lvm.c lzio.c
+
+include $(BUILD_SHARED_LIBRARY)
+
+
diff --git a/misc/liblua/CMakeLists.txt b/misc/liblua/CMakeLists.txt
new file mode 100644
index 0000000..4bc3a99
--- /dev/null
+++ b/misc/liblua/CMakeLists.txt
@@ -0,0 +1,20 @@
+#this file is included only when system Lua library is not found
+
+file(GLOB lua_src *.c *.h)
+
+if(WIN32)
+ add_definitions(-DLUA_BUILD_AS_DLL)
+ add_library(lua SHARED ${lua_src})
+
+ set(LUA_LIBRARY lua.dll)
+
+ set_target_properties(lua PROPERTIES PREFIX "")
+ install(TARGETS lua RUNTIME DESTINATION ${target_library_install_dir})
+else(WIN32)
+ add_definitions(-DLUA_USE_LINUX)
+ add_library(lua STATIC ${lua_src})
+ set(LUA_LIBRARY lua)
+endif(WIN32)
+
+
+
diff --git a/misc/liblua/Xcode/Lua.xcodeproj/default.mode1v3 b/misc/liblua/Xcode/Lua.xcodeproj/default.mode1v3
new file mode 100644
index 0000000..64252df
--- /dev/null
+++ b/misc/liblua/Xcode/Lua.xcodeproj/default.mode1v3
@@ -0,0 +1,1357 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>BundlePath</key>
+ <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1v3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>619599841364E41A00B429B6</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1v3</string>
+ <key>MajorVersion</key>
+ <integer>33</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-combo-popup</string>
+ <string>active-executable-popup</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>buildOrClean</string>
+ <string>build-and-go</string>
+ <string>clean-target</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>0867D691FE84028FC02AAC07</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 445}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 463}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>2068 295 788 504 1920 0 1920 1200 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>203pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>MyNewFile14.java</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>MyNewFile14.java</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {580, 277}}</string>
+ <key>RubberWindowFrame</key>
+ <string>2068 295 788 504 1920 0 1920 1200 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>277pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 282}, {580, 181}}</string>
+ <key>RubberWindowFrame</key>
+ <string>2068 295 788 504 1920 0 1920 1200 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>181pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>580pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>619599821364E41A00B429B6</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>619599831364E41A00B429B6</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfigUserDefaultsMinorVersion</key>
+ <string>2</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.defaultV3</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.shortV3</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarConfigUserDefaultsMinorVersion</key>
+ <string>2</string>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>619599851364E41A00B429B6</string>
+ <string>/Users/vittorio/hedgewars/trunk/misc/liblua/Xcode/Lua.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>2068 295 788 504 1920 0 1920 1200 </string>
+ <key>WindowToolsV3</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {500, 218}}</string>
+ <key>RubberWindowFrame</key>
+ <string>2089 276 500 500 1920 0 1920 1200 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>218pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build Results</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 223}, {500, 236}}</string>
+ <key>RubberWindowFrame</key>
+ <string>2089 276 500 500 1920 0 1920 1200 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>236pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>459pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>619599851364E41A00B429B6</string>
+ <string>619599861364E41A00B429B6</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.buildV3</string>
+ <key>WindowContentMinSize</key>
+ <string>486 300</string>
+ <key>WindowString</key>
+ <string>2089 276 500 500 1920 0 1920 1200 </string>
+ <key>WindowToolGUID</key>
+ <string>619599851364E41A00B429B6</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {317, 164}}</string>
+ <string>{{317, 0}, {377, 164}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {694, 164}}</string>
+ <string>{{0, 164}, {694, 216}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleDrawerSize</key>
+ <string>{100, 120}</string>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {694, 380}}</string>
+ <key>RubberWindowFrame</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>1C0AD2AB069F1E9B00FABCE6</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>1C0AD2AC069F1E9B00FABCE6</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ <key>WindowString</key>
+ <string>321 238 694 422 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528D0623707200166675</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 167}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{8, 0}, {773, 254}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>428pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>1C530D58069F1CE1000CFCEE</string>
+ <string>1C530D59069F1CE1000CFCEE</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1C530D5A069F1CE1000CFCEE</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {650, 250}}</string>
+ <key>RubberWindowFrame</key>
+ <string>516 632 650 250 0 0 1680 1027 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>209pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>209pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>1C78EAAE065D492600B07095</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.consoleV3</string>
+ <key>WindowString</key>
+ <string>650 41 650 250 0 0 1280 1002 </string>
+ <key>WindowToolGUID</key>
+ <string>1C78EAAD065D492600B07095</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.snapshots</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Snapshots</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCSnapshotModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <string>Yes</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.snapshots</string>
+ <key>WindowString</key>
+ <string>315 824 300 550 0 0 1440 878 </string>
+ <key>WindowToolIsVisible</key>
+ <string>Yes</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.0950012207031</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>0</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>3</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <string>1CDDB66907F98D9800BB5817</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpointsV3</string>
+ <key>WindowString</key>
+ <string>315 424 744 409 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1CDDB66807F98D9800BB5817</string>
+ <key>WindowToolIsVisible</key>
+ <integer>1</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimatorV3</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.projectFormatConflicts</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Format Conflicts</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCProjectFormatConflictsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowContentMinSize</key>
+ <string>450 300</string>
+ <key>WindowString</key>
+ <string>50 850 472 307 0 0 1440 877</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {374, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 331}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 105}, {374, 395}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>97</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>PBXModuleWindowStatusBarHidden2</key>
+ <integer>1</integer>
+ <key>RubberWindowFrame</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>1C0AD2B0069F1E9B00FABCE6</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>385 179 630 352 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.refactoring</string>
+ <key>IncludeInToolsMenu</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{0, 0}, {500, 335}</string>
+ <key>RubberWindowFrame</key>
+ <string>{0, 0}, {500, 335}</string>
+ </dict>
+ <key>Module</key>
+ <string>XCRefactoringModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Refactoring</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCRefactoringModule</string>
+ </array>
+ <key>WindowString</key>
+ <string>200 200 500 356 0 0 1920 1200 </string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/misc/liblua/Xcode/Lua.xcodeproj/default.pbxuser b/misc/liblua/Xcode/Lua.xcodeproj/default.pbxuser
new file mode 100644
index 0000000..722cef9
--- /dev/null
+++ b/misc/liblua/Xcode/Lua.xcodeproj/default.pbxuser
@@ -0,0 +1,110 @@
+// !$*UTF8*$!
+{
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ activeBuildConfigurationName = Release;
+ activeSDKPreference = iphoneos4.2;
+ activeTarget = D2AAC07D0554694100DB518D /* libLua */;
+ addToTargets = (
+ D2AAC07D0554694100DB518D /* libLua */,
+ );
+ codeSenseManager = 619598BC1364C73500B429B6 /* Code sense */;
+ perUserDictionary = {
+ PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 341,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 301,
+ 60,
+ 20,
+ 48.16259765625,
+ 43,
+ 43,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXTargetDataSource_PrimaryAttribute,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ );
+ };
+ PBXPerProjectTemplateStateSaveDate = 325371811;
+ PBXWorkspaceStateSaveDate = 325371811;
+ };
+ perUserProjectItems = {
+ 619599331364C7D300B429B6 /* XCBuildMessageTextBookmark */ = 619599331364C7D300B429B6 /* XCBuildMessageTextBookmark */;
+ 6195995E1364C95D00B429B6 /* PBXTextBookmark */ = 6195995E1364C95D00B429B6 /* PBXTextBookmark */;
+ };
+ sourceControlManager = 619598BB1364C73500B429B6 /* Source Control */;
+ userBuildSettings = {
+ };
+ };
+ 619598BB1364C73500B429B6 /* Source Control */ = {
+ isa = PBXSourceControlManager;
+ fallbackIsa = XCSourceControlManager;
+ isSCMEnabled = 0;
+ scmConfiguration = {
+ repositoryNamesForRoots = {
+ "" = "";
+ };
+ };
+ };
+ 619598BC1364C73500B429B6 /* Code sense */ = {
+ isa = PBXCodeSenseManager;
+ indexTemplatePath = "";
+ };
+ 619598F61364C7BD00B429B6 /* lvm.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {439, 11745}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 214}";
+ };
+ };
+ 619599331364C7D300B429B6 /* XCBuildMessageTextBookmark */ = {
+ isa = PBXTextBookmark;
+ comments = "Compile /Users/vittorio/hedgewars/trunk/misc/liblua/Xcode/../lvm.c";
+ fRef = 619598F61364C7BD00B429B6 /* lvm.c */;
+ fallbackIsa = XCBuildMessageTextBookmark;
+ rLen = 0;
+ rLoc = 0;
+ rType = 1;
+ };
+ 6195995E1364C95D00B429B6 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619598F61364C7BD00B429B6 /* lvm.c */;
+ name = "lvm.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 233;
+ vrLoc = 0;
+ };
+ D2AAC07D0554694100DB518D /* libLua */ = {
+ activeExec = 0;
+ };
+}
diff --git a/misc/liblua/Xcode/Lua.xcodeproj/project.pbxproj b/misc/liblua/Xcode/Lua.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..089ed41
--- /dev/null
+++ b/misc/liblua/Xcode/Lua.xcodeproj/project.pbxproj
@@ -0,0 +1,445 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 619598FB1364C7BD00B429B6 /* lapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598C61364C7BD00B429B6 /* lapi.c */; };
+ 619598FC1364C7BD00B429B6 /* lapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598C71364C7BD00B429B6 /* lapi.h */; };
+ 619598FD1364C7BD00B429B6 /* lauxlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598C81364C7BD00B429B6 /* lauxlib.c */; };
+ 619598FE1364C7BD00B429B6 /* lauxlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598C91364C7BD00B429B6 /* lauxlib.h */; };
+ 619598FF1364C7BD00B429B6 /* lbaselib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598CA1364C7BD00B429B6 /* lbaselib.c */; };
+ 619599001364C7BD00B429B6 /* lcode.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598CB1364C7BD00B429B6 /* lcode.c */; };
+ 619599011364C7BD00B429B6 /* lcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598CC1364C7BD00B429B6 /* lcode.h */; };
+ 619599021364C7BD00B429B6 /* ldblib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598CD1364C7BD00B429B6 /* ldblib.c */; };
+ 619599031364C7BD00B429B6 /* ldebug.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598CE1364C7BD00B429B6 /* ldebug.c */; };
+ 619599041364C7BD00B429B6 /* ldebug.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598CF1364C7BD00B429B6 /* ldebug.h */; };
+ 619599051364C7BD00B429B6 /* ldo.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D01364C7BD00B429B6 /* ldo.c */; };
+ 619599061364C7BD00B429B6 /* ldo.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598D11364C7BD00B429B6 /* ldo.h */; };
+ 619599071364C7BD00B429B6 /* ldump.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D21364C7BD00B429B6 /* ldump.c */; };
+ 619599081364C7BD00B429B6 /* lfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D31364C7BD00B429B6 /* lfunc.c */; };
+ 619599091364C7BD00B429B6 /* lfunc.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598D41364C7BD00B429B6 /* lfunc.h */; };
+ 6195990A1364C7BD00B429B6 /* lgc.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D51364C7BD00B429B6 /* lgc.c */; };
+ 6195990B1364C7BD00B429B6 /* lgc.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598D61364C7BD00B429B6 /* lgc.h */; };
+ 6195990C1364C7BD00B429B6 /* linit.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D71364C7BD00B429B6 /* linit.c */; };
+ 6195990D1364C7BD00B429B6 /* liolib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D81364C7BD00B429B6 /* liolib.c */; };
+ 6195990E1364C7BD00B429B6 /* llex.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598D91364C7BD00B429B6 /* llex.c */; };
+ 6195990F1364C7BD00B429B6 /* llex.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598DA1364C7BD00B429B6 /* llex.h */; };
+ 619599101364C7BD00B429B6 /* llimits.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598DB1364C7BD00B429B6 /* llimits.h */; };
+ 619599111364C7BD00B429B6 /* lmathlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598DC1364C7BD00B429B6 /* lmathlib.c */; };
+ 619599121364C7BD00B429B6 /* lmem.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598DD1364C7BD00B429B6 /* lmem.c */; };
+ 619599131364C7BD00B429B6 /* lmem.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598DE1364C7BD00B429B6 /* lmem.h */; };
+ 619599141364C7BD00B429B6 /* loadlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598DF1364C7BD00B429B6 /* loadlib.c */; };
+ 619599151364C7BD00B429B6 /* lobject.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E01364C7BD00B429B6 /* lobject.c */; };
+ 619599161364C7BD00B429B6 /* lobject.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598E11364C7BD00B429B6 /* lobject.h */; };
+ 619599171364C7BD00B429B6 /* lopcodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E21364C7BD00B429B6 /* lopcodes.c */; };
+ 619599181364C7BD00B429B6 /* lopcodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598E31364C7BD00B429B6 /* lopcodes.h */; };
+ 619599191364C7BD00B429B6 /* loslib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E41364C7BD00B429B6 /* loslib.c */; };
+ 6195991A1364C7BD00B429B6 /* lparser.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E51364C7BD00B429B6 /* lparser.c */; };
+ 6195991B1364C7BD00B429B6 /* lparser.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598E61364C7BD00B429B6 /* lparser.h */; };
+ 6195991C1364C7BD00B429B6 /* lstate.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E71364C7BD00B429B6 /* lstate.c */; };
+ 6195991D1364C7BD00B429B6 /* lstate.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598E81364C7BD00B429B6 /* lstate.h */; };
+ 6195991E1364C7BD00B429B6 /* lstring.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598E91364C7BD00B429B6 /* lstring.c */; };
+ 6195991F1364C7BD00B429B6 /* lstring.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598EA1364C7BD00B429B6 /* lstring.h */; };
+ 619599201364C7BD00B429B6 /* lstrlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598EB1364C7BD00B429B6 /* lstrlib.c */; };
+ 619599211364C7BD00B429B6 /* ltable.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598EC1364C7BD00B429B6 /* ltable.c */; };
+ 619599221364C7BD00B429B6 /* ltable.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598ED1364C7BD00B429B6 /* ltable.h */; };
+ 619599231364C7BD00B429B6 /* ltablib.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598EE1364C7BD00B429B6 /* ltablib.c */; };
+ 619599241364C7BD00B429B6 /* ltm.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598EF1364C7BD00B429B6 /* ltm.c */; };
+ 619599251364C7BD00B429B6 /* ltm.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F01364C7BD00B429B6 /* ltm.h */; };
+ 619599261364C7BD00B429B6 /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F11364C7BD00B429B6 /* lua.h */; };
+ 619599271364C7BD00B429B6 /* luaconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F21364C7BD00B429B6 /* luaconf.h */; };
+ 619599281364C7BD00B429B6 /* lualib.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F31364C7BD00B429B6 /* lualib.h */; };
+ 619599291364C7BD00B429B6 /* lundump.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598F41364C7BD00B429B6 /* lundump.c */; };
+ 6195992A1364C7BD00B429B6 /* lundump.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F51364C7BD00B429B6 /* lundump.h */; };
+ 6195992B1364C7BD00B429B6 /* lvm.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598F61364C7BD00B429B6 /* lvm.c */; };
+ 6195992C1364C7BD00B429B6 /* lvm.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F71364C7BD00B429B6 /* lvm.h */; };
+ 6195992D1364C7BD00B429B6 /* lzio.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598F81364C7BD00B429B6 /* lzio.c */; };
+ 6195992E1364C7BD00B429B6 /* lzio.h in Headers */ = {isa = PBXBuildFile; fileRef = 619598F91364C7BD00B429B6 /* lzio.h */; };
+ 6195992F1364C7BD00B429B6 /* print.c in Sources */ = {isa = PBXBuildFile; fileRef = 619598FA1364C7BD00B429B6 /* print.c */; };
+ AA747D9F0F9514B9006C5449 /* Lua_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Lua_Prefix.pch */; };
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 619598C61364C7BD00B429B6 /* lapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lapi.c; path = ../lapi.c; sourceTree = SOURCE_ROOT; };
+ 619598C71364C7BD00B429B6 /* lapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lapi.h; path = ../lapi.h; sourceTree = SOURCE_ROOT; };
+ 619598C81364C7BD00B429B6 /* lauxlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lauxlib.c; path = ../lauxlib.c; sourceTree = SOURCE_ROOT; };
+ 619598C91364C7BD00B429B6 /* lauxlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lauxlib.h; path = ../lauxlib.h; sourceTree = SOURCE_ROOT; };
+ 619598CA1364C7BD00B429B6 /* lbaselib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lbaselib.c; path = ../lbaselib.c; sourceTree = SOURCE_ROOT; };
+ 619598CB1364C7BD00B429B6 /* lcode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lcode.c; path = ../lcode.c; sourceTree = SOURCE_ROOT; };
+ 619598CC1364C7BD00B429B6 /* lcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lcode.h; path = ../lcode.h; sourceTree = SOURCE_ROOT; };
+ 619598CD1364C7BD00B429B6 /* ldblib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldblib.c; path = ../ldblib.c; sourceTree = SOURCE_ROOT; };
+ 619598CE1364C7BD00B429B6 /* ldebug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldebug.c; path = ../ldebug.c; sourceTree = SOURCE_ROOT; };
+ 619598CF1364C7BD00B429B6 /* ldebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldebug.h; path = ../ldebug.h; sourceTree = SOURCE_ROOT; };
+ 619598D01364C7BD00B429B6 /* ldo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldo.c; path = ../ldo.c; sourceTree = SOURCE_ROOT; };
+ 619598D11364C7BD00B429B6 /* ldo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ldo.h; path = ../ldo.h; sourceTree = SOURCE_ROOT; };
+ 619598D21364C7BD00B429B6 /* ldump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ldump.c; path = ../ldump.c; sourceTree = SOURCE_ROOT; };
+ 619598D31364C7BD00B429B6 /* lfunc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lfunc.c; path = ../lfunc.c; sourceTree = SOURCE_ROOT; };
+ 619598D41364C7BD00B429B6 /* lfunc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lfunc.h; path = ../lfunc.h; sourceTree = SOURCE_ROOT; };
+ 619598D51364C7BD00B429B6 /* lgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lgc.c; path = ../lgc.c; sourceTree = SOURCE_ROOT; };
+ 619598D61364C7BD00B429B6 /* lgc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lgc.h; path = ../lgc.h; sourceTree = SOURCE_ROOT; };
+ 619598D71364C7BD00B429B6 /* linit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = linit.c; path = ../linit.c; sourceTree = SOURCE_ROOT; };
+ 619598D81364C7BD00B429B6 /* liolib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = liolib.c; path = ../liolib.c; sourceTree = SOURCE_ROOT; };
+ 619598D91364C7BD00B429B6 /* llex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = llex.c; path = ../llex.c; sourceTree = SOURCE_ROOT; };
+ 619598DA1364C7BD00B429B6 /* llex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llex.h; path = ../llex.h; sourceTree = SOURCE_ROOT; };
+ 619598DB1364C7BD00B429B6 /* llimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = llimits.h; path = ../llimits.h; sourceTree = SOURCE_ROOT; };
+ 619598DC1364C7BD00B429B6 /* lmathlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lmathlib.c; path = ../lmathlib.c; sourceTree = SOURCE_ROOT; };
+ 619598DD1364C7BD00B429B6 /* lmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lmem.c; path = ../lmem.c; sourceTree = SOURCE_ROOT; };
+ 619598DE1364C7BD00B429B6 /* lmem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lmem.h; path = ../lmem.h; sourceTree = SOURCE_ROOT; };
+ 619598DF1364C7BD00B429B6 /* loadlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = loadlib.c; path = ../loadlib.c; sourceTree = SOURCE_ROOT; };
+ 619598E01364C7BD00B429B6 /* lobject.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lobject.c; path = ../lobject.c; sourceTree = SOURCE_ROOT; };
+ 619598E11364C7BD00B429B6 /* lobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lobject.h; path = ../lobject.h; sourceTree = SOURCE_ROOT; };
+ 619598E21364C7BD00B429B6 /* lopcodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lopcodes.c; path = ../lopcodes.c; sourceTree = SOURCE_ROOT; };
+ 619598E31364C7BD00B429B6 /* lopcodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lopcodes.h; path = ../lopcodes.h; sourceTree = SOURCE_ROOT; };
+ 619598E41364C7BD00B429B6 /* loslib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = loslib.c; path = ../loslib.c; sourceTree = SOURCE_ROOT; };
+ 619598E51364C7BD00B429B6 /* lparser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lparser.c; path = ../lparser.c; sourceTree = SOURCE_ROOT; };
+ 619598E61364C7BD00B429B6 /* lparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lparser.h; path = ../lparser.h; sourceTree = SOURCE_ROOT; };
+ 619598E71364C7BD00B429B6 /* lstate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstate.c; path = ../lstate.c; sourceTree = SOURCE_ROOT; };
+ 619598E81364C7BD00B429B6 /* lstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstate.h; path = ../lstate.h; sourceTree = SOURCE_ROOT; };
+ 619598E91364C7BD00B429B6 /* lstring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstring.c; path = ../lstring.c; sourceTree = SOURCE_ROOT; };
+ 619598EA1364C7BD00B429B6 /* lstring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lstring.h; path = ../lstring.h; sourceTree = SOURCE_ROOT; };
+ 619598EB1364C7BD00B429B6 /* lstrlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lstrlib.c; path = ../lstrlib.c; sourceTree = SOURCE_ROOT; };
+ 619598EC1364C7BD00B429B6 /* ltable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltable.c; path = ../ltable.c; sourceTree = SOURCE_ROOT; };
+ 619598ED1364C7BD00B429B6 /* ltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltable.h; path = ../ltable.h; sourceTree = SOURCE_ROOT; };
+ 619598EE1364C7BD00B429B6 /* ltablib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltablib.c; path = ../ltablib.c; sourceTree = SOURCE_ROOT; };
+ 619598EF1364C7BD00B429B6 /* ltm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ltm.c; path = ../ltm.c; sourceTree = SOURCE_ROOT; };
+ 619598F01364C7BD00B429B6 /* ltm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ltm.h; path = ../ltm.h; sourceTree = SOURCE_ROOT; };
+ 619598F11364C7BD00B429B6 /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lua.h; path = ../lua.h; sourceTree = SOURCE_ROOT; };
+ 619598F21364C7BD00B429B6 /* luaconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = luaconf.h; path = ../luaconf.h; sourceTree = SOURCE_ROOT; };
+ 619598F31364C7BD00B429B6 /* lualib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lualib.h; path = ../lualib.h; sourceTree = SOURCE_ROOT; };
+ 619598F41364C7BD00B429B6 /* lundump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lundump.c; path = ../lundump.c; sourceTree = SOURCE_ROOT; };
+ 619598F51364C7BD00B429B6 /* lundump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lundump.h; path = ../lundump.h; sourceTree = SOURCE_ROOT; };
+ 619598F61364C7BD00B429B6 /* lvm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lvm.c; path = ../lvm.c; sourceTree = SOURCE_ROOT; };
+ 619598F71364C7BD00B429B6 /* lvm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lvm.h; path = ../lvm.h; sourceTree = SOURCE_ROOT; };
+ 619598F81364C7BD00B429B6 /* lzio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lzio.c; path = ../lzio.c; sourceTree = SOURCE_ROOT; };
+ 619598F91364C7BD00B429B6 /* lzio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lzio.h; path = ../lzio.h; sourceTree = SOURCE_ROOT; };
+ 619598FA1364C7BD00B429B6 /* print.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = print.c; path = ../print.c; sourceTree = SOURCE_ROOT; };
+ AA747D9E0F9514B9006C5449 /* Lua_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Lua_Prefix.pch; sourceTree = SOURCE_ROOT; };
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D2AAC07E0554694100DB518D /* libLua.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libLua.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D2AAC07C0554694100DB518D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DFFF38A50411DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D2AAC07E0554694100DB518D /* libLua.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* Lua */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AEFE84172EC02AAC07 /* Sources */,
+ 32C88DFF0371C24200C91783 /* Other Sources */,
+ 0867D69AFE84028FC02AAC07 /* Frameworks */,
+ 034768DFFF38A50411DB9C8B /* Products */,
+ );
+ name = Lua;
+ sourceTree = "<group>";
+ };
+ 0867D69AFE84028FC02AAC07 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 08FB77AEFE84172EC02AAC07 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 619598C61364C7BD00B429B6 /* lapi.c */,
+ 619598C71364C7BD00B429B6 /* lapi.h */,
+ 619598C81364C7BD00B429B6 /* lauxlib.c */,
+ 619598C91364C7BD00B429B6 /* lauxlib.h */,
+ 619598CA1364C7BD00B429B6 /* lbaselib.c */,
+ 619598CB1364C7BD00B429B6 /* lcode.c */,
+ 619598CC1364C7BD00B429B6 /* lcode.h */,
+ 619598CD1364C7BD00B429B6 /* ldblib.c */,
+ 619598CE1364C7BD00B429B6 /* ldebug.c */,
+ 619598CF1364C7BD00B429B6 /* ldebug.h */,
+ 619598D01364C7BD00B429B6 /* ldo.c */,
+ 619598D11364C7BD00B429B6 /* ldo.h */,
+ 619598D21364C7BD00B429B6 /* ldump.c */,
+ 619598D31364C7BD00B429B6 /* lfunc.c */,
+ 619598D41364C7BD00B429B6 /* lfunc.h */,
+ 619598D51364C7BD00B429B6 /* lgc.c */,
+ 619598D61364C7BD00B429B6 /* lgc.h */,
+ 619598D71364C7BD00B429B6 /* linit.c */,
+ 619598D81364C7BD00B429B6 /* liolib.c */,
+ 619598D91364C7BD00B429B6 /* llex.c */,
+ 619598DA1364C7BD00B429B6 /* llex.h */,
+ 619598DB1364C7BD00B429B6 /* llimits.h */,
+ 619598DC1364C7BD00B429B6 /* lmathlib.c */,
+ 619598DD1364C7BD00B429B6 /* lmem.c */,
+ 619598DE1364C7BD00B429B6 /* lmem.h */,
+ 619598DF1364C7BD00B429B6 /* loadlib.c */,
+ 619598E01364C7BD00B429B6 /* lobject.c */,
+ 619598E11364C7BD00B429B6 /* lobject.h */,
+ 619598E21364C7BD00B429B6 /* lopcodes.c */,
+ 619598E31364C7BD00B429B6 /* lopcodes.h */,
+ 619598E41364C7BD00B429B6 /* loslib.c */,
+ 619598E51364C7BD00B429B6 /* lparser.c */,
+ 619598E61364C7BD00B429B6 /* lparser.h */,
+ 619598E71364C7BD00B429B6 /* lstate.c */,
+ 619598E81364C7BD00B429B6 /* lstate.h */,
+ 619598E91364C7BD00B429B6 /* lstring.c */,
+ 619598EA1364C7BD00B429B6 /* lstring.h */,
+ 619598EB1364C7BD00B429B6 /* lstrlib.c */,
+ 619598EC1364C7BD00B429B6 /* ltable.c */,
+ 619598ED1364C7BD00B429B6 /* ltable.h */,
+ 619598EE1364C7BD00B429B6 /* ltablib.c */,
+ 619598EF1364C7BD00B429B6 /* ltm.c */,
+ 619598F01364C7BD00B429B6 /* ltm.h */,
+ 619598F11364C7BD00B429B6 /* lua.h */,
+ 619598F21364C7BD00B429B6 /* luaconf.h */,
+ 619598F31364C7BD00B429B6 /* lualib.h */,
+ 619598F41364C7BD00B429B6 /* lundump.c */,
+ 619598F51364C7BD00B429B6 /* lundump.h */,
+ 619598F61364C7BD00B429B6 /* lvm.c */,
+ 619598F71364C7BD00B429B6 /* lvm.h */,
+ 619598F81364C7BD00B429B6 /* lzio.c */,
+ 619598F91364C7BD00B429B6 /* lzio.h */,
+ 619598FA1364C7BD00B429B6 /* print.c */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 32C88DFF0371C24200C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ AA747D9E0F9514B9006C5449 /* Lua_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC07A0554694100DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AA747D9F0F9514B9006C5449 /* Lua_Prefix.pch in Headers */,
+ 619598FC1364C7BD00B429B6 /* lapi.h in Headers */,
+ 619598FE1364C7BD00B429B6 /* lauxlib.h in Headers */,
+ 619599011364C7BD00B429B6 /* lcode.h in Headers */,
+ 619599041364C7BD00B429B6 /* ldebug.h in Headers */,
+ 619599061364C7BD00B429B6 /* ldo.h in Headers */,
+ 619599091364C7BD00B429B6 /* lfunc.h in Headers */,
+ 6195990B1364C7BD00B429B6 /* lgc.h in Headers */,
+ 6195990F1364C7BD00B429B6 /* llex.h in Headers */,
+ 619599101364C7BD00B429B6 /* llimits.h in Headers */,
+ 619599131364C7BD00B429B6 /* lmem.h in Headers */,
+ 619599161364C7BD00B429B6 /* lobject.h in Headers */,
+ 619599181364C7BD00B429B6 /* lopcodes.h in Headers */,
+ 6195991B1364C7BD00B429B6 /* lparser.h in Headers */,
+ 6195991D1364C7BD00B429B6 /* lstate.h in Headers */,
+ 6195991F1364C7BD00B429B6 /* lstring.h in Headers */,
+ 619599221364C7BD00B429B6 /* ltable.h in Headers */,
+ 619599251364C7BD00B429B6 /* ltm.h in Headers */,
+ 619599261364C7BD00B429B6 /* lua.h in Headers */,
+ 619599271364C7BD00B429B6 /* luaconf.h in Headers */,
+ 619599281364C7BD00B429B6 /* lualib.h in Headers */,
+ 6195992A1364C7BD00B429B6 /* lundump.h in Headers */,
+ 6195992C1364C7BD00B429B6 /* lvm.h in Headers */,
+ 6195992E1364C7BD00B429B6 /* lzio.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC07D0554694100DB518D /* libLua */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libLua" */;
+ buildPhases = (
+ D2AAC07A0554694100DB518D /* Headers */,
+ D2AAC07B0554694100DB518D /* Sources */,
+ D2AAC07C0554694100DB518D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = libLua;
+ productName = Lua;
+ productReference = D2AAC07E0554694100DB518D /* libLua.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Lua" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 0867D691FE84028FC02AAC07 /* Lua */;
+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D2AAC07D0554694100DB518D /* libLua */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC07B0554694100DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 619598FB1364C7BD00B429B6 /* lapi.c in Sources */,
+ 619598FD1364C7BD00B429B6 /* lauxlib.c in Sources */,
+ 619598FF1364C7BD00B429B6 /* lbaselib.c in Sources */,
+ 619599001364C7BD00B429B6 /* lcode.c in Sources */,
+ 619599021364C7BD00B429B6 /* ldblib.c in Sources */,
+ 619599031364C7BD00B429B6 /* ldebug.c in Sources */,
+ 619599051364C7BD00B429B6 /* ldo.c in Sources */,
+ 619599071364C7BD00B429B6 /* ldump.c in Sources */,
+ 619599081364C7BD00B429B6 /* lfunc.c in Sources */,
+ 6195990A1364C7BD00B429B6 /* lgc.c in Sources */,
+ 6195990C1364C7BD00B429B6 /* linit.c in Sources */,
+ 6195990D1364C7BD00B429B6 /* liolib.c in Sources */,
+ 6195990E1364C7BD00B429B6 /* llex.c in Sources */,
+ 619599111364C7BD00B429B6 /* lmathlib.c in Sources */,
+ 619599121364C7BD00B429B6 /* lmem.c in Sources */,
+ 619599141364C7BD00B429B6 /* loadlib.c in Sources */,
+ 619599151364C7BD00B429B6 /* lobject.c in Sources */,
+ 619599171364C7BD00B429B6 /* lopcodes.c in Sources */,
+ 619599191364C7BD00B429B6 /* loslib.c in Sources */,
+ 6195991A1364C7BD00B429B6 /* lparser.c in Sources */,
+ 6195991C1364C7BD00B429B6 /* lstate.c in Sources */,
+ 6195991E1364C7BD00B429B6 /* lstring.c in Sources */,
+ 619599201364C7BD00B429B6 /* lstrlib.c in Sources */,
+ 619599211364C7BD00B429B6 /* ltable.c in Sources */,
+ 619599231364C7BD00B429B6 /* ltablib.c in Sources */,
+ 619599241364C7BD00B429B6 /* ltm.c in Sources */,
+ 619599291364C7BD00B429B6 /* lundump.c in Sources */,
+ 6195992B1364C7BD00B429B6 /* lvm.c in Sources */,
+ 6195992D1364C7BD00B429B6 /* lzio.c in Sources */,
+ 6195992F1364C7BD00B429B6 /* print.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB921F08733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = NO;
+ DSTROOT = /tmp/Lua.dst;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Lua_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Lua;
+ };
+ name = Debug;
+ };
+ 1DEB922008733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ DSTROOT = /tmp/Lua.dst;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Lua_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Lua;
+ };
+ name = Release;
+ };
+ 1DEB922308733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 1DEB922408733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_FAST_MATH = YES;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "libLua" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB921F08733DC00010E9CD /* Debug */,
+ 1DEB922008733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Lua" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB922308733DC00010E9CD /* Debug */,
+ 1DEB922408733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch b/misc/liblua/Xcode/Lua_Prefix.pch
similarity index 100%
copy from misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch
copy to misc/liblua/Xcode/Lua_Prefix.pch
diff --git a/misc/liblua/lapi.c b/misc/liblua/lapi.c
new file mode 100644
index 0000000..86ebb51
--- /dev/null
+++ b/misc/liblua/lapi.c
@@ -0,0 +1,1087 @@
+/*
+** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $
+** Lua API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define lapi_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+
+
+
+const char lua_ident[] =
+ "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
+ "$Authors: " LUA_AUTHORS " $\n"
+ "$URL: www.lua.org $\n";
+
+
+
+#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
+
+#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)
+
+#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
+
+
+
+static TValue *index2adr (lua_State *L, int idx) {
+ if (idx > 0) {
+ TValue *o = L->base + (idx - 1);
+ api_check(L, idx <= L->ci->top - L->base);
+ if (o >= L->top) return cast(TValue *, luaO_nilobject);
+ else return o;
+ }
+ else if (idx > LUA_REGISTRYINDEX) {
+ api_check(L, idx != 0 && -idx <= L->top - L->base);
+ return L->top + idx;
+ }
+ else switch (idx) { /* pseudo-indices */
+ case LUA_REGISTRYINDEX: return registry(L);
+ case LUA_ENVIRONINDEX: {
+ Closure *func = curr_func(L);
+ sethvalue(L, &L->env, func->c.env);
+ return &L->env;
+ }
+ case LUA_GLOBALSINDEX: return gt(L);
+ default: {
+ Closure *func = curr_func(L);
+ idx = LUA_GLOBALSINDEX - idx;
+ return (idx <= func->c.nupvalues)
+ ? &func->c.upvalue[idx-1]
+ : cast(TValue *, luaO_nilobject);
+ }
+ }
+}
+
+
+static Table *getcurrenv (lua_State *L) {
+ if (L->ci == L->base_ci) /* no enclosing function? */
+ return hvalue(gt(L)); /* use global table as environment */
+ else {
+ Closure *func = curr_func(L);
+ return func->c.env;
+ }
+}
+
+
+void luaA_pushobject (lua_State *L, const TValue *o) {
+ setobj2s(L, L->top, o);
+ api_incr_top(L);
+}
+
+
+LUA_API int lua_checkstack (lua_State *L, int size) {
+ int res = 1;
+ lua_lock(L);
+ if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK)
+ res = 0; /* stack overflow */
+ else if (size > 0) {
+ luaD_checkstack(L, size);
+ if (L->ci->top < L->top + size)
+ L->ci->top = L->top + size;
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
+ int i;
+ if (from == to) return;
+ lua_lock(to);
+ api_checknelems(from, n);
+ api_check(from, G(from) == G(to));
+ api_check(from, to->ci->top - to->top >= n);
+ from->top -= n;
+ for (i = 0; i < n; i++) {
+ setobj2s(to, to->top++, from->top + i);
+ }
+ lua_unlock(to);
+}
+
+
+LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
+ to->nCcalls = from->nCcalls;
+}
+
+
+LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
+ lua_CFunction old;
+ lua_lock(L);
+ old = G(L)->panic;
+ G(L)->panic = panicf;
+ lua_unlock(L);
+ return old;
+}
+
+
+LUA_API lua_State *lua_newthread (lua_State *L) {
+ lua_State *L1;
+ lua_lock(L);
+ luaC_checkGC(L);
+ L1 = luaE_newthread(L);
+ setthvalue(L, L->top, L1);
+ api_incr_top(L);
+ lua_unlock(L);
+ luai_userstatethread(L, L1);
+ return L1;
+}
+
+
+
+/*
+** basic stack manipulation
+*/
+
+
+LUA_API int lua_gettop (lua_State *L) {
+ return cast_int(L->top - L->base);
+}
+
+
+LUA_API void lua_settop (lua_State *L, int idx) {
+ lua_lock(L);
+ if (idx >= 0) {
+ api_check(L, idx <= L->stack_last - L->base);
+ while (L->top < L->base + idx)
+ setnilvalue(L->top++);
+ L->top = L->base + idx;
+ }
+ else {
+ api_check(L, -(idx+1) <= (L->top - L->base));
+ L->top += idx+1; /* `subtract' index (index is negative) */
+ }
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_remove (lua_State *L, int idx) {
+ StkId p;
+ lua_lock(L);
+ p = index2adr(L, idx);
+ api_checkvalidindex(L, p);
+ while (++p < L->top) setobjs2s(L, p-1, p);
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_insert (lua_State *L, int idx) {
+ StkId p;
+ StkId q;
+ lua_lock(L);
+ p = index2adr(L, idx);
+ api_checkvalidindex(L, p);
+ for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
+ setobjs2s(L, p, L->top);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_replace (lua_State *L, int idx) {
+ StkId o;
+ lua_lock(L);
+ /* explicit test for incompatible code */
+ if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
+ luaG_runerror(L, "no calling environment");
+ api_checknelems(L, 1);
+ o = index2adr(L, idx);
+ api_checkvalidindex(L, o);
+ if (idx == LUA_ENVIRONINDEX) {
+ Closure *func = curr_func(L);
+ api_check(L, ttistable(L->top - 1));
+ func->c.env = hvalue(L->top - 1);
+ luaC_barrier(L, func, L->top - 1);
+ }
+ else {
+ setobj(L, o, L->top - 1);
+ if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
+ luaC_barrier(L, curr_func(L), L->top - 1);
+ }
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushvalue (lua_State *L, int idx) {
+ lua_lock(L);
+ setobj2s(L, L->top, index2adr(L, idx));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+
+/*
+** access functions (stack -> C)
+*/
+
+
+LUA_API int lua_type (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
+}
+
+
+LUA_API const char *lua_typename (lua_State *L, int t) {
+ UNUSED(L);
+ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
+}
+
+
+LUA_API int lua_iscfunction (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ return iscfunction(o);
+}
+
+
+LUA_API int lua_isnumber (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = index2adr(L, idx);
+ return tonumber(o, &n);
+}
+
+
+LUA_API int lua_isstring (lua_State *L, int idx) {
+ int t = lua_type(L, idx);
+ return (t == LUA_TSTRING || t == LUA_TNUMBER);
+}
+
+
+LUA_API int lua_isuserdata (lua_State *L, int idx) {
+ const TValue *o = index2adr(L, idx);
+ return (ttisuserdata(o) || ttislightuserdata(o));
+}
+
+
+LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
+ StkId o1 = index2adr(L, index1);
+ StkId o2 = index2adr(L, index2);
+ return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
+ : luaO_rawequalObj(o1, o2);
+}
+
+
+LUA_API int lua_equal (lua_State *L, int index1, int index2) {
+ StkId o1, o2;
+ int i;
+ lua_lock(L); /* may call tag method */
+ o1 = index2adr(L, index1);
+ o2 = index2adr(L, index2);
+ i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
+ lua_unlock(L);
+ return i;
+}
+
+
+LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
+ StkId o1, o2;
+ int i;
+ lua_lock(L); /* may call tag method */
+ o1 = index2adr(L, index1);
+ o2 = index2adr(L, index2);
+ i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
+ : luaV_lessthan(L, o1, o2);
+ lua_unlock(L);
+ return i;
+}
+
+
+
+LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = index2adr(L, idx);
+ if (tonumber(o, &n))
+ return nvalue(o);
+ else
+ return 0;
+}
+
+
+LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = index2adr(L, idx);
+ if (tonumber(o, &n)) {
+ lua_Integer res;
+ lua_Number num = nvalue(o);
+ lua_number2integer(res, num);
+ return res;
+ }
+ else
+ return 0;
+}
+
+
+LUA_API int lua_toboolean (lua_State *L, int idx) {
+ const TValue *o = index2adr(L, idx);
+ return !l_isfalse(o);
+}
+
+
+LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
+ StkId o = index2adr(L, idx);
+ if (!ttisstring(o)) {
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+ if (!luaV_tostring(L, o)) { /* conversion failed? */
+ if (len != NULL) *len = 0;
+ lua_unlock(L);
+ return NULL;
+ }
+ luaC_checkGC(L);
+ o = index2adr(L, idx); /* previous call may reallocate the stack */
+ lua_unlock(L);
+ }
+ if (len != NULL) *len = tsvalue(o)->len;
+ return svalue(o);
+}
+
+
+LUA_API size_t lua_objlen (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ switch (ttype(o)) {
+ case LUA_TSTRING: return tsvalue(o)->len;
+ case LUA_TUSERDATA: return uvalue(o)->len;
+ case LUA_TTABLE: return luaH_getn(hvalue(o));
+ case LUA_TNUMBER: {
+ size_t l;
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+ l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
+ lua_unlock(L);
+ return l;
+ }
+ default: return 0;
+ }
+}
+
+
+LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
+}
+
+
+LUA_API void *lua_touserdata (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ switch (ttype(o)) {
+ case LUA_TUSERDATA: return (rawuvalue(o) + 1);
+ case LUA_TLIGHTUSERDATA: return pvalue(o);
+ default: return NULL;
+ }
+}
+
+
+LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ return (!ttisthread(o)) ? NULL : thvalue(o);
+}
+
+
+LUA_API const void *lua_topointer (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+ switch (ttype(o)) {
+ case LUA_TTABLE: return hvalue(o);
+ case LUA_TFUNCTION: return clvalue(o);
+ case LUA_TTHREAD: return thvalue(o);
+ case LUA_TUSERDATA:
+ case LUA_TLIGHTUSERDATA:
+ return lua_touserdata(L, idx);
+ default: return NULL;
+ }
+}
+
+
+
+/*
+** push functions (C -> stack)
+*/
+
+
+LUA_API void lua_pushnil (lua_State *L) {
+ lua_lock(L);
+ setnilvalue(L->top);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+ lua_lock(L);
+ setnvalue(L->top, n);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
+ lua_lock(L);
+ setnvalue(L->top, cast_num(n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushstring (lua_State *L, const char *s) {
+ if (s == NULL)
+ lua_pushnil(L);
+ else
+ lua_pushlstring(L, s, strlen(s));
+}
+
+
+LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp) {
+ const char *ret;
+ lua_lock(L);
+ luaC_checkGC(L);
+ ret = luaO_pushvfstring(L, fmt, argp);
+ lua_unlock(L);
+ return ret;
+}
+
+
+LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
+ const char *ret;
+ va_list argp;
+ lua_lock(L);
+ luaC_checkGC(L);
+ va_start(argp, fmt);
+ ret = luaO_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ lua_unlock(L);
+ return ret;
+}
+
+
+LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
+ Closure *cl;
+ lua_lock(L);
+ luaC_checkGC(L);
+ api_checknelems(L, n);
+ cl = luaF_newCclosure(L, n, getcurrenv(L));
+ cl->c.f = fn;
+ L->top -= n;
+ while (n--)
+ setobj2n(L, &cl->c.upvalue[n], L->top+n);
+ setclvalue(L, L->top, cl);
+ lua_assert(iswhite(obj2gco(cl)));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushboolean (lua_State *L, int b) {
+ lua_lock(L);
+ setbvalue(L->top, (b != 0)); /* ensure that true is 1 */
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
+ lua_lock(L);
+ setpvalue(L->top, p);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API int lua_pushthread (lua_State *L) {
+ lua_lock(L);
+ setthvalue(L, L->top, L);
+ api_incr_top(L);
+ lua_unlock(L);
+ return (G(L)->mainthread == L);
+}
+
+
+
+/*
+** get functions (Lua -> stack)
+*/
+
+
+LUA_API void lua_gettable (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ t = index2adr(L, idx);
+ api_checkvalidindex(L, t);
+ luaV_gettable(L, t, L->top - 1, L->top - 1);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
+ StkId t;
+ TValue key;
+ lua_lock(L);
+ t = index2adr(L, idx);
+ api_checkvalidindex(L, t);
+ setsvalue(L, &key, luaS_new(L, k));
+ luaV_gettable(L, t, &key, L->top);
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawget (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ t = index2adr(L, idx);
+ api_check(L, ttistable(t));
+ setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
+ StkId o;
+ lua_lock(L);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+ setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
+ lua_lock(L);
+ luaC_checkGC(L);
+ sethvalue(L, L->top, luaH_new(L, narray, nrec));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+LUA_API int lua_getmetatable (lua_State *L, int objindex) {
+ const TValue *obj;
+ Table *mt = NULL;
+ int res;
+ lua_lock(L);
+ obj = index2adr(L, objindex);
+ switch (ttype(obj)) {
+ case LUA_TTABLE:
+ mt = hvalue(obj)->metatable;
+ break;
+ case LUA_TUSERDATA:
+ mt = uvalue(obj)->metatable;
+ break;
+ default:
+ mt = G(L)->mt[ttype(obj)];
+ break;
+ }
+ if (mt == NULL)
+ res = 0;
+ else {
+ sethvalue(L, L->top, mt);
+ api_incr_top(L);
+ res = 1;
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+LUA_API void lua_getfenv (lua_State *L, int idx) {
+ StkId o;
+ lua_lock(L);
+ o = index2adr(L, idx);
+ api_checkvalidindex(L, o);
+ switch (ttype(o)) {
+ case LUA_TFUNCTION:
+ sethvalue(L, L->top, clvalue(o)->c.env);
+ break;
+ case LUA_TUSERDATA:
+ sethvalue(L, L->top, uvalue(o)->env);
+ break;
+ case LUA_TTHREAD:
+ setobj2s(L, L->top, gt(thvalue(o)));
+ break;
+ default:
+ setnilvalue(L->top);
+ break;
+ }
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
+/*
+** set functions (stack -> Lua)
+*/
+
+
+LUA_API void lua_settable (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 2);
+ t = index2adr(L, idx);
+ api_checkvalidindex(L, t);
+ luaV_settable(L, t, L->top - 2, L->top - 1);
+ L->top -= 2; /* pop index and value */
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
+ StkId t;
+ TValue key;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = index2adr(L, idx);
+ api_checkvalidindex(L, t);
+ setsvalue(L, &key, luaS_new(L, k));
+ luaV_settable(L, t, &key, L->top - 1);
+ L->top--; /* pop value */
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawset (lua_State *L, int idx) {
+ StkId t;
+ lua_lock(L);
+ api_checknelems(L, 2);
+ t = index2adr(L, idx);
+ api_check(L, ttistable(t));
+ setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
+ luaC_barriert(L, hvalue(t), L->top-1);
+ L->top -= 2;
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
+ StkId o;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+ setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
+ luaC_barriert(L, hvalue(o), L->top-1);
+ L->top--;
+ lua_unlock(L);
+}
+
+
+LUA_API int lua_setmetatable (lua_State *L, int objindex) {
+ TValue *obj;
+ Table *mt;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ obj = index2adr(L, objindex);
+ api_checkvalidindex(L, obj);
+ if (ttisnil(L->top - 1))
+ mt = NULL;
+ else {
+ api_check(L, ttistable(L->top - 1));
+ mt = hvalue(L->top - 1);
+ }
+ switch (ttype(obj)) {
+ case LUA_TTABLE: {
+ hvalue(obj)->metatable = mt;
+ if (mt)
+ luaC_objbarriert(L, hvalue(obj), mt);
+ break;
+ }
+ case LUA_TUSERDATA: {
+ uvalue(obj)->metatable = mt;
+ if (mt)
+ luaC_objbarrier(L, rawuvalue(obj), mt);
+ break;
+ }
+ default: {
+ G(L)->mt[ttype(obj)] = mt;
+ break;
+ }
+ }
+ L->top--;
+ lua_unlock(L);
+ return 1;
+}
+
+
+LUA_API int lua_setfenv (lua_State *L, int idx) {
+ StkId o;
+ int res = 1;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = index2adr(L, idx);
+ api_checkvalidindex(L, o);
+ api_check(L, ttistable(L->top - 1));
+ switch (ttype(o)) {
+ case LUA_TFUNCTION:
+ clvalue(o)->c.env = hvalue(L->top - 1);
+ break;
+ case LUA_TUSERDATA:
+ uvalue(o)->env = hvalue(L->top - 1);
+ break;
+ case LUA_TTHREAD:
+ sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1));
+ break;
+ default:
+ res = 0;
+ break;
+ }
+ if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
+ L->top--;
+ lua_unlock(L);
+ return res;
+}
+
+
+/*
+** `load' and `call' functions (run Lua code)
+*/
+
+
+#define adjustresults(L,nres) \
+ { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; }
+
+
+#define checkresults(L,na,nr) \
+ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
+
+
+LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
+ StkId func;
+ lua_lock(L);
+ api_checknelems(L, nargs+1);
+ checkresults(L, nargs, nresults);
+ func = L->top - (nargs+1);
+ luaD_call(L, func, nresults);
+ adjustresults(L, nresults);
+ lua_unlock(L);
+}
+
+
+
+/*
+** Execute a protected call.
+*/
+struct CallS { /* data to `f_call' */
+ StkId func;
+ int nresults;
+};
+
+
+static void f_call (lua_State *L, void *ud) {
+ struct CallS *c = cast(struct CallS *, ud);
+ luaD_call(L, c->func, c->nresults);
+}
+
+
+
+LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
+ struct CallS c;
+ int status;
+ ptrdiff_t func;
+ lua_lock(L);
+ api_checknelems(L, nargs+1);
+ checkresults(L, nargs, nresults);
+ if (errfunc == 0)
+ func = 0;
+ else {
+ StkId o = index2adr(L, errfunc);
+ api_checkvalidindex(L, o);
+ func = savestack(L, o);
+ }
+ c.func = L->top - (nargs+1); /* function to be called */
+ c.nresults = nresults;
+ status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
+ adjustresults(L, nresults);
+ lua_unlock(L);
+ return status;
+}
+
+
+/*
+** Execute a protected C call.
+*/
+struct CCallS { /* data to `f_Ccall' */
+ lua_CFunction func;
+ void *ud;
+};
+
+
+static void f_Ccall (lua_State *L, void *ud) {
+ struct CCallS *c = cast(struct CCallS *, ud);
+ Closure *cl;
+ cl = luaF_newCclosure(L, 0, getcurrenv(L));
+ cl->c.f = c->func;
+ setclvalue(L, L->top, cl); /* push function */
+ api_incr_top(L);
+ setpvalue(L->top, c->ud); /* push only argument */
+ api_incr_top(L);
+ luaD_call(L, L->top - 2, 0);
+}
+
+
+LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
+ struct CCallS c;
+ int status;
+ lua_lock(L);
+ c.func = func;
+ c.ud = ud;
+ status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
+ const char *chunkname) {
+ ZIO z;
+ int status;
+ lua_lock(L);
+ if (!chunkname) chunkname = "?";
+ luaZ_init(L, &z, reader, data);
+ status = luaD_protectedparser(L, &z, chunkname);
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
+ int status;
+ TValue *o;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ o = L->top - 1;
+ if (isLfunction(o))
+ status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
+ else
+ status = 1;
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_status (lua_State *L) {
+ return L->status;
+}
+
+
+/*
+** Garbage-collection function
+*/
+
+LUA_API int lua_gc (lua_State *L, int what, int data) {
+ int res = 0;
+ global_State *g;
+ lua_lock(L);
+ g = G(L);
+ switch (what) {
+ case LUA_GCSTOP: {
+ g->GCthreshold = MAX_LUMEM;
+ break;
+ }
+ case LUA_GCRESTART: {
+ g->GCthreshold = g->totalbytes;
+ break;
+ }
+ case LUA_GCCOLLECT: {
+ luaC_fullgc(L);
+ break;
+ }
+ case LUA_GCCOUNT: {
+ /* GC values are expressed in Kbytes: #bytes/2^10 */
+ res = cast_int(g->totalbytes >> 10);
+ break;
+ }
+ case LUA_GCCOUNTB: {
+ res = cast_int(g->totalbytes & 0x3ff);
+ break;
+ }
+ case LUA_GCSTEP: {
+ lu_mem a = (cast(lu_mem, data) << 10);
+ if (a <= g->totalbytes)
+ g->GCthreshold = g->totalbytes - a;
+ else
+ g->GCthreshold = 0;
+ while (g->GCthreshold <= g->totalbytes) {
+ luaC_step(L);
+ if (g->gcstate == GCSpause) { /* end of cycle? */
+ res = 1; /* signal it */
+ break;
+ }
+ }
+ break;
+ }
+ case LUA_GCSETPAUSE: {
+ res = g->gcpause;
+ g->gcpause = data;
+ break;
+ }
+ case LUA_GCSETSTEPMUL: {
+ res = g->gcstepmul;
+ g->gcstepmul = data;
+ break;
+ }
+ default: res = -1; /* invalid option */
+ }
+ lua_unlock(L);
+ return res;
+}
+
+
+
+/*
+** miscellaneous functions
+*/
+
+
+LUA_API int lua_error (lua_State *L) {
+ lua_lock(L);
+ api_checknelems(L, 1);
+ luaG_errormsg(L);
+ lua_unlock(L);
+ return 0; /* to avoid warnings */
+}
+
+
+LUA_API int lua_next (lua_State *L, int idx) {
+ StkId t;
+ int more;
+ lua_lock(L);
+ t = index2adr(L, idx);
+ api_check(L, ttistable(t));
+ more = luaH_next(L, hvalue(t), L->top - 1);
+ if (more) {
+ api_incr_top(L);
+ }
+ else /* no more elements */
+ L->top -= 1; /* remove key */
+ lua_unlock(L);
+ return more;
+}
+
+
+LUA_API void lua_concat (lua_State *L, int n) {
+ lua_lock(L);
+ api_checknelems(L, n);
+ if (n >= 2) {
+ luaC_checkGC(L);
+ luaV_concat(L, n, cast_int(L->top - L->base) - 1);
+ L->top -= (n-1);
+ }
+ else if (n == 0) { /* push empty string */
+ setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
+ api_incr_top(L);
+ }
+ /* else n == 1; nothing to do */
+ lua_unlock(L);
+}
+
+
+LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
+ lua_Alloc f;
+ lua_lock(L);
+ if (ud) *ud = G(L)->ud;
+ f = G(L)->frealloc;
+ lua_unlock(L);
+ return f;
+}
+
+
+LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
+ lua_lock(L);
+ G(L)->ud = ud;
+ G(L)->frealloc = f;
+ lua_unlock(L);
+}
+
+
+LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
+ Udata *u;
+ lua_lock(L);
+ luaC_checkGC(L);
+ u = luaS_newudata(L, size, getcurrenv(L));
+ setuvalue(L, L->top, u);
+ api_incr_top(L);
+ lua_unlock(L);
+ return u + 1;
+}
+
+
+
+
+static const char *aux_upvalue (StkId fi, int n, TValue **val) {
+ Closure *f;
+ if (!ttisfunction(fi)) return NULL;
+ f = clvalue(fi);
+ if (f->c.isC) {
+ if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
+ *val = &f->c.upvalue[n-1];
+ return "";
+ }
+ else {
+ Proto *p = f->l.p;
+ if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
+ *val = f->l.upvals[n-1]->v;
+ return getstr(p->upvalues[n-1]);
+ }
+}
+
+
+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
+ const char *name;
+ TValue *val;
+ lua_lock(L);
+ name = aux_upvalue(index2adr(L, funcindex), n, &val);
+ if (name) {
+ setobj2s(L, L->top, val);
+ api_incr_top(L);
+ }
+ lua_unlock(L);
+ return name;
+}
+
+
+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
+ const char *name;
+ TValue *val;
+ StkId fi;
+ lua_lock(L);
+ fi = index2adr(L, funcindex);
+ api_checknelems(L, 1);
+ name = aux_upvalue(fi, n, &val);
+ if (name) {
+ L->top--;
+ setobj(L, val, L->top);
+ luaC_barrier(L, clvalue(fi), L->top);
+ }
+ lua_unlock(L);
+ return name;
+}
+
diff --git a/misc/liblua/lapi.h b/misc/liblua/lapi.h
new file mode 100644
index 0000000..2c3fab2
--- /dev/null
+++ b/misc/liblua/lapi.h
@@ -0,0 +1,16 @@
+/*
+** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
+** Auxiliary functions from Lua API
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lapi_h
+#define lapi_h
+
+
+#include "lobject.h"
+
+
+LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
+
+#endif
diff --git a/misc/liblua/lauxlib.c b/misc/liblua/lauxlib.c
new file mode 100644
index 0000000..10f14e2
--- /dev/null
+++ b/misc/liblua/lauxlib.c
@@ -0,0 +1,652 @@
+/*
+** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* This file uses only the official API of Lua.
+** Any function declared here could be written as an application function.
+*/
+
+#define lauxlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+
+
+#define FREELIST_REF 0 /* free list of references */
+
+
+/* convert a stack index to positive */
+#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
+ lua_gettop(L) + (i) + 1)
+
+
+/*
+** {======================================================
+** Error-report functions
+** =======================================================
+*/
+
+
+LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
+ lua_Debug ar;
+ if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
+ return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
+ lua_getinfo(L, "n", &ar);
+ if (strcmp(ar.namewhat, "method") == 0) {
+ narg--; /* do not count `self' */
+ if (narg == 0) /* error is in the self argument itself? */
+ return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
+ ar.name, extramsg);
+ }
+ if (ar.name == NULL)
+ ar.name = "?";
+ return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
+ narg, ar.name, extramsg);
+}
+
+
+LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
+ tname, luaL_typename(L, narg));
+ return luaL_argerror(L, narg, msg);
+}
+
+
+static void tag_error (lua_State *L, int narg, int tag) {
+ luaL_typerror(L, narg, lua_typename(L, tag));
+}
+
+
+LUALIB_API void luaL_where (lua_State *L, int level) {
+ lua_Debug ar;
+ if (lua_getstack(L, level, &ar)) { /* check function at level */
+ lua_getinfo(L, "Sl", &ar); /* get info about it */
+ if (ar.currentline > 0) { /* is there info? */
+ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
+ return;
+ }
+ }
+ lua_pushliteral(L, ""); /* else, no information available... */
+}
+
+
+LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ luaL_where(L, 1);
+ lua_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ lua_concat(L, 2);
+ return lua_error(L);
+}
+
+/* }====================================================== */
+
+
+LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
+ const char *const lst[]) {
+ const char *name = (def) ? luaL_optstring(L, narg, def) :
+ luaL_checkstring(L, narg);
+ int i;
+ for (i=0; lst[i]; i++)
+ if (strcmp(lst[i], name) == 0)
+ return i;
+ return luaL_argerror(L, narg,
+ lua_pushfstring(L, "invalid option " LUA_QS, name));
+}
+
+
+LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
+ if (!lua_isnil(L, -1)) /* name already in use? */
+ return 0; /* leave previous value on top, but return 0 */
+ lua_pop(L, 1);
+ lua_newtable(L); /* create metatable */
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
+ return 1;
+}
+
+
+LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
+ void *p = lua_touserdata(L, ud);
+ if (p != NULL) { /* value is a userdata? */
+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return p;
+ }
+ }
+ }
+ luaL_typerror(L, ud, tname); /* else error */
+ return NULL; /* to avoid warnings */
+}
+
+
+LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
+ if (!lua_checkstack(L, space))
+ luaL_error(L, "stack overflow (%s)", mes);
+}
+
+
+LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
+ if (lua_type(L, narg) != t)
+ tag_error(L, narg, t);
+}
+
+
+LUALIB_API void luaL_checkany (lua_State *L, int narg) {
+ if (lua_type(L, narg) == LUA_TNONE)
+ luaL_argerror(L, narg, "value expected");
+}
+
+
+LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
+ const char *s = lua_tolstring(L, narg, len);
+ if (!s) tag_error(L, narg, LUA_TSTRING);
+ return s;
+}
+
+
+LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
+ const char *def, size_t *len) {
+ if (lua_isnoneornil(L, narg)) {
+ if (len)
+ *len = (def ? strlen(def) : 0);
+ return def;
+ }
+ else return luaL_checklstring(L, narg, len);
+}
+
+
+LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
+ lua_Number d = lua_tonumber(L, narg);
+ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
+ tag_error(L, narg, LUA_TNUMBER);
+ return d;
+}
+
+
+LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
+ return luaL_opt(L, luaL_checknumber, narg, def);
+}
+
+
+LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
+ lua_Integer d = lua_tointeger(L, narg);
+ if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
+ tag_error(L, narg, LUA_TNUMBER);
+ return d;
+}
+
+
+LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
+ lua_Integer def) {
+ return luaL_opt(L, luaL_checkinteger, narg, def);
+}
+
+
+LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+ if (!lua_getmetatable(L, obj)) /* no metatable? */
+ return 0;
+ lua_pushstring(L, event);
+ lua_rawget(L, -2);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 2); /* remove metatable and metafield */
+ return 0;
+ }
+ else {
+ lua_remove(L, -2); /* remove only metatable */
+ return 1;
+ }
+}
+
+
+LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
+ obj = abs_index(L, obj);
+ if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
+ return 0;
+ lua_pushvalue(L, obj);
+ lua_call(L, 1, 1);
+ return 1;
+}
+
+
+LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
+ const luaL_Reg *l) {
+ luaI_openlib(L, libname, l, 0);
+}
+
+
+static int libsize (const luaL_Reg *l) {
+ int size = 0;
+ for (; l->name; l++) size++;
+ return size;
+}
+
+
+LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup) {
+ if (libname) {
+ int size = libsize(l);
+ /* check whether lib already exists */
+ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
+ lua_getfield(L, -1, libname); /* get _LOADED[libname] */
+ if (!lua_istable(L, -1)) { /* not found? */
+ lua_pop(L, 1); /* remove previous result */
+ /* try global variable (and create one if it does not exist) */
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
+ luaL_error(L, "name conflict for module " LUA_QS, libname);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
+ }
+ lua_remove(L, -2); /* remove _LOADED table */
+ lua_insert(L, -(nup+1)); /* move library table to below upvalues */
+ }
+ for (; l->name; l++) {
+ int i;
+ for (i=0; i<nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(L, -nup);
+ lua_pushcclosure(L, l->func, nup);
+ lua_setfield(L, -(nup+2), l->name);
+ }
+ lua_pop(L, nup); /* remove upvalues */
+}
+
+
+
+/*
+** {======================================================
+** getn-setn: size for arrays
+** =======================================================
+*/
+
+#if defined(LUA_COMPAT_GETN)
+
+static int checkint (lua_State *L, int topop) {
+ int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
+ lua_pop(L, topop);
+ return n;
+}
+
+
+static void getsizes (lua_State *L) {
+ lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
+ if (lua_isnil(L, -1)) { /* no `size' table? */
+ lua_pop(L, 1); /* remove nil */
+ lua_newtable(L); /* create it */
+ lua_pushvalue(L, -1); /* `size' will be its own metatable */
+ lua_setmetatable(L, -2);
+ lua_pushliteral(L, "kv");
+ lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */
+ }
+}
+
+
+LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
+ t = abs_index(L, t);
+ lua_pushliteral(L, "n");
+ lua_rawget(L, t);
+ if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
+ lua_pushliteral(L, "n"); /* use it */
+ lua_pushinteger(L, n);
+ lua_rawset(L, t);
+ }
+ else { /* use `sizes' */
+ getsizes(L);
+ lua_pushvalue(L, t);
+ lua_pushinteger(L, n);
+ lua_rawset(L, -3); /* sizes[t] = n */
+ lua_pop(L, 1); /* remove `sizes' */
+ }
+}
+
+
+LUALIB_API int luaL_getn (lua_State *L, int t) {
+ int n;
+ t = abs_index(L, t);
+ lua_pushliteral(L, "n"); /* try t.n */
+ lua_rawget(L, t);
+ if ((n = checkint(L, 1)) >= 0) return n;
+ getsizes(L); /* else try sizes[t] */
+ lua_pushvalue(L, t);
+ lua_rawget(L, -2);
+ if ((n = checkint(L, 2)) >= 0) return n;
+ return (int)lua_objlen(L, t);
+}
+
+#endif
+
+/* }====================================================== */
+
+
+
+LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
+ const char *r) {
+ const char *wild;
+ size_t l = strlen(p);
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ while ((wild = strstr(s, p)) != NULL) {
+ luaL_addlstring(&b, s, wild - s); /* push prefix */
+ luaL_addstring(&b, r); /* push replacement in place of pattern */
+ s = wild + l; /* continue after `p' */
+ }
+ luaL_addstring(&b, s); /* push last suffix */
+ luaL_pushresult(&b);
+ return lua_tostring(L, -1);
+}
+
+
+LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
+ const char *fname, int szhint) {
+ const char *e;
+ lua_pushvalue(L, idx);
+ do {
+ e = strchr(fname, '.');
+ if (e == NULL) e = fname + strlen(fname);
+ lua_pushlstring(L, fname, e - fname);
+ lua_rawget(L, -2);
+ if (lua_isnil(L, -1)) { /* no such field? */
+ lua_pop(L, 1); /* remove this nil */
+ lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
+ lua_pushlstring(L, fname, e - fname);
+ lua_pushvalue(L, -2);
+ lua_settable(L, -4); /* set new table into field */
+ }
+ else if (!lua_istable(L, -1)) { /* field has a non-table value? */
+ lua_pop(L, 2); /* remove table and value */
+ return fname; /* return problematic part of the name */
+ }
+ lua_remove(L, -2); /* remove previous table */
+ fname = e + 1;
+ } while (*e == '.');
+ return NULL;
+}
+
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+
+#define bufflen(B) ((B)->p - (B)->buffer)
+#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
+
+#define LIMIT (LUA_MINSTACK/2)
+
+
+static int emptybuffer (luaL_Buffer *B) {
+ size_t l = bufflen(B);
+ if (l == 0) return 0; /* put nothing on stack */
+ else {
+ lua_pushlstring(B->L, B->buffer, l);
+ B->p = B->buffer;
+ B->lvl++;
+ return 1;
+ }
+}
+
+
+static void adjuststack (luaL_Buffer *B) {
+ if (B->lvl > 1) {
+ lua_State *L = B->L;
+ int toget = 1; /* number of levels to concat */
+ size_t toplen = lua_strlen(L, -1);
+ do {
+ size_t l = lua_strlen(L, -(toget+1));
+ if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
+ toplen += l;
+ toget++;
+ }
+ else break;
+ } while (toget < B->lvl);
+ lua_concat(L, toget);
+ B->lvl = B->lvl - toget + 1;
+ }
+}
+
+
+LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
+ if (emptybuffer(B))
+ adjuststack(B);
+ return B->buffer;
+}
+
+
+LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
+ while (l--)
+ luaL_addchar(B, *s++);
+}
+
+
+LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
+ luaL_addlstring(B, s, strlen(s));
+}
+
+
+LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
+ emptybuffer(B);
+ lua_concat(B->L, B->lvl);
+ B->lvl = 1;
+}
+
+
+LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
+ lua_State *L = B->L;
+ size_t vl;
+ const char *s = lua_tolstring(L, -1, &vl);
+ if (vl <= bufffree(B)) { /* fit into buffer? */
+ memcpy(B->p, s, vl); /* put it there */
+ B->p += vl;
+ lua_pop(L, 1); /* remove from stack */
+ }
+ else {
+ if (emptybuffer(B))
+ lua_insert(L, -2); /* put buffer before new value */
+ B->lvl++; /* add new value into B stack */
+ adjuststack(B);
+ }
+}
+
+
+LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
+ B->L = L;
+ B->p = B->buffer;
+ B->lvl = 0;
+}
+
+/* }====================================================== */
+
+
+LUALIB_API int luaL_ref (lua_State *L, int t) {
+ int ref;
+ t = abs_index(L, t);
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1); /* remove from stack */
+ return LUA_REFNIL; /* `nil' has a unique fixed reference */
+ }
+ lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
+ ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
+ lua_pop(L, 1); /* remove it from stack */
+ if (ref != 0) { /* any free element? */
+ lua_rawgeti(L, t, ref); /* remove it from list */
+ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
+ }
+ else { /* no free elements */
+ ref = (int)lua_objlen(L, t);
+ ref++; /* create new reference */
+ }
+ lua_rawseti(L, t, ref);
+ return ref;
+}
+
+
+LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
+ if (ref >= 0) {
+ t = abs_index(L, t);
+ lua_rawgeti(L, t, FREELIST_REF);
+ lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
+ lua_pushinteger(L, ref);
+ lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
+ }
+}
+
+
+
+/*
+** {======================================================
+** Load functions
+** =======================================================
+*/
+
+typedef struct LoadF {
+ int extraline;
+ FILE *f;
+ char buff[LUAL_BUFFERSIZE];
+} LoadF;
+
+
+static const char *getF (lua_State *L, void *ud, size_t *size) {
+ LoadF *lf = (LoadF *)ud;
+ (void)L;
+ if (lf->extraline) {
+ lf->extraline = 0;
+ *size = 1;
+ return "\n";
+ }
+ if (feof(lf->f)) return NULL;
+ *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
+ return (*size > 0) ? lf->buff : NULL;
+}
+
+
+static int errfile (lua_State *L, const char *what, int fnameindex) {
+ const char *serr = strerror(errno);
+ const char *filename = lua_tostring(L, fnameindex) + 1;
+ lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
+ lua_remove(L, fnameindex);
+ return LUA_ERRFILE;
+}
+
+
+LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
+ LoadF lf;
+ int status, readstatus;
+ int c;
+ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
+ lf.extraline = 0;
+ if (filename == NULL) {
+ lua_pushliteral(L, "=stdin");
+ lf.f = stdin;
+ }
+ else {
+ lua_pushfstring(L, "@%s", filename);
+ lf.f = fopen(filename, "r");
+ if (lf.f == NULL) return errfile(L, "open", fnameindex);
+ }
+ c = getc(lf.f);
+ if (c == '#') { /* Unix exec. file? */
+ lf.extraline = 1;
+ while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
+ if (c == '\n') c = getc(lf.f);
+ }
+ if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
+ lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
+ if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
+ /* skip eventual `#!...' */
+ while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
+ lf.extraline = 0;
+ }
+ ungetc(c, lf.f);
+ status = lua_load(L, getF, &lf, lua_tostring(L, -1));
+ readstatus = ferror(lf.f);
+ if (filename) fclose(lf.f); /* close file (even in case of errors) */
+ if (readstatus) {
+ lua_settop(L, fnameindex); /* ignore results from `lua_load' */
+ return errfile(L, "read", fnameindex);
+ }
+ lua_remove(L, fnameindex);
+ return status;
+}
+
+
+typedef struct LoadS {
+ const char *s;
+ size_t size;
+} LoadS;
+
+
+static const char *getS (lua_State *L, void *ud, size_t *size) {
+ LoadS *ls = (LoadS *)ud;
+ (void)L;
+ if (ls->size == 0) return NULL;
+ *size = ls->size;
+ ls->size = 0;
+ return ls->s;
+}
+
+
+LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
+ const char *name) {
+ LoadS ls;
+ ls.s = buff;
+ ls.size = size;
+ return lua_load(L, getS, &ls, name);
+}
+
+
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
+ return luaL_loadbuffer(L, s, strlen(s), s);
+}
+
+
+
+/* }====================================================== */
+
+
+static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+ (void)ud;
+ (void)osize;
+ if (nsize == 0) {
+ free(ptr);
+ return NULL;
+ }
+ else
+ return realloc(ptr, nsize);
+}
+
+
+static int panic (lua_State *L) {
+ (void)L; /* to avoid warnings */
+ fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
+ lua_tostring(L, -1));
+ return 0;
+}
+
+
+LUALIB_API lua_State *luaL_newstate (void) {
+ lua_State *L = lua_newstate(l_alloc, NULL);
+ if (L) lua_atpanic(L, &panic);
+ return L;
+}
+
diff --git a/misc/liblua/lauxlib.h b/misc/liblua/lauxlib.h
new file mode 100644
index 0000000..3425823
--- /dev/null
+++ b/misc/liblua/lauxlib.h
@@ -0,0 +1,174 @@
+/*
+** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+
+#if defined(LUA_COMPAT_GETN)
+LUALIB_API int (luaL_getn) (lua_State *L, int t);
+LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
+#else
+#define luaL_getn(L,i) ((int)lua_objlen(L, i))
+#define luaL_setn(L,i,j) ((void)0) /* no op! */
+#endif
+
+#if defined(LUA_COMPAT_OPENLIB)
+#define luaI_openlib luaL_openlib
+#endif
+
+
+/* extra error code for `luaL_load' */
+#define LUA_ERRFILE (LUA_ERRERR+1)
+
+
+typedef struct luaL_Reg {
+ const char *name;
+ lua_CFunction func;
+} luaL_Reg;
+
+
+
+LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup);
+LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
+ const luaL_Reg *l);
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
+LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
+ size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
+ const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
+
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
+ lua_Integer def);
+
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
+
+LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
+ const char *const lst[]);
+
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+
+LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
+LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
+ const char *name);
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+
+LUALIB_API lua_State *(luaL_newstate) (void);
+
+
+LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+ const char *r);
+
+LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
+ const char *fname, int szhint);
+
+
+
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define luaL_argcheck(L, cond,numarg,extramsg) \
+ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
+#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
+#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
+#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
+
+#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
+
+#define luaL_dofile(L, fn) \
+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_dostring(L, s) \
+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+
+
+typedef struct luaL_Buffer {
+ char *p; /* current position in buffer */
+ int lvl; /* number of strings in the stack (level) */
+ lua_State *L;
+ char buffer[LUAL_BUFFERSIZE];
+} luaL_Buffer;
+
+#define luaL_addchar(B,c) \
+ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
+ (*(B)->p++ = (char)(c)))
+
+/* compatibility only */
+#define luaL_putchar(B,c) luaL_addchar(B,c)
+
+#define luaL_addsize(B,n) ((B)->p += (n))
+
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+
+
+/* }====================================================== */
+
+
+/* compatibility with ref system */
+
+/* pre-defined references */
+#define LUA_NOREF (-2)
+#define LUA_REFNIL (-1)
+
+#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
+ (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
+
+#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
+
+#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
+
+
+#define luaL_reg luaL_Reg
+
+#endif
+
+
diff --git a/misc/liblua/lbaselib.c b/misc/liblua/lbaselib.c
new file mode 100644
index 0000000..2a4c079
--- /dev/null
+++ b/misc/liblua/lbaselib.c
@@ -0,0 +1,653 @@
+/*
+** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
+** Basic library
+** See Copyright Notice in lua.h
+*/
+
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lbaselib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+
+/*
+** If your system does not support `stdout', you can just remove this function.
+** If you need, you can define your own `print' function, following this
+** model but changing `fputs' to put the strings at a proper place
+** (a console window or a log file, for instance).
+*/
+static int luaB_print (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ int i;
+ lua_getglobal(L, "tostring");
+ for (i=1; i<=n; i++) {
+ const char *s;
+ lua_pushvalue(L, -1); /* function to be called */
+ lua_pushvalue(L, i); /* value to print */
+ lua_call(L, 1, 1);
+ s = lua_tostring(L, -1); /* get result */
+ if (s == NULL)
+ return luaL_error(L, LUA_QL("tostring") " must return a string to "
+ LUA_QL("print"));
+ if (i>1) fputs("\t", stdout);
+ fputs(s, stdout);
+ lua_pop(L, 1); /* pop result */
+ }
+ fputs("\n", stdout);
+ return 0;
+}
+
+
+static int luaB_tonumber (lua_State *L) {
+ int base = luaL_optint(L, 2, 10);
+ if (base == 10) { /* standard conversion */
+ luaL_checkany(L, 1);
+ if (lua_isnumber(L, 1)) {
+ lua_pushnumber(L, lua_tonumber(L, 1));
+ return 1;
+ }
+ }
+ else {
+ const char *s1 = luaL_checkstring(L, 1);
+ char *s2;
+ unsigned long n;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+ n = strtoul(s1, &s2, base);
+ if (s1 != s2) { /* at least one valid digit? */
+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
+ if (*s2 == '\0') { /* no invalid trailing characters? */
+ lua_pushnumber(L, (lua_Number)n);
+ return 1;
+ }
+ }
+ }
+ lua_pushnil(L); /* else not a number */
+ return 1;
+}
+
+
+static int luaB_error (lua_State *L) {
+ int level = luaL_optint(L, 2, 1);
+ lua_settop(L, 1);
+ if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
+ luaL_where(L, level);
+ lua_pushvalue(L, 1);
+ lua_concat(L, 2);
+ }
+ return lua_error(L);
+}
+
+
+static int luaB_getmetatable (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_getmetatable(L, 1)) {
+ lua_pushnil(L);
+ return 1; /* no metatable */
+ }
+ luaL_getmetafield(L, 1, "__metatable");
+ return 1; /* returns either __metatable field (if present) or metatable */
+}
+
+
+static int luaB_setmetatable (lua_State *L) {
+ int t = lua_type(L, 2);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+ "nil or table expected");
+ if (luaL_getmetafield(L, 1, "__metatable"))
+ luaL_error(L, "cannot change a protected metatable");
+ lua_settop(L, 2);
+ lua_setmetatable(L, 1);
+ return 1;
+}
+
+
+static void getfunc (lua_State *L, int opt) {
+ if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
+ else {
+ lua_Debug ar;
+ int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
+ luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
+ if (lua_getstack(L, level, &ar) == 0)
+ luaL_argerror(L, 1, "invalid level");
+ lua_getinfo(L, "f", &ar);
+ if (lua_isnil(L, -1))
+ luaL_error(L, "no function environment for tail call at level %d",
+ level);
+ }
+}
+
+
+static int luaB_getfenv (lua_State *L) {
+ getfunc(L, 1);
+ if (lua_iscfunction(L, -1)) /* is a C function? */
+ lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
+ else
+ lua_getfenv(L, -1);
+ return 1;
+}
+
+
+static int luaB_setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ getfunc(L, 0);
+ lua_pushvalue(L, 2);
+ if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
+ /* change environment of current thread */
+ lua_pushthread(L);
+ lua_insert(L, -2);
+ lua_setfenv(L, -2);
+ return 0;
+ }
+ else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
+ luaL_error(L,
+ LUA_QL("setfenv") " cannot change environment of given object");
+ return 1;
+}
+
+
+static int luaB_rawequal (lua_State *L) {
+ luaL_checkany(L, 1);
+ luaL_checkany(L, 2);
+ lua_pushboolean(L, lua_rawequal(L, 1, 2));
+ return 1;
+}
+
+
+static int luaB_rawget (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checkany(L, 2);
+ lua_settop(L, 2);
+ lua_rawget(L, 1);
+ return 1;
+}
+
+static int luaB_rawset (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checkany(L, 2);
+ luaL_checkany(L, 3);
+ lua_settop(L, 3);
+ lua_rawset(L, 1);
+ return 1;
+}
+
+
+static int luaB_gcinfo (lua_State *L) {
+ lua_pushinteger(L, lua_getgccount(L));
+ return 1;
+}
+
+
+static int luaB_collectgarbage (lua_State *L) {
+ static const char *const opts[] = {"stop", "restart", "collect",
+ "count", "step", "setpause", "setstepmul", NULL};
+ static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
+ LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
+ int o = luaL_checkoption(L, 1, "collect", opts);
+ int ex = luaL_optint(L, 2, 0);
+ int res = lua_gc(L, optsnum[o], ex);
+ switch (optsnum[o]) {
+ case LUA_GCCOUNT: {
+ int b = lua_gc(L, LUA_GCCOUNTB, 0);
+ lua_pushnumber(L, res + ((lua_Number)b/1024));
+ return 1;
+ }
+ case LUA_GCSTEP: {
+ lua_pushboolean(L, res);
+ return 1;
+ }
+ default: {
+ lua_pushnumber(L, res);
+ return 1;
+ }
+ }
+}
+
+
+static int luaB_type (lua_State *L) {
+ luaL_checkany(L, 1);
+ lua_pushstring(L, luaL_typename(L, 1));
+ return 1;
+}
+
+
+static int luaB_next (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_settop(L, 2); /* create a 2nd argument if there isn't one */
+ if (lua_next(L, 1))
+ return 2;
+ else {
+ lua_pushnil(L);
+ return 1;
+ }
+}
+
+
+static int luaB_pairs (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
+ lua_pushvalue(L, 1); /* state, */
+ lua_pushnil(L); /* and initial value */
+ return 3;
+}
+
+
+static int ipairsaux (lua_State *L) {
+ int i = luaL_checkint(L, 2);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ i++; /* next value */
+ lua_pushinteger(L, i);
+ lua_rawgeti(L, 1, i);
+ return (lua_isnil(L, -1)) ? 0 : 2;
+}
+
+
+static int luaB_ipairs (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
+ lua_pushvalue(L, 1); /* state, */
+ lua_pushinteger(L, 0); /* and initial value */
+ return 3;
+}
+
+
+static int load_aux (lua_State *L, int status) {
+ if (status == 0) /* OK? */
+ return 1;
+ else {
+ lua_pushnil(L);
+ lua_insert(L, -2); /* put before error message */
+ return 2; /* return nil plus error message */
+ }
+}
+
+
+static int luaB_loadstring (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ const char *chunkname = luaL_optstring(L, 2, s);
+ return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
+}
+
+
+static int luaB_loadfile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ return load_aux(L, luaL_loadfile(L, fname));
+}
+
+
+/*
+** Reader for generic `load' function: `lua_load' uses the
+** stack for internal stuff, so the reader cannot change the
+** stack top. Instead, it keeps its resulting string in a
+** reserved slot inside the stack.
+*/
+static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
+ (void)ud; /* to avoid warnings */
+ luaL_checkstack(L, 2, "too many nested functions");
+ lua_pushvalue(L, 1); /* get function */
+ lua_call(L, 0, 1); /* call it */
+ if (lua_isnil(L, -1)) {
+ *size = 0;
+ return NULL;
+ }
+ else if (lua_isstring(L, -1)) {
+ lua_replace(L, 3); /* save string in a reserved stack slot */
+ return lua_tolstring(L, 3, size);
+ }
+ else luaL_error(L, "reader function must return a string");
+ return NULL; /* to avoid warnings */
+}
+
+
+static int luaB_load (lua_State *L) {
+ int status;
+ const char *cname = luaL_optstring(L, 2, "=(load)");
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
+ status = lua_load(L, generic_reader, NULL, cname);
+ return load_aux(L, status);
+}
+
+
+static int luaB_dofile (lua_State *L) {
+ const char *fname = luaL_optstring(L, 1, NULL);
+ int n = lua_gettop(L);
+ if (luaL_loadfile(L, fname) != 0) lua_error(L);
+ lua_call(L, 0, LUA_MULTRET);
+ return lua_gettop(L) - n;
+}
+
+
+static int luaB_assert (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_toboolean(L, 1))
+ return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
+ return lua_gettop(L);
+}
+
+
+static int luaB_unpack (lua_State *L) {
+ int i, e, n;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ i = luaL_optint(L, 2, 1);
+ e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
+ if (i > e) return 0; /* empty range */
+ n = e - i + 1; /* number of elements */
+ if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
+ return luaL_error(L, "too many results to unpack");
+ lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
+ while (i++ < e) /* push arg[i + 1...e] */
+ lua_rawgeti(L, 1, i);
+ return n;
+}
+
+
+static int luaB_select (lua_State *L) {
+ int n = lua_gettop(L);
+ if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
+ lua_pushinteger(L, n-1);
+ return 1;
+ }
+ else {
+ int i = luaL_checkint(L, 1);
+ if (i < 0) i = n + i;
+ else if (i > n) i = n;
+ luaL_argcheck(L, 1 <= i, 1, "index out of range");
+ return n - i;
+ }
+}
+
+
+static int luaB_pcall (lua_State *L) {
+ int status;
+ luaL_checkany(L, 1);
+ status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
+ lua_pushboolean(L, (status == 0));
+ lua_insert(L, 1);
+ return lua_gettop(L); /* return status + all results */
+}
+
+
+static int luaB_xpcall (lua_State *L) {
+ int status;
+ luaL_checkany(L, 2);
+ lua_settop(L, 2);
+ lua_insert(L, 1); /* put error function under function to be called */
+ status = lua_pcall(L, 0, LUA_MULTRET, 1);
+ lua_pushboolean(L, (status == 0));
+ lua_replace(L, 1);
+ return lua_gettop(L); /* return status + all results */
+}
+
+
+static int luaB_tostring (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */
+ return 1; /* use its value */
+ switch (lua_type(L, 1)) {
+ case LUA_TNUMBER:
+ lua_pushstring(L, lua_tostring(L, 1));
+ break;
+ case LUA_TSTRING:
+ lua_pushvalue(L, 1);
+ break;
+ case LUA_TBOOLEAN:
+ lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
+ break;
+ case LUA_TNIL:
+ lua_pushliteral(L, "nil");
+ break;
+ default:
+ lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
+ break;
+ }
+ return 1;
+}
+
+
+static int luaB_newproxy (lua_State *L) {
+ lua_settop(L, 1);
+ lua_newuserdata(L, 0); /* create proxy */
+ if (lua_toboolean(L, 1) == 0)
+ return 1; /* no metatable */
+ else if (lua_isboolean(L, 1)) {
+ lua_newtable(L); /* create a new metatable `m' ... */
+ lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
+ lua_pushboolean(L, 1);
+ lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
+ }
+ else {
+ int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
+ if (lua_getmetatable(L, 1)) {
+ lua_rawget(L, lua_upvalueindex(1));
+ validproxy = lua_toboolean(L, -1);
+ lua_pop(L, 1); /* remove value */
+ }
+ luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
+ lua_getmetatable(L, 1); /* metatable is valid; get it */
+ }
+ lua_setmetatable(L, 2);
+ return 1;
+}
+
+
+static const luaL_Reg base_funcs[] = {
+ {"assert", luaB_assert},
+ {"collectgarbage", luaB_collectgarbage},
+ {"dofile", luaB_dofile},
+ {"error", luaB_error},
+ {"gcinfo", luaB_gcinfo},
+ {"getfenv", luaB_getfenv},
+ {"getmetatable", luaB_getmetatable},
+ {"loadfile", luaB_loadfile},
+ {"load", luaB_load},
+ {"loadstring", luaB_loadstring},
+ {"next", luaB_next},
+ {"pcall", luaB_pcall},
+ {"print", luaB_print},
+ {"rawequal", luaB_rawequal},
+ {"rawget", luaB_rawget},
+ {"rawset", luaB_rawset},
+ {"select", luaB_select},
+ {"setfenv", luaB_setfenv},
+ {"setmetatable", luaB_setmetatable},
+ {"tonumber", luaB_tonumber},
+ {"tostring", luaB_tostring},
+ {"type", luaB_type},
+ {"unpack", luaB_unpack},
+ {"xpcall", luaB_xpcall},
+ {NULL, NULL}
+};
+
+
+/*
+** {======================================================
+** Coroutine library
+** =======================================================
+*/
+
+#define CO_RUN 0 /* running */
+#define CO_SUS 1 /* suspended */
+#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
+#define CO_DEAD 3
+
+static const char *const statnames[] =
+ {"running", "suspended", "normal", "dead"};
+
+static int costatus (lua_State *L, lua_State *co) {
+ if (L == co) return CO_RUN;
+ switch (lua_status(co)) {
+ case LUA_YIELD:
+ return CO_SUS;
+ case 0: {
+ lua_Debug ar;
+ if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
+ return CO_NOR; /* it is running */
+ else if (lua_gettop(co) == 0)
+ return CO_DEAD;
+ else
+ return CO_SUS; /* initial state */
+ }
+ default: /* some error occured */
+ return CO_DEAD;
+ }
+}
+
+
+static int luaB_costatus (lua_State *L) {
+ lua_State *co = lua_tothread(L, 1);
+ luaL_argcheck(L, co, 1, "coroutine expected");
+ lua_pushstring(L, statnames[costatus(L, co)]);
+ return 1;
+}
+
+
+static int auxresume (lua_State *L, lua_State *co, int narg) {
+ int status = costatus(L, co);
+ if (!lua_checkstack(co, narg))
+ luaL_error(L, "too many arguments to resume");
+ if (status != CO_SUS) {
+ lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
+ return -1; /* error flag */
+ }
+ lua_xmove(L, co, narg);
+ lua_setlevel(L, co);
+ status = lua_resume(co, narg);
+ if (status == 0 || status == LUA_YIELD) {
+ int nres = lua_gettop(co);
+ if (!lua_checkstack(L, nres + 1))
+ luaL_error(L, "too many results to resume");
+ lua_xmove(co, L, nres); /* move yielded values */
+ return nres;
+ }
+ else {
+ lua_xmove(co, L, 1); /* move error message */
+ return -1; /* error flag */
+ }
+}
+
+
+static int luaB_coresume (lua_State *L) {
+ lua_State *co = lua_tothread(L, 1);
+ int r;
+ luaL_argcheck(L, co, 1, "coroutine expected");
+ r = auxresume(L, co, lua_gettop(L) - 1);
+ if (r < 0) {
+ lua_pushboolean(L, 0);
+ lua_insert(L, -2);
+ return 2; /* return false + error message */
+ }
+ else {
+ lua_pushboolean(L, 1);
+ lua_insert(L, -(r + 1));
+ return r + 1; /* return true + `resume' returns */
+ }
+}
+
+
+static int luaB_auxwrap (lua_State *L) {
+ lua_State *co = lua_tothread(L, lua_upvalueindex(1));
+ int r = auxresume(L, co, lua_gettop(L));
+ if (r < 0) {
+ if (lua_isstring(L, -1)) { /* error object is a string? */
+ luaL_where(L, 1); /* add extra info */
+ lua_insert(L, -2);
+ lua_concat(L, 2);
+ }
+ lua_error(L); /* propagate error */
+ }
+ return r;
+}
+
+
+static int luaB_cocreate (lua_State *L) {
+ lua_State *NL = lua_newthread(L);
+ luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
+ "Lua function expected");
+ lua_pushvalue(L, 1); /* move function to top */
+ lua_xmove(L, NL, 1); /* move function from L to NL */
+ return 1;
+}
+
+
+static int luaB_cowrap (lua_State *L) {
+ luaB_cocreate(L);
+ lua_pushcclosure(L, luaB_auxwrap, 1);
+ return 1;
+}
+
+
+static int luaB_yield (lua_State *L) {
+ return lua_yield(L, lua_gettop(L));
+}
+
+
+static int luaB_corunning (lua_State *L) {
+ if (lua_pushthread(L))
+ lua_pushnil(L); /* main thread is not a coroutine */
+ return 1;
+}
+
+
+static const luaL_Reg co_funcs[] = {
+ {"create", luaB_cocreate},
+ {"resume", luaB_coresume},
+ {"running", luaB_corunning},
+ {"status", luaB_costatus},
+ {"wrap", luaB_cowrap},
+ {"yield", luaB_yield},
+ {NULL, NULL}
+};
+
+/* }====================================================== */
+
+
+static void auxopen (lua_State *L, const char *name,
+ lua_CFunction f, lua_CFunction u) {
+ lua_pushcfunction(L, u);
+ lua_pushcclosure(L, f, 1);
+ lua_setfield(L, -2, name);
+}
+
+
+static void base_open (lua_State *L) {
+ /* set global _G */
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_setglobal(L, "_G");
+ /* open lib into global table */
+ luaL_register(L, "_G", base_funcs);
+ lua_pushliteral(L, LUA_VERSION);
+ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
+ /* `ipairs' and `pairs' need auxliliary functions as upvalues */
+ auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
+ auxopen(L, "pairs", luaB_pairs, luaB_next);
+ /* `newproxy' needs a weaktable as upvalue */
+ lua_createtable(L, 0, 1); /* new table `w' */
+ lua_pushvalue(L, -1); /* `w' will be its own metatable */
+ lua_setmetatable(L, -2);
+ lua_pushliteral(L, "kv");
+ lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
+ lua_pushcclosure(L, luaB_newproxy, 1);
+ lua_setglobal(L, "newproxy"); /* set global `newproxy' */
+}
+
+
+LUALIB_API int luaopen_base (lua_State *L) {
+ base_open(L);
+ luaL_register(L, LUA_COLIBNAME, co_funcs);
+ return 2;
+}
+
diff --git a/misc/liblua/lcode.c b/misc/liblua/lcode.c
new file mode 100644
index 0000000..cff626b
--- /dev/null
+++ b/misc/liblua/lcode.c
@@ -0,0 +1,839 @@
+/*
+** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+
+#define lcode_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "ltable.h"
+
+
+#define hasjumps(e) ((e)->t != (e)->f)
+
+
+static int isnumeral(expdesc *e) {
+ return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
+}
+
+
+void luaK_nil (FuncState *fs, int from, int n) {
+ Instruction *previous;
+ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
+ if (fs->pc == 0) { /* function start? */
+ if (from >= fs->nactvar)
+ return; /* positions are already clean */
+ }
+ else {
+ previous = &fs->f->code[fs->pc-1];
+ if (GET_OPCODE(*previous) == OP_LOADNIL) {
+ int pfrom = GETARG_A(*previous);
+ int pto = GETARG_B(*previous);
+ if (pfrom <= from && from <= pto+1) { /* can connect both? */
+ if (from+n-1 > pto)
+ SETARG_B(*previous, from+n-1);
+ return;
+ }
+ }
+ }
+ }
+ luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
+}
+
+
+int luaK_jump (FuncState *fs) {
+ int jpc = fs->jpc; /* save list of jumps to here */
+ int j;
+ fs->jpc = NO_JUMP;
+ j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+ luaK_concat(fs, &j, jpc); /* keep them on hold */
+ return j;
+}
+
+
+void luaK_ret (FuncState *fs, int first, int nret) {
+ luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
+}
+
+
+static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
+ luaK_codeABC(fs, op, A, B, C);
+ return luaK_jump(fs);
+}
+
+
+static void fixjump (FuncState *fs, int pc, int dest) {
+ Instruction *jmp = &fs->f->code[pc];
+ int offset = dest-(pc+1);
+ lua_assert(dest != NO_JUMP);
+ if (abs(offset) > MAXARG_sBx)
+ luaX_syntaxerror(fs->ls, "control structure too long");
+ SETARG_sBx(*jmp, offset);
+}
+
+
+/*
+** returns current `pc' and marks it as a jump target (to avoid wrong
+** optimizations with consecutive instructions not in the same basic block).
+*/
+int luaK_getlabel (FuncState *fs) {
+ fs->lasttarget = fs->pc;
+ return fs->pc;
+}
+
+
+static int getjump (FuncState *fs, int pc) {
+ int offset = GETARG_sBx(fs->f->code[pc]);
+ if (offset == NO_JUMP) /* point to itself represents end of list */
+ return NO_JUMP; /* end of list */
+ else
+ return (pc+1)+offset; /* turn offset into absolute position */
+}
+
+
+static Instruction *getjumpcontrol (FuncState *fs, int pc) {
+ Instruction *pi = &fs->f->code[pc];
+ if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
+ return pi-1;
+ else
+ return pi;
+}
+
+
+/*
+** check whether list has any jump that do not produce a value
+** (or produce an inverted value)
+*/
+static int need_value (FuncState *fs, int list) {
+ for (; list != NO_JUMP; list = getjump(fs, list)) {
+ Instruction i = *getjumpcontrol(fs, list);
+ if (GET_OPCODE(i) != OP_TESTSET) return 1;
+ }
+ return 0; /* not found */
+}
+
+
+static int patchtestreg (FuncState *fs, int node, int reg) {
+ Instruction *i = getjumpcontrol(fs, node);
+ if (GET_OPCODE(*i) != OP_TESTSET)
+ return 0; /* cannot patch other instructions */
+ if (reg != NO_REG && reg != GETARG_B(*i))
+ SETARG_A(*i, reg);
+ else /* no register to put value or register already has the value */
+ *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
+
+ return 1;
+}
+
+
+static void removevalues (FuncState *fs, int list) {
+ for (; list != NO_JUMP; list = getjump(fs, list))
+ patchtestreg(fs, list, NO_REG);
+}
+
+
+static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
+ int dtarget) {
+ while (list != NO_JUMP) {
+ int next = getjump(fs, list);
+ if (patchtestreg(fs, list, reg))
+ fixjump(fs, list, vtarget);
+ else
+ fixjump(fs, list, dtarget); /* jump to default target */
+ list = next;
+ }
+}
+
+
+static void dischargejpc (FuncState *fs) {
+ patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
+ fs->jpc = NO_JUMP;
+}
+
+
+void luaK_patchlist (FuncState *fs, int list, int target) {
+ if (target == fs->pc)
+ luaK_patchtohere(fs, list);
+ else {
+ lua_assert(target < fs->pc);
+ patchlistaux(fs, list, target, NO_REG, target);
+ }
+}
+
+
+void luaK_patchtohere (FuncState *fs, int list) {
+ luaK_getlabel(fs);
+ luaK_concat(fs, &fs->jpc, list);
+}
+
+
+void luaK_concat (FuncState *fs, int *l1, int l2) {
+ if (l2 == NO_JUMP) return;
+ else if (*l1 == NO_JUMP)
+ *l1 = l2;
+ else {
+ int list = *l1;
+ int next;
+ while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
+ list = next;
+ fixjump(fs, list, l2);
+ }
+}
+
+
+void luaK_checkstack (FuncState *fs, int n) {
+ int newstack = fs->freereg + n;
+ if (newstack > fs->f->maxstacksize) {
+ if (newstack >= MAXSTACK)
+ luaX_syntaxerror(fs->ls, "function or expression too complex");
+ fs->f->maxstacksize = cast_byte(newstack);
+ }
+}
+
+
+void luaK_reserveregs (FuncState *fs, int n) {
+ luaK_checkstack(fs, n);
+ fs->freereg += n;
+}
+
+
+static void freereg (FuncState *fs, int reg) {
+ if (!ISK(reg) && reg >= fs->nactvar) {
+ fs->freereg--;
+ lua_assert(reg == fs->freereg);
+ }
+}
+
+
+static void freeexp (FuncState *fs, expdesc *e) {
+ if (e->k == VNONRELOC)
+ freereg(fs, e->u.s.info);
+}
+
+
+static int addk (FuncState *fs, TValue *k, TValue *v) {
+ lua_State *L = fs->L;
+ TValue *idx = luaH_set(L, fs->h, k);
+ Proto *f = fs->f;
+ int oldsize = f->sizek;
+ if (ttisnumber(idx)) {
+ lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
+ return cast_int(nvalue(idx));
+ }
+ else { /* constant not found; create a new entry */
+ setnvalue(idx, cast_num(fs->nk));
+ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
+ MAXARG_Bx, "constant table overflow");
+ while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
+ setobj(L, &f->k[fs->nk], v);
+ luaC_barrier(L, f, v);
+ return fs->nk++;
+ }
+}
+
+
+int luaK_stringK (FuncState *fs, TString *s) {
+ TValue o;
+ setsvalue(fs->L, &o, s);
+ return addk(fs, &o, &o);
+}
+
+
+int luaK_numberK (FuncState *fs, lua_Number r) {
+ TValue o;
+ setnvalue(&o, r);
+ return addk(fs, &o, &o);
+}
+
+
+static int boolK (FuncState *fs, int b) {
+ TValue o;
+ setbvalue(&o, b);
+ return addk(fs, &o, &o);
+}
+
+
+static int nilK (FuncState *fs) {
+ TValue k, v;
+ setnilvalue(&v);
+ /* cannot use nil as key; instead use table itself to represent nil */
+ sethvalue(fs->L, &k, fs->h);
+ return addk(fs, &k, &v);
+}
+
+
+void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
+ if (e->k == VCALL) { /* expression is an open function call? */
+ SETARG_C(getcode(fs, e), nresults+1);
+ }
+ else if (e->k == VVARARG) {
+ SETARG_B(getcode(fs, e), nresults+1);
+ SETARG_A(getcode(fs, e), fs->freereg);
+ luaK_reserveregs(fs, 1);
+ }
+}
+
+
+void luaK_setoneret (FuncState *fs, expdesc *e) {
+ if (e->k == VCALL) { /* expression is an open function call? */
+ e->k = VNONRELOC;
+ e->u.s.info = GETARG_A(getcode(fs, e));
+ }
+ else if (e->k == VVARARG) {
+ SETARG_B(getcode(fs, e), 2);
+ e->k = VRELOCABLE; /* can relocate its simple result */
+ }
+}
+
+
+void luaK_dischargevars (FuncState *fs, expdesc *e) {
+ switch (e->k) {
+ case VLOCAL: {
+ e->k = VNONRELOC;
+ break;
+ }
+ case VUPVAL: {
+ e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VGLOBAL: {
+ e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VINDEXED: {
+ freereg(fs, e->u.s.aux);
+ freereg(fs, e->u.s.info);
+ e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
+ e->k = VRELOCABLE;
+ break;
+ }
+ case VVARARG:
+ case VCALL: {
+ luaK_setoneret(fs, e);
+ break;
+ }
+ default: break; /* there is one value available (somewhere) */
+ }
+}
+
+
+static int code_label (FuncState *fs, int A, int b, int jump) {
+ luaK_getlabel(fs); /* those instructions may be jump targets */
+ return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
+}
+
+
+static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: {
+ luaK_nil(fs, reg, 1);
+ break;
+ }
+ case VFALSE: case VTRUE: {
+ luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+ break;
+ }
+ case VK: {
+ luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
+ break;
+ }
+ case VKNUM: {
+ luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
+ break;
+ }
+ case VRELOCABLE: {
+ Instruction *pc = &getcode(fs, e);
+ SETARG_A(*pc, reg);
+ break;
+ }
+ case VNONRELOC: {
+ if (reg != e->u.s.info)
+ luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
+ break;
+ }
+ default: {
+ lua_assert(e->k == VVOID || e->k == VJMP);
+ return; /* nothing to do... */
+ }
+ }
+ e->u.s.info = reg;
+ e->k = VNONRELOC;
+}
+
+
+static void discharge2anyreg (FuncState *fs, expdesc *e) {
+ if (e->k != VNONRELOC) {
+ luaK_reserveregs(fs, 1);
+ discharge2reg(fs, e, fs->freereg-1);
+ }
+}
+
+
+static void exp2reg (FuncState *fs, expdesc *e, int reg) {
+ discharge2reg(fs, e, reg);
+ if (e->k == VJMP)
+ luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */
+ if (hasjumps(e)) {
+ int final; /* position after whole expression */
+ int p_f = NO_JUMP; /* position of an eventual LOAD false */
+ int p_t = NO_JUMP; /* position of an eventual LOAD true */
+ if (need_value(fs, e->t) || need_value(fs, e->f)) {
+ int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
+ p_f = code_label(fs, reg, 0, 1);
+ p_t = code_label(fs, reg, 1, 0);
+ luaK_patchtohere(fs, fj);
+ }
+ final = luaK_getlabel(fs);
+ patchlistaux(fs, e->f, final, reg, p_f);
+ patchlistaux(fs, e->t, final, reg, p_t);
+ }
+ e->f = e->t = NO_JUMP;
+ e->u.s.info = reg;
+ e->k = VNONRELOC;
+}
+
+
+void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ freeexp(fs, e);
+ luaK_reserveregs(fs, 1);
+ exp2reg(fs, e, fs->freereg - 1);
+}
+
+
+int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ if (e->k == VNONRELOC) {
+ if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */
+ if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */
+ exp2reg(fs, e, e->u.s.info); /* put value on it */
+ return e->u.s.info;
+ }
+ }
+ luaK_exp2nextreg(fs, e); /* default */
+ return e->u.s.info;
+}
+
+
+void luaK_exp2val (FuncState *fs, expdesc *e) {
+ if (hasjumps(e))
+ luaK_exp2anyreg(fs, e);
+ else
+ luaK_dischargevars(fs, e);
+}
+
+
+int luaK_exp2RK (FuncState *fs, expdesc *e) {
+ luaK_exp2val(fs, e);
+ switch (e->k) {
+ case VKNUM:
+ case VTRUE:
+ case VFALSE:
+ case VNIL: {
+ if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
+ e->u.s.info = (e->k == VNIL) ? nilK(fs) :
+ (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
+ boolK(fs, (e->k == VTRUE));
+ e->k = VK;
+ return RKASK(e->u.s.info);
+ }
+ else break;
+ }
+ case VK: {
+ if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */
+ return RKASK(e->u.s.info);
+ else break;
+ }
+ default: break;
+ }
+ /* not a constant in the right range: put it in a register */
+ return luaK_exp2anyreg(fs, e);
+}
+
+
+void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
+ switch (var->k) {
+ case VLOCAL: {
+ freeexp(fs, ex);
+ exp2reg(fs, ex, var->u.s.info);
+ return;
+ }
+ case VUPVAL: {
+ int e = luaK_exp2anyreg(fs, ex);
+ luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
+ break;
+ }
+ case VGLOBAL: {
+ int e = luaK_exp2anyreg(fs, ex);
+ luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
+ break;
+ }
+ case VINDEXED: {
+ int e = luaK_exp2RK(fs, ex);
+ luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
+ break;
+ }
+ default: {
+ lua_assert(0); /* invalid var kind to store */
+ break;
+ }
+ }
+ freeexp(fs, ex);
+}
+
+
+void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
+ int func;
+ luaK_exp2anyreg(fs, e);
+ freeexp(fs, e);
+ func = fs->freereg;
+ luaK_reserveregs(fs, 2);
+ luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
+ freeexp(fs, key);
+ e->u.s.info = func;
+ e->k = VNONRELOC;
+}
+
+
+static void invertjump (FuncState *fs, expdesc *e) {
+ Instruction *pc = getjumpcontrol(fs, e->u.s.info);
+ lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
+ GET_OPCODE(*pc) != OP_TEST);
+ SETARG_A(*pc, !(GETARG_A(*pc)));
+}
+
+
+static int jumponcond (FuncState *fs, expdesc *e, int cond) {
+ if (e->k == VRELOCABLE) {
+ Instruction ie = getcode(fs, e);
+ if (GET_OPCODE(ie) == OP_NOT) {
+ fs->pc--; /* remove previous OP_NOT */
+ return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
+ }
+ /* else go through */
+ }
+ discharge2anyreg(fs, e);
+ freeexp(fs, e);
+ return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
+}
+
+
+void luaK_goiftrue (FuncState *fs, expdesc *e) {
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VK: case VKNUM: case VTRUE: {
+ pc = NO_JUMP; /* always true; do nothing */
+ break;
+ }
+ case VFALSE: {
+ pc = luaK_jump(fs); /* always jump */
+ break;
+ }
+ case VJMP: {
+ invertjump(fs, e);
+ pc = e->u.s.info;
+ break;
+ }
+ default: {
+ pc = jumponcond(fs, e, 0);
+ break;
+ }
+ }
+ luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
+ luaK_patchtohere(fs, e->t);
+ e->t = NO_JUMP;
+}
+
+
+static void luaK_goiffalse (FuncState *fs, expdesc *e) {
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: case VFALSE: {
+ pc = NO_JUMP; /* always false; do nothing */
+ break;
+ }
+ case VTRUE: {
+ pc = luaK_jump(fs); /* always jump */
+ break;
+ }
+ case VJMP: {
+ pc = e->u.s.info;
+ break;
+ }
+ default: {
+ pc = jumponcond(fs, e, 1);
+ break;
+ }
+ }
+ luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
+ luaK_patchtohere(fs, e->f);
+ e->f = NO_JUMP;
+}
+
+
+static void codenot (FuncState *fs, expdesc *e) {
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+ case VNIL: case VFALSE: {
+ e->k = VTRUE;
+ break;
+ }
+ case VK: case VKNUM: case VTRUE: {
+ e->k = VFALSE;
+ break;
+ }
+ case VJMP: {
+ invertjump(fs, e);
+ break;
+ }
+ case VRELOCABLE:
+ case VNONRELOC: {
+ discharge2anyreg(fs, e);
+ freeexp(fs, e);
+ e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
+ e->k = VRELOCABLE;
+ break;
+ }
+ default: {
+ lua_assert(0); /* cannot happen */
+ break;
+ }
+ }
+ /* interchange true and false lists */
+ { int temp = e->f; e->f = e->t; e->t = temp; }
+ removevalues(fs, e->f);
+ removevalues(fs, e->t);
+}
+
+
+void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
+ t->u.s.aux = luaK_exp2RK(fs, k);
+ t->k = VINDEXED;
+}
+
+
+static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
+ lua_Number v1, v2, r;
+ if (!isnumeral(e1) || !isnumeral(e2)) return 0;
+ v1 = e1->u.nval;
+ v2 = e2->u.nval;
+ switch (op) {
+ case OP_ADD: r = luai_numadd(v1, v2); break;
+ case OP_SUB: r = luai_numsub(v1, v2); break;
+ case OP_MUL: r = luai_nummul(v1, v2); break;
+ case OP_DIV:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
+ r = luai_numdiv(v1, v2); break;
+ case OP_MOD:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
+ r = luai_nummod(v1, v2); break;
+ case OP_POW: r = luai_numpow(v1, v2); break;
+ case OP_UNM: r = luai_numunm(v1); break;
+ case OP_LEN: return 0; /* no constant folding for 'len' */
+ default: lua_assert(0); r = 0; break;
+ }
+ if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
+ e1->u.nval = r;
+ return 1;
+}
+
+
+static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
+ if (constfolding(op, e1, e2))
+ return;
+ else {
+ int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
+ int o1 = luaK_exp2RK(fs, e1);
+ if (o1 > o2) {
+ freeexp(fs, e1);
+ freeexp(fs, e2);
+ }
+ else {
+ freeexp(fs, e2);
+ freeexp(fs, e1);
+ }
+ e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
+ e1->k = VRELOCABLE;
+ }
+}
+
+
+static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
+ expdesc *e2) {
+ int o1 = luaK_exp2RK(fs, e1);
+ int o2 = luaK_exp2RK(fs, e2);
+ freeexp(fs, e2);
+ freeexp(fs, e1);
+ if (cond == 0 && op != OP_EQ) {
+ int temp; /* exchange args to replace by `<' or `<=' */
+ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
+ cond = 1;
+ }
+ e1->u.s.info = condjump(fs, op, cond, o1, o2);
+ e1->k = VJMP;
+}
+
+
+void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
+ expdesc e2;
+ e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
+ switch (op) {
+ case OPR_MINUS: {
+ if (!isnumeral(e))
+ luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
+ codearith(fs, OP_UNM, e, &e2);
+ break;
+ }
+ case OPR_NOT: codenot(fs, e); break;
+ case OPR_LEN: {
+ luaK_exp2anyreg(fs, e); /* cannot operate on constants */
+ codearith(fs, OP_LEN, e, &e2);
+ break;
+ }
+ default: lua_assert(0);
+ }
+}
+
+
+void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
+ switch (op) {
+ case OPR_AND: {
+ luaK_goiftrue(fs, v);
+ break;
+ }
+ case OPR_OR: {
+ luaK_goiffalse(fs, v);
+ break;
+ }
+ case OPR_CONCAT: {
+ luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
+ break;
+ }
+ case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+ case OPR_MOD: case OPR_POW: {
+ if (!isnumeral(v)) luaK_exp2RK(fs, v);
+ break;
+ }
+ default: {
+ luaK_exp2RK(fs, v);
+ break;
+ }
+ }
+}
+
+
+void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
+ switch (op) {
+ case OPR_AND: {
+ lua_assert(e1->t == NO_JUMP); /* list must be closed */
+ luaK_dischargevars(fs, e2);
+ luaK_concat(fs, &e2->f, e1->f);
+ *e1 = *e2;
+ break;
+ }
+ case OPR_OR: {
+ lua_assert(e1->f == NO_JUMP); /* list must be closed */
+ luaK_dischargevars(fs, e2);
+ luaK_concat(fs, &e2->t, e1->t);
+ *e1 = *e2;
+ break;
+ }
+ case OPR_CONCAT: {
+ luaK_exp2val(fs, e2);
+ if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
+ lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
+ freeexp(fs, e1);
+ SETARG_B(getcode(fs, e2), e1->u.s.info);
+ e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
+ }
+ else {
+ luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
+ codearith(fs, OP_CONCAT, e1, e2);
+ }
+ break;
+ }
+ case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
+ case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
+ case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
+ case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
+ case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
+ case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
+ case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
+ case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
+ case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
+ case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
+ case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
+ case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
+ default: lua_assert(0);
+ }
+}
+
+
+void luaK_fixline (FuncState *fs, int line) {
+ fs->f->lineinfo[fs->pc - 1] = line;
+}
+
+
+static int luaK_code (FuncState *fs, Instruction i, int line) {
+ Proto *f = fs->f;
+ dischargejpc(fs); /* `pc' will change */
+ /* put new instruction in code array */
+ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
+ MAX_INT, "code size overflow");
+ f->code[fs->pc] = i;
+ /* save corresponding line information */
+ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
+ MAX_INT, "code size overflow");
+ f->lineinfo[fs->pc] = line;
+ return fs->pc++;
+}
+
+
+int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
+ lua_assert(getOpMode(o) == iABC);
+ lua_assert(getBMode(o) != OpArgN || b == 0);
+ lua_assert(getCMode(o) != OpArgN || c == 0);
+ return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
+}
+
+
+int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
+ lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+ lua_assert(getCMode(o) == OpArgN);
+ return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
+}
+
+
+void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
+ int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+ int b = (tostore == LUA_MULTRET) ? 0 : tostore;
+ lua_assert(tostore != 0);
+ if (c <= MAXARG_C)
+ luaK_codeABC(fs, OP_SETLIST, base, b, c);
+ else {
+ luaK_codeABC(fs, OP_SETLIST, base, b, 0);
+ luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
+ }
+ fs->freereg = base + 1; /* free registers with list values */
+}
+
diff --git a/misc/liblua/lcode.h b/misc/liblua/lcode.h
new file mode 100644
index 0000000..b941c60
--- /dev/null
+++ b/misc/liblua/lcode.h
@@ -0,0 +1,76 @@
+/*
+** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
+** Code generator for Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lcode_h
+#define lcode_h
+
+#include "llex.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+
+
+/*
+** Marks the end of a patch list. It is an invalid value both as an absolute
+** address, and as a list link (would link an element to itself).
+*/
+#define NO_JUMP (-1)
+
+
+/*
+** grep "ORDER OPR" if you change these enums
+*/
+typedef enum BinOpr {
+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
+ OPR_CONCAT,
+ OPR_NE, OPR_EQ,
+ OPR_LT, OPR_LE, OPR_GT, OPR_GE,
+ OPR_AND, OPR_OR,
+ OPR_NOBINOPR
+} BinOpr;
+
+
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
+
+
+#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info])
+
+#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
+
+#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
+
+LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
+LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
+LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
+LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
+LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
+LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
+LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
+LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
+LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
+LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
+LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
+LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
+LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
+LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
+LUAI_FUNC int luaK_jump (FuncState *fs);
+LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
+LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
+LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
+LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
+LUAI_FUNC int luaK_getlabel (FuncState *fs);
+LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
+LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
+LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
+
+
+#endif
diff --git a/misc/liblua/ldblib.c b/misc/liblua/ldblib.c
new file mode 100644
index 0000000..5e1314e
--- /dev/null
+++ b/misc/liblua/ldblib.c
@@ -0,0 +1,397 @@
+/*
+** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $
+** Interface from Lua to its debug API
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldblib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+static int db_getregistry (lua_State *L) {
+ lua_pushvalue(L, LUA_REGISTRYINDEX);
+ return 1;
+}
+
+
+static int db_getmetatable (lua_State *L) {
+ luaL_checkany(L, 1);
+ if (!lua_getmetatable(L, 1)) {
+ lua_pushnil(L); /* no metatable */
+ }
+ return 1;
+}
+
+
+static int db_setmetatable (lua_State *L) {
+ int t = lua_type(L, 2);
+ luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
+ "nil or table expected");
+ lua_settop(L, 2);
+ lua_pushboolean(L, lua_setmetatable(L, 1));
+ return 1;
+}
+
+
+static int db_getfenv (lua_State *L) {
+ lua_getfenv(L, 1);
+ return 1;
+}
+
+
+static int db_setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ lua_settop(L, 2);
+ if (lua_setfenv(L, 1) == 0)
+ luaL_error(L, LUA_QL("setfenv")
+ " cannot change environment of given object");
+ return 1;
+}
+
+
+static void settabss (lua_State *L, const char *i, const char *v) {
+ lua_pushstring(L, v);
+ lua_setfield(L, -2, i);
+}
+
+
+static void settabsi (lua_State *L, const char *i, int v) {
+ lua_pushinteger(L, v);
+ lua_setfield(L, -2, i);
+}
+
+
+static lua_State *getthread (lua_State *L, int *arg) {
+ if (lua_isthread(L, 1)) {
+ *arg = 1;
+ return lua_tothread(L, 1);
+ }
+ else {
+ *arg = 0;
+ return L;
+ }
+}
+
+
+static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
+ if (L == L1) {
+ lua_pushvalue(L, -2);
+ lua_remove(L, -3);
+ }
+ else
+ lua_xmove(L1, L, 1);
+ lua_setfield(L, -2, fname);
+}
+
+
+static int db_getinfo (lua_State *L) {
+ lua_Debug ar;
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ const char *options = luaL_optstring(L, arg+2, "flnSu");
+ if (lua_isnumber(L, arg+1)) {
+ if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
+ lua_pushnil(L); /* level out of range */
+ return 1;
+ }
+ }
+ else if (lua_isfunction(L, arg+1)) {
+ lua_pushfstring(L, ">%s", options);
+ options = lua_tostring(L, -1);
+ lua_pushvalue(L, arg+1);
+ lua_xmove(L, L1, 1);
+ }
+ else
+ return luaL_argerror(L, arg+1, "function or level expected");
+ if (!lua_getinfo(L1, options, &ar))
+ return luaL_argerror(L, arg+2, "invalid option");
+ lua_createtable(L, 0, 2);
+ if (strchr(options, 'S')) {
+ settabss(L, "source", ar.source);
+ settabss(L, "short_src", ar.short_src);
+ settabsi(L, "linedefined", ar.linedefined);
+ settabsi(L, "lastlinedefined", ar.lastlinedefined);
+ settabss(L, "what", ar.what);
+ }
+ if (strchr(options, 'l'))
+ settabsi(L, "currentline", ar.currentline);
+ if (strchr(options, 'u'))
+ settabsi(L, "nups", ar.nups);
+ if (strchr(options, 'n')) {
+ settabss(L, "name", ar.name);
+ settabss(L, "namewhat", ar.namewhat);
+ }
+ if (strchr(options, 'L'))
+ treatstackoption(L, L1, "activelines");
+ if (strchr(options, 'f'))
+ treatstackoption(L, L1, "func");
+ return 1; /* return table */
+}
+
+
+static int db_getlocal (lua_State *L) {
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ lua_Debug ar;
+ const char *name;
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ return luaL_argerror(L, arg+1, "level out of range");
+ name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
+ if (name) {
+ lua_xmove(L1, L, 1);
+ lua_pushstring(L, name);
+ lua_pushvalue(L, -2);
+ return 2;
+ }
+ else {
+ lua_pushnil(L);
+ return 1;
+ }
+}
+
+
+static int db_setlocal (lua_State *L) {
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ lua_Debug ar;
+ if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
+ return luaL_argerror(L, arg+1, "level out of range");
+ luaL_checkany(L, arg+3);
+ lua_settop(L, arg+3);
+ lua_xmove(L, L1, 1);
+ lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
+ return 1;
+}
+
+
+static int auxupvalue (lua_State *L, int get) {
+ const char *name;
+ int n = luaL_checkint(L, 2);
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
+ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
+ if (name == NULL) return 0;
+ lua_pushstring(L, name);
+ lua_insert(L, -(get+1));
+ return get + 1;
+}
+
+
+static int db_getupvalue (lua_State *L) {
+ return auxupvalue(L, 1);
+}
+
+
+static int db_setupvalue (lua_State *L) {
+ luaL_checkany(L, 3);
+ return auxupvalue(L, 0);
+}
+
+
+
+static const char KEY_HOOK = 'h';
+
+
+static void hookf (lua_State *L, lua_Debug *ar) {
+ static const char *const hooknames[] =
+ {"call", "return", "line", "count", "tail return"};
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ lua_pushlightuserdata(L, L);
+ lua_rawget(L, -2);
+ if (lua_isfunction(L, -1)) {
+ lua_pushstring(L, hooknames[(int)ar->event]);
+ if (ar->currentline >= 0)
+ lua_pushinteger(L, ar->currentline);
+ else lua_pushnil(L);
+ lua_assert(lua_getinfo(L, "lS", ar));
+ lua_call(L, 2, 0);
+ }
+}
+
+
+static int makemask (const char *smask, int count) {
+ int mask = 0;
+ if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
+ if (strchr(smask, 'r')) mask |= LUA_MASKRET;
+ if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
+ if (count > 0) mask |= LUA_MASKCOUNT;
+ return mask;
+}
+
+
+static char *unmakemask (int mask, char *smask) {
+ int i = 0;
+ if (mask & LUA_MASKCALL) smask[i++] = 'c';
+ if (mask & LUA_MASKRET) smask[i++] = 'r';
+ if (mask & LUA_MASKLINE) smask[i++] = 'l';
+ smask[i] = '\0';
+ return smask;
+}
+
+
+static void gethooktable (lua_State *L) {
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 1);
+ lua_pushlightuserdata(L, (void *)&KEY_HOOK);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+}
+
+
+static int db_sethook (lua_State *L) {
+ int arg, mask, count;
+ lua_Hook func;
+ lua_State *L1 = getthread(L, &arg);
+ if (lua_isnoneornil(L, arg+1)) {
+ lua_settop(L, arg+1);
+ func = NULL; mask = 0; count = 0; /* turn off hooks */
+ }
+ else {
+ const char *smask = luaL_checkstring(L, arg+2);
+ luaL_checktype(L, arg+1, LUA_TFUNCTION);
+ count = luaL_optint(L, arg+3, 0);
+ func = hookf; mask = makemask(smask, count);
+ }
+ gethooktable(L);
+ lua_pushlightuserdata(L, L1);
+ lua_pushvalue(L, arg+1);
+ lua_rawset(L, -3); /* set new hook */
+ lua_pop(L, 1); /* remove hook table */
+ lua_sethook(L1, func, mask, count); /* set hooks */
+ return 0;
+}
+
+
+static int db_gethook (lua_State *L) {
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ char buff[5];
+ int mask = lua_gethookmask(L1);
+ lua_Hook hook = lua_gethook(L1);
+ if (hook != NULL && hook != hookf) /* external hook? */
+ lua_pushliteral(L, "external hook");
+ else {
+ gethooktable(L);
+ lua_pushlightuserdata(L, L1);
+ lua_rawget(L, -2); /* get hook */
+ lua_remove(L, -2); /* remove hook table */
+ }
+ lua_pushstring(L, unmakemask(mask, buff));
+ lua_pushinteger(L, lua_gethookcount(L1));
+ return 3;
+}
+
+
+static int db_debug (lua_State *L) {
+ for (;;) {
+ char buffer[250];
+ fputs("lua_debug> ", stderr);
+ if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
+ strcmp(buffer, "cont\n") == 0)
+ return 0;
+ if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
+ lua_pcall(L, 0, 0, 0)) {
+ fputs(lua_tostring(L, -1), stderr);
+ fputs("\n", stderr);
+ }
+ lua_settop(L, 0); /* remove eventual returns */
+ }
+}
+
+
+#define LEVELS1 12 /* size of the first part of the stack */
+#define LEVELS2 10 /* size of the second part of the stack */
+
+static int db_errorfb (lua_State *L) {
+ int level;
+ int firstpart = 1; /* still before eventual `...' */
+ int arg;
+ lua_State *L1 = getthread(L, &arg);
+ lua_Debug ar;
+ if (lua_isnumber(L, arg+2)) {
+ level = (int)lua_tointeger(L, arg+2);
+ lua_pop(L, 1);
+ }
+ else
+ level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
+ if (lua_gettop(L) == arg)
+ lua_pushliteral(L, "");
+ else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
+ else lua_pushliteral(L, "\n");
+ lua_pushliteral(L, "stack traceback:");
+ while (lua_getstack(L1, level++, &ar)) {
+ if (level > LEVELS1 && firstpart) {
+ /* no more than `LEVELS2' more levels? */
+ if (!lua_getstack(L1, level+LEVELS2, &ar))
+ level--; /* keep going */
+ else {
+ lua_pushliteral(L, "\n\t..."); /* too many levels */
+ while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
+ level++;
+ }
+ firstpart = 0;
+ continue;
+ }
+ lua_pushliteral(L, "\n\t");
+ lua_getinfo(L1, "Snl", &ar);
+ lua_pushfstring(L, "%s:", ar.short_src);
+ if (ar.currentline > 0)
+ lua_pushfstring(L, "%d:", ar.currentline);
+ if (*ar.namewhat != '\0') /* is there a name? */
+ lua_pushfstring(L, " in function " LUA_QS, ar.name);
+ else {
+ if (*ar.what == 'm') /* main? */
+ lua_pushfstring(L, " in main chunk");
+ else if (*ar.what == 'C' || *ar.what == 't')
+ lua_pushliteral(L, " ?"); /* C function or tail call */
+ else
+ lua_pushfstring(L, " in function <%s:%d>",
+ ar.short_src, ar.linedefined);
+ }
+ lua_concat(L, lua_gettop(L) - arg);
+ }
+ lua_concat(L, lua_gettop(L) - arg);
+ return 1;
+}
+
+
+static const luaL_Reg dblib[] = {
+ {"debug", db_debug},
+ {"getfenv", db_getfenv},
+ {"gethook", db_gethook},
+ {"getinfo", db_getinfo},
+ {"getlocal", db_getlocal},
+ {"getregistry", db_getregistry},
+ {"getmetatable", db_getmetatable},
+ {"getupvalue", db_getupvalue},
+ {"setfenv", db_setfenv},
+ {"sethook", db_sethook},
+ {"setlocal", db_setlocal},
+ {"setmetatable", db_setmetatable},
+ {"setupvalue", db_setupvalue},
+ {"traceback", db_errorfb},
+ {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_debug (lua_State *L) {
+ luaL_register(L, LUA_DBLIBNAME, dblib);
+ return 1;
+}
+
diff --git a/misc/liblua/ldebug.c b/misc/liblua/ldebug.c
new file mode 100644
index 0000000..69456b9
--- /dev/null
+++ b/misc/liblua/ldebug.c
@@ -0,0 +1,638 @@
+/*
+** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
+** Debug Interface
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+
+#define ldebug_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lapi.h"
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+
+static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
+
+
+static int currentpc (lua_State *L, CallInfo *ci) {
+ if (!isLua(ci)) return -1; /* function is not a Lua function? */
+ if (ci == L->ci)
+ ci->savedpc = L->savedpc;
+ return pcRel(ci->savedpc, ci_func(ci)->l.p);
+}
+
+
+static int currentline (lua_State *L, CallInfo *ci) {
+ int pc = currentpc(L, ci);
+ if (pc < 0)
+ return -1; /* only active lua functions have current-line information */
+ else
+ return getline(ci_func(ci)->l.p, pc);
+}
+
+
+/*
+** this function can be called asynchronous (e.g. during a signal)
+*/
+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
+ if (func == NULL || mask == 0) { /* turn off hooks? */
+ mask = 0;
+ func = NULL;
+ }
+ L->hook = func;
+ L->basehookcount = count;
+ resethookcount(L);
+ L->hookmask = cast_byte(mask);
+ return 1;
+}
+
+
+LUA_API lua_Hook lua_gethook (lua_State *L) {
+ return L->hook;
+}
+
+
+LUA_API int lua_gethookmask (lua_State *L) {
+ return L->hookmask;
+}
+
+
+LUA_API int lua_gethookcount (lua_State *L) {
+ return L->basehookcount;
+}
+
+
+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
+ int status;
+ CallInfo *ci;
+ lua_lock(L);
+ for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
+ level--;
+ if (f_isLua(ci)) /* Lua function? */
+ level -= ci->tailcalls; /* skip lost tail calls */
+ }
+ if (level == 0 && ci > L->base_ci) { /* level found? */
+ status = 1;
+ ar->i_ci = cast_int(ci - L->base_ci);
+ }
+ else if (level < 0) { /* level is of a lost tail call? */
+ status = 1;
+ ar->i_ci = 0;
+ }
+ else status = 0; /* no such level */
+ lua_unlock(L);
+ return status;
+}
+
+
+static Proto *getluaproto (CallInfo *ci) {
+ return (isLua(ci) ? ci_func(ci)->l.p : NULL);
+}
+
+
+static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
+ const char *name;
+ Proto *fp = getluaproto(ci);
+ if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
+ return name; /* is a local variable in a Lua function */
+ else {
+ StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
+ if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
+ return "(*temporary)";
+ else
+ return NULL;
+ }
+}
+
+
+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
+ CallInfo *ci = L->base_ci + ar->i_ci;
+ const char *name = findlocal(L, ci, n);
+ lua_lock(L);
+ if (name)
+ luaA_pushobject(L, ci->base + (n - 1));
+ lua_unlock(L);
+ return name;
+}
+
+
+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
+ CallInfo *ci = L->base_ci + ar->i_ci;
+ const char *name = findlocal(L, ci, n);
+ lua_lock(L);
+ if (name)
+ setobjs2s(L, ci->base + (n - 1), L->top - 1);
+ L->top--; /* pop value */
+ lua_unlock(L);
+ return name;
+}
+
+
+static void funcinfo (lua_Debug *ar, Closure *cl) {
+ if (cl->c.isC) {
+ ar->source = "=[C]";
+ ar->linedefined = -1;
+ ar->lastlinedefined = -1;
+ ar->what = "C";
+ }
+ else {
+ ar->source = getstr(cl->l.p->source);
+ ar->linedefined = cl->l.p->linedefined;
+ ar->lastlinedefined = cl->l.p->lastlinedefined;
+ ar->what = (ar->linedefined == 0) ? "main" : "Lua";
+ }
+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+}
+
+
+static void info_tailcall (lua_Debug *ar) {
+ ar->name = ar->namewhat = "";
+ ar->what = "tail";
+ ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
+ ar->source = "=(tail call)";
+ luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
+ ar->nups = 0;
+}
+
+
+static void collectvalidlines (lua_State *L, Closure *f) {
+ if (f == NULL || f->c.isC) {
+ setnilvalue(L->top);
+ }
+ else {
+ Table *t = luaH_new(L, 0, 0);
+ int *lineinfo = f->l.p->lineinfo;
+ int i;
+ for (i=0; i<f->l.p->sizelineinfo; i++)
+ setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
+ sethvalue(L, L->top, t);
+ }
+ incr_top(L);
+}
+
+
+static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
+ Closure *f, CallInfo *ci) {
+ int status = 1;
+ if (f == NULL) {
+ info_tailcall(ar);
+ return status;
+ }
+ for (; *what; what++) {
+ switch (*what) {
+ case 'S': {
+ funcinfo(ar, f);
+ break;
+ }
+ case 'l': {
+ ar->currentline = (ci) ? currentline(L, ci) : -1;
+ break;
+ }
+ case 'u': {
+ ar->nups = f->c.nupvalues;
+ break;
+ }
+ case 'n': {
+ ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
+ if (ar->namewhat == NULL) {
+ ar->namewhat = ""; /* not found */
+ ar->name = NULL;
+ }
+ break;
+ }
+ case 'L':
+ case 'f': /* handled by lua_getinfo */
+ break;
+ default: status = 0; /* invalid option */
+ }
+ }
+ return status;
+}
+
+
+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
+ int status;
+ Closure *f = NULL;
+ CallInfo *ci = NULL;
+ lua_lock(L);
+ if (*what == '>') {
+ StkId func = L->top - 1;
+ luai_apicheck(L, ttisfunction(func));
+ what++; /* skip the '>' */
+ f = clvalue(func);
+ L->top--; /* pop function */
+ }
+ else if (ar->i_ci != 0) { /* no tail call? */
+ ci = L->base_ci + ar->i_ci;
+ lua_assert(ttisfunction(ci->func));
+ f = clvalue(ci->func);
+ }
+ status = auxgetinfo(L, what, ar, f, ci);
+ if (strchr(what, 'f')) {
+ if (f == NULL) setnilvalue(L->top);
+ else setclvalue(L, L->top, f);
+ incr_top(L);
+ }
+ if (strchr(what, 'L'))
+ collectvalidlines(L, f);
+ lua_unlock(L);
+ return status;
+}
+
+
+/*
+** {======================================================
+** Symbolic Execution and code checker
+** =======================================================
+*/
+
+#define check(x) if (!(x)) return 0;
+
+#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
+
+#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
+
+
+
+static int precheck (const Proto *pt) {
+ check(pt->maxstacksize <= MAXSTACK);
+ check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
+ check(!(pt->is_vararg & VARARG_NEEDSARG) ||
+ (pt->is_vararg & VARARG_HASARG));
+ check(pt->sizeupvalues <= pt->nups);
+ check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
+ check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
+ return 1;
+}
+
+
+#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
+
+int luaG_checkopenop (Instruction i) {
+ switch (GET_OPCODE(i)) {
+ case OP_CALL:
+ case OP_TAILCALL:
+ case OP_RETURN:
+ case OP_SETLIST: {
+ check(GETARG_B(i) == 0);
+ return 1;
+ }
+ default: return 0; /* invalid instruction after an open call */
+ }
+}
+
+
+static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
+ switch (mode) {
+ case OpArgN: check(r == 0); break;
+ case OpArgU: break;
+ case OpArgR: checkreg(pt, r); break;
+ case OpArgK:
+ check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
+ break;
+ }
+ return 1;
+}
+
+
+static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
+ int pc;
+ int last; /* stores position of last instruction that changed `reg' */
+ last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
+ check(precheck(pt));
+ for (pc = 0; pc < lastpc; pc++) {
+ Instruction i = pt->code[pc];
+ OpCode op = GET_OPCODE(i);
+ int a = GETARG_A(i);
+ int b = 0;
+ int c = 0;
+ check(op < NUM_OPCODES);
+ checkreg(pt, a);
+ switch (getOpMode(op)) {
+ case iABC: {
+ b = GETARG_B(i);
+ c = GETARG_C(i);
+ check(checkArgMode(pt, b, getBMode(op)));
+ check(checkArgMode(pt, c, getCMode(op)));
+ break;
+ }
+ case iABx: {
+ b = GETARG_Bx(i);
+ if (getBMode(op) == OpArgK) check(b < pt->sizek);
+ break;
+ }
+ case iAsBx: {
+ b = GETARG_sBx(i);
+ if (getBMode(op) == OpArgR) {
+ int dest = pc+1+b;
+ check(0 <= dest && dest < pt->sizecode);
+ if (dest > 0) {
+ int j;
+ /* check that it does not jump to a setlist count; this
+ is tricky, because the count from a previous setlist may
+ have the same value of an invalid setlist; so, we must
+ go all the way back to the first of them (if any) */
+ for (j = 0; j < dest; j++) {
+ Instruction d = pt->code[dest-1-j];
+ if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
+ }
+ /* if 'j' is even, previous value is not a setlist (even if
+ it looks like one) */
+ check((j&1) == 0);
+ }
+ }
+ break;
+ }
+ }
+ if (testAMode(op)) {
+ if (a == reg) last = pc; /* change register `a' */
+ }
+ if (testTMode(op)) {
+ check(pc+2 < pt->sizecode); /* check skip */
+ check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
+ }
+ switch (op) {
+ case OP_LOADBOOL: {
+ if (c == 1) { /* does it jump? */
+ check(pc+2 < pt->sizecode); /* check its jump */
+ check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
+ GETARG_C(pt->code[pc+1]) != 0);
+ }
+ break;
+ }
+ case OP_LOADNIL: {
+ if (a <= reg && reg <= b)
+ last = pc; /* set registers from `a' to `b' */
+ break;
+ }
+ case OP_GETUPVAL:
+ case OP_SETUPVAL: {
+ check(b < pt->nups);
+ break;
+ }
+ case OP_GETGLOBAL:
+ case OP_SETGLOBAL: {
+ check(ttisstring(&pt->k[b]));
+ break;
+ }
+ case OP_SELF: {
+ checkreg(pt, a+1);
+ if (reg == a+1) last = pc;
+ break;
+ }
+ case OP_CONCAT: {
+ check(b < c); /* at least two operands */
+ break;
+ }
+ case OP_TFORLOOP: {
+ check(c >= 1); /* at least one result (control variable) */
+ checkreg(pt, a+2+c); /* space for results */
+ if (reg >= a+2) last = pc; /* affect all regs above its base */
+ break;
+ }
+ case OP_FORLOOP:
+ case OP_FORPREP:
+ checkreg(pt, a+3);
+ /* go through */
+ case OP_JMP: {
+ int dest = pc+1+b;
+ /* not full check and jump is forward and do not skip `lastpc'? */
+ if (reg != NO_REG && pc < dest && dest <= lastpc)
+ pc += b; /* do the jump */
+ break;
+ }
+ case OP_CALL:
+ case OP_TAILCALL: {
+ if (b != 0) {
+ checkreg(pt, a+b-1);
+ }
+ c--; /* c = num. returns */
+ if (c == LUA_MULTRET) {
+ check(checkopenop(pt, pc));
+ }
+ else if (c != 0)
+ checkreg(pt, a+c-1);
+ if (reg >= a) last = pc; /* affect all registers above base */
+ break;
+ }
+ case OP_RETURN: {
+ b--; /* b = num. returns */
+ if (b > 0) checkreg(pt, a+b-1);
+ break;
+ }
+ case OP_SETLIST: {
+ if (b > 0) checkreg(pt, a + b);
+ if (c == 0) {
+ pc++;
+ check(pc < pt->sizecode - 1);
+ }
+ break;
+ }
+ case OP_CLOSURE: {
+ int nup, j;
+ check(b < pt->sizep);
+ nup = pt->p[b]->nups;
+ check(pc + nup < pt->sizecode);
+ for (j = 1; j <= nup; j++) {
+ OpCode op1 = GET_OPCODE(pt->code[pc + j]);
+ check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
+ }
+ if (reg != NO_REG) /* tracing? */
+ pc += nup; /* do not 'execute' these pseudo-instructions */
+ break;
+ }
+ case OP_VARARG: {
+ check((pt->is_vararg & VARARG_ISVARARG) &&
+ !(pt->is_vararg & VARARG_NEEDSARG));
+ b--;
+ if (b == LUA_MULTRET) check(checkopenop(pt, pc));
+ checkreg(pt, a+b-1);
+ break;
+ }
+ default: break;
+ }
+ }
+ return pt->code[last];
+}
+
+#undef check
+#undef checkjump
+#undef checkreg
+
+/* }====================================================== */
+
+
+int luaG_checkcode (const Proto *pt) {
+ return (symbexec(pt, pt->sizecode, NO_REG) != 0);
+}
+
+
+static const char *kname (Proto *p, int c) {
+ if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
+ return svalue(&p->k[INDEXK(c)]);
+ else
+ return "?";
+}
+
+
+static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
+ const char **name) {
+ if (isLua(ci)) { /* a Lua function? */
+ Proto *p = ci_func(ci)->l.p;
+ int pc = currentpc(L, ci);
+ Instruction i;
+ *name = luaF_getlocalname(p, stackpos+1, pc);
+ if (*name) /* is a local? */
+ return "local";
+ i = symbexec(p, pc, stackpos); /* try symbolic execution */
+ lua_assert(pc != -1);
+ switch (GET_OPCODE(i)) {
+ case OP_GETGLOBAL: {
+ int g = GETARG_Bx(i); /* global index */
+ lua_assert(ttisstring(&p->k[g]));
+ *name = svalue(&p->k[g]);
+ return "global";
+ }
+ case OP_MOVE: {
+ int a = GETARG_A(i);
+ int b = GETARG_B(i); /* move from `b' to `a' */
+ if (b < a)
+ return getobjname(L, ci, b, name); /* get name for `b' */
+ break;
+ }
+ case OP_GETTABLE: {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ return "field";
+ }
+ case OP_GETUPVAL: {
+ int u = GETARG_B(i); /* upvalue index */
+ *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
+ return "upvalue";
+ }
+ case OP_SELF: {
+ int k = GETARG_C(i); /* key index */
+ *name = kname(p, k);
+ return "method";
+ }
+ default: break;
+ }
+ }
+ return NULL; /* no useful name found */
+}
+
+
+static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
+ Instruction i;
+ if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
+ return NULL; /* calling function is not Lua (or is unknown) */
+ ci--; /* calling function */
+ i = ci_func(ci)->l.p->code[currentpc(L, ci)];
+ if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
+ GET_OPCODE(i) == OP_TFORLOOP)
+ return getobjname(L, ci, GETARG_A(i), name);
+ else
+ return NULL; /* no useful name can be found */
+}
+
+
+/* only ANSI way to check whether a pointer points to an array */
+static int isinstack (CallInfo *ci, const TValue *o) {
+ StkId p;
+ for (p = ci->base; p < ci->top; p++)
+ if (o == p) return 1;
+ return 0;
+}
+
+
+void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+ const char *name = NULL;
+ const char *t = luaT_typenames[ttype(o)];
+ const char *kind = (isinstack(L->ci, o)) ?
+ getobjname(L, L->ci, cast_int(o - L->base), &name) :
+ NULL;
+ if (kind)
+ luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
+ op, kind, name, t);
+ else
+ luaG_runerror(L, "attempt to %s a %s value", op, t);
+}
+
+
+void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+ if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
+ lua_assert(!ttisstring(p1) && !ttisnumber(p1));
+ luaG_typeerror(L, p1, "concatenate");
+}
+
+
+void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
+ TValue temp;
+ if (luaV_tonumber(p1, &temp) == NULL)
+ p2 = p1; /* first operand is wrong */
+ luaG_typeerror(L, p2, "perform arithmetic on");
+}
+
+
+int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+ const char *t1 = luaT_typenames[ttype(p1)];
+ const char *t2 = luaT_typenames[ttype(p2)];
+ if (t1[2] == t2[2])
+ luaG_runerror(L, "attempt to compare two %s values", t1);
+ else
+ luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
+ return 0;
+}
+
+
+static void addinfo (lua_State *L, const char *msg) {
+ CallInfo *ci = L->ci;
+ if (isLua(ci)) { /* is Lua code? */
+ char buff[LUA_IDSIZE]; /* add file:line information */
+ int line = currentline(L, ci);
+ luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
+ luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
+ }
+}
+
+
+void luaG_errormsg (lua_State *L) {
+ if (L->errfunc != 0) { /* is there an error handling function? */
+ StkId errfunc = restorestack(L, L->errfunc);
+ if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
+ setobjs2s(L, L->top, L->top - 1); /* move argument */
+ setobjs2s(L, L->top - 1, errfunc); /* push function */
+ incr_top(L);
+ luaD_call(L, L->top - 2, 1); /* call it */
+ }
+ luaD_throw(L, LUA_ERRRUN);
+}
+
+
+void luaG_runerror (lua_State *L, const char *fmt, ...) {
+ va_list argp;
+ va_start(argp, fmt);
+ addinfo(L, luaO_pushvfstring(L, fmt, argp));
+ va_end(argp);
+ luaG_errormsg(L);
+}
+
diff --git a/misc/liblua/ldebug.h b/misc/liblua/ldebug.h
new file mode 100644
index 0000000..ba28a97
--- /dev/null
+++ b/misc/liblua/ldebug.h
@@ -0,0 +1,33 @@
+/*
+** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $
+** Auxiliary functions from Debug Interface module
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldebug_h
+#define ldebug_h
+
+
+#include "lstate.h"
+
+
+#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
+
+#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
+
+#define resethookcount(L) (L->hookcount = L->basehookcount)
+
+
+LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
+ const char *opname);
+LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
+ const TValue *p2);
+LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
+LUAI_FUNC void luaG_errormsg (lua_State *L);
+LUAI_FUNC int luaG_checkcode (const Proto *pt);
+LUAI_FUNC int luaG_checkopenop (Instruction i);
+
+#endif
diff --git a/misc/liblua/ldo.c b/misc/liblua/ldo.c
new file mode 100644
index 0000000..7cac000
--- /dev/null
+++ b/misc/liblua/ldo.c
@@ -0,0 +1,518 @@
+/*
+** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ldo_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lundump.h"
+#include "lvm.h"
+#include "lzio.h"
+
+
+
+
+/*
+** {======================================================
+** Error-recovery functions
+** =======================================================
+*/
+
+
+/* chain list of long jump buffers */
+struct lua_longjmp {
+ struct lua_longjmp *previous;
+ luai_jmpbuf b;
+ volatile int status; /* error code */
+};
+
+
+void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
+ switch (errcode) {
+ case LUA_ERRMEM: {
+ setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
+ break;
+ }
+ case LUA_ERRERR: {
+ setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
+ break;
+ }
+ case LUA_ERRSYNTAX:
+ case LUA_ERRRUN: {
+ setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
+ break;
+ }
+ }
+ L->top = oldtop + 1;
+}
+
+
+static void restore_stack_limit (lua_State *L) {
+ lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
+ if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */
+ int inuse = cast_int(L->ci - L->base_ci);
+ if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */
+ luaD_reallocCI(L, LUAI_MAXCALLS);
+ }
+}
+
+
+static void resetstack (lua_State *L, int status) {
+ L->ci = L->base_ci;
+ L->base = L->ci->base;
+ luaF_close(L, L->base); /* close eventual pending closures */
+ luaD_seterrorobj(L, status, L->base);
+ L->nCcalls = L->baseCcalls;
+ L->allowhook = 1;
+ restore_stack_limit(L);
+ L->errfunc = 0;
+ L->errorJmp = NULL;
+}
+
+
+void luaD_throw (lua_State *L, int errcode) {
+ if (L->errorJmp) {
+ L->errorJmp->status = errcode;
+ LUAI_THROW(L, L->errorJmp);
+ }
+ else {
+ L->status = cast_byte(errcode);
+ if (G(L)->panic) {
+ resetstack(L, errcode);
+ lua_unlock(L);
+ G(L)->panic(L);
+ }
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
+ struct lua_longjmp lj;
+ lj.status = 0;
+ lj.previous = L->errorJmp; /* chain new error handler */
+ L->errorJmp = &lj;
+ LUAI_TRY(L, &lj,
+ (*f)(L, ud);
+ );
+ L->errorJmp = lj.previous; /* restore old error handler */
+ return lj.status;
+}
+
+/* }====================================================== */
+
+
+static void correctstack (lua_State *L, TValue *oldstack) {
+ CallInfo *ci;
+ GCObject *up;
+ L->top = (L->top - oldstack) + L->stack;
+ for (up = L->openupval; up != NULL; up = up->gch.next)
+ gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
+ for (ci = L->base_ci; ci <= L->ci; ci++) {
+ ci->top = (ci->top - oldstack) + L->stack;
+ ci->base = (ci->base - oldstack) + L->stack;
+ ci->func = (ci->func - oldstack) + L->stack;
+ }
+ L->base = (L->base - oldstack) + L->stack;
+}
+
+
+void luaD_reallocstack (lua_State *L, int newsize) {
+ TValue *oldstack = L->stack;
+ int realsize = newsize + 1 + EXTRA_STACK;
+ lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1);
+ luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue);
+ L->stacksize = realsize;
+ L->stack_last = L->stack+newsize;
+ correctstack(L, oldstack);
+}
+
+
+void luaD_reallocCI (lua_State *L, int newsize) {
+ CallInfo *oldci = L->base_ci;
+ luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo);
+ L->size_ci = newsize;
+ L->ci = (L->ci - oldci) + L->base_ci;
+ L->end_ci = L->base_ci + L->size_ci - 1;
+}
+
+
+void luaD_growstack (lua_State *L, int n) {
+ if (n <= L->stacksize) /* double size is enough? */
+ luaD_reallocstack(L, 2*L->stacksize);
+ else
+ luaD_reallocstack(L, L->stacksize + n);
+}
+
+
+static CallInfo *growCI (lua_State *L) {
+ if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */
+ luaD_throw(L, LUA_ERRERR);
+ else {
+ luaD_reallocCI(L, 2*L->size_ci);
+ if (L->size_ci > LUAI_MAXCALLS)
+ luaG_runerror(L, "stack overflow");
+ }
+ return ++L->ci;
+}
+
+
+void luaD_callhook (lua_State *L, int event, int line) {
+ lua_Hook hook = L->hook;
+ if (hook && L->allowhook) {
+ ptrdiff_t top = savestack(L, L->top);
+ ptrdiff_t ci_top = savestack(L, L->ci->top);
+ lua_Debug ar;
+ ar.event = event;
+ ar.currentline = line;
+ if (event == LUA_HOOKTAILRET)
+ ar.i_ci = 0; /* tail call; no debug information about it */
+ else
+ ar.i_ci = cast_int(L->ci - L->base_ci);
+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
+ L->ci->top = L->top + LUA_MINSTACK;
+ lua_assert(L->ci->top <= L->stack_last);
+ L->allowhook = 0; /* cannot call hooks inside a hook */
+ lua_unlock(L);
+ (*hook)(L, &ar);
+ lua_lock(L);
+ lua_assert(!L->allowhook);
+ L->allowhook = 1;
+ L->ci->top = restorestack(L, ci_top);
+ L->top = restorestack(L, top);
+ }
+}
+
+
+static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
+ int i;
+ int nfixargs = p->numparams;
+ Table *htab = NULL;
+ StkId base, fixed;
+ for (; actual < nfixargs; ++actual)
+ setnilvalue(L->top++);
+#if defined(LUA_COMPAT_VARARG)
+ if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
+ int nvar = actual - nfixargs; /* number of extra arguments */
+ lua_assert(p->is_vararg & VARARG_HASARG);
+ luaC_checkGC(L);
+ htab = luaH_new(L, nvar, 1); /* create `arg' table */
+ for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
+ setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
+ /* store counter in field `n' */
+ setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
+ }
+#endif
+ /* move fixed parameters to final position */
+ fixed = L->top - actual; /* first fixed argument */
+ base = L->top; /* final position of first argument */
+ for (i=0; i<nfixargs; i++) {
+ setobjs2s(L, L->top++, fixed+i);
+ setnilvalue(fixed+i);
+ }
+ /* add `arg' parameter */
+ if (htab) {
+ sethvalue(L, L->top++, htab);
+ lua_assert(iswhite(obj2gco(htab)));
+ }
+ return base;
+}
+
+
+static StkId tryfuncTM (lua_State *L, StkId func) {
+ const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
+ StkId p;
+ ptrdiff_t funcr = savestack(L, func);
+ if (!ttisfunction(tm))
+ luaG_typeerror(L, func, "call");
+ /* Open a hole inside the stack at `func' */
+ for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
+ incr_top(L);
+ func = restorestack(L, funcr); /* previous call may change stack */
+ setobj2s(L, func, tm); /* tag method is the new function to be called */
+ return func;
+}
+
+
+
+#define inc_ci(L) \
+ ((L->ci == L->end_ci) ? growCI(L) : \
+ (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci))
+
+
+int luaD_precall (lua_State *L, StkId func, int nresults) {
+ LClosure *cl;
+ ptrdiff_t funcr;
+ if (!ttisfunction(func)) /* `func' is not a function? */
+ func = tryfuncTM(L, func); /* check the `function' tag method */
+ funcr = savestack(L, func);
+ cl = &clvalue(func)->l;
+ L->ci->savedpc = L->savedpc;
+ if (!cl->isC) { /* Lua function? prepare its call */
+ CallInfo *ci;
+ StkId st, base;
+ Proto *p = cl->p;
+ luaD_checkstack(L, p->maxstacksize);
+ func = restorestack(L, funcr);
+ if (!p->is_vararg) { /* no varargs? */
+ base = func + 1;
+ if (L->top > base + p->numparams)
+ L->top = base + p->numparams;
+ }
+ else { /* vararg function */
+ int nargs = cast_int(L->top - func) - 1;
+ base = adjust_varargs(L, p, nargs);
+ func = restorestack(L, funcr); /* previous call may change the stack */
+ }
+ ci = inc_ci(L); /* now `enter' new function */
+ ci->func = func;
+ L->base = ci->base = base;
+ ci->top = L->base + p->maxstacksize;
+ lua_assert(ci->top <= L->stack_last);
+ L->savedpc = p->code; /* starting point */
+ ci->tailcalls = 0;
+ ci->nresults = nresults;
+ for (st = L->top; st < ci->top; st++)
+ setnilvalue(st);
+ L->top = ci->top;
+ if (L->hookmask & LUA_MASKCALL) {
+ L->savedpc++; /* hooks assume 'pc' is already incremented */
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ L->savedpc--; /* correct 'pc' */
+ }
+ return PCRLUA;
+ }
+ else { /* if is a C function, call it */
+ CallInfo *ci;
+ int n;
+ luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
+ ci = inc_ci(L); /* now `enter' new function */
+ ci->func = restorestack(L, funcr);
+ L->base = ci->base = ci->func + 1;
+ ci->top = L->top + LUA_MINSTACK;
+ lua_assert(ci->top <= L->stack_last);
+ ci->nresults = nresults;
+ if (L->hookmask & LUA_MASKCALL)
+ luaD_callhook(L, LUA_HOOKCALL, -1);
+ lua_unlock(L);
+ n = (*curr_func(L)->c.f)(L); /* do the actual call */
+ lua_lock(L);
+ if (n < 0) /* yielding? */
+ return PCRYIELD;
+ else {
+ luaD_poscall(L, L->top - n);
+ return PCRC;
+ }
+ }
+}
+
+
+static StkId callrethooks (lua_State *L, StkId firstResult) {
+ ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
+ luaD_callhook(L, LUA_HOOKRET, -1);
+ if (f_isLua(L->ci)) { /* Lua function? */
+ while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */
+ luaD_callhook(L, LUA_HOOKTAILRET, -1);
+ }
+ return restorestack(L, fr);
+}
+
+
+int luaD_poscall (lua_State *L, StkId firstResult) {
+ StkId res;
+ int wanted, i;
+ CallInfo *ci;
+ if (L->hookmask & LUA_MASKRET)
+ firstResult = callrethooks(L, firstResult);
+ ci = L->ci--;
+ res = ci->func; /* res == final position of 1st result */
+ wanted = ci->nresults;
+ L->base = (ci - 1)->base; /* restore base */
+ L->savedpc = (ci - 1)->savedpc; /* restore savedpc */
+ /* move results to correct place */
+ for (i = wanted; i != 0 && firstResult < L->top; i--)
+ setobjs2s(L, res++, firstResult++);
+ while (i-- > 0)
+ setnilvalue(res++);
+ L->top = res;
+ return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
+}
+
+
+/*
+** Call a function (C or Lua). The function to be called is at *func.
+** The arguments are on the stack, right after the function.
+** When returns, all the results are on the stack, starting at the original
+** function position.
+*/
+void luaD_call (lua_State *L, StkId func, int nResults) {
+ if (++L->nCcalls >= LUAI_MAXCCALLS) {
+ if (L->nCcalls == LUAI_MAXCCALLS)
+ luaG_runerror(L, "C stack overflow");
+ else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
+ luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
+ }
+ if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
+ luaV_execute(L, 1); /* call it */
+ L->nCcalls--;
+ luaC_checkGC(L);
+}
+
+
+static void resume (lua_State *L, void *ud) {
+ StkId firstArg = cast(StkId, ud);
+ CallInfo *ci = L->ci;
+ if (L->status == 0) { /* start coroutine? */
+ lua_assert(ci == L->base_ci && firstArg > L->base);
+ if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
+ return;
+ }
+ else { /* resuming from previous yield */
+ lua_assert(L->status == LUA_YIELD);
+ L->status = 0;
+ if (!f_isLua(ci)) { /* `common' yield? */
+ /* finish interrupted execution of `OP_CALL' */
+ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
+ GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL);
+ if (luaD_poscall(L, firstArg)) /* complete it... */
+ L->top = L->ci->top; /* and correct top if not multiple results */
+ }
+ else /* yielded inside a hook: just continue its execution */
+ L->base = L->ci->base;
+ }
+ luaV_execute(L, cast_int(L->ci - L->base_ci));
+}
+
+
+static int resume_error (lua_State *L, const char *msg) {
+ L->top = L->ci->base;
+ setsvalue2s(L, L->top, luaS_new(L, msg));
+ incr_top(L);
+ lua_unlock(L);
+ return LUA_ERRRUN;
+}
+
+
+LUA_API int lua_resume (lua_State *L, int nargs) {
+ int status;
+ lua_lock(L);
+ if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci))
+ return resume_error(L, "cannot resume non-suspended coroutine");
+ if (L->nCcalls >= LUAI_MAXCCALLS)
+ return resume_error(L, "C stack overflow");
+ luai_userstateresume(L, nargs);
+ lua_assert(L->errfunc == 0);
+ L->baseCcalls = ++L->nCcalls;
+ status = luaD_rawrunprotected(L, resume, L->top - nargs);
+ if (status != 0) { /* error? */
+ L->status = cast_byte(status); /* mark thread as `dead' */
+ luaD_seterrorobj(L, status, L->top);
+ L->ci->top = L->top;
+ }
+ else {
+ lua_assert(L->nCcalls == L->baseCcalls);
+ status = L->status;
+ }
+ --L->nCcalls;
+ lua_unlock(L);
+ return status;
+}
+
+
+LUA_API int lua_yield (lua_State *L, int nresults) {
+ luai_userstateyield(L, nresults);
+ lua_lock(L);
+ if (L->nCcalls > L->baseCcalls)
+ luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
+ L->base = L->top - nresults; /* protect stack slots below */
+ L->status = LUA_YIELD;
+ lua_unlock(L);
+ return -1;
+}
+
+
+int luaD_pcall (lua_State *L, Pfunc func, void *u,
+ ptrdiff_t old_top, ptrdiff_t ef) {
+ int status;
+ unsigned short oldnCcalls = L->nCcalls;
+ ptrdiff_t old_ci = saveci(L, L->ci);
+ lu_byte old_allowhooks = L->allowhook;
+ ptrdiff_t old_errfunc = L->errfunc;
+ L->errfunc = ef;
+ status = luaD_rawrunprotected(L, func, u);
+ if (status != 0) { /* an error occurred? */
+ StkId oldtop = restorestack(L, old_top);
+ luaF_close(L, oldtop); /* close eventual pending closures */
+ luaD_seterrorobj(L, status, oldtop);
+ L->nCcalls = oldnCcalls;
+ L->ci = restoreci(L, old_ci);
+ L->base = L->ci->base;
+ L->savedpc = L->ci->savedpc;
+ L->allowhook = old_allowhooks;
+ restore_stack_limit(L);
+ }
+ L->errfunc = old_errfunc;
+ return status;
+}
+
+
+
+/*
+** Execute a protected parser.
+*/
+struct SParser { /* data to `f_parser' */
+ ZIO *z;
+ Mbuffer buff; /* buffer to be used by the scanner */
+ const char *name;
+};
+
+static void f_parser (lua_State *L, void *ud) {
+ int i;
+ Proto *tf;
+ Closure *cl;
+ struct SParser *p = cast(struct SParser *, ud);
+ int c = luaZ_lookahead(p->z);
+ luaC_checkGC(L);
+ tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
+ &p->buff, p->name);
+ cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
+ cl->l.p = tf;
+ for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
+ cl->l.upvals[i] = luaF_newupval(L);
+ setclvalue(L, L->top, cl);
+ incr_top(L);
+}
+
+
+int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
+ struct SParser p;
+ int status;
+ p.z = z; p.name = name;
+ luaZ_initbuffer(L, &p.buff);
+ status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
+ luaZ_freebuffer(L, &p.buff);
+ return status;
+}
+
+
diff --git a/misc/liblua/ldo.h b/misc/liblua/ldo.h
new file mode 100644
index 0000000..98fddac
--- /dev/null
+++ b/misc/liblua/ldo.h
@@ -0,0 +1,57 @@
+/*
+** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $
+** Stack and Call structure of Lua
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ldo_h
+#define ldo_h
+
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lzio.h"
+
+
+#define luaD_checkstack(L,n) \
+ if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
+ luaD_growstack(L, n); \
+ else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));
+
+
+#define incr_top(L) {luaD_checkstack(L,1); L->top++;}
+
+#define savestack(L,p) ((char *)(p) - (char *)L->stack)
+#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
+
+#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
+#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
+
+
+/* results from luaD_precall */
+#define PCRLUA 0 /* initiated a call to a Lua function */
+#define PCRC 1 /* did a call to a C function */
+#define PCRYIELD 2 /* C funtion yielded */
+
+
+/* type of protected functions, to be ran by `runprotected' */
+typedef void (*Pfunc) (lua_State *L, void *ud);
+
+LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
+LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
+LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
+LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
+LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
+ ptrdiff_t oldtop, ptrdiff_t ef);
+LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
+LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
+LUAI_FUNC void luaD_growstack (lua_State *L, int n);
+
+LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
+LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+
+LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
+
+#endif
+
diff --git a/misc/liblua/ldump.c b/misc/liblua/ldump.c
new file mode 100644
index 0000000..c9d3d48
--- /dev/null
+++ b/misc/liblua/ldump.c
@@ -0,0 +1,164 @@
+/*
+** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
+** save precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#include <stddef.h>
+
+#define ldump_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lundump.h"
+
+typedef struct {
+ lua_State* L;
+ lua_Writer writer;
+ void* data;
+ int strip;
+ int status;
+} DumpState;
+
+#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
+#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
+
+static void DumpBlock(const void* b, size_t size, DumpState* D)
+{
+ if (D->status==0)
+ {
+ lua_unlock(D->L);
+ D->status=(*D->writer)(D->L,b,size,D->data);
+ lua_lock(D->L);
+ }
+}
+
+static void DumpChar(int y, DumpState* D)
+{
+ char x=(char)y;
+ DumpVar(x,D);
+}
+
+static void DumpInt(int x, DumpState* D)
+{
+ DumpVar(x,D);
+}
+
+static void DumpNumber(lua_Number x, DumpState* D)
+{
+ DumpVar(x,D);
+}
+
+static void DumpVector(const void* b, int n, size_t size, DumpState* D)
+{
+ DumpInt(n,D);
+ DumpMem(b,n,size,D);
+}
+
+static void DumpString(const TString* s, DumpState* D)
+{
+ if (s==NULL || getstr(s)==NULL)
+ {
+ size_t size=0;
+ DumpVar(size,D);
+ }
+ else
+ {
+ size_t size=s->tsv.len+1; /* include trailing '\0' */
+ DumpVar(size,D);
+ DumpBlock(getstr(s),size,D);
+ }
+}
+
+#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
+
+static void DumpConstants(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizek;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+ const TValue* o=&f->k[i];
+ DumpChar(ttype(o),D);
+ switch (ttype(o))
+ {
+ case LUA_TNIL:
+ break;
+ case LUA_TBOOLEAN:
+ DumpChar(bvalue(o),D);
+ break;
+ case LUA_TNUMBER:
+ DumpNumber(nvalue(o),D);
+ break;
+ case LUA_TSTRING:
+ DumpString(rawtsvalue(o),D);
+ break;
+ default:
+ lua_assert(0); /* cannot happen */
+ break;
+ }
+ }
+ n=f->sizep;
+ DumpInt(n,D);
+ for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
+}
+
+static void DumpDebug(const Proto* f, DumpState* D)
+{
+ int i,n;
+ n= (D->strip) ? 0 : f->sizelineinfo;
+ DumpVector(f->lineinfo,n,sizeof(int),D);
+ n= (D->strip) ? 0 : f->sizelocvars;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+ DumpString(f->locvars[i].varname,D);
+ DumpInt(f->locvars[i].startpc,D);
+ DumpInt(f->locvars[i].endpc,D);
+ }
+ n= (D->strip) ? 0 : f->sizeupvalues;
+ DumpInt(n,D);
+ for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
+}
+
+static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
+{
+ DumpString((f->source==p || D->strip) ? NULL : f->source,D);
+ DumpInt(f->linedefined,D);
+ DumpInt(f->lastlinedefined,D);
+ DumpChar(f->nups,D);
+ DumpChar(f->numparams,D);
+ DumpChar(f->is_vararg,D);
+ DumpChar(f->maxstacksize,D);
+ DumpCode(f,D);
+ DumpConstants(f,D);
+ DumpDebug(f,D);
+}
+
+static void DumpHeader(DumpState* D)
+{
+ char h[LUAC_HEADERSIZE];
+ luaU_header(h);
+ DumpBlock(h,LUAC_HEADERSIZE,D);
+}
+
+/*
+** dump Lua function as precompiled chunk
+*/
+int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
+{
+ DumpState D;
+ D.L=L;
+ D.writer=w;
+ D.data=data;
+ D.strip=strip;
+ D.status=0;
+ DumpHeader(&D);
+ DumpFunction(f,NULL,&D);
+ return D.status;
+}
diff --git a/misc/liblua/lfunc.c b/misc/liblua/lfunc.c
new file mode 100644
index 0000000..813e88f
--- /dev/null
+++ b/misc/liblua/lfunc.c
@@ -0,0 +1,174 @@
+/*
+** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define lfunc_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
+ Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
+ luaC_link(L, obj2gco(c), LUA_TFUNCTION);
+ c->c.isC = 1;
+ c->c.env = e;
+ c->c.nupvalues = cast_byte(nelems);
+ return c;
+}
+
+
+Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
+ Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
+ luaC_link(L, obj2gco(c), LUA_TFUNCTION);
+ c->l.isC = 0;
+ c->l.env = e;
+ c->l.nupvalues = cast_byte(nelems);
+ while (nelems--) c->l.upvals[nelems] = NULL;
+ return c;
+}
+
+
+UpVal *luaF_newupval (lua_State *L) {
+ UpVal *uv = luaM_new(L, UpVal);
+ luaC_link(L, obj2gco(uv), LUA_TUPVAL);
+ uv->v = &uv->u.value;
+ setnilvalue(uv->v);
+ return uv;
+}
+
+
+UpVal *luaF_findupval (lua_State *L, StkId level) {
+ global_State *g = G(L);
+ GCObject **pp = &L->openupval;
+ UpVal *p;
+ UpVal *uv;
+ while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) {
+ lua_assert(p->v != &p->u.value);
+ if (p->v == level) { /* found a corresponding upvalue? */
+ if (isdead(g, obj2gco(p))) /* is it dead? */
+ changewhite(obj2gco(p)); /* ressurect it */
+ return p;
+ }
+ pp = &p->next;
+ }
+ uv = luaM_new(L, UpVal); /* not found: create a new one */
+ uv->tt = LUA_TUPVAL;
+ uv->marked = luaC_white(g);
+ uv->v = level; /* current value lives in the stack */
+ uv->next = *pp; /* chain it in the proper position */
+ *pp = obj2gco(uv);
+ uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
+ uv->u.l.next = g->uvhead.u.l.next;
+ uv->u.l.next->u.l.prev = uv;
+ g->uvhead.u.l.next = uv;
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ return uv;
+}
+
+
+static void unlinkupval (UpVal *uv) {
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
+ uv->u.l.prev->u.l.next = uv->u.l.next;
+}
+
+
+void luaF_freeupval (lua_State *L, UpVal *uv) {
+ if (uv->v != &uv->u.value) /* is it open? */
+ unlinkupval(uv); /* remove from open list */
+ luaM_free(L, uv); /* free upvalue */
+}
+
+
+void luaF_close (lua_State *L, StkId level) {
+ UpVal *uv;
+ global_State *g = G(L);
+ while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) {
+ GCObject *o = obj2gco(uv);
+ lua_assert(!isblack(o) && uv->v != &uv->u.value);
+ L->openupval = uv->next; /* remove from `open' list */
+ if (isdead(g, o))
+ luaF_freeupval(L, uv); /* free upvalue */
+ else {
+ unlinkupval(uv);
+ setobj(L, &uv->u.value, uv->v);
+ uv->v = &uv->u.value; /* now current value lives here */
+ luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
+ }
+ }
+}
+
+
+Proto *luaF_newproto (lua_State *L) {
+ Proto *f = luaM_new(L, Proto);
+ luaC_link(L, obj2gco(f), LUA_TPROTO);
+ f->k = NULL;
+ f->sizek = 0;
+ f->p = NULL;
+ f->sizep = 0;
+ f->code = NULL;
+ f->sizecode = 0;
+ f->sizelineinfo = 0;
+ f->sizeupvalues = 0;
+ f->nups = 0;
+ f->upvalues = NULL;
+ f->numparams = 0;
+ f->is_vararg = 0;
+ f->maxstacksize = 0;
+ f->lineinfo = NULL;
+ f->sizelocvars = 0;
+ f->locvars = NULL;
+ f->linedefined = 0;
+ f->lastlinedefined = 0;
+ f->source = NULL;
+ return f;
+}
+
+
+void luaF_freeproto (lua_State *L, Proto *f) {
+ luaM_freearray(L, f->code, f->sizecode, Instruction);
+ luaM_freearray(L, f->p, f->sizep, Proto *);
+ luaM_freearray(L, f->k, f->sizek, TValue);
+ luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
+ luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+ luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
+ luaM_free(L, f);
+}
+
+
+void luaF_freeclosure (lua_State *L, Closure *c) {
+ int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
+ sizeLclosure(c->l.nupvalues);
+ luaM_freemem(L, c, size);
+}
+
+
+/*
+** Look for n-th local variable at line `line' in function `func'.
+** Returns NULL if not found.
+*/
+const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
+ int i;
+ for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
+ if (pc < f->locvars[i].endpc) { /* is variable active? */
+ local_number--;
+ if (local_number == 0)
+ return getstr(f->locvars[i].varname);
+ }
+ }
+ return NULL; /* not found */
+}
+
diff --git a/misc/liblua/lfunc.h b/misc/liblua/lfunc.h
new file mode 100644
index 0000000..a68cf51
--- /dev/null
+++ b/misc/liblua/lfunc.h
@@ -0,0 +1,34 @@
+/*
+** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $
+** Auxiliary functions to manipulate prototypes and closures
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lfunc_h
+#define lfunc_h
+
+
+#include "lobject.h"
+
+
+#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
+ cast(int, sizeof(TValue)*((n)-1)))
+
+#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
+ cast(int, sizeof(TValue *)*((n)-1)))
+
+
+LUAI_FUNC Proto *luaF_newproto (lua_State *L);
+LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
+LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
+LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
+LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
+LUAI_FUNC void luaF_close (lua_State *L, StkId level);
+LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
+LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
+LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
+LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
+ int pc);
+
+
+#endif
diff --git a/misc/liblua/lgc.c b/misc/liblua/lgc.c
new file mode 100644
index 0000000..e0c69a7
--- /dev/null
+++ b/misc/liblua/lgc.c
@@ -0,0 +1,711 @@
+/*
+** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#include <string.h>
+
+#define lgc_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+#define GCSTEPSIZE 1024u
+#define GCSWEEPMAX 40
+#define GCSWEEPCOST 10
+#define GCFINALIZECOST 100
+
+
+#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
+
+#define makewhite(g,x) \
+ ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g)))
+
+#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
+#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT)
+
+#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
+
+
+#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
+#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
+
+
+#define KEYWEAK bitmask(KEYWEAKBIT)
+#define VALUEWEAK bitmask(VALUEWEAKBIT)
+
+
+
+#define markvalue(g,o) { checkconsistency(o); \
+ if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }
+
+#define markobject(g,t) { if (iswhite(obj2gco(t))) \
+ reallymarkobject(g, obj2gco(t)); }
+
+
+#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
+
+
+static void removeentry (Node *n) {
+ lua_assert(ttisnil(gval(n)));
+ if (iscollectable(gkey(n)))
+ setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
+}
+
+
+static void reallymarkobject (global_State *g, GCObject *o) {
+ lua_assert(iswhite(o) && !isdead(g, o));
+ white2gray(o);
+ switch (o->gch.tt) {
+ case LUA_TSTRING: {
+ return;
+ }
+ case LUA_TUSERDATA: {
+ Table *mt = gco2u(o)->metatable;
+ gray2black(o); /* udata are never gray */
+ if (mt) markobject(g, mt);
+ markobject(g, gco2u(o)->env);
+ return;
+ }
+ case LUA_TUPVAL: {
+ UpVal *uv = gco2uv(o);
+ markvalue(g, uv->v);
+ if (uv->v == &uv->u.value) /* closed? */
+ gray2black(o); /* open upvalues are never black */
+ return;
+ }
+ case LUA_TFUNCTION: {
+ gco2cl(o)->c.gclist = g->gray;
+ g->gray = o;
+ break;
+ }
+ case LUA_TTABLE: {
+ gco2h(o)->gclist = g->gray;
+ g->gray = o;
+ break;
+ }
+ case LUA_TTHREAD: {
+ gco2th(o)->gclist = g->gray;
+ g->gray = o;
+ break;
+ }
+ case LUA_TPROTO: {
+ gco2p(o)->gclist = g->gray;
+ g->gray = o;
+ break;
+ }
+ default: lua_assert(0);
+ }
+}
+
+
+static void marktmu (global_State *g) {
+ GCObject *u = g->tmudata;
+ if (u) {
+ do {
+ u = u->gch.next;
+ makewhite(g, u); /* may be marked, if left from previous GC */
+ reallymarkobject(g, u);
+ } while (u != g->tmudata);
+ }
+}
+
+
+/* move `dead' udata that need finalization to list `tmudata' */
+size_t luaC_separateudata (lua_State *L, int all) {
+ global_State *g = G(L);
+ size_t deadmem = 0;
+ GCObject **p = &g->mainthread->next;
+ GCObject *curr;
+ while ((curr = *p) != NULL) {
+ if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
+ p = &curr->gch.next; /* don't bother with them */
+ else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
+ markfinalized(gco2u(curr)); /* don't need finalization */
+ p = &curr->gch.next;
+ }
+ else { /* must call its gc method */
+ deadmem += sizeudata(gco2u(curr));
+ markfinalized(gco2u(curr));
+ *p = curr->gch.next;
+ /* link `curr' at the end of `tmudata' list */
+ if (g->tmudata == NULL) /* list is empty? */
+ g->tmudata = curr->gch.next = curr; /* creates a circular list */
+ else {
+ curr->gch.next = g->tmudata->gch.next;
+ g->tmudata->gch.next = curr;
+ g->tmudata = curr;
+ }
+ }
+ }
+ return deadmem;
+}
+
+
+static int traversetable (global_State *g, Table *h) {
+ int i;
+ int weakkey = 0;
+ int weakvalue = 0;
+ const TValue *mode;
+ if (h->metatable)
+ markobject(g, h->metatable);
+ mode = gfasttm(g, h->metatable, TM_MODE);
+ if (mode && ttisstring(mode)) { /* is there a weak mode? */
+ weakkey = (strchr(svalue(mode), 'k') != NULL);
+ weakvalue = (strchr(svalue(mode), 'v') != NULL);
+ if (weakkey || weakvalue) { /* is really weak? */
+ h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
+ h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
+ (weakvalue << VALUEWEAKBIT));
+ h->gclist = g->weak; /* must be cleared after GC, ... */
+ g->weak = obj2gco(h); /* ... so put in the appropriate list */
+ }
+ }
+ if (weakkey && weakvalue) return 1;
+ if (!weakvalue) {
+ i = h->sizearray;
+ while (i--)
+ markvalue(g, &h->array[i]);
+ }
+ i = sizenode(h);
+ while (i--) {
+ Node *n = gnode(h, i);
+ lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
+ if (ttisnil(gval(n)))
+ removeentry(n); /* remove empty entries */
+ else {
+ lua_assert(!ttisnil(gkey(n)));
+ if (!weakkey) markvalue(g, gkey(n));
+ if (!weakvalue) markvalue(g, gval(n));
+ }
+ }
+ return weakkey || weakvalue;
+}
+
+
+/*
+** All marks are conditional because a GC may happen while the
+** prototype is still being created
+*/
+static void traverseproto (global_State *g, Proto *f) {
+ int i;
+ if (f->source) stringmark(f->source);
+ for (i=0; i<f->sizek; i++) /* mark literals */
+ markvalue(g, &f->k[i]);
+ for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
+ if (f->upvalues[i])
+ stringmark(f->upvalues[i]);
+ }
+ for (i=0; i<f->sizep; i++) { /* mark nested protos */
+ if (f->p[i])
+ markobject(g, f->p[i]);
+ }
+ for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */
+ if (f->locvars[i].varname)
+ stringmark(f->locvars[i].varname);
+ }
+}
+
+
+
+static void traverseclosure (global_State *g, Closure *cl) {
+ markobject(g, cl->c.env);
+ if (cl->c.isC) {
+ int i;
+ for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
+ markvalue(g, &cl->c.upvalue[i]);
+ }
+ else {
+ int i;
+ lua_assert(cl->l.nupvalues == cl->l.p->nups);
+ markobject(g, cl->l.p);
+ for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
+ markobject(g, cl->l.upvals[i]);
+ }
+}
+
+
+static void checkstacksizes (lua_State *L, StkId max) {
+ int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */
+ int s_used = cast_int(max - L->stack); /* part of stack in use */
+ if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */
+ return; /* do not touch the stacks */
+ if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
+ luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
+ condhardstacktests(luaD_reallocCI(L, ci_used + 1));
+ if (4*s_used < L->stacksize &&
+ 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
+ luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
+ condhardstacktests(luaD_reallocstack(L, s_used));
+}
+
+
+static void traversestack (global_State *g, lua_State *l) {
+ StkId o, lim;
+ CallInfo *ci;
+ markvalue(g, gt(l));
+ lim = l->top;
+ for (ci = l->base_ci; ci <= l->ci; ci++) {
+ lua_assert(ci->top <= l->stack_last);
+ if (lim < ci->top) lim = ci->top;
+ }
+ for (o = l->stack; o < l->top; o++)
+ markvalue(g, o);
+ for (; o <= lim; o++)
+ setnilvalue(o);
+ checkstacksizes(l, lim);
+}
+
+
+/*
+** traverse one gray object, turning it to black.
+** Returns `quantity' traversed.
+*/
+static l_mem propagatemark (global_State *g) {
+ GCObject *o = g->gray;
+ lua_assert(isgray(o));
+ gray2black(o);
+ switch (o->gch.tt) {
+ case LUA_TTABLE: {
+ Table *h = gco2h(o);
+ g->gray = h->gclist;
+ if (traversetable(g, h)) /* table is weak? */
+ black2gray(o); /* keep it gray */
+ return sizeof(Table) + sizeof(TValue) * h->sizearray +
+ sizeof(Node) * sizenode(h);
+ }
+ case LUA_TFUNCTION: {
+ Closure *cl = gco2cl(o);
+ g->gray = cl->c.gclist;
+ traverseclosure(g, cl);
+ return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
+ sizeLclosure(cl->l.nupvalues);
+ }
+ case LUA_TTHREAD: {
+ lua_State *th = gco2th(o);
+ g->gray = th->gclist;
+ th->gclist = g->grayagain;
+ g->grayagain = o;
+ black2gray(o);
+ traversestack(g, th);
+ return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
+ sizeof(CallInfo) * th->size_ci;
+ }
+ case LUA_TPROTO: {
+ Proto *p = gco2p(o);
+ g->gray = p->gclist;
+ traverseproto(g, p);
+ return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
+ sizeof(Proto *) * p->sizep +
+ sizeof(TValue) * p->sizek +
+ sizeof(int) * p->sizelineinfo +
+ sizeof(LocVar) * p->sizelocvars +
+ sizeof(TString *) * p->sizeupvalues;
+ }
+ default: lua_assert(0); return 0;
+ }
+}
+
+
+static size_t propagateall (global_State *g) {
+ size_t m = 0;
+ while (g->gray) m += propagatemark(g);
+ return m;
+}
+
+
+/*
+** The next function tells whether a key or value can be cleared from
+** a weak table. Non-collectable objects are never removed from weak
+** tables. Strings behave as `values', so are never removed too. for
+** other objects: if really collected, cannot keep them; for userdata
+** being finalized, keep them in keys, but not in values
+*/
+static int iscleared (const TValue *o, int iskey) {
+ if (!iscollectable(o)) return 0;
+ if (ttisstring(o)) {
+ stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
+ return 0;
+ }
+ return iswhite(gcvalue(o)) ||
+ (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
+}
+
+
+/*
+** clear collected entries from weaktables
+*/
+static void cleartable (GCObject *l) {
+ while (l) {
+ Table *h = gco2h(l);
+ int i = h->sizearray;
+ lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
+ testbit(h->marked, KEYWEAKBIT));
+ if (testbit(h->marked, VALUEWEAKBIT)) {
+ while (i--) {
+ TValue *o = &h->array[i];
+ if (iscleared(o, 0)) /* value was collected? */
+ setnilvalue(o); /* remove value */
+ }
+ }
+ i = sizenode(h);
+ while (i--) {
+ Node *n = gnode(h, i);
+ if (!ttisnil(gval(n)) && /* non-empty entry? */
+ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
+ setnilvalue(gval(n)); /* remove value ... */
+ removeentry(n); /* remove entry from table */
+ }
+ }
+ l = h->gclist;
+ }
+}
+
+
+static void freeobj (lua_State *L, GCObject *o) {
+ switch (o->gch.tt) {
+ case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
+ case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
+ case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
+ case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
+ case LUA_TTHREAD: {
+ lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
+ luaE_freethread(L, gco2th(o));
+ break;
+ }
+ case LUA_TSTRING: {
+ G(L)->strt.nuse--;
+ luaM_freemem(L, o, sizestring(gco2ts(o)));
+ break;
+ }
+ case LUA_TUSERDATA: {
+ luaM_freemem(L, o, sizeudata(gco2u(o)));
+ break;
+ }
+ default: lua_assert(0);
+ }
+}
+
+
+
+#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
+
+
+static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
+ GCObject *curr;
+ global_State *g = G(L);
+ int deadmask = otherwhite(g);
+ while ((curr = *p) != NULL && count-- > 0) {
+ if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
+ sweepwholelist(L, &gco2th(curr)->openupval);
+ if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
+ lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
+ makewhite(g, curr); /* make it white (for next cycle) */
+ p = &curr->gch.next;
+ }
+ else { /* must erase `curr' */
+ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
+ *p = curr->gch.next;
+ if (curr == g->rootgc) /* is the first element of the list? */
+ g->rootgc = curr->gch.next; /* adjust first */
+ freeobj(L, curr);
+ }
+ }
+ return p;
+}
+
+
+static void checkSizes (lua_State *L) {
+ global_State *g = G(L);
+ /* check size of string hash */
+ if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
+ g->strt.size > MINSTRTABSIZE*2)
+ luaS_resize(L, g->strt.size/2); /* table is too big */
+ /* check size of buffer */
+ if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
+ size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
+ luaZ_resizebuffer(L, &g->buff, newsize);
+ }
+}
+
+
+static void GCTM (lua_State *L) {
+ global_State *g = G(L);
+ GCObject *o = g->tmudata->gch.next; /* get first element */
+ Udata *udata = rawgco2u(o);
+ const TValue *tm;
+ /* remove udata from `tmudata' */
+ if (o == g->tmudata) /* last element? */
+ g->tmudata = NULL;
+ else
+ g->tmudata->gch.next = udata->uv.next;
+ udata->uv.next = g->mainthread->next; /* return it to `root' list */
+ g->mainthread->next = o;
+ makewhite(g, o);
+ tm = fasttm(L, udata->uv.metatable, TM_GC);
+ if (tm != NULL) {
+ lu_byte oldah = L->allowhook;
+ lu_mem oldt = g->GCthreshold;
+ L->allowhook = 0; /* stop debug hooks during GC tag method */
+ g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */
+ setobj2s(L, L->top, tm);
+ setuvalue(L, L->top+1, udata);
+ L->top += 2;
+ luaD_call(L, L->top - 2, 0);
+ L->allowhook = oldah; /* restore hooks */
+ g->GCthreshold = oldt; /* restore threshold */
+ }
+}
+
+
+/*
+** Call all GC tag methods
+*/
+void luaC_callGCTM (lua_State *L) {
+ while (G(L)->tmudata)
+ GCTM(L);
+}
+
+
+void luaC_freeall (lua_State *L) {
+ global_State *g = G(L);
+ int i;
+ g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
+ sweepwholelist(L, &g->rootgc);
+ for (i = 0; i < g->strt.size; i++) /* free all string lists */
+ sweepwholelist(L, &g->strt.hash[i]);
+}
+
+
+static void markmt (global_State *g) {
+ int i;
+ for (i=0; i<NUM_TAGS; i++)
+ if (g->mt[i]) markobject(g, g->mt[i]);
+}
+
+
+/* mark root set */
+static void markroot (lua_State *L) {
+ global_State *g = G(L);
+ g->gray = NULL;
+ g->grayagain = NULL;
+ g->weak = NULL;
+ markobject(g, g->mainthread);
+ /* make global table be traversed before main stack */
+ markvalue(g, gt(g->mainthread));
+ markvalue(g, registry(L));
+ markmt(g);
+ g->gcstate = GCSpropagate;
+}
+
+
+static void remarkupvals (global_State *g) {
+ UpVal *uv;
+ for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
+ lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
+ if (isgray(obj2gco(uv)))
+ markvalue(g, uv->v);
+ }
+}
+
+
+static void atomic (lua_State *L) {
+ global_State *g = G(L);
+ size_t udsize; /* total size of userdata to be finalized */
+ /* remark occasional upvalues of (maybe) dead threads */
+ remarkupvals(g);
+ /* traverse objects cautch by write barrier and by 'remarkupvals' */
+ propagateall(g);
+ /* remark weak tables */
+ g->gray = g->weak;
+ g->weak = NULL;
+ lua_assert(!iswhite(obj2gco(g->mainthread)));
+ markobject(g, L); /* mark running thread */
+ markmt(g); /* mark basic metatables (again) */
+ propagateall(g);
+ /* remark gray again */
+ g->gray = g->grayagain;
+ g->grayagain = NULL;
+ propagateall(g);
+ udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
+ marktmu(g); /* mark `preserved' userdata */
+ udsize += propagateall(g); /* remark, to propagate `preserveness' */
+ cleartable(g->weak); /* remove collected objects from weak tables */
+ /* flip current white */
+ g->currentwhite = cast_byte(otherwhite(g));
+ g->sweepstrgc = 0;
+ g->sweepgc = &g->rootgc;
+ g->gcstate = GCSsweepstring;
+ g->estimate = g->totalbytes - udsize; /* first estimate */
+}
+
+
+static l_mem singlestep (lua_State *L) {
+ global_State *g = G(L);
+ /*lua_checkmemory(L);*/
+ switch (g->gcstate) {
+ case GCSpause: {
+ markroot(L); /* start a new collection */
+ return 0;
+ }
+ case GCSpropagate: {
+ if (g->gray)
+ return propagatemark(g);
+ else { /* no more `gray' objects */
+ atomic(L); /* finish mark phase */
+ return 0;
+ }
+ }
+ case GCSsweepstring: {
+ lu_mem old = g->totalbytes;
+ sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
+ if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
+ g->gcstate = GCSsweep; /* end sweep-string phase */
+ lua_assert(old >= g->totalbytes);
+ g->estimate -= old - g->totalbytes;
+ return GCSWEEPCOST;
+ }
+ case GCSsweep: {
+ lu_mem old = g->totalbytes;
+ g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
+ if (*g->sweepgc == NULL) { /* nothing more to sweep? */
+ checkSizes(L);
+ g->gcstate = GCSfinalize; /* end sweep phase */
+ }
+ lua_assert(old >= g->totalbytes);
+ g->estimate -= old - g->totalbytes;
+ return GCSWEEPMAX*GCSWEEPCOST;
+ }
+ case GCSfinalize: {
+ if (g->tmudata) {
+ GCTM(L);
+ if (g->estimate > GCFINALIZECOST)
+ g->estimate -= GCFINALIZECOST;
+ return GCFINALIZECOST;
+ }
+ else {
+ g->gcstate = GCSpause; /* end collection */
+ g->gcdept = 0;
+ return 0;
+ }
+ }
+ default: lua_assert(0); return 0;
+ }
+}
+
+
+void luaC_step (lua_State *L) {
+ global_State *g = G(L);
+ l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
+ if (lim == 0)
+ lim = (MAX_LUMEM-1)/2; /* no limit */
+ g->gcdept += g->totalbytes - g->GCthreshold;
+ do {
+ lim -= singlestep(L);
+ if (g->gcstate == GCSpause)
+ break;
+ } while (lim > 0);
+ if (g->gcstate != GCSpause) {
+ if (g->gcdept < GCSTEPSIZE)
+ g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/
+ else {
+ g->gcdept -= GCSTEPSIZE;
+ g->GCthreshold = g->totalbytes;
+ }
+ }
+ else {
+ lua_assert(g->totalbytes >= g->estimate);
+ setthreshold(g);
+ }
+}
+
+
+void luaC_fullgc (lua_State *L) {
+ global_State *g = G(L);
+ if (g->gcstate <= GCSpropagate) {
+ /* reset sweep marks to sweep all elements (returning them to white) */
+ g->sweepstrgc = 0;
+ g->sweepgc = &g->rootgc;
+ /* reset other collector lists */
+ g->gray = NULL;
+ g->grayagain = NULL;
+ g->weak = NULL;
+ g->gcstate = GCSsweepstring;
+ }
+ lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
+ /* finish any pending sweep phase */
+ while (g->gcstate != GCSfinalize) {
+ lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
+ singlestep(L);
+ }
+ markroot(L);
+ while (g->gcstate != GCSpause) {
+ singlestep(L);
+ }
+ setthreshold(g);
+}
+
+
+void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
+ global_State *g = G(L);
+ lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
+ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+ lua_assert(ttype(&o->gch) != LUA_TTABLE);
+ /* must keep invariant? */
+ if (g->gcstate == GCSpropagate)
+ reallymarkobject(g, v); /* restore invariant */
+ else /* don't mind */
+ makewhite(g, o); /* mark as white just to avoid other barriers */
+}
+
+
+void luaC_barrierback (lua_State *L, Table *t) {
+ global_State *g = G(L);
+ GCObject *o = obj2gco(t);
+ lua_assert(isblack(o) && !isdead(g, o));
+ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+ black2gray(o); /* make table gray (again) */
+ t->gclist = g->grayagain;
+ g->grayagain = o;
+}
+
+
+void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
+ global_State *g = G(L);
+ o->gch.next = g->rootgc;
+ g->rootgc = o;
+ o->gch.marked = luaC_white(g);
+ o->gch.tt = tt;
+}
+
+
+void luaC_linkupval (lua_State *L, UpVal *uv) {
+ global_State *g = G(L);
+ GCObject *o = obj2gco(uv);
+ o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */
+ g->rootgc = o;
+ if (isgray(o)) {
+ if (g->gcstate == GCSpropagate) {
+ gray2black(o); /* closed upvalues need barrier */
+ luaC_barrier(L, uv, uv->v);
+ }
+ else { /* sweep phase: sweep it (turning it into white) */
+ makewhite(g, o);
+ lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
+ }
+ }
+}
+
diff --git a/misc/liblua/lgc.h b/misc/liblua/lgc.h
new file mode 100644
index 0000000..5a8dc60
--- /dev/null
+++ b/misc/liblua/lgc.h
@@ -0,0 +1,110 @@
+/*
+** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
+** Garbage Collector
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lgc_h
+#define lgc_h
+
+
+#include "lobject.h"
+
+
+/*
+** Possible states of the Garbage Collector
+*/
+#define GCSpause 0
+#define GCSpropagate 1
+#define GCSsweepstring 2
+#define GCSsweep 3
+#define GCSfinalize 4
+
+
+/*
+** some userful bit tricks
+*/
+#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
+#define setbits(x,m) ((x) |= (m))
+#define testbits(x,m) ((x) & (m))
+#define bitmask(b) (1<<(b))
+#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
+#define l_setbit(x,b) setbits(x, bitmask(b))
+#define resetbit(x,b) resetbits(x, bitmask(b))
+#define testbit(x,b) testbits(x, bitmask(b))
+#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
+#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
+#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))
+
+
+
+/*
+** Layout for bit use in `marked' field:
+** bit 0 - object is white (type 0)
+** bit 1 - object is white (type 1)
+** bit 2 - object is black
+** bit 3 - for userdata: has been finalized
+** bit 3 - for tables: has weak keys
+** bit 4 - for tables: has weak values
+** bit 5 - object is fixed (should not be collected)
+** bit 6 - object is "super" fixed (only the main thread)
+*/
+
+
+#define WHITE0BIT 0
+#define WHITE1BIT 1
+#define BLACKBIT 2
+#define FINALIZEDBIT 3
+#define KEYWEAKBIT 3
+#define VALUEWEAKBIT 4
+#define FIXEDBIT 5
+#define SFIXEDBIT 6
+#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
+
+
+#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
+#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
+#define isgray(x) (!isblack(x) && !iswhite(x))
+
+#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
+#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
+
+#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
+#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
+
+#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
+
+#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
+
+
+#define luaC_checkGC(L) { \
+ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
+ if (G(L)->totalbytes >= G(L)->GCthreshold) \
+ luaC_step(L); }
+
+
+#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
+ luaC_barrierf(L,obj2gco(p),gcvalue(v)); }
+
+#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
+ luaC_barrierback(L,t); }
+
+#define luaC_objbarrier(L,p,o) \
+ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
+ luaC_barrierf(L,obj2gco(p),obj2gco(o)); }
+
+#define luaC_objbarriert(L,t,o) \
+ { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }
+
+LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
+LUAI_FUNC void luaC_callGCTM (lua_State *L);
+LUAI_FUNC void luaC_freeall (lua_State *L);
+LUAI_FUNC void luaC_step (lua_State *L);
+LUAI_FUNC void luaC_fullgc (lua_State *L);
+LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
+LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
+LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
+LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
+
+
+#endif
diff --git a/misc/liblua/linit.c b/misc/liblua/linit.c
new file mode 100644
index 0000000..c1f90df
--- /dev/null
+++ b/misc/liblua/linit.c
@@ -0,0 +1,38 @@
+/*
+** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
+** Initialization of libraries for lua.c
+** See Copyright Notice in lua.h
+*/
+
+
+#define linit_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lualib.h"
+#include "lauxlib.h"
+
+
+static const luaL_Reg lualibs[] = {
+ {"", luaopen_base},
+ {LUA_LOADLIBNAME, luaopen_package},
+ {LUA_TABLIBNAME, luaopen_table},
+ {LUA_IOLIBNAME, luaopen_io},
+ {LUA_OSLIBNAME, luaopen_os},
+ {LUA_STRLIBNAME, luaopen_string},
+ {LUA_MATHLIBNAME, luaopen_math},
+ {LUA_DBLIBNAME, luaopen_debug},
+ {NULL, NULL}
+};
+
+
+LUALIB_API void luaL_openlibs (lua_State *L) {
+ const luaL_Reg *lib = lualibs;
+ for (; lib->func; lib++) {
+ lua_pushcfunction(L, lib->func);
+ lua_pushstring(L, lib->name);
+ lua_call(L, 1, 0);
+ }
+}
+
diff --git a/misc/liblua/liolib.c b/misc/liblua/liolib.c
new file mode 100644
index 0000000..e79ed1c
--- /dev/null
+++ b/misc/liblua/liolib.c
@@ -0,0 +1,553 @@
+/*
+** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
+** Standard I/O (and system) library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define liolib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+
+#define IO_INPUT 1
+#define IO_OUTPUT 2
+
+
+static const char *const fnames[] = {"input", "output"};
+
+
+static int pushresult (lua_State *L, int i, const char *filename) {
+ int en = errno; /* calls to Lua API may change this value */
+ if (i) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ lua_pushnil(L);
+ if (filename)
+ lua_pushfstring(L, "%s: %s", filename, strerror(en));
+ else
+ lua_pushfstring(L, "%s", strerror(en));
+ lua_pushinteger(L, en);
+ return 3;
+ }
+}
+
+
+static void fileerror (lua_State *L, int arg, const char *filename) {
+ lua_pushfstring(L, "%s: %s", filename, strerror(errno));
+ luaL_argerror(L, arg, lua_tostring(L, -1));
+}
+
+
+#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+
+
+static int io_type (lua_State *L) {
+ void *ud;
+ luaL_checkany(L, 1);
+ ud = lua_touserdata(L, 1);
+ lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
+ if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
+ lua_pushnil(L); /* not a file */
+ else if (*((FILE **)ud) == NULL)
+ lua_pushliteral(L, "closed file");
+ else
+ lua_pushliteral(L, "file");
+ return 1;
+}
+
+
+static FILE *tofile (lua_State *L) {
+ FILE **f = tofilep(L);
+ if (*f == NULL)
+ luaL_error(L, "attempt to use a closed file");
+ return *f;
+}
+
+
+
+/*
+** When creating file handles, always creates a `closed' file handle
+** before opening the actual file; so, if there is a memory error, the
+** file is not left opened.
+*/
+static FILE **newfile (lua_State *L) {
+ FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
+ *pf = NULL; /* file handle is currently `closed' */
+ luaL_getmetatable(L, LUA_FILEHANDLE);
+ lua_setmetatable(L, -2);
+ return pf;
+}
+
+
+/*
+** function to (not) close the standard files stdin, stdout, and stderr
+*/
+static int io_noclose (lua_State *L) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "cannot close standard file");
+ return 2;
+}
+
+
+/*
+** function to close 'popen' files
+*/
+static int io_pclose (lua_State *L) {
+ FILE **p = tofilep(L);
+ int ok = lua_pclose(L, *p);
+ *p = NULL;
+ return pushresult(L, ok, NULL);
+}
+
+
+/*
+** function to close regular files
+*/
+static int io_fclose (lua_State *L) {
+ FILE **p = tofilep(L);
+ int ok = (fclose(*p) == 0);
+ *p = NULL;
+ return pushresult(L, ok, NULL);
+}
+
+
+static int aux_close (lua_State *L) {
+ lua_getfenv(L, 1);
+ lua_getfield(L, -1, "__close");
+ return (lua_tocfunction(L, -1))(L);
+}
+
+
+static int io_close (lua_State *L) {
+ if (lua_isnone(L, 1))
+ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
+ tofile(L); /* make sure argument is a file */
+ return aux_close(L);
+}
+
+
+static int io_gc (lua_State *L) {
+ FILE *f = *tofilep(L);
+ /* ignore closed files */
+ if (f != NULL)
+ aux_close(L);
+ return 0;
+}
+
+
+static int io_tostring (lua_State *L) {
+ FILE *f = *tofilep(L);
+ if (f == NULL)
+ lua_pushliteral(L, "file (closed)");
+ else
+ lua_pushfstring(L, "file (%p)", f);
+ return 1;
+}
+
+
+static int io_open (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, mode);
+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+}
+
+
+/*
+** this function has a separated environment, which defines the
+** correct __close for 'popen' files
+*/
+static int io_popen (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ FILE **pf = newfile(L);
+ *pf = lua_popen(L, filename, mode);
+ return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+}
+
+
+static int io_tmpfile (lua_State *L) {
+ FILE **pf = newfile(L);
+ *pf = tmpfile();
+ return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
+}
+
+
+static FILE *getiofile (lua_State *L, int findex) {
+ FILE *f;
+ lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
+ f = *(FILE **)lua_touserdata(L, -1);
+ if (f == NULL)
+ luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
+ return f;
+}
+
+
+static int g_iofile (lua_State *L, int f, const char *mode) {
+ if (!lua_isnoneornil(L, 1)) {
+ const char *filename = lua_tostring(L, 1);
+ if (filename) {
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, mode);
+ if (*pf == NULL)
+ fileerror(L, 1, filename);
+ }
+ else {
+ tofile(L); /* check that it's a valid file handle */
+ lua_pushvalue(L, 1);
+ }
+ lua_rawseti(L, LUA_ENVIRONINDEX, f);
+ }
+ /* return current value */
+ lua_rawgeti(L, LUA_ENVIRONINDEX, f);
+ return 1;
+}
+
+
+static int io_input (lua_State *L) {
+ return g_iofile(L, IO_INPUT, "r");
+}
+
+
+static int io_output (lua_State *L) {
+ return g_iofile(L, IO_OUTPUT, "w");
+}
+
+
+static int io_readline (lua_State *L);
+
+
+static void aux_lines (lua_State *L, int idx, int toclose) {
+ lua_pushvalue(L, idx);
+ lua_pushboolean(L, toclose); /* close/not close file when finished */
+ lua_pushcclosure(L, io_readline, 2);
+}
+
+
+static int f_lines (lua_State *L) {
+ tofile(L); /* check that it's a valid file handle */
+ aux_lines(L, 1, 0);
+ return 1;
+}
+
+
+static int io_lines (lua_State *L) {
+ if (lua_isnoneornil(L, 1)) { /* no arguments? */
+ /* will iterate over default input */
+ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
+ return f_lines(L);
+ }
+ else {
+ const char *filename = luaL_checkstring(L, 1);
+ FILE **pf = newfile(L);
+ *pf = fopen(filename, "r");
+ if (*pf == NULL)
+ fileerror(L, 1, filename);
+ aux_lines(L, lua_gettop(L), 1);
+ return 1;
+ }
+}
+
+
+/*
+** {======================================================
+** READ
+** =======================================================
+*/
+
+
+static int read_number (lua_State *L, FILE *f) {
+ lua_Number d;
+ if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
+ lua_pushnumber(L, d);
+ return 1;
+ }
+ else return 0; /* read fails */
+}
+
+
+static int test_eof (lua_State *L, FILE *f) {
+ int c = getc(f);
+ ungetc(c, f);
+ lua_pushlstring(L, NULL, 0);
+ return (c != EOF);
+}
+
+
+static int read_line (lua_State *L, FILE *f) {
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ for (;;) {
+ size_t l;
+ char *p = luaL_prepbuffer(&b);
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
+ luaL_pushresult(&b); /* close buffer */
+ return (lua_objlen(L, -1) > 0); /* check whether read something */
+ }
+ l = strlen(p);
+ if (l == 0 || p[l-1] != '\n')
+ luaL_addsize(&b, l);
+ else {
+ luaL_addsize(&b, l - 1); /* do not include `eol' */
+ luaL_pushresult(&b); /* close buffer */
+ return 1; /* read at least an `eol' */
+ }
+ }
+}
+
+
+static int read_chars (lua_State *L, FILE *f, size_t n) {
+ size_t rlen; /* how much to read */
+ size_t nr; /* number of chars actually read */
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
+ do {
+ char *p = luaL_prepbuffer(&b);
+ if (rlen > n) rlen = n; /* cannot read more than asked */
+ nr = fread(p, sizeof(char), rlen, f);
+ luaL_addsize(&b, nr);
+ n -= nr; /* still have to read `n' chars */
+ } while (n > 0 && nr == rlen); /* until end of count or eof */
+ luaL_pushresult(&b); /* close buffer */
+ return (n == 0 || lua_objlen(L, -1) > 0);
+}
+
+
+static int g_read (lua_State *L, FILE *f, int first) {
+ int nargs = lua_gettop(L) - 1;
+ int success;
+ int n;
+ clearerr(f);
+ if (nargs == 0) { /* no arguments? */
+ success = read_line(L, f);
+ n = first+1; /* to return 1 result */
+ }
+ else { /* ensure stack space for all results and for auxlib's buffer */
+ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
+ success = 1;
+ for (n = first; nargs-- && success; n++) {
+ if (lua_type(L, n) == LUA_TNUMBER) {
+ size_t l = (size_t)lua_tointeger(L, n);
+ success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
+ }
+ else {
+ const char *p = lua_tostring(L, n);
+ luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
+ switch (p[1]) {
+ case 'n': /* number */
+ success = read_number(L, f);
+ break;
+ case 'l': /* line */
+ success = read_line(L, f);
+ break;
+ case 'a': /* file */
+ read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
+ success = 1; /* always success */
+ break;
+ default:
+ return luaL_argerror(L, n, "invalid format");
+ }
+ }
+ }
+ }
+ if (ferror(f))
+ return pushresult(L, 0, NULL);
+ if (!success) {
+ lua_pop(L, 1); /* remove last result */
+ lua_pushnil(L); /* push nil instead */
+ }
+ return n - first;
+}
+
+
+static int io_read (lua_State *L) {
+ return g_read(L, getiofile(L, IO_INPUT), 1);
+}
+
+
+static int f_read (lua_State *L) {
+ return g_read(L, tofile(L), 2);
+}
+
+
+static int io_readline (lua_State *L) {
+ FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
+ int sucess;
+ if (f == NULL) /* file is already closed? */
+ luaL_error(L, "file is already closed");
+ sucess = read_line(L, f);
+ if (ferror(f))
+ return luaL_error(L, "%s", strerror(errno));
+ if (sucess) return 1;
+ else { /* EOF */
+ if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
+ lua_settop(L, 0);
+ lua_pushvalue(L, lua_upvalueindex(1));
+ aux_close(L); /* close it */
+ }
+ return 0;
+ }
+}
+
+/* }====================================================== */
+
+
+static int g_write (lua_State *L, FILE *f, int arg) {
+ int nargs = lua_gettop(L) - 1;
+ int status = 1;
+ for (; nargs--; arg++) {
+ if (lua_type(L, arg) == LUA_TNUMBER) {
+ /* optimization: could be done exactly as for strings */
+ status = status &&
+ fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+ }
+ else {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ status = status && (fwrite(s, sizeof(char), l, f) == l);
+ }
+ }
+ return pushresult(L, status, NULL);
+}
+
+
+static int io_write (lua_State *L) {
+ return g_write(L, getiofile(L, IO_OUTPUT), 1);
+}
+
+
+static int f_write (lua_State *L) {
+ return g_write(L, tofile(L), 2);
+}
+
+
+static int f_seek (lua_State *L) {
+ static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+ static const char *const modenames[] = {"set", "cur", "end", NULL};
+ FILE *f = tofile(L);
+ int op = luaL_checkoption(L, 2, "cur", modenames);
+ long offset = luaL_optlong(L, 3, 0);
+ op = fseek(f, offset, mode[op]);
+ if (op)
+ return pushresult(L, 0, NULL); /* error */
+ else {
+ lua_pushinteger(L, ftell(f));
+ return 1;
+ }
+}
+
+
+static int f_setvbuf (lua_State *L) {
+ static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
+ static const char *const modenames[] = {"no", "full", "line", NULL};
+ FILE *f = tofile(L);
+ int op = luaL_checkoption(L, 2, NULL, modenames);
+ lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
+ int res = setvbuf(f, NULL, mode[op], sz);
+ return pushresult(L, res == 0, NULL);
+}
+
+
+
+static int io_flush (lua_State *L) {
+ return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+}
+
+
+static int f_flush (lua_State *L) {
+ return pushresult(L, fflush(tofile(L)) == 0, NULL);
+}
+
+
+static const luaL_Reg iolib[] = {
+ {"close", io_close},
+ {"flush", io_flush},
+ {"input", io_input},
+ {"lines", io_lines},
+ {"open", io_open},
+ {"output", io_output},
+ {"popen", io_popen},
+ {"read", io_read},
+ {"tmpfile", io_tmpfile},
+ {"type", io_type},
+ {"write", io_write},
+ {NULL, NULL}
+};
+
+
+static const luaL_Reg flib[] = {
+ {"close", io_close},
+ {"flush", f_flush},
+ {"lines", f_lines},
+ {"read", f_read},
+ {"seek", f_seek},
+ {"setvbuf", f_setvbuf},
+ {"write", f_write},
+ {"__gc", io_gc},
+ {"__tostring", io_tostring},
+ {NULL, NULL}
+};
+
+
+static void createmeta (lua_State *L) {
+ luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
+ lua_pushvalue(L, -1); /* push metatable */
+ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
+ luaL_register(L, NULL, flib); /* file methods */
+}
+
+
+static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
+ *newfile(L) = f;
+ if (k > 0) {
+ lua_pushvalue(L, -1);
+ lua_rawseti(L, LUA_ENVIRONINDEX, k);
+ }
+ lua_pushvalue(L, -2); /* copy environment */
+ lua_setfenv(L, -2); /* set it */
+ lua_setfield(L, -3, fname);
+}
+
+
+static void newfenv (lua_State *L, lua_CFunction cls) {
+ lua_createtable(L, 0, 1);
+ lua_pushcfunction(L, cls);
+ lua_setfield(L, -2, "__close");
+}
+
+
+LUALIB_API int luaopen_io (lua_State *L) {
+ createmeta(L);
+ /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
+ newfenv(L, io_fclose);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ /* open library */
+ luaL_register(L, LUA_IOLIBNAME, iolib);
+ /* create (and set) default files */
+ newfenv(L, io_noclose); /* close function for default files */
+ createstdfile(L, stdin, IO_INPUT, "stdin");
+ createstdfile(L, stdout, IO_OUTPUT, "stdout");
+ createstdfile(L, stderr, 0, "stderr");
+ lua_pop(L, 1); /* pop environment for default files */
+ lua_getfield(L, -1, "popen");
+ newfenv(L, io_pclose); /* create environment for 'popen' */
+ lua_setfenv(L, -2); /* set fenv for 'popen' */
+ lua_pop(L, 1); /* pop 'popen' */
+ return 1;
+}
+
diff --git a/misc/liblua/llex.c b/misc/liblua/llex.c
new file mode 100644
index 0000000..7575a57
--- /dev/null
+++ b/misc/liblua/llex.c
@@ -0,0 +1,467 @@
+/*
+** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <locale.h>
+#include <string.h>
+
+#define llex_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldo.h"
+#include "llex.h"
+#include "lobject.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "lzio.h"
+
+
+
+#define next(ls) (ls->current = zgetc(ls->z))
+
+
+
+
+#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
+
+
+/* ORDER RESERVED */
+const char *const luaX_tokens [] = {
+ "and", "break", "do", "else", "elseif",
+ "end", "false", "for", "function", "if",
+ "in", "local", "nil", "not", "or", "repeat",
+ "return", "then", "true", "until", "while",
+ "..", "...", "==", ">=", "<=", "~=",
+ "<number>", "<name>", "<string>", "<eof>",
+ NULL
+};
+
+
+#define save_and_next(ls) (save(ls, ls->current), next(ls))
+
+
+static void save (LexState *ls, int c) {
+ Mbuffer *b = ls->buff;
+ if (b->n + 1 > b->buffsize) {
+ size_t newsize;
+ if (b->buffsize >= MAX_SIZET/2)
+ luaX_lexerror(ls, "lexical element too long", 0);
+ newsize = b->buffsize * 2;
+ luaZ_resizebuffer(ls->L, b, newsize);
+ }
+ b->buffer[b->n++] = cast(char, c);
+}
+
+
+void luaX_init (lua_State *L) {
+ int i;
+ for (i=0; i<NUM_RESERVED; i++) {
+ TString *ts = luaS_new(L, luaX_tokens[i]);
+ luaS_fix(ts); /* reserved words are never collected */
+ lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
+ ts->tsv.reserved = cast_byte(i+1); /* reserved word */
+ }
+}
+
+
+#define MAXSRC 80
+
+
+const char *luaX_token2str (LexState *ls, int token) {
+ if (token < FIRST_RESERVED) {
+ lua_assert(token == cast(unsigned char, token));
+ return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) :
+ luaO_pushfstring(ls->L, "%c", token);
+ }
+ else
+ return luaX_tokens[token-FIRST_RESERVED];
+}
+
+
+static const char *txtToken (LexState *ls, int token) {
+ switch (token) {
+ case TK_NAME:
+ case TK_STRING:
+ case TK_NUMBER:
+ save(ls, '\0');
+ return luaZ_buffer(ls->buff);
+ default:
+ return luaX_token2str(ls, token);
+ }
+}
+
+
+void luaX_lexerror (LexState *ls, const char *msg, int token) {
+ char buff[MAXSRC];
+ luaO_chunkid(buff, getstr(ls->source), MAXSRC);
+ msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
+ if (token)
+ luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token));
+ luaD_throw(ls->L, LUA_ERRSYNTAX);
+}
+
+
+void luaX_syntaxerror (LexState *ls, const char *msg) {
+ luaX_lexerror(ls, msg, ls->t.token);
+}
+
+
+TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
+ lua_State *L = ls->L;
+ TString *ts = luaS_newlstr(L, str, l);
+ TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
+ if (ttisnil(o))
+ setbvalue(o, 1); /* make sure `str' will not be collected */
+ return ts;
+}
+
+
+static void inclinenumber (LexState *ls) {
+ int old = ls->current;
+ lua_assert(currIsNewline(ls));
+ next(ls); /* skip `\n' or `\r' */
+ if (currIsNewline(ls) && ls->current != old)
+ next(ls); /* skip `\n\r' or `\r\n' */
+ if (++ls->linenumber >= MAX_INT)
+ luaX_syntaxerror(ls, "chunk has too many lines");
+}
+
+
+void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
+ ls->decpoint = '.';
+ ls->L = L;
+ ls->lookahead.token = TK_EOS; /* no look-ahead token */
+ ls->z = z;
+ ls->fs = NULL;
+ ls->linenumber = 1;
+ ls->lastline = 1;
+ ls->source = source;
+ luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
+ next(ls); /* read first char */
+}
+
+
+
+/*
+** =======================================================
+** LEXICAL ANALYZER
+** =======================================================
+*/
+
+
+
+static int check_next (LexState *ls, const char *set) {
+ if (!strchr(set, ls->current))
+ return 0;
+ save_and_next(ls);
+ return 1;
+}
+
+
+static void buffreplace (LexState *ls, char from, char to) {
+ size_t n = luaZ_bufflen(ls->buff);
+ char *p = luaZ_buffer(ls->buff);
+ while (n--)
+ if (p[n] == from) p[n] = to;
+}
+
+
+static void trydecpoint (LexState *ls, SemInfo *seminfo) {
+ /* format error: try to update decimal point separator */
+#ifndef ANDROID
+ struct lconv *cv = localeconv();
+#endif
+ char old = ls->decpoint;
+#ifdef ANDROID
+ ls->decpoint = '.';
+#else
+ ls->decpoint = (cv ? cv->decimal_point[0] : '.');
+#endif
+ buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
+ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
+ /* format error with correct decimal point: no more options */
+ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
+ luaX_lexerror(ls, "malformed number", TK_NUMBER);
+ }
+}
+
+
+/* LUA_NUMBER */
+static void read_numeral (LexState *ls, SemInfo *seminfo) {
+ lua_assert(isdigit(ls->current));
+ do {
+ save_and_next(ls);
+ } while (isdigit(ls->current) || ls->current == '.');
+ if (check_next(ls, "Ee")) /* `E'? */
+ check_next(ls, "+-"); /* optional exponent sign */
+ while (isalnum(ls->current) || ls->current == '_')
+ save_and_next(ls);
+ save(ls, '\0');
+ buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
+ if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
+ trydecpoint(ls, seminfo); /* try to update decimal point separator */
+}
+
+
+static int skip_sep (LexState *ls) {
+ int count = 0;
+ int s = ls->current;
+ lua_assert(s == '[' || s == ']');
+ save_and_next(ls);
+ while (ls->current == '=') {
+ save_and_next(ls);
+ count++;
+ }
+ return (ls->current == s) ? count : (-count) - 1;
+}
+
+
+static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
+ int cont = 0;
+ (void)(cont); /* avoid warnings when `cont' is not used */
+ save_and_next(ls); /* skip 2nd `[' */
+ if (currIsNewline(ls)) /* string starts with a newline? */
+ inclinenumber(ls); /* skip it */
+ for (;;) {
+ switch (ls->current) {
+ case EOZ:
+ luaX_lexerror(ls, (seminfo) ? "unfinished long string" :
+ "unfinished long comment", TK_EOS);
+ break; /* to avoid warnings */
+#if defined(LUA_COMPAT_LSTR)
+ case '[': {
+ if (skip_sep(ls) == sep) {
+ save_and_next(ls); /* skip 2nd `[' */
+ cont++;
+#if LUA_COMPAT_LSTR == 1
+ if (sep == 0)
+ luaX_lexerror(ls, "nesting of [[...]] is deprecated", '[');
+#endif
+ }
+ break;
+ }
+#endif
+ case ']': {
+ if (skip_sep(ls) == sep) {
+ save_and_next(ls); /* skip 2nd `]' */
+#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2
+ cont--;
+ if (sep == 0 && cont >= 0) break;
+#endif
+ goto endloop;
+ }
+ break;
+ }
+ case '\n':
+ case '\r': {
+ save(ls, '\n');
+ inclinenumber(ls);
+ if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
+ break;
+ }
+ default: {
+ if (seminfo) save_and_next(ls);
+ else next(ls);
+ }
+ }
+ } endloop:
+ if (seminfo)
+ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
+ luaZ_bufflen(ls->buff) - 2*(2 + sep));
+}
+
+
+static void read_string (LexState *ls, int del, SemInfo *seminfo) {
+ save_and_next(ls);
+ while (ls->current != del) {
+ switch (ls->current) {
+ case EOZ:
+ luaX_lexerror(ls, "unfinished string", TK_EOS);
+ continue; /* to avoid warnings */
+ case '\n':
+ case '\r':
+ luaX_lexerror(ls, "unfinished string", TK_STRING);
+ continue; /* to avoid warnings */
+ case '\\': {
+ int c;
+ next(ls); /* do not save the `\' */
+ switch (ls->current) {
+ case 'a': c = '\a'; break;
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
+ case '\n': /* go through */
+ case '\r': save(ls, '\n'); inclinenumber(ls); continue;
+ case EOZ: continue; /* will raise an error next loop */
+ default: {
+ if (!isdigit(ls->current))
+ save_and_next(ls); /* handles \\, \", \', and \? */
+ else { /* \xxx */
+ int i = 0;
+ c = 0;
+ do {
+ c = 10*c + (ls->current-'0');
+ next(ls);
+ } while (++i<3 && isdigit(ls->current));
+ if (c > UCHAR_MAX)
+ luaX_lexerror(ls, "escape sequence too large", TK_STRING);
+ save(ls, c);
+ }
+ continue;
+ }
+ }
+ save(ls, c);
+ next(ls);
+ continue;
+ }
+ default:
+ save_and_next(ls);
+ }
+ }
+ save_and_next(ls); /* skip delimiter */
+ seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
+ luaZ_bufflen(ls->buff) - 2);
+}
+
+
+static int llex (LexState *ls, SemInfo *seminfo) {
+ luaZ_resetbuffer(ls->buff);
+ for (;;) {
+ switch (ls->current) {
+ case '\n':
+ case '\r': {
+ inclinenumber(ls);
+ continue;
+ }
+ case '-': {
+ next(ls);
+ if (ls->current != '-') return '-';
+ /* else is a comment */
+ next(ls);
+ if (ls->current == '[') {
+ int sep = skip_sep(ls);
+ luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
+ if (sep >= 0) {
+ read_long_string(ls, NULL, sep); /* long comment */
+ luaZ_resetbuffer(ls->buff);
+ continue;
+ }
+ }
+ /* else short comment */
+ while (!currIsNewline(ls) && ls->current != EOZ)
+ next(ls);
+ continue;
+ }
+ case '[': {
+ int sep = skip_sep(ls);
+ if (sep >= 0) {
+ read_long_string(ls, seminfo, sep);
+ return TK_STRING;
+ }
+ else if (sep == -1) return '[';
+ else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING);
+ }
+ case '=': {
+ next(ls);
+ if (ls->current != '=') return '=';
+ else { next(ls); return TK_EQ; }
+ }
+ case '<': {
+ next(ls);
+ if (ls->current != '=') return '<';
+ else { next(ls); return TK_LE; }
+ }
+ case '>': {
+ next(ls);
+ if (ls->current != '=') return '>';
+ else { next(ls); return TK_GE; }
+ }
+ case '~': {
+ next(ls);
+ if (ls->current != '=') return '~';
+ else { next(ls); return TK_NE; }
+ }
+ case '"':
+ case '\'': {
+ read_string(ls, ls->current, seminfo);
+ return TK_STRING;
+ }
+ case '.': {
+ save_and_next(ls);
+ if (check_next(ls, ".")) {
+ if (check_next(ls, "."))
+ return TK_DOTS; /* ... */
+ else return TK_CONCAT; /* .. */
+ }
+ else if (!isdigit(ls->current)) return '.';
+ else {
+ read_numeral(ls, seminfo);
+ return TK_NUMBER;
+ }
+ }
+ case EOZ: {
+ return TK_EOS;
+ }
+ default: {
+ if (isspace(ls->current)) {
+ lua_assert(!currIsNewline(ls));
+ next(ls);
+ continue;
+ }
+ else if (isdigit(ls->current)) {
+ read_numeral(ls, seminfo);
+ return TK_NUMBER;
+ }
+ else if (isalpha(ls->current) || ls->current == '_') {
+ /* identifier or reserved word */
+ TString *ts;
+ do {
+ save_and_next(ls);
+ } while (isalnum(ls->current) || ls->current == '_');
+ ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
+ luaZ_bufflen(ls->buff));
+ if (ts->tsv.reserved > 0) /* reserved word? */
+ return ts->tsv.reserved - 1 + FIRST_RESERVED;
+ else {
+ seminfo->ts = ts;
+ return TK_NAME;
+ }
+ }
+ else {
+ int c = ls->current;
+ next(ls);
+ return c; /* single-char tokens (+ - / ...) */
+ }
+ }
+ }
+ }
+}
+
+
+void luaX_next (LexState *ls) {
+ ls->lastline = ls->linenumber;
+ if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
+ ls->t = ls->lookahead; /* use this one */
+ ls->lookahead.token = TK_EOS; /* and discharge it */
+ }
+ else
+ ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
+}
+
+
+void luaX_lookahead (LexState *ls) {
+ lua_assert(ls->lookahead.token == TK_EOS);
+ ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
+}
+
diff --git a/misc/liblua/llex.h b/misc/liblua/llex.h
new file mode 100644
index 0000000..a9201ce
--- /dev/null
+++ b/misc/liblua/llex.h
@@ -0,0 +1,81 @@
+/*
+** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lexical Analyzer
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llex_h
+#define llex_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+
+#define FIRST_RESERVED 257
+
+/* maximum length of a reserved word */
+#define TOKEN_LEN (sizeof("function")/sizeof(char))
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER RESERVED"
+*/
+enum RESERVED {
+ /* terminal symbols denoted by reserved words */
+ TK_AND = FIRST_RESERVED, TK_BREAK,
+ TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+ TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+ /* other terminal symbols */
+ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
+ TK_NAME, TK_STRING, TK_EOS
+};
+
+/* number of reserved words */
+#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
+
+
+/* array with token `names' */
+LUAI_DATA const char *const luaX_tokens [];
+
+
+typedef union {
+ lua_Number r;
+ TString *ts;
+} SemInfo; /* semantics information */
+
+
+typedef struct Token {
+ int token;
+ SemInfo seminfo;
+} Token;
+
+
+typedef struct LexState {
+ int current; /* current character (charint) */
+ int linenumber; /* input line counter */
+ int lastline; /* line of last token `consumed' */
+ Token t; /* current token */
+ Token lookahead; /* look ahead token */
+ struct FuncState *fs; /* `FuncState' is private to the parser */
+ struct lua_State *L;
+ ZIO *z; /* input stream */
+ Mbuffer *buff; /* buffer for tokens */
+ TString *source; /* current source name */
+ char decpoint; /* locale decimal point */
+} LexState;
+
+
+LUAI_FUNC void luaX_init (lua_State *L);
+LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
+ TString *source);
+LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
+LUAI_FUNC void luaX_next (LexState *ls);
+LUAI_FUNC void luaX_lookahead (LexState *ls);
+LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
+LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
+LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
+
+
+#endif
diff --git a/misc/liblua/llimits.h b/misc/liblua/llimits.h
new file mode 100644
index 0000000..20475d4
--- /dev/null
+++ b/misc/liblua/llimits.h
@@ -0,0 +1,128 @@
+/*
+** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $
+** Limits, basic types, and some other `installation-dependent' definitions
+** See Copyright Notice in lua.h
+*/
+
+#ifndef llimits_h
+#define llimits_h
+
+
+#include <limits.h>
+#include <stddef.h>
+
+
+#include "lua.h"
+
+
+typedef LUAI_UINT32 lu_int32;
+
+typedef LUAI_UMEM lu_mem;
+
+typedef LUAI_MEM l_mem;
+
+
+
+/* chars used as small naturals (so that `char' is reserved for characters) */
+typedef unsigned char lu_byte;
+
+
+#define MAX_SIZET ((size_t)(~(size_t)0)-2)
+
+#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
+
+
+#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
+
+/*
+** conversion of pointer to integer
+** this is for hashing only; there is no problem if the integer
+** cannot hold the whole pointer value
+*/
+#define IntPoint(p) ((unsigned int)(lu_mem)(p))
+
+
+
+/* type to ensure maximum alignment */
+typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
+
+
+/* result of a `usual argument conversion' over lua_Number */
+typedef LUAI_UACNUMBER l_uacNumber;
+
+
+/* internal assertions for in-house debugging */
+#ifdef lua_assert
+
+#define check_exp(c,e) (lua_assert(c), (e))
+#define api_check(l,e) lua_assert(e)
+
+#else
+
+#define lua_assert(c) ((void)0)
+#define check_exp(c,e) (e)
+#define api_check luai_apicheck
+
+#endif
+
+
+#ifndef UNUSED
+#define UNUSED(x) ((void)(x)) /* to avoid warnings */
+#endif
+
+
+#ifndef cast
+#define cast(t, exp) ((t)(exp))
+#endif
+
+#define cast_byte(i) cast(lu_byte, (i))
+#define cast_num(i) cast(lua_Number, (i))
+#define cast_int(i) cast(int, (i))
+
+
+
+/*
+** type for virtual-machine instructions
+** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+*/
+typedef lu_int32 Instruction;
+
+
+
+/* maximum stack for a Lua function */
+#define MAXSTACK 250
+
+
+
+/* minimum size for the string table (must be power of 2) */
+#ifndef MINSTRTABSIZE
+#define MINSTRTABSIZE 32
+#endif
+
+
+/* minimum size for string buffer */
+#ifndef LUA_MINBUFFER
+#define LUA_MINBUFFER 32
+#endif
+
+
+#ifndef lua_lock
+#define lua_lock(L) ((void) 0)
+#define lua_unlock(L) ((void) 0)
+#endif
+
+#ifndef luai_threadyield
+#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
+#endif
+
+
+/*
+** macro to control inclusion of some hard tests on stack reallocation
+*/
+#ifndef HARDSTACKTESTS
+#define condhardstacktests(x) ((void)0)
+#else
+#define condhardstacktests(x) x
+#endif
+
+#endif
diff --git a/misc/liblua/lmathlib.c b/misc/liblua/lmathlib.c
new file mode 100644
index 0000000..441fbf7
--- /dev/null
+++ b/misc/liblua/lmathlib.c
@@ -0,0 +1,263 @@
+/*
+** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $
+** Standard mathematical library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdlib.h>
+#include <math.h>
+
+#define lmathlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#undef PI
+#define PI (3.14159265358979323846)
+#define RADIANS_PER_DEGREE (PI/180.0)
+
+
+
+static int math_abs (lua_State *L) {
+ lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_sin (lua_State *L) {
+ lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_sinh (lua_State *L) {
+ lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_cos (lua_State *L) {
+ lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_cosh (lua_State *L) {
+ lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_tan (lua_State *L) {
+ lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_tanh (lua_State *L) {
+ lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_asin (lua_State *L) {
+ lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_acos (lua_State *L) {
+ lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_atan (lua_State *L) {
+ lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_atan2 (lua_State *L) {
+ lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+}
+
+static int math_ceil (lua_State *L) {
+ lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_floor (lua_State *L) {
+ lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_fmod (lua_State *L) {
+ lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+}
+
+static int math_modf (lua_State *L) {
+ double ip;
+ double fp = modf(luaL_checknumber(L, 1), &ip);
+ lua_pushnumber(L, ip);
+ lua_pushnumber(L, fp);
+ return 2;
+}
+
+static int math_sqrt (lua_State *L) {
+ lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_pow (lua_State *L) {
+ lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+}
+
+static int math_log (lua_State *L) {
+ lua_pushnumber(L, log(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_log10 (lua_State *L) {
+ lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_exp (lua_State *L) {
+ lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
+ return 1;
+}
+
+static int math_deg (lua_State *L) {
+ lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
+ return 1;
+}
+
+static int math_rad (lua_State *L) {
+ lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
+ return 1;
+}
+
+static int math_frexp (lua_State *L) {
+ int e;
+ lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
+ lua_pushinteger(L, e);
+ return 2;
+}
+
+static int math_ldexp (lua_State *L) {
+ lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
+ return 1;
+}
+
+
+
+static int math_min (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmin = luaL_checknumber(L, 1);
+ int i;
+ for (i=2; i<=n; i++) {
+ lua_Number d = luaL_checknumber(L, i);
+ if (d < dmin)
+ dmin = d;
+ }
+ lua_pushnumber(L, dmin);
+ return 1;
+}
+
+
+static int math_max (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmax = luaL_checknumber(L, 1);
+ int i;
+ for (i=2; i<=n; i++) {
+ lua_Number d = luaL_checknumber(L, i);
+ if (d > dmax)
+ dmax = d;
+ }
+ lua_pushnumber(L, dmax);
+ return 1;
+}
+
+
+static int math_random (lua_State *L) {
+ /* the `%' avoids the (rare) case of r==1, and is needed also because on
+ some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
+ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+ switch (lua_gettop(L)) { /* check number of arguments */
+ case 0: { /* no arguments */
+ lua_pushnumber(L, r); /* Number between 0 and 1 */
+ break;
+ }
+ case 1: { /* only upper limit */
+ int u = luaL_checkint(L, 1);
+ luaL_argcheck(L, 1<=u, 1, "interval is empty");
+ lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
+ break;
+ }
+ case 2: { /* lower and upper limits */
+ int l = luaL_checkint(L, 1);
+ int u = luaL_checkint(L, 2);
+ luaL_argcheck(L, l<=u, 2, "interval is empty");
+ lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
+ break;
+ }
+ default: return luaL_error(L, "wrong number of arguments");
+ }
+ return 1;
+}
+
+
+static int math_randomseed (lua_State *L) {
+ srand(luaL_checkint(L, 1));
+ return 0;
+}
+
+
+static const luaL_Reg mathlib[] = {
+ {"abs", math_abs},
+ {"acos", math_acos},
+ {"asin", math_asin},
+ {"atan2", math_atan2},
+ {"atan", math_atan},
+ {"ceil", math_ceil},
+ {"cosh", math_cosh},
+ {"cos", math_cos},
+ {"deg", math_deg},
+ {"exp", math_exp},
+ {"floor", math_floor},
+ {"fmod", math_fmod},
+ {"frexp", math_frexp},
+ {"ldexp", math_ldexp},
+ {"log10", math_log10},
+ {"log", math_log},
+ {"max", math_max},
+ {"min", math_min},
+ {"modf", math_modf},
+ {"pow", math_pow},
+ {"rad", math_rad},
+ {"random", math_random},
+ {"randomseed", math_randomseed},
+ {"sinh", math_sinh},
+ {"sin", math_sin},
+ {"sqrt", math_sqrt},
+ {"tanh", math_tanh},
+ {"tan", math_tan},
+ {NULL, NULL}
+};
+
+
+/*
+** Open math library
+*/
+LUALIB_API int luaopen_math (lua_State *L) {
+ luaL_register(L, LUA_MATHLIBNAME, mathlib);
+ lua_pushnumber(L, PI);
+ lua_setfield(L, -2, "pi");
+ lua_pushnumber(L, HUGE_VAL);
+ lua_setfield(L, -2, "huge");
+#if defined(LUA_COMPAT_MOD)
+ lua_getfield(L, -1, "fmod");
+ lua_setfield(L, -2, "mod");
+#endif
+ return 1;
+}
+
diff --git a/misc/liblua/lmem.c b/misc/liblua/lmem.c
new file mode 100644
index 0000000..ae7d8c9
--- /dev/null
+++ b/misc/liblua/lmem.c
@@ -0,0 +1,86 @@
+/*
+** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define lmem_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+
+/*
+** About the realloc function:
+** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
+** (`osize' is the old size, `nsize' is the new size)
+**
+** Lua ensures that (ptr == NULL) iff (osize == 0).
+**
+** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
+**
+** * frealloc(ud, p, x, 0) frees the block `p'
+** (in this specific case, frealloc must return NULL).
+** particularly, frealloc(ud, NULL, 0, 0) does nothing
+** (which is equivalent to free(NULL) in ANSI C)
+**
+** frealloc returns NULL if it cannot create or reallocate the area
+** (any reallocation to an equal or smaller size cannot fail!)
+*/
+
+
+
+#define MINSIZEARRAY 4
+
+
+void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
+ int limit, const char *errormsg) {
+ void *newblock;
+ int newsize;
+ if (*size >= limit/2) { /* cannot double it? */
+ if (*size >= limit) /* cannot grow even a little? */
+ luaG_runerror(L, errormsg);
+ newsize = limit; /* still have at least one free place */
+ }
+ else {
+ newsize = (*size)*2;
+ if (newsize < MINSIZEARRAY)
+ newsize = MINSIZEARRAY; /* minimum size */
+ }
+ newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
+ *size = newsize; /* update only when everything else is OK */
+ return newblock;
+}
+
+
+void *luaM_toobig (lua_State *L) {
+ luaG_runerror(L, "memory allocation error: block too big");
+ return NULL; /* to avoid warnings */
+}
+
+
+
+/*
+** generic allocation routine.
+*/
+void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
+ global_State *g = G(L);
+ lua_assert((osize == 0) == (block == NULL));
+ block = (*g->frealloc)(g->ud, block, osize, nsize);
+ if (block == NULL && nsize > 0)
+ luaD_throw(L, LUA_ERRMEM);
+ lua_assert((nsize == 0) == (block == NULL));
+ g->totalbytes = (g->totalbytes - osize) + nsize;
+ return block;
+}
+
diff --git a/misc/liblua/lmem.h b/misc/liblua/lmem.h
new file mode 100644
index 0000000..7c2dcb3
--- /dev/null
+++ b/misc/liblua/lmem.h
@@ -0,0 +1,49 @@
+/*
+** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
+** Interface to Memory Manager
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lmem_h
+#define lmem_h
+
+
+#include <stddef.h>
+
+#include "llimits.h"
+#include "lua.h"
+
+#define MEMERRMSG "not enough memory"
+
+
+#define luaM_reallocv(L,b,on,n,e) \
+ ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
+ luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
+ luaM_toobig(L))
+
+#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
+#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
+#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))
+
+#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
+#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
+#define luaM_newvector(L,n,t) \
+ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
+
+#define luaM_growvector(L,v,nelems,size,t,limit,e) \
+ if ((nelems)+1 > (size)) \
+ ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
+
+#define luaM_reallocvector(L, v,oldn,n,t) \
+ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
+
+
+LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
+ size_t size);
+LUAI_FUNC void *luaM_toobig (lua_State *L);
+LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
+ size_t size_elem, int limit,
+ const char *errormsg);
+
+#endif
+
diff --git a/misc/liblua/loadlib.c b/misc/liblua/loadlib.c
new file mode 100644
index 0000000..0eac6fb
--- /dev/null
+++ b/misc/liblua/loadlib.c
@@ -0,0 +1,666 @@
+/*
+** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
+** Dynamic library loader for Lua
+** See Copyright Notice in lua.h
+**
+** This module contains an implementation of loadlib for Unix systems
+** that have dlfcn, an implementation for Darwin (Mac OS X), an
+** implementation for Windows, and a stub for other systems.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define loadlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/* prefix for open functions in C libraries */
+#define LUA_POF "luaopen_"
+
+/* separator for open functions in C libraries */
+#define LUA_OFSEP "_"
+
+
+#define LIBPREFIX "LOADLIB: "
+
+#define POF LUA_POF
+#define LIB_FAIL "open"
+
+
+/* error codes for ll_loadfunc */
+#define ERRLIB 1
+#define ERRFUNC 2
+
+#define setprogdir(L) ((void)0)
+
+
+static void ll_unloadlib (void *lib);
+static void *ll_load (lua_State *L, const char *path);
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
+
+
+
+#if defined(LUA_DL_DLOPEN)
+/*
+** {========================================================================
+** This is an implementation of loadlib based on the dlfcn interface.
+** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
+** as an emulation layer on top of native functions.
+** =========================================================================
+*/
+
+#include <dlfcn.h>
+
+static void ll_unloadlib (void *lib) {
+ dlclose(lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+ void *lib = dlopen(path, RTLD_NOW);
+ if (lib == NULL) lua_pushstring(L, dlerror());
+ return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+ lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
+ if (f == NULL) lua_pushstring(L, dlerror());
+ return f;
+}
+
+/* }====================================================== */
+
+
+
+#elif defined(LUA_DL_DLL)
+/*
+** {======================================================================
+** This is an implementation of loadlib for Windows using native functions.
+** =======================================================================
+*/
+
+#include <windows.h>
+
+
+#undef setprogdir
+
+static void setprogdir (lua_State *L) {
+ char buff[MAX_PATH + 1];
+ char *lb;
+ DWORD nsize = sizeof(buff)/sizeof(char);
+ DWORD n = GetModuleFileNameA(NULL, buff, nsize);
+ if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
+ luaL_error(L, "unable to get ModuleFileName");
+ else {
+ *lb = '\0';
+ luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
+ lua_remove(L, -2); /* remove original string */
+ }
+}
+
+
+static void pusherror (lua_State *L) {
+ int error = GetLastError();
+ char buffer[128];
+ if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, error, 0, buffer, sizeof(buffer), NULL))
+ lua_pushstring(L, buffer);
+ else
+ lua_pushfstring(L, "system error %d\n", error);
+}
+
+static void ll_unloadlib (void *lib) {
+ FreeLibrary((HINSTANCE)lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+ HINSTANCE lib = LoadLibraryA(path);
+ if (lib == NULL) pusherror(L);
+ return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+ lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
+ if (f == NULL) pusherror(L);
+ return f;
+}
+
+/* }====================================================== */
+
+
+
+#elif defined(LUA_DL_DYLD)
+/*
+** {======================================================================
+** Native Mac OS X / Darwin Implementation
+** =======================================================================
+*/
+
+#include <mach-o/dyld.h>
+
+
+/* Mac appends a `_' before C function names */
+#undef POF
+#define POF "_" LUA_POF
+
+
+static void pusherror (lua_State *L) {
+ const char *err_str;
+ const char *err_file;
+ NSLinkEditErrors err;
+ int err_num;
+ NSLinkEditError(&err, &err_num, &err_file, &err_str);
+ lua_pushstring(L, err_str);
+}
+
+
+static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
+ switch (ret) {
+ case NSObjectFileImageInappropriateFile:
+ return "file is not a bundle";
+ case NSObjectFileImageArch:
+ return "library is for wrong CPU type";
+ case NSObjectFileImageFormat:
+ return "bad format";
+ case NSObjectFileImageAccess:
+ return "cannot access file";
+ case NSObjectFileImageFailure:
+ default:
+ return "unable to load library";
+ }
+}
+
+
+static void ll_unloadlib (void *lib) {
+ NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+ NSObjectFileImage img;
+ NSObjectFileImageReturnCode ret;
+ /* this would be a rare case, but prevents crashing if it happens */
+ if(!_dyld_present()) {
+ lua_pushliteral(L, "dyld not present");
+ return NULL;
+ }
+ ret = NSCreateObjectFileImageFromFile(path, &img);
+ if (ret == NSObjectFileImageSuccess) {
+ NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
+ NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+ NSDestroyObjectFileImage(img);
+ if (mod == NULL) pusherror(L);
+ return mod;
+ }
+ lua_pushstring(L, errorfromcode(ret));
+ return NULL;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+ NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
+ if (nss == NULL) {
+ lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
+ return NULL;
+ }
+ return (lua_CFunction)NSAddressOfSymbol(nss);
+}
+
+/* }====================================================== */
+
+
+
+#else
+/*
+** {======================================================
+** Fallback for other systems
+** =======================================================
+*/
+
+#undef LIB_FAIL
+#define LIB_FAIL "absent"
+
+
+#define DLMSG "dynamic libraries not enabled; check your Lua installation"
+
+
+static void ll_unloadlib (void *lib) {
+ (void)lib; /* to avoid warnings */
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+ (void)path; /* to avoid warnings */
+ lua_pushliteral(L, DLMSG);
+ return NULL;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+ (void)lib; (void)sym; /* to avoid warnings */
+ lua_pushliteral(L, DLMSG);
+ return NULL;
+}
+
+/* }====================================================== */
+#endif
+
+
+
+static void **ll_register (lua_State *L, const char *path) {
+ void **plib;
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
+ lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
+ if (!lua_isnil(L, -1)) /* is there an entry? */
+ plib = (void **)lua_touserdata(L, -1);
+ else { /* no entry yet; create one */
+ lua_pop(L, 1);
+ plib = (void **)lua_newuserdata(L, sizeof(const void *));
+ *plib = NULL;
+ luaL_getmetatable(L, "_LOADLIB");
+ lua_setmetatable(L, -2);
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
+ lua_pushvalue(L, -2);
+ lua_settable(L, LUA_REGISTRYINDEX);
+ }
+ return plib;
+}
+
+
+/*
+** __gc tag method: calls library's `ll_unloadlib' function with the lib
+** handle
+*/
+static int gctm (lua_State *L) {
+ void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
+ if (*lib) ll_unloadlib(*lib);
+ *lib = NULL; /* mark library as closed */
+ return 0;
+}
+
+
+static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
+ void **reg = ll_register(L, path);
+ if (*reg == NULL) *reg = ll_load(L, path);
+ if (*reg == NULL)
+ return ERRLIB; /* unable to load library */
+ else {
+ lua_CFunction f = ll_sym(L, *reg, sym);
+ if (f == NULL)
+ return ERRFUNC; /* unable to find function */
+ lua_pushcfunction(L, f);
+ return 0; /* return function */
+ }
+}
+
+
+static int ll_loadlib (lua_State *L) {
+ const char *path = luaL_checkstring(L, 1);
+ const char *init = luaL_checkstring(L, 2);
+ int stat = ll_loadfunc(L, path, init);
+ if (stat == 0) /* no errors? */
+ return 1; /* return the loaded function */
+ else { /* error; error message is on stack top */
+ lua_pushnil(L);
+ lua_insert(L, -2);
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
+ return 3; /* return nil, error message, and where */
+ }
+}
+
+
+
+/*
+** {======================================================
+** 'require' function
+** =======================================================
+*/
+
+
+static int readable (const char *filename) {
+ FILE *f = fopen(filename, "r"); /* try to open file */
+ if (f == NULL) return 0; /* open failed */
+ fclose(f);
+ return 1;
+}
+
+
+static const char *pushnexttemplate (lua_State *L, const char *path) {
+ const char *l;
+ while (*path == *LUA_PATHSEP) path++; /* skip separators */
+ if (*path == '\0') return NULL; /* no more templates */
+ l = strchr(path, *LUA_PATHSEP); /* find next separator */
+ if (l == NULL) l = path + strlen(path);
+ lua_pushlstring(L, path, l - path); /* template */
+ return l;
+}
+
+
+static const char *findfile (lua_State *L, const char *name,
+ const char *pname) {
+ const char *path;
+ name = luaL_gsub(L, name, ".", LUA_DIRSEP);
+ lua_getfield(L, LUA_ENVIRONINDEX, pname);
+ path = lua_tostring(L, -1);
+ if (path == NULL)
+ luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+ lua_pushliteral(L, ""); /* error accumulator */
+ while ((path = pushnexttemplate(L, path)) != NULL) {
+ const char *filename;
+ filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
+ lua_remove(L, -2); /* remove path template */
+ if (readable(filename)) /* does file exist and is readable? */
+ return filename; /* return that file name */
+ lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
+ lua_remove(L, -2); /* remove file name */
+ lua_concat(L, 2); /* add entry to possible error message */
+ }
+ return NULL; /* not found */
+}
+
+
+static void loaderror (lua_State *L, const char *filename) {
+ luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
+ lua_tostring(L, 1), filename, lua_tostring(L, -1));
+}
+
+
+static int loader_Lua (lua_State *L) {
+ const char *filename;
+ const char *name = luaL_checkstring(L, 1);
+ filename = findfile(L, name, "path");
+ if (filename == NULL) return 1; /* library not found in this path */
+ if (luaL_loadfile(L, filename) != 0)
+ loaderror(L, filename);
+ return 1; /* library loaded successfully */
+}
+
+
+static const char *mkfuncname (lua_State *L, const char *modname) {
+ const char *funcname;
+ const char *mark = strchr(modname, *LUA_IGMARK);
+ if (mark) modname = mark + 1;
+ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
+ funcname = lua_pushfstring(L, POF"%s", funcname);
+ lua_remove(L, -2); /* remove 'gsub' result */
+ return funcname;
+}
+
+
+static int loader_C (lua_State *L) {
+ const char *funcname;
+ const char *name = luaL_checkstring(L, 1);
+ const char *filename = findfile(L, name, "cpath");
+ if (filename == NULL) return 1; /* library not found in this path */
+ funcname = mkfuncname(L, name);
+ if (ll_loadfunc(L, filename, funcname) != 0)
+ loaderror(L, filename);
+ return 1; /* library loaded successfully */
+}
+
+
+static int loader_Croot (lua_State *L) {
+ const char *funcname;
+ const char *filename;
+ const char *name = luaL_checkstring(L, 1);
+ const char *p = strchr(name, '.');
+ int stat;
+ if (p == NULL) return 0; /* is root */
+ lua_pushlstring(L, name, p - name);
+ filename = findfile(L, lua_tostring(L, -1), "cpath");
+ if (filename == NULL) return 1; /* root not found */
+ funcname = mkfuncname(L, name);
+ if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
+ if (stat != ERRFUNC) loaderror(L, filename); /* real error */
+ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
+ name, filename);
+ return 1; /* function not found */
+ }
+ return 1;
+}
+
+
+static int loader_preload (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ lua_getfield(L, LUA_ENVIRONINDEX, "preload");
+ if (!lua_istable(L, -1))
+ luaL_error(L, LUA_QL("package.preload") " must be a table");
+ lua_getfield(L, -1, name);
+ if (lua_isnil(L, -1)) /* not found? */
+ lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
+ return 1;
+}
+
+
+static const int sentinel_ = 0;
+#define sentinel ((void *)&sentinel_)
+
+
+static int ll_require (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ int i;
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 2, name);
+ if (lua_toboolean(L, -1)) { /* is it there? */
+ if (lua_touserdata(L, -1) == sentinel) /* check loops */
+ luaL_error(L, "loop or previous error loading module " LUA_QS, name);
+ return 1; /* package is already loaded */
+ }
+ /* else must load it; iterate over available loaders */
+ lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
+ if (!lua_istable(L, -1))
+ luaL_error(L, LUA_QL("package.loaders") " must be a table");
+ lua_pushliteral(L, ""); /* error message accumulator */
+ for (i=1; ; i++) {
+ lua_rawgeti(L, -2, i); /* get a loader */
+ if (lua_isnil(L, -1))
+ luaL_error(L, "module " LUA_QS " not found:%s",
+ name, lua_tostring(L, -2));
+ lua_pushstring(L, name);
+ lua_call(L, 1, 1); /* call it */
+ if (lua_isfunction(L, -1)) /* did it find module? */
+ break; /* module loaded successfully */
+ else if (lua_isstring(L, -1)) /* loader returned error message? */
+ lua_concat(L, 2); /* accumulate it */
+ else
+ lua_pop(L, 1);
+ }
+ lua_pushlightuserdata(L, sentinel);
+ lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
+ lua_pushstring(L, name); /* pass name as argument to module */
+ lua_call(L, 1, 1); /* run loaded module */
+ if (!lua_isnil(L, -1)) /* non-nil return? */
+ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
+ lua_getfield(L, 2, name);
+ if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
+ lua_pushboolean(L, 1); /* use true as result */
+ lua_pushvalue(L, -1); /* extra copy to be returned */
+ lua_setfield(L, 2, name); /* _LOADED[name] = true */
+ }
+ return 1;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** 'module' function
+** =======================================================
+*/
+
+
+static void setfenv (lua_State *L) {
+ lua_Debug ar;
+ if (lua_getstack(L, 1, &ar) == 0 ||
+ lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
+ lua_iscfunction(L, -1))
+ luaL_error(L, LUA_QL("module") " not called from a Lua function");
+ lua_pushvalue(L, -2);
+ lua_setfenv(L, -2);
+ lua_pop(L, 1);
+}
+
+
+static void dooptions (lua_State *L, int n) {
+ int i;
+ for (i = 2; i <= n; i++) {
+ lua_pushvalue(L, i); /* get option (a function) */
+ lua_pushvalue(L, -2); /* module */
+ lua_call(L, 1, 0);
+ }
+}
+
+
+static void modinit (lua_State *L, const char *modname) {
+ const char *dot;
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "_M"); /* module._M = module */
+ lua_pushstring(L, modname);
+ lua_setfield(L, -2, "_NAME");
+ dot = strrchr(modname, '.'); /* look for last dot in module name */
+ if (dot == NULL) dot = modname;
+ else dot++;
+ /* set _PACKAGE as package name (full module name minus last part) */
+ lua_pushlstring(L, modname, dot - modname);
+ lua_setfield(L, -2, "_PACKAGE");
+}
+
+
+static int ll_module (lua_State *L) {
+ const char *modname = luaL_checkstring(L, 1);
+ int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
+ if (!lua_istable(L, -1)) { /* not found? */
+ lua_pop(L, 1); /* remove previous result */
+ /* try global variable (and create one if it does not exist) */
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
+ return luaL_error(L, "name conflict for module " LUA_QS, modname);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
+ }
+ /* check whether table already has a _NAME field */
+ lua_getfield(L, -1, "_NAME");
+ if (!lua_isnil(L, -1)) /* is table an initialized module? */
+ lua_pop(L, 1);
+ else { /* no; initialize it */
+ lua_pop(L, 1);
+ modinit(L, modname);
+ }
+ lua_pushvalue(L, -1);
+ setfenv(L);
+ dooptions(L, loaded - 1);
+ return 0;
+}
+
+
+static int ll_seeall (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ if (!lua_getmetatable(L, 1)) {
+ lua_createtable(L, 0, 1); /* create new metatable */
+ lua_pushvalue(L, -1);
+ lua_setmetatable(L, 1);
+ }
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_setfield(L, -2, "__index"); /* mt.__index = _G */
+ return 0;
+}
+
+
+/* }====================================================== */
+
+
+
+/* auxiliary mark (for internal use) */
+#define AUXMARK "\1"
+
+static void setpath (lua_State *L, const char *fieldname, const char *envname,
+ const char *def) {
+ const char *path = getenv(envname);
+ if (path == NULL) /* no environment variable? */
+ lua_pushstring(L, def); /* use default */
+ else {
+ /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
+ path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
+ LUA_PATHSEP AUXMARK LUA_PATHSEP);
+ luaL_gsub(L, path, AUXMARK, def);
+ lua_remove(L, -2);
+ }
+ setprogdir(L);
+ lua_setfield(L, -2, fieldname);
+}
+
+
+static const luaL_Reg pk_funcs[] = {
+ {"loadlib", ll_loadlib},
+ {"seeall", ll_seeall},
+ {NULL, NULL}
+};
+
+
+static const luaL_Reg ll_funcs[] = {
+ {"module", ll_module},
+ {"require", ll_require},
+ {NULL, NULL}
+};
+
+
+static const lua_CFunction loaders[] =
+ {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
+
+
+LUALIB_API int luaopen_package (lua_State *L) {
+ int i;
+ /* create new type _LOADLIB */
+ luaL_newmetatable(L, "_LOADLIB");
+ lua_pushcfunction(L, gctm);
+ lua_setfield(L, -2, "__gc");
+ /* create `package' table */
+ luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
+#if defined(LUA_COMPAT_LOADLIB)
+ lua_getfield(L, -1, "loadlib");
+ lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
+#endif
+ lua_pushvalue(L, -1);
+ lua_replace(L, LUA_ENVIRONINDEX);
+ /* create `loaders' table */
+ lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1);
+ /* fill it with pre-defined loaders */
+ for (i=0; loaders[i] != NULL; i++) {
+ lua_pushcfunction(L, loaders[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+ lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
+ setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
+ setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
+ /* store config information */
+ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
+ LUA_EXECDIR "\n" LUA_IGMARK);
+ lua_setfield(L, -2, "config");
+ /* set field `loaded' */
+ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
+ lua_setfield(L, -2, "loaded");
+ /* set field `preload' */
+ lua_newtable(L);
+ lua_setfield(L, -2, "preload");
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ luaL_register(L, NULL, ll_funcs); /* open lib into global table */
+ lua_pop(L, 1);
+ return 1; /* return 'package' table */
+}
+
diff --git a/misc/liblua/lobject.c b/misc/liblua/lobject.c
new file mode 100644
index 0000000..4ff5073
--- /dev/null
+++ b/misc/liblua/lobject.c
@@ -0,0 +1,214 @@
+/*
+** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
+** Some generic functions over Lua objects
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lobject_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "lvm.h"
+
+
+
+const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
+
+
+/*
+** converts an integer to a "floating point byte", represented as
+** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+** eeeee != 0 and (xxx) otherwise.
+*/
+int luaO_int2fb (unsigned int x) {
+ int e = 0; /* expoent */
+ while (x >= 16) {
+ x = (x+1) >> 1;
+ e++;
+ }
+ if (x < 8) return x;
+ else return ((e+1) << 3) | (cast_int(x) - 8);
+}
+
+
+/* converts back */
+int luaO_fb2int (int x) {
+ int e = (x >> 3) & 31;
+ if (e == 0) return x;
+ else return ((x & 7)+8) << (e - 1);
+}
+
+
+int luaO_log2 (unsigned int x) {
+ static const lu_byte log_2[256] = {
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+ };
+ int l = -1;
+ while (x >= 256) { l += 8; x >>= 8; }
+ return l + log_2[x];
+
+}
+
+
+int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
+ if (ttype(t1) != ttype(t2)) return 0;
+ else switch (ttype(t1)) {
+ case LUA_TNIL:
+ return 1;
+ case LUA_TNUMBER:
+ return luai_numeq(nvalue(t1), nvalue(t2));
+ case LUA_TBOOLEAN:
+ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
+ case LUA_TLIGHTUSERDATA:
+ return pvalue(t1) == pvalue(t2);
+ default:
+ lua_assert(iscollectable(t1));
+ return gcvalue(t1) == gcvalue(t2);
+ }
+}
+
+
+int luaO_str2d (const char *s, lua_Number *result) {
+ char *endptr;
+ *result = lua_str2number(s, &endptr);
+ if (endptr == s) return 0; /* conversion failed */
+ if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
+ *result = cast_num(strtoul(s, &endptr, 16));
+ if (*endptr == '\0') return 1; /* most common case */
+ while (isspace(cast(unsigned char, *endptr))) endptr++;
+ if (*endptr != '\0') return 0; /* invalid trailing characters? */
+ return 1;
+}
+
+
+
+static void pushstr (lua_State *L, const char *str) {
+ setsvalue2s(L, L->top, luaS_new(L, str));
+ incr_top(L);
+}
+
+
+/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+ int n = 1;
+ pushstr(L, "");
+ for (;;) {
+ const char *e = strchr(fmt, '%');
+ if (e == NULL) break;
+ setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
+ incr_top(L);
+ switch (*(e+1)) {
+ case 's': {
+ const char *s = va_arg(argp, char *);
+ if (s == NULL) s = "(null)";
+ pushstr(L, s);
+ break;
+ }
+ case 'c': {
+ char buff[2];
+ buff[0] = cast(char, va_arg(argp, int));
+ buff[1] = '\0';
+ pushstr(L, buff);
+ break;
+ }
+ case 'd': {
+ setnvalue(L->top, cast_num(va_arg(argp, int)));
+ incr_top(L);
+ break;
+ }
+ case 'f': {
+ setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+ incr_top(L);
+ break;
+ }
+ case 'p': {
+ char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
+ sprintf(buff, "%p", va_arg(argp, void *));
+ pushstr(L, buff);
+ break;
+ }
+ case '%': {
+ pushstr(L, "%");
+ break;
+ }
+ default: {
+ char buff[3];
+ buff[0] = '%';
+ buff[1] = *(e+1);
+ buff[2] = '\0';
+ pushstr(L, buff);
+ break;
+ }
+ }
+ n += 2;
+ fmt = e+2;
+ }
+ pushstr(L, fmt);
+ luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
+ L->top -= n;
+ return svalue(L->top - 1);
+}
+
+
+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+ const char *msg;
+ va_list argp;
+ va_start(argp, fmt);
+ msg = luaO_pushvfstring(L, fmt, argp);
+ va_end(argp);
+ return msg;
+}
+
+
+void luaO_chunkid (char *out, const char *source, size_t bufflen) {
+ if (*source == '=') {
+ strncpy(out, source+1, bufflen); /* remove first char */
+ out[bufflen-1] = '\0'; /* ensures null termination */
+ }
+ else { /* out = "source", or "...source" */
+ if (*source == '@') {
+ size_t l;
+ source++; /* skip the `@' */
+ bufflen -= sizeof(" '...' ");
+ l = strlen(source);
+ strcpy(out, "");
+ if (l > bufflen) {
+ source += (l-bufflen); /* get last part of file name */
+ strcat(out, "...");
+ }
+ strcat(out, source);
+ }
+ else { /* out = [string "string"] */
+ size_t len = strcspn(source, "\n\r"); /* stop at first newline */
+ bufflen -= sizeof(" [string \"...\"] ");
+ if (len > bufflen) len = bufflen;
+ strcpy(out, "[string \"");
+ if (source[len] != '\0') { /* must truncate? */
+ strncat(out, source, len);
+ strcat(out, "...");
+ }
+ else
+ strcat(out, source);
+ strcat(out, "\"]");
+ }
+ }
+}
diff --git a/misc/liblua/lobject.h b/misc/liblua/lobject.h
new file mode 100644
index 0000000..577c6cc
--- /dev/null
+++ b/misc/liblua/lobject.h
@@ -0,0 +1,381 @@
+/*
+** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
+** Type definitions for Lua objects
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lobject_h
+#define lobject_h
+
+
+#include <stdarg.h>
+
+
+#include "llimits.h"
+#include "lua.h"
+
+
+/* tags for values visible from Lua */
+#define LAST_TAG LUA_TTHREAD
+
+#define NUM_TAGS (LAST_TAG+1)
+
+
+/*
+** Extra tags for non-values
+*/
+#define LUA_TPROTO (LAST_TAG+1)
+#define LUA_TUPVAL (LAST_TAG+2)
+#define LUA_TDEADKEY (LAST_TAG+3)
+
+
+/*
+** Union of all collectable objects
+*/
+typedef union GCObject GCObject;
+
+
+/*
+** Common Header for all collectable objects (in macro form, to be
+** included in other objects)
+*/
+#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
+
+
+/*
+** Common header in struct form
+*/
+typedef struct GCheader {
+ CommonHeader;
+} GCheader;
+
+
+
+
+/*
+** Union of all Lua values
+*/
+typedef union {
+ GCObject *gc;
+ void *p;
+ lua_Number n;
+ int b;
+} Value;
+
+
+/*
+** Tagged Values
+*/
+
+#define TValuefields Value value; int tt
+
+typedef struct lua_TValue {
+ TValuefields;
+} TValue;
+
+
+/* Macros to test type */
+#define ttisnil(o) (ttype(o) == LUA_TNIL)
+#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
+#define ttisstring(o) (ttype(o) == LUA_TSTRING)
+#define ttistable(o) (ttype(o) == LUA_TTABLE)
+#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
+#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
+#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
+#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
+#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
+
+/* Macros to access values */
+#define ttype(o) ((o)->tt)
+#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
+#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
+#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
+#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
+#define tsvalue(o) (&rawtsvalue(o)->tsv)
+#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
+#define uvalue(o) (&rawuvalue(o)->uv)
+#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
+#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
+#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
+#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
+
+#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
+
+/*
+** for internal debug only
+*/
+#define checkconsistency(obj) \
+ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
+
+#define checkliveness(g,obj) \
+ lua_assert(!iscollectable(obj) || \
+ ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
+
+
+/* Macros to set values */
+#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+
+#define setnvalue(obj,x) \
+ { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
+
+#define setpvalue(obj,x) \
+ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
+
+#define setbvalue(obj,x) \
+ { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
+
+#define setsvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
+ checkliveness(G(L),i_o); }
+
+#define setuvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
+ checkliveness(G(L),i_o); }
+
+#define setthvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
+ checkliveness(G(L),i_o); }
+
+#define setclvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
+ checkliveness(G(L),i_o); }
+
+#define sethvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
+ checkliveness(G(L),i_o); }
+
+#define setptvalue(L,obj,x) \
+ { TValue *i_o=(obj); \
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
+ checkliveness(G(L),i_o); }
+
+
+
+
+#define setobj(L,obj1,obj2) \
+ { const TValue *o2=(obj2); TValue *o1=(obj1); \
+ o1->value = o2->value; o1->tt=o2->tt; \
+ checkliveness(G(L),o1); }
+
+
+/*
+** different types of sets, according to destination
+*/
+
+/* from stack to (same) stack */
+#define setobjs2s setobj
+/* to stack (not from same stack) */
+#define setobj2s setobj
+#define setsvalue2s setsvalue
+#define sethvalue2s sethvalue
+#define setptvalue2s setptvalue
+/* from table to same table */
+#define setobjt2t setobj
+/* to table */
+#define setobj2t setobj
+/* to new object */
+#define setobj2n setobj
+#define setsvalue2n setsvalue
+
+#define setttype(obj, tt) (ttype(obj) = (tt))
+
+
+#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
+
+
+
+typedef TValue *StkId; /* index to stack elements */
+
+
+/*
+** String headers for string table
+*/
+typedef union TString {
+ L_Umaxalign dummy; /* ensures maximum alignment for strings */
+ struct {
+ CommonHeader;
+ lu_byte reserved;
+ unsigned int hash;
+ size_t len;
+ } tsv;
+} TString;
+
+
+#define getstr(ts) cast(const char *, (ts) + 1)
+#define svalue(o) getstr(rawtsvalue(o))
+
+
+
+typedef union Udata {
+ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
+ struct {
+ CommonHeader;
+ struct Table *metatable;
+ struct Table *env;
+ size_t len;
+ } uv;
+} Udata;
+
+
+
+
+/*
+** Function Prototypes
+*/
+typedef struct Proto {
+ CommonHeader;
+ TValue *k; /* constants used by the function */
+ Instruction *code;
+ struct Proto **p; /* functions defined inside the function */
+ int *lineinfo; /* map from opcodes to source lines */
+ struct LocVar *locvars; /* information about local variables */
+ TString **upvalues; /* upvalue names */
+ TString *source;
+ int sizeupvalues;
+ int sizek; /* size of `k' */
+ int sizecode;
+ int sizelineinfo;
+ int sizep; /* size of `p' */
+ int sizelocvars;
+ int linedefined;
+ int lastlinedefined;
+ GCObject *gclist;
+ lu_byte nups; /* number of upvalues */
+ lu_byte numparams;
+ lu_byte is_vararg;
+ lu_byte maxstacksize;
+} Proto;
+
+
+/* masks for new-style vararg */
+#define VARARG_HASARG 1
+#define VARARG_ISVARARG 2
+#define VARARG_NEEDSARG 4
+
+
+typedef struct LocVar {
+ TString *varname;
+ int startpc; /* first point where variable is active */
+ int endpc; /* first point where variable is dead */
+} LocVar;
+
+
+
+/*
+** Upvalues
+*/
+
+typedef struct UpVal {
+ CommonHeader;
+ TValue *v; /* points to stack or to its own value */
+ union {
+ TValue value; /* the value (when closed) */
+ struct { /* double linked list (when open) */
+ struct UpVal *prev;
+ struct UpVal *next;
+ } l;
+ } u;
+} UpVal;
+
+
+/*
+** Closures
+*/
+
+#define ClosureHeader \
+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
+ struct Table *env
+
+typedef struct CClosure {
+ ClosureHeader;
+ lua_CFunction f;
+ TValue upvalue[1];
+} CClosure;
+
+
+typedef struct LClosure {
+ ClosureHeader;
+ struct Proto *p;
+ UpVal *upvals[1];
+} LClosure;
+
+
+typedef union Closure {
+ CClosure c;
+ LClosure l;
+} Closure;
+
+
+#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
+#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
+
+
+/*
+** Tables
+*/
+
+typedef union TKey {
+ struct {
+ TValuefields;
+ struct Node *next; /* for chaining */
+ } nk;
+ TValue tvk;
+} TKey;
+
+
+typedef struct Node {
+ TValue i_val;
+ TKey i_key;
+} Node;
+
+
+typedef struct Table {
+ CommonHeader;
+ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
+ lu_byte lsizenode; /* log2 of size of `node' array */
+ struct Table *metatable;
+ TValue *array; /* array part */
+ Node *node;
+ Node *lastfree; /* any free position is before this position */
+ GCObject *gclist;
+ int sizearray; /* size of `array' array */
+} Table;
+
+
+
+/*
+** `module' operation for hashing (size is always a power of 2)
+*/
+#define lmod(s,size) \
+ (check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
+
+
+#define twoto(x) (1<<(x))
+#define sizenode(t) (twoto((t)->lsizenode))
+
+
+#define luaO_nilobject (&luaO_nilobject_)
+
+LUAI_DATA const TValue luaO_nilobject_;
+
+#define ceillog2(x) (luaO_log2((x)-1) + 1)
+
+LUAI_FUNC int luaO_log2 (unsigned int x);
+LUAI_FUNC int luaO_int2fb (unsigned int x);
+LUAI_FUNC int luaO_fb2int (int x);
+LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
+LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
+LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp);
+LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+
+
+#endif
+
diff --git a/misc/liblua/lopcodes.c b/misc/liblua/lopcodes.c
new file mode 100644
index 0000000..4cc7452
--- /dev/null
+++ b/misc/liblua/lopcodes.c
@@ -0,0 +1,102 @@
+/*
+** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
+** See Copyright Notice in lua.h
+*/
+
+
+#define lopcodes_c
+#define LUA_CORE
+
+
+#include "lopcodes.h"
+
+
+/* ORDER OP */
+
+const char *const luaP_opnames[NUM_OPCODES+1] = {
+ "MOVE",
+ "LOADK",
+ "LOADBOOL",
+ "LOADNIL",
+ "GETUPVAL",
+ "GETGLOBAL",
+ "GETTABLE",
+ "SETGLOBAL",
+ "SETUPVAL",
+ "SETTABLE",
+ "NEWTABLE",
+ "SELF",
+ "ADD",
+ "SUB",
+ "MUL",
+ "DIV",
+ "MOD",
+ "POW",
+ "UNM",
+ "NOT",
+ "LEN",
+ "CONCAT",
+ "JMP",
+ "EQ",
+ "LT",
+ "LE",
+ "TEST",
+ "TESTSET",
+ "CALL",
+ "TAILCALL",
+ "RETURN",
+ "FORLOOP",
+ "FORPREP",
+ "TFORLOOP",
+ "SETLIST",
+ "CLOSE",
+ "CLOSURE",
+ "VARARG",
+ NULL
+};
+
+
+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
+
+const lu_byte luaP_opmodes[NUM_OPCODES] = {
+/* T A B C mode opcode */
+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
+ ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
+ ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
+ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
+};
+
diff --git a/misc/liblua/lopcodes.h b/misc/liblua/lopcodes.h
new file mode 100644
index 0000000..b4b86cf
--- /dev/null
+++ b/misc/liblua/lopcodes.h
@@ -0,0 +1,268 @@
+/*
+** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
+** Opcodes for Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lopcodes_h
+#define lopcodes_h
+
+#include "llimits.h"
+
+
+/*===========================================================================
+ We assume that instructions are unsigned numbers.
+ All instructions have an opcode in the first 6 bits.
+ Instructions can have the following fields:
+ `A' : 8 bits
+ `B' : 9 bits
+ `C' : 9 bits
+ `Bx' : 18 bits (`B' and `C' together)
+ `sBx' : signed Bx
+
+ A signed argument is represented in excess K; that is, the number
+ value is the unsigned value minus K. K is exactly the maximum value
+ for that argument (so that -max is represented by 0, and +max is
+ represented by 2*max), which is half the maximum for the corresponding
+ unsigned argument.
+===========================================================================*/
+
+
+enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
+
+
+/*
+** size and position of opcode arguments.
+*/
+#define SIZE_C 9
+#define SIZE_B 9
+#define SIZE_Bx (SIZE_C + SIZE_B)
+#define SIZE_A 8
+
+#define SIZE_OP 6
+
+#define POS_OP 0
+#define POS_A (POS_OP + SIZE_OP)
+#define POS_C (POS_A + SIZE_A)
+#define POS_B (POS_C + SIZE_C)
+#define POS_Bx POS_C
+
+
+/*
+** limits for opcode arguments.
+** we use (signed) int to manipulate most arguments,
+** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
+*/
+#if SIZE_Bx < LUAI_BITSINT-1
+#define MAXARG_Bx ((1<<SIZE_Bx)-1)
+#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
+#else
+#define MAXARG_Bx MAX_INT
+#define MAXARG_sBx MAX_INT
+#endif
+
+
+#define MAXARG_A ((1<<SIZE_A)-1)
+#define MAXARG_B ((1<<SIZE_B)-1)
+#define MAXARG_C ((1<<SIZE_C)-1)
+
+
+/* creates a mask with `n' 1 bits at position `p' */
+#define MASK1(n,p) ((~((~(Instruction)0)<<n))<<p)
+
+/* creates a mask with `n' 0 bits at position `p' */
+#define MASK0(n,p) (~MASK1(n,p))
+
+/*
+** the following macros help to manipulate instructions
+*/
+
+#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
+#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
+ ((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
+
+#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
+#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
+ ((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
+
+#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
+#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
+ ((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
+
+#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
+#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
+ ((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
+
+#define GETARG_Bx(i) (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
+#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
+ ((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
+
+#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
+#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+
+
+#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
+ | (cast(Instruction, a)<<POS_A) \
+ | (cast(Instruction, b)<<POS_B) \
+ | (cast(Instruction, c)<<POS_C))
+
+#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
+ | (cast(Instruction, a)<<POS_A) \
+ | (cast(Instruction, bc)<<POS_Bx))
+
+
+/*
+** Macros to operate RK indices
+*/
+
+/* this bit 1 means constant (0 means register) */
+#define BITRK (1 << (SIZE_B - 1))
+
+/* test whether value is a constant */
+#define ISK(x) ((x) & BITRK)
+
+/* gets the index of the constant */
+#define INDEXK(r) ((int)(r) & ~BITRK)
+
+#define MAXINDEXRK (BITRK - 1)
+
+/* code a constant index as a RK value */
+#define RKASK(x) ((x) | BITRK)
+
+
+/*
+** invalid register that fits in 8 bits
+*/
+#define NO_REG MAXARG_A
+
+
+/*
+** R(x) - register
+** Kst(x) - constant (in constant table)
+** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
+*/
+
+
+/*
+** grep "ORDER OP" if you change these enums
+*/
+
+typedef enum {
+/*----------------------------------------------------------------------
+name args description
+------------------------------------------------------------------------*/
+OP_MOVE,/* A B R(A) := R(B) */
+OP_LOADK,/* A Bx R(A) := Kst(Bx) */
+OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
+OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
+OP_GETUPVAL,/* A B R(A) := UpValue[B] */
+
+OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
+OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
+
+OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
+OP_SETUPVAL,/* A B UpValue[B] := R(A) */
+OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
+
+OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
+
+OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
+
+OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
+OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
+OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
+OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
+OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
+OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
+OP_UNM,/* A B R(A) := -R(B) */
+OP_NOT,/* A B R(A) := not R(B) */
+OP_LEN,/* A B R(A) := length of R(B) */
+
+OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
+
+OP_JMP,/* sBx pc+=sBx */
+
+OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
+OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
+OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
+
+OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+
+OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
+
+OP_FORLOOP,/* A sBx R(A)+=R(A+2);
+ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
+OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
+
+OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
+ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
+OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
+
+OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
+OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
+
+OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
+} OpCode;
+
+
+#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
+
+
+
+/*===========================================================================
+ Notes:
+ (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
+ and can be 0: OP_CALL then sets `top' to last_result+1, so
+ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
+
+ (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
+ set top (like in OP_CALL with C == 0).
+
+ (*) In OP_RETURN, if (B == 0) then return up to `top'
+
+ (*) In OP_SETLIST, if (B == 0) then B = `top';
+ if (C == 0) then next `instruction' is real C
+
+ (*) For comparisons, A specifies what condition the test should accept
+ (true or false).
+
+ (*) All `skips' (pc++) assume that next instruction is a jump
+===========================================================================*/
+
+
+/*
+** masks for instruction properties. The format is:
+** bits 0-1: op mode
+** bits 2-3: C arg mode
+** bits 4-5: B arg mode
+** bit 6: instruction set register A
+** bit 7: operator is a test
+*/
+
+enum OpArgMask {
+ OpArgN, /* argument is not used */
+ OpArgU, /* argument is used */
+ OpArgR, /* argument is a register or a jump offset */
+ OpArgK /* argument is a constant or register/constant */
+};
+
+LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
+
+#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
+#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
+#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
+#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
+#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
+
+
+LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
+
+
+/* number of list items to accumulate before a SETLIST instruction */
+#define LFIELDS_PER_FLUSH 50
+
+
+#endif
diff --git a/misc/liblua/loslib.c b/misc/liblua/loslib.c
new file mode 100644
index 0000000..da06a57
--- /dev/null
+++ b/misc/liblua/loslib.c
@@ -0,0 +1,243 @@
+/*
+** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
+** Standard Operating System library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define loslib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+static int os_pushresult (lua_State *L, int i, const char *filename) {
+ int en = errno; /* calls to Lua API may change this value */
+ if (i) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ lua_pushnil(L);
+ lua_pushfstring(L, "%s: %s", filename, strerror(en));
+ lua_pushinteger(L, en);
+ return 3;
+ }
+}
+
+
+static int os_execute (lua_State *L) {
+ lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
+ return 1;
+}
+
+
+static int os_remove (lua_State *L) {
+ const char *filename = luaL_checkstring(L, 1);
+ return os_pushresult(L, remove(filename) == 0, filename);
+}
+
+
+static int os_rename (lua_State *L) {
+ const char *fromname = luaL_checkstring(L, 1);
+ const char *toname = luaL_checkstring(L, 2);
+ return os_pushresult(L, rename(fromname, toname) == 0, fromname);
+}
+
+
+static int os_tmpname (lua_State *L) {
+ char buff[LUA_TMPNAMBUFSIZE];
+ int err;
+ lua_tmpnam(buff, err);
+ if (err)
+ return luaL_error(L, "unable to generate a unique filename");
+ lua_pushstring(L, buff);
+ return 1;
+}
+
+
+static int os_getenv (lua_State *L) {
+ lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
+ return 1;
+}
+
+
+static int os_clock (lua_State *L) {
+ lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+ return 1;
+}
+
+
+/*
+** {======================================================
+** Time/Date operations
+** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
+** wday=%w+1, yday=%j, isdst=? }
+** =======================================================
+*/
+
+static void setfield (lua_State *L, const char *key, int value) {
+ lua_pushinteger(L, value);
+ lua_setfield(L, -2, key);
+}
+
+static void setboolfield (lua_State *L, const char *key, int value) {
+ if (value < 0) /* undefined? */
+ return; /* does not set field */
+ lua_pushboolean(L, value);
+ lua_setfield(L, -2, key);
+}
+
+static int getboolfield (lua_State *L, const char *key) {
+ int res;
+ lua_getfield(L, -1, key);
+ res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return res;
+}
+
+
+static int getfield (lua_State *L, const char *key, int d) {
+ int res;
+ lua_getfield(L, -1, key);
+ if (lua_isnumber(L, -1))
+ res = (int)lua_tointeger(L, -1);
+ else {
+ if (d < 0)
+ return luaL_error(L, "field " LUA_QS " missing in date table", key);
+ res = d;
+ }
+ lua_pop(L, 1);
+ return res;
+}
+
+
+static int os_date (lua_State *L) {
+ const char *s = luaL_optstring(L, 1, "%c");
+ time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
+ struct tm *stm;
+ if (*s == '!') { /* UTC? */
+ stm = gmtime(&t);
+ s++; /* skip `!' */
+ }
+ else
+ stm = localtime(&t);
+ if (stm == NULL) /* invalid date? */
+ lua_pushnil(L);
+ else if (strcmp(s, "*t") == 0) {
+ lua_createtable(L, 0, 9); /* 9 = number of fields */
+ setfield(L, "sec", stm->tm_sec);
+ setfield(L, "min", stm->tm_min);
+ setfield(L, "hour", stm->tm_hour);
+ setfield(L, "day", stm->tm_mday);
+ setfield(L, "month", stm->tm_mon+1);
+ setfield(L, "year", stm->tm_year+1900);
+ setfield(L, "wday", stm->tm_wday+1);
+ setfield(L, "yday", stm->tm_yday+1);
+ setboolfield(L, "isdst", stm->tm_isdst);
+ }
+ else {
+ char cc[3];
+ luaL_Buffer b;
+ cc[0] = '%'; cc[2] = '\0';
+ luaL_buffinit(L, &b);
+ for (; *s; s++) {
+ if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
+ luaL_addchar(&b, *s);
+ else {
+ size_t reslen;
+ char buff[200]; /* should be big enough for any conversion result */
+ cc[1] = *(++s);
+ reslen = strftime(buff, sizeof(buff), cc, stm);
+ luaL_addlstring(&b, buff, reslen);
+ }
+ }
+ luaL_pushresult(&b);
+ }
+ return 1;
+}
+
+
+static int os_time (lua_State *L) {
+ time_t t;
+ if (lua_isnoneornil(L, 1)) /* called without args? */
+ t = time(NULL); /* get current time */
+ else {
+ struct tm ts;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_settop(L, 1); /* make sure table is at the top */
+ ts.tm_sec = getfield(L, "sec", 0);
+ ts.tm_min = getfield(L, "min", 0);
+ ts.tm_hour = getfield(L, "hour", 12);
+ ts.tm_mday = getfield(L, "day", -1);
+ ts.tm_mon = getfield(L, "month", -1) - 1;
+ ts.tm_year = getfield(L, "year", -1) - 1900;
+ ts.tm_isdst = getboolfield(L, "isdst");
+ t = mktime(&ts);
+ }
+ if (t == (time_t)(-1))
+ lua_pushnil(L);
+ else
+ lua_pushnumber(L, (lua_Number)t);
+ return 1;
+}
+
+
+static int os_difftime (lua_State *L) {
+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+ (time_t)(luaL_optnumber(L, 2, 0))));
+ return 1;
+}
+
+/* }====================================================== */
+
+
+static int os_setlocale (lua_State *L) {
+ static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+ LC_NUMERIC, LC_TIME};
+ static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+ "numeric", "time", NULL};
+ const char *l = luaL_optstring(L, 1, NULL);
+ int op = luaL_checkoption(L, 2, "all", catnames);
+ lua_pushstring(L, setlocale(cat[op], l));
+ return 1;
+}
+
+
+static int os_exit (lua_State *L) {
+ exit(luaL_optint(L, 1, EXIT_SUCCESS));
+}
+
+static const luaL_Reg syslib[] = {
+ {"clock", os_clock},
+ {"date", os_date},
+ {"difftime", os_difftime},
+ {"execute", os_execute},
+ {"exit", os_exit},
+ {"getenv", os_getenv},
+ {"remove", os_remove},
+ {"rename", os_rename},
+ {"setlocale", os_setlocale},
+ {"time", os_time},
+ {"tmpname", os_tmpname},
+ {NULL, NULL}
+};
+
+/* }====================================================== */
+
+
+
+LUALIB_API int luaopen_os (lua_State *L) {
+ luaL_register(L, LUA_OSLIBNAME, syslib);
+ return 1;
+}
+
diff --git a/misc/liblua/lparser.c b/misc/liblua/lparser.c
new file mode 100644
index 0000000..1e2a9a8
--- /dev/null
+++ b/misc/liblua/lparser.c
@@ -0,0 +1,1339 @@
+/*
+** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lparser_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lcode.h"
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lparser.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+
+
+
+#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
+
+#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
+
+#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
+
+
+/*
+** nodes for block list (list of active blocks)
+*/
+typedef struct BlockCnt {
+ struct BlockCnt *previous; /* chain */
+ int breaklist; /* list of jumps out of this loop */
+ lu_byte nactvar; /* # active locals outside the breakable structure */
+ lu_byte upval; /* true if some variable in the block is an upvalue */
+ lu_byte isbreakable; /* true if `block' is a loop */
+} BlockCnt;
+
+
+
+/*
+** prototypes for recursive non-terminal functions
+*/
+static void chunk (LexState *ls);
+static void expr (LexState *ls, expdesc *v);
+
+
+static void anchor_token (LexState *ls) {
+ if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
+ TString *ts = ls->t.seminfo.ts;
+ luaX_newstring(ls, getstr(ts), ts->tsv.len);
+ }
+}
+
+
+static void error_expected (LexState *ls, int token) {
+ luaX_syntaxerror(ls,
+ luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
+}
+
+
+static void errorlimit (FuncState *fs, int limit, const char *what) {
+ const char *msg = (fs->f->linedefined == 0) ?
+ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
+ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
+ fs->f->linedefined, limit, what);
+ luaX_lexerror(fs->ls, msg, 0);
+}
+
+
+static int testnext (LexState *ls, int c) {
+ if (ls->t.token == c) {
+ luaX_next(ls);
+ return 1;
+ }
+ else return 0;
+}
+
+
+static void check (LexState *ls, int c) {
+ if (ls->t.token != c)
+ error_expected(ls, c);
+}
+
+static void checknext (LexState *ls, int c) {
+ check(ls, c);
+ luaX_next(ls);
+}
+
+
+#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
+
+
+
+static void check_match (LexState *ls, int what, int who, int where) {
+ if (!testnext(ls, what)) {
+ if (where == ls->linenumber)
+ error_expected(ls, what);
+ else {
+ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
+ LUA_QS " expected (to close " LUA_QS " at line %d)",
+ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
+ }
+ }
+}
+
+
+static TString *str_checkname (LexState *ls) {
+ TString *ts;
+ check(ls, TK_NAME);
+ ts = ls->t.seminfo.ts;
+ luaX_next(ls);
+ return ts;
+}
+
+
+static void init_exp (expdesc *e, expkind k, int i) {
+ e->f = e->t = NO_JUMP;
+ e->k = k;
+ e->u.s.info = i;
+}
+
+
+static void codestring (LexState *ls, expdesc *e, TString *s) {
+ init_exp(e, VK, luaK_stringK(ls->fs, s));
+}
+
+
+static void checkname(LexState *ls, expdesc *e) {
+ codestring(ls, e, str_checkname(ls));
+}
+
+
+static int registerlocalvar (LexState *ls, TString *varname) {
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ int oldsize = f->sizelocvars;
+ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
+ LocVar, SHRT_MAX, "too many local variables");
+ while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
+ f->locvars[fs->nlocvars].varname = varname;
+ luaC_objbarrier(ls->L, f, varname);
+ return fs->nlocvars++;
+}
+
+
+#define new_localvarliteral(ls,v,n) \
+ new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
+
+
+static void new_localvar (LexState *ls, TString *name, int n) {
+ FuncState *fs = ls->fs;
+ luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
+ fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
+}
+
+
+static void adjustlocalvars (LexState *ls, int nvars) {
+ FuncState *fs = ls->fs;
+ fs->nactvar = cast_byte(fs->nactvar + nvars);
+ for (; nvars; nvars--) {
+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
+ }
+}
+
+
+static void removevars (LexState *ls, int tolevel) {
+ FuncState *fs = ls->fs;
+ while (fs->nactvar > tolevel)
+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
+}
+
+
+static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
+ int i;
+ Proto *f = fs->f;
+ int oldsize = f->sizeupvalues;
+ for (i=0; i<f->nups; i++) {
+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
+ lua_assert(f->upvalues[i] == name);
+ return i;
+ }
+ }
+ /* new one */
+ luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
+ luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
+ TString *, MAX_INT, "");
+ while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
+ f->upvalues[f->nups] = name;
+ luaC_objbarrier(fs->L, f, name);
+ lua_assert(v->k == VLOCAL || v->k == VUPVAL);
+ fs->upvalues[f->nups].k = cast_byte(v->k);
+ fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
+ return f->nups++;
+}
+
+
+static int searchvar (FuncState *fs, TString *n) {
+ int i;
+ for (i=fs->nactvar-1; i >= 0; i--) {
+ if (n == getlocvar(fs, i).varname)
+ return i;
+ }
+ return -1; /* not found */
+}
+
+
+static void markupval (FuncState *fs, int level) {
+ BlockCnt *bl = fs->bl;
+ while (bl && bl->nactvar > level) bl = bl->previous;
+ if (bl) bl->upval = 1;
+}
+
+
+static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
+ if (fs == NULL) { /* no more levels? */
+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
+ return VGLOBAL;
+ }
+ else {
+ int v = searchvar(fs, n); /* look up at current level */
+ if (v >= 0) {
+ init_exp(var, VLOCAL, v);
+ if (!base)
+ markupval(fs, v); /* local will be used as an upval */
+ return VLOCAL;
+ }
+ else { /* not found at current level; try upper one */
+ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
+ return VGLOBAL;
+ var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
+ var->k = VUPVAL; /* upvalue in this level */
+ return VUPVAL;
+ }
+ }
+}
+
+
+static void singlevar (LexState *ls, expdesc *var) {
+ TString *varname = str_checkname(ls);
+ FuncState *fs = ls->fs;
+ if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
+ var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
+}
+
+
+static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
+ FuncState *fs = ls->fs;
+ int extra = nvars - nexps;
+ if (hasmultret(e->k)) {
+ extra++; /* includes call itself */
+ if (extra < 0) extra = 0;
+ luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
+ if (extra > 1) luaK_reserveregs(fs, extra-1);
+ }
+ else {
+ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
+ if (extra > 0) {
+ int reg = fs->freereg;
+ luaK_reserveregs(fs, extra);
+ luaK_nil(fs, reg, extra);
+ }
+ }
+}
+
+
+static void enterlevel (LexState *ls) {
+ if (++ls->L->nCcalls > LUAI_MAXCCALLS)
+ luaX_lexerror(ls, "chunk has too many syntax levels", 0);
+}
+
+
+#define leavelevel(ls) ((ls)->L->nCcalls--)
+
+
+static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
+ bl->breaklist = NO_JUMP;
+ bl->isbreakable = isbreakable;
+ bl->nactvar = fs->nactvar;
+ bl->upval = 0;
+ bl->previous = fs->bl;
+ fs->bl = bl;
+ lua_assert(fs->freereg == fs->nactvar);
+}
+
+
+static void leaveblock (FuncState *fs) {
+ BlockCnt *bl = fs->bl;
+ fs->bl = bl->previous;
+ removevars(fs->ls, bl->nactvar);
+ if (bl->upval)
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ /* a block either controls scope or breaks (never both) */
+ lua_assert(!bl->isbreakable || !bl->upval);
+ lua_assert(bl->nactvar == fs->nactvar);
+ fs->freereg = fs->nactvar; /* free registers */
+ luaK_patchtohere(fs, bl->breaklist);
+}
+
+
+static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ int oldsize = f->sizep;
+ int i;
+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
+ MAXARG_Bx, "constant table overflow");
+ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
+ f->p[fs->np++] = func->f;
+ luaC_objbarrier(ls->L, f, func->f);
+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
+ for (i=0; i<func->f->nups; i++) {
+ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
+ }
+}
+
+
+static void open_func (LexState *ls, FuncState *fs) {
+ lua_State *L = ls->L;
+ Proto *f = luaF_newproto(L);
+ fs->f = f;
+ fs->prev = ls->fs; /* linked list of funcstates */
+ fs->ls = ls;
+ fs->L = L;
+ ls->fs = fs;
+ fs->pc = 0;
+ fs->lasttarget = -1;
+ fs->jpc = NO_JUMP;
+ fs->freereg = 0;
+ fs->nk = 0;
+ fs->np = 0;
+ fs->nlocvars = 0;
+ fs->nactvar = 0;
+ fs->bl = NULL;
+ f->source = ls->source;
+ f->maxstacksize = 2; /* registers 0/1 are always valid */
+ fs->h = luaH_new(L, 0, 0);
+ /* anchor table of constants and prototype (to avoid being collected) */
+ sethvalue2s(L, L->top, fs->h);
+ incr_top(L);
+ setptvalue2s(L, L->top, f);
+ incr_top(L);
+}
+
+
+static void close_func (LexState *ls) {
+ lua_State *L = ls->L;
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ removevars(ls, 0);
+ luaK_ret(fs, 0, 0); /* final return */
+ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
+ f->sizecode = fs->pc;
+ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
+ f->sizelineinfo = fs->pc;
+ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
+ f->sizek = fs->nk;
+ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
+ f->sizep = fs->np;
+ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
+ f->sizelocvars = fs->nlocvars;
+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
+ f->sizeupvalues = f->nups;
+ lua_assert(luaG_checkcode(f));
+ lua_assert(fs->bl == NULL);
+ ls->fs = fs->prev;
+ L->top -= 2; /* remove table and prototype from the stack */
+ /* last token read was anchored in defunct function; must reanchor it */
+ if (fs) anchor_token(ls);
+}
+
+
+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
+ struct LexState lexstate;
+ struct FuncState funcstate;
+ lexstate.buff = buff;
+ luaX_setinput(L, &lexstate, z, luaS_new(L, name));
+ open_func(&lexstate, &funcstate);
+ funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
+ luaX_next(&lexstate); /* read first token */
+ chunk(&lexstate);
+ check(&lexstate, TK_EOS);
+ close_func(&lexstate);
+ lua_assert(funcstate.prev == NULL);
+ lua_assert(funcstate.f->nups == 0);
+ lua_assert(lexstate.fs == NULL);
+ return funcstate.f;
+}
+
+
+
+/*============================================================*/
+/* GRAMMAR RULES */
+/*============================================================*/
+
+
+static void field (LexState *ls, expdesc *v) {
+ /* field -> ['.' | ':'] NAME */
+ FuncState *fs = ls->fs;
+ expdesc key;
+ luaK_exp2anyreg(fs, v);
+ luaX_next(ls); /* skip the dot or colon */
+ checkname(ls, &key);
+ luaK_indexed(fs, v, &key);
+}
+
+
+static void yindex (LexState *ls, expdesc *v) {
+ /* index -> '[' expr ']' */
+ luaX_next(ls); /* skip the '[' */
+ expr(ls, v);
+ luaK_exp2val(ls->fs, v);
+ checknext(ls, ']');
+}
+
+
+/*
+** {======================================================================
+** Rules for Constructors
+** =======================================================================
+*/
+
+
+struct ConsControl {
+ expdesc v; /* last list item read */
+ expdesc *t; /* table descriptor */
+ int nh; /* total number of `record' elements */
+ int na; /* total number of array elements */
+ int tostore; /* number of array elements pending to be stored */
+};
+
+
+static void recfield (LexState *ls, struct ConsControl *cc) {
+ /* recfield -> (NAME | `['exp1`]') = exp1 */
+ FuncState *fs = ls->fs;
+ int reg = ls->fs->freereg;
+ expdesc key, val;
+ int rkkey;
+ if (ls->t.token == TK_NAME) {
+ luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
+ checkname(ls, &key);
+ }
+ else /* ls->t.token == '[' */
+ yindex(ls, &key);
+ cc->nh++;
+ checknext(ls, '=');
+ rkkey = luaK_exp2RK(fs, &key);
+ expr(ls, &val);
+ luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
+ fs->freereg = reg; /* free registers */
+}
+
+
+static void closelistfield (FuncState *fs, struct ConsControl *cc) {
+ if (cc->v.k == VVOID) return; /* there is no list item */
+ luaK_exp2nextreg(fs, &cc->v);
+ cc->v.k = VVOID;
+ if (cc->tostore == LFIELDS_PER_FLUSH) {
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
+ cc->tostore = 0; /* no more items pending */
+ }
+}
+
+
+static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
+ if (cc->tostore == 0) return;
+ if (hasmultret(cc->v.k)) {
+ luaK_setmultret(fs, &cc->v);
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
+ cc->na--; /* do not count last expression (unknown number of elements) */
+ }
+ else {
+ if (cc->v.k != VVOID)
+ luaK_exp2nextreg(fs, &cc->v);
+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
+ }
+}
+
+
+static void listfield (LexState *ls, struct ConsControl *cc) {
+ expr(ls, &cc->v);
+ luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
+ cc->na++;
+ cc->tostore++;
+}
+
+
+static void constructor (LexState *ls, expdesc *t) {
+ /* constructor -> ?? */
+ FuncState *fs = ls->fs;
+ int line = ls->linenumber;
+ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
+ struct ConsControl cc;
+ cc.na = cc.nh = cc.tostore = 0;
+ cc.t = t;
+ init_exp(t, VRELOCABLE, pc);
+ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
+ checknext(ls, '{');
+ do {
+ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
+ if (ls->t.token == '}') break;
+ closelistfield(fs, &cc);
+ switch(ls->t.token) {
+ case TK_NAME: { /* may be listfields or recfields */
+ luaX_lookahead(ls);
+ if (ls->lookahead.token != '=') /* expression? */
+ listfield(ls, &cc);
+ else
+ recfield(ls, &cc);
+ break;
+ }
+ case '[': { /* constructor_item -> recfield */
+ recfield(ls, &cc);
+ break;
+ }
+ default: { /* constructor_part -> listfield */
+ listfield(ls, &cc);
+ break;
+ }
+ }
+ } while (testnext(ls, ',') || testnext(ls, ';'));
+ check_match(ls, '}', '{', line);
+ lastlistfield(fs, &cc);
+ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
+ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
+}
+
+/* }====================================================================== */
+
+
+
+static void parlist (LexState *ls) {
+ /* parlist -> [ param { `,' param } ] */
+ FuncState *fs = ls->fs;
+ Proto *f = fs->f;
+ int nparams = 0;
+ f->is_vararg = 0;
+ if (ls->t.token != ')') { /* is `parlist' not empty? */
+ do {
+ switch (ls->t.token) {
+ case TK_NAME: { /* param -> NAME */
+ new_localvar(ls, str_checkname(ls), nparams++);
+ break;
+ }
+ case TK_DOTS: { /* param -> `...' */
+ luaX_next(ls);
+#if defined(LUA_COMPAT_VARARG)
+ /* use `arg' as default name */
+ new_localvarliteral(ls, "arg", nparams++);
+ f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
+#endif
+ f->is_vararg |= VARARG_ISVARARG;
+ break;
+ }
+ default: luaX_syntaxerror(ls, "<name> or " LUA_QL("...") " expected");
+ }
+ } while (!f->is_vararg && testnext(ls, ','));
+ }
+ adjustlocalvars(ls, nparams);
+ f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
+}
+
+
+static void body (LexState *ls, expdesc *e, int needself, int line) {
+ /* body -> `(' parlist `)' chunk END */
+ FuncState new_fs;
+ open_func(ls, &new_fs);
+ new_fs.f->linedefined = line;
+ checknext(ls, '(');
+ if (needself) {
+ new_localvarliteral(ls, "self", 0);
+ adjustlocalvars(ls, 1);
+ }
+ parlist(ls);
+ checknext(ls, ')');
+ chunk(ls);
+ new_fs.f->lastlinedefined = ls->linenumber;
+ check_match(ls, TK_END, TK_FUNCTION, line);
+ close_func(ls);
+ pushclosure(ls, &new_fs, e);
+}
+
+
+static int explist1 (LexState *ls, expdesc *v) {
+ /* explist1 -> expr { `,' expr } */
+ int n = 1; /* at least one expression */
+ expr(ls, v);
+ while (testnext(ls, ',')) {
+ luaK_exp2nextreg(ls->fs, v);
+ expr(ls, v);
+ n++;
+ }
+ return n;
+}
+
+
+static void funcargs (LexState *ls, expdesc *f) {
+ FuncState *fs = ls->fs;
+ expdesc args;
+ int base, nparams;
+ int line = ls->linenumber;
+ switch (ls->t.token) {
+ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
+ if (line != ls->lastline)
+ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
+ luaX_next(ls);
+ if (ls->t.token == ')') /* arg list is empty? */
+ args.k = VVOID;
+ else {
+ explist1(ls, &args);
+ luaK_setmultret(fs, &args);
+ }
+ check_match(ls, ')', '(', line);
+ break;
+ }
+ case '{': { /* funcargs -> constructor */
+ constructor(ls, &args);
+ break;
+ }
+ case TK_STRING: { /* funcargs -> STRING */
+ codestring(ls, &args, ls->t.seminfo.ts);
+ luaX_next(ls); /* must use `seminfo' before `next' */
+ break;
+ }
+ default: {
+ luaX_syntaxerror(ls, "function arguments expected");
+ return;
+ }
+ }
+ lua_assert(f->k == VNONRELOC);
+ base = f->u.s.info; /* base register for call */
+ if (hasmultret(args.k))
+ nparams = LUA_MULTRET; /* open call */
+ else {
+ if (args.k != VVOID)
+ luaK_exp2nextreg(fs, &args); /* close last argument */
+ nparams = fs->freereg - (base+1);
+ }
+ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
+ luaK_fixline(fs, line);
+ fs->freereg = base+1; /* call remove function and arguments and leaves
+ (unless changed) one result */
+}
+
+
+
+
+/*
+** {======================================================================
+** Expression parsing
+** =======================================================================
+*/
+
+
+static void prefixexp (LexState *ls, expdesc *v) {
+ /* prefixexp -> NAME | '(' expr ')' */
+ switch (ls->t.token) {
+ case '(': {
+ int line = ls->linenumber;
+ luaX_next(ls);
+ expr(ls, v);
+ check_match(ls, ')', '(', line);
+ luaK_dischargevars(ls->fs, v);
+ return;
+ }
+ case TK_NAME: {
+ singlevar(ls, v);
+ return;
+ }
+ default: {
+ luaX_syntaxerror(ls, "unexpected symbol");
+ return;
+ }
+ }
+}
+
+
+static void primaryexp (LexState *ls, expdesc *v) {
+ /* primaryexp ->
+ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
+ FuncState *fs = ls->fs;
+ prefixexp(ls, v);
+ for (;;) {
+ switch (ls->t.token) {
+ case '.': { /* field */
+ field(ls, v);
+ break;
+ }
+ case '[': { /* `[' exp1 `]' */
+ expdesc key;
+ luaK_exp2anyreg(fs, v);
+ yindex(ls, &key);
+ luaK_indexed(fs, v, &key);
+ break;
+ }
+ case ':': { /* `:' NAME funcargs */
+ expdesc key;
+ luaX_next(ls);
+ checkname(ls, &key);
+ luaK_self(fs, v, &key);
+ funcargs(ls, v);
+ break;
+ }
+ case '(': case TK_STRING: case '{': { /* funcargs */
+ luaK_exp2nextreg(fs, v);
+ funcargs(ls, v);
+ break;
+ }
+ default: return;
+ }
+ }
+}
+
+
+static void simpleexp (LexState *ls, expdesc *v) {
+ /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
+ constructor | FUNCTION body | primaryexp */
+ switch (ls->t.token) {
+ case TK_NUMBER: {
+ init_exp(v, VKNUM, 0);
+ v->u.nval = ls->t.seminfo.r;
+ break;
+ }
+ case TK_STRING: {
+ codestring(ls, v, ls->t.seminfo.ts);
+ break;
+ }
+ case TK_NIL: {
+ init_exp(v, VNIL, 0);
+ break;
+ }
+ case TK_TRUE: {
+ init_exp(v, VTRUE, 0);
+ break;
+ }
+ case TK_FALSE: {
+ init_exp(v, VFALSE, 0);
+ break;
+ }
+ case TK_DOTS: { /* vararg */
+ FuncState *fs = ls->fs;
+ check_condition(ls, fs->f->is_vararg,
+ "cannot use " LUA_QL("...") " outside a vararg function");
+ fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
+ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
+ break;
+ }
+ case '{': { /* constructor */
+ constructor(ls, v);
+ return;
+ }
+ case TK_FUNCTION: {
+ luaX_next(ls);
+ body(ls, v, 0, ls->linenumber);
+ return;
+ }
+ default: {
+ primaryexp(ls, v);
+ return;
+ }
+ }
+ luaX_next(ls);
+}
+
+
+static UnOpr getunopr (int op) {
+ switch (op) {
+ case TK_NOT: return OPR_NOT;
+ case '-': return OPR_MINUS;
+ case '#': return OPR_LEN;
+ default: return OPR_NOUNOPR;
+ }
+}
+
+
+static BinOpr getbinopr (int op) {
+ switch (op) {
+ case '+': return OPR_ADD;
+ case '-': return OPR_SUB;
+ case '*': return OPR_MUL;
+ case '/': return OPR_DIV;
+ case '%': return OPR_MOD;
+ case '^': return OPR_POW;
+ case TK_CONCAT: return OPR_CONCAT;
+ case TK_NE: return OPR_NE;
+ case TK_EQ: return OPR_EQ;
+ case '<': return OPR_LT;
+ case TK_LE: return OPR_LE;
+ case '>': return OPR_GT;
+ case TK_GE: return OPR_GE;
+ case TK_AND: return OPR_AND;
+ case TK_OR: return OPR_OR;
+ default: return OPR_NOBINOPR;
+ }
+}
+
+
+static const struct {
+ lu_byte left; /* left priority for each binary operator */
+ lu_byte right; /* right priority */
+} priority[] = { /* ORDER OPR */
+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
+ {10, 9}, {5, 4}, /* power and concat (right associative) */
+ {3, 3}, {3, 3}, /* equality and inequality */
+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
+ {2, 2}, {1, 1} /* logical (and/or) */
+};
+
+#define UNARY_PRIORITY 8 /* priority for unary operators */
+
+
+/*
+** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
+** where `binop' is any binary operator with a priority higher than `limit'
+*/
+static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
+ BinOpr op;
+ UnOpr uop;
+ enterlevel(ls);
+ uop = getunopr(ls->t.token);
+ if (uop != OPR_NOUNOPR) {
+ luaX_next(ls);
+ subexpr(ls, v, UNARY_PRIORITY);
+ luaK_prefix(ls->fs, uop, v);
+ }
+ else simpleexp(ls, v);
+ /* expand while operators have priorities higher than `limit' */
+ op = getbinopr(ls->t.token);
+ while (op != OPR_NOBINOPR && priority[op].left > limit) {
+ expdesc v2;
+ BinOpr nextop;
+ luaX_next(ls);
+ luaK_infix(ls->fs, op, v);
+ /* read sub-expression with higher priority */
+ nextop = subexpr(ls, &v2, priority[op].right);
+ luaK_posfix(ls->fs, op, v, &v2);
+ op = nextop;
+ }
+ leavelevel(ls);
+ return op; /* return first untreated operator */
+}
+
+
+static void expr (LexState *ls, expdesc *v) {
+ subexpr(ls, v, 0);
+}
+
+/* }==================================================================== */
+
+
+
+/*
+** {======================================================================
+** Rules for Statements
+** =======================================================================
+*/
+
+
+static int block_follow (int token) {
+ switch (token) {
+ case TK_ELSE: case TK_ELSEIF: case TK_END:
+ case TK_UNTIL: case TK_EOS:
+ return 1;
+ default: return 0;
+ }
+}
+
+
+static void block (LexState *ls) {
+ /* block -> chunk */
+ FuncState *fs = ls->fs;
+ BlockCnt bl;
+ enterblock(fs, &bl, 0);
+ chunk(ls);
+ lua_assert(bl.breaklist == NO_JUMP);
+ leaveblock(fs);
+}
+
+
+/*
+** structure to chain all variables in the left-hand side of an
+** assignment
+*/
+struct LHS_assign {
+ struct LHS_assign *prev;
+ expdesc v; /* variable (global, local, upvalue, or indexed) */
+};
+
+
+/*
+** check whether, in an assignment to a local variable, the local variable
+** is needed in a previous assignment (to a table). If so, save original
+** local value in a safe place and use this safe copy in the previous
+** assignment.
+*/
+static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
+ FuncState *fs = ls->fs;
+ int extra = fs->freereg; /* eventual position to save local variable */
+ int conflict = 0;
+ for (; lh; lh = lh->prev) {
+ if (lh->v.k == VINDEXED) {
+ if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
+ conflict = 1;
+ lh->v.u.s.info = extra; /* previous assignment will use safe copy */
+ }
+ if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
+ conflict = 1;
+ lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
+ }
+ }
+ }
+ if (conflict) {
+ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
+ luaK_reserveregs(fs, 1);
+ }
+}
+
+
+static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
+ expdesc e;
+ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
+ "syntax error");
+ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
+ struct LHS_assign nv;
+ nv.prev = lh;
+ primaryexp(ls, &nv.v);
+ if (nv.v.k == VLOCAL)
+ check_conflict(ls, lh, &nv.v);
+ luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
+ "variables in assignment");
+ assignment(ls, &nv, nvars+1);
+ }
+ else { /* assignment -> `=' explist1 */
+ int nexps;
+ checknext(ls, '=');
+ nexps = explist1(ls, &e);
+ if (nexps != nvars) {
+ adjust_assign(ls, nvars, nexps, &e);
+ if (nexps > nvars)
+ ls->fs->freereg -= nexps - nvars; /* remove extra values */
+ }
+ else {
+ luaK_setoneret(ls->fs, &e); /* close last expression */
+ luaK_storevar(ls->fs, &lh->v, &e);
+ return; /* avoid default */
+ }
+ }
+ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
+ luaK_storevar(ls->fs, &lh->v, &e);
+}
+
+
+static int cond (LexState *ls) {
+ /* cond -> exp */
+ expdesc v;
+ expr(ls, &v); /* read condition */
+ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
+ luaK_goiftrue(ls->fs, &v);
+ return v.f;
+}
+
+
+static void breakstat (LexState *ls) {
+ FuncState *fs = ls->fs;
+ BlockCnt *bl = fs->bl;
+ int upval = 0;
+ while (bl && !bl->isbreakable) {
+ upval |= bl->upval;
+ bl = bl->previous;
+ }
+ if (!bl)
+ luaX_syntaxerror(ls, "no loop to break");
+ if (upval)
+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
+}
+
+
+static void whilestat (LexState *ls, int line) {
+ /* whilestat -> WHILE cond DO block END */
+ FuncState *fs = ls->fs;
+ int whileinit;
+ int condexit;
+ BlockCnt bl;
+ luaX_next(ls); /* skip WHILE */
+ whileinit = luaK_getlabel(fs);
+ condexit = cond(ls);
+ enterblock(fs, &bl, 1);
+ checknext(ls, TK_DO);
+ block(ls);
+ luaK_patchlist(fs, luaK_jump(fs), whileinit);
+ check_match(ls, TK_END, TK_WHILE, line);
+ leaveblock(fs);
+ luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
+}
+
+
+static void repeatstat (LexState *ls, int line) {
+ /* repeatstat -> REPEAT block UNTIL cond */
+ int condexit;
+ FuncState *fs = ls->fs;
+ int repeat_init = luaK_getlabel(fs);
+ BlockCnt bl1, bl2;
+ enterblock(fs, &bl1, 1); /* loop block */
+ enterblock(fs, &bl2, 0); /* scope block */
+ luaX_next(ls); /* skip REPEAT */
+ chunk(ls);
+ check_match(ls, TK_UNTIL, TK_REPEAT, line);
+ condexit = cond(ls); /* read condition (inside scope block) */
+ if (!bl2.upval) { /* no upvalues? */
+ leaveblock(fs); /* finish scope */
+ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
+ }
+ else { /* complete semantics when there are upvalues */
+ breakstat(ls); /* if condition then break */
+ luaK_patchtohere(ls->fs, condexit); /* else... */
+ leaveblock(fs); /* finish scope... */
+ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
+ }
+ leaveblock(fs); /* finish loop */
+}
+
+
+static int exp1 (LexState *ls) {
+ expdesc e;
+ int k;
+ expr(ls, &e);
+ k = e.k;
+ luaK_exp2nextreg(ls->fs, &e);
+ return k;
+}
+
+
+static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
+ /* forbody -> DO block */
+ BlockCnt bl;
+ FuncState *fs = ls->fs;
+ int prep, endfor;
+ adjustlocalvars(ls, 3); /* control variables */
+ checknext(ls, TK_DO);
+ prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
+ enterblock(fs, &bl, 0); /* scope for declared variables */
+ adjustlocalvars(ls, nvars);
+ luaK_reserveregs(fs, nvars);
+ block(ls);
+ leaveblock(fs); /* end of scope for declared variables */
+ luaK_patchtohere(fs, prep);
+ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
+ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
+ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
+ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
+}
+
+
+static void fornum (LexState *ls, TString *varname, int line) {
+ /* fornum -> NAME = exp1,exp1[,exp1] forbody */
+ FuncState *fs = ls->fs;
+ int base = fs->freereg;
+ new_localvarliteral(ls, "(for index)", 0);
+ new_localvarliteral(ls, "(for limit)", 1);
+ new_localvarliteral(ls, "(for step)", 2);
+ new_localvar(ls, varname, 3);
+ checknext(ls, '=');
+ exp1(ls); /* initial value */
+ checknext(ls, ',');
+ exp1(ls); /* limit */
+ if (testnext(ls, ','))
+ exp1(ls); /* optional step */
+ else { /* default step = 1 */
+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
+ luaK_reserveregs(fs, 1);
+ }
+ forbody(ls, base, line, 1, 1);
+}
+
+
+static void forlist (LexState *ls, TString *indexname) {
+ /* forlist -> NAME {,NAME} IN explist1 forbody */
+ FuncState *fs = ls->fs;
+ expdesc e;
+ int nvars = 0;
+ int line;
+ int base = fs->freereg;
+ /* create control variables */
+ new_localvarliteral(ls, "(for generator)", nvars++);
+ new_localvarliteral(ls, "(for state)", nvars++);
+ new_localvarliteral(ls, "(for control)", nvars++);
+ /* create declared variables */
+ new_localvar(ls, indexname, nvars++);
+ while (testnext(ls, ','))
+ new_localvar(ls, str_checkname(ls), nvars++);
+ checknext(ls, TK_IN);
+ line = ls->linenumber;
+ adjust_assign(ls, 3, explist1(ls, &e), &e);
+ luaK_checkstack(fs, 3); /* extra space to call generator */
+ forbody(ls, base, line, nvars - 3, 0);
+}
+
+
+static void forstat (LexState *ls, int line) {
+ /* forstat -> FOR (fornum | forlist) END */
+ FuncState *fs = ls->fs;
+ TString *varname;
+ BlockCnt bl;
+ enterblock(fs, &bl, 1); /* scope for loop and control variables */
+ luaX_next(ls); /* skip `for' */
+ varname = str_checkname(ls); /* first variable name */
+ switch (ls->t.token) {
+ case '=': fornum(ls, varname, line); break;
+ case ',': case TK_IN: forlist(ls, varname); break;
+ default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
+ }
+ check_match(ls, TK_END, TK_FOR, line);
+ leaveblock(fs); /* loop scope (`break' jumps to this point) */
+}
+
+
+static int test_then_block (LexState *ls) {
+ /* test_then_block -> [IF | ELSEIF] cond THEN block */
+ int condexit;
+ luaX_next(ls); /* skip IF or ELSEIF */
+ condexit = cond(ls);
+ checknext(ls, TK_THEN);
+ block(ls); /* `then' part */
+ return condexit;
+}
+
+
+static void ifstat (LexState *ls, int line) {
+ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
+ FuncState *fs = ls->fs;
+ int flist;
+ int escapelist = NO_JUMP;
+ flist = test_then_block(ls); /* IF cond THEN block */
+ while (ls->t.token == TK_ELSEIF) {
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
+ luaK_patchtohere(fs, flist);
+ flist = test_then_block(ls); /* ELSEIF cond THEN block */
+ }
+ if (ls->t.token == TK_ELSE) {
+ luaK_concat(fs, &escapelist, luaK_jump(fs));
+ luaK_patchtohere(fs, flist);
+ luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
+ block(ls); /* `else' part */
+ }
+ else
+ luaK_concat(fs, &escapelist, flist);
+ luaK_patchtohere(fs, escapelist);
+ check_match(ls, TK_END, TK_IF, line);
+}
+
+
+static void localfunc (LexState *ls) {
+ expdesc v, b;
+ FuncState *fs = ls->fs;
+ new_localvar(ls, str_checkname(ls), 0);
+ init_exp(&v, VLOCAL, fs->freereg);
+ luaK_reserveregs(fs, 1);
+ adjustlocalvars(ls, 1);
+ body(ls, &b, 0, ls->linenumber);
+ luaK_storevar(fs, &v, &b);
+ /* debug information will only see the variable after this point! */
+ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
+}
+
+
+static void localstat (LexState *ls) {
+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
+ int nvars = 0;
+ int nexps;
+ expdesc e;
+ do {
+ new_localvar(ls, str_checkname(ls), nvars++);
+ } while (testnext(ls, ','));
+ if (testnext(ls, '='))
+ nexps = explist1(ls, &e);
+ else {
+ e.k = VVOID;
+ nexps = 0;
+ }
+ adjust_assign(ls, nvars, nexps, &e);
+ adjustlocalvars(ls, nvars);
+}
+
+
+static int funcname (LexState *ls, expdesc *v) {
+ /* funcname -> NAME {field} [`:' NAME] */
+ int needself = 0;
+ singlevar(ls, v);
+ while (ls->t.token == '.')
+ field(ls, v);
+ if (ls->t.token == ':') {
+ needself = 1;
+ field(ls, v);
+ }
+ return needself;
+}
+
+
+static void funcstat (LexState *ls, int line) {
+ /* funcstat -> FUNCTION funcname body */
+ int needself;
+ expdesc v, b;
+ luaX_next(ls); /* skip FUNCTION */
+ needself = funcname(ls, &v);
+ body(ls, &b, needself, line);
+ luaK_storevar(ls->fs, &v, &b);
+ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
+}
+
+
+static void exprstat (LexState *ls) {
+ /* stat -> func | assignment */
+ FuncState *fs = ls->fs;
+ struct LHS_assign v;
+ primaryexp(ls, &v.v);
+ if (v.v.k == VCALL) /* stat -> func */
+ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
+ else { /* stat -> assignment */
+ v.prev = NULL;
+ assignment(ls, &v, 1);
+ }
+}
+
+
+static void retstat (LexState *ls) {
+ /* stat -> RETURN explist */
+ FuncState *fs = ls->fs;
+ expdesc e;
+ int first, nret; /* registers with returned values */
+ luaX_next(ls); /* skip RETURN */
+ if (block_follow(ls->t.token) || ls->t.token == ';')
+ first = nret = 0; /* return no values */
+ else {
+ nret = explist1(ls, &e); /* optional return values */
+ if (hasmultret(e.k)) {
+ luaK_setmultret(fs, &e);
+ if (e.k == VCALL && nret == 1) { /* tail call? */
+ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
+ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
+ }
+ first = fs->nactvar;
+ nret = LUA_MULTRET; /* return all values */
+ }
+ else {
+ if (nret == 1) /* only one single value? */
+ first = luaK_exp2anyreg(fs, &e);
+ else {
+ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
+ first = fs->nactvar; /* return all `active' values */
+ lua_assert(nret == fs->freereg - first);
+ }
+ }
+ }
+ luaK_ret(fs, first, nret);
+}
+
+
+static int statement (LexState *ls) {
+ int line = ls->linenumber; /* may be needed for error messages */
+ switch (ls->t.token) {
+ case TK_IF: { /* stat -> ifstat */
+ ifstat(ls, line);
+ return 0;
+ }
+ case TK_WHILE: { /* stat -> whilestat */
+ whilestat(ls, line);
+ return 0;
+ }
+ case TK_DO: { /* stat -> DO block END */
+ luaX_next(ls); /* skip DO */
+ block(ls);
+ check_match(ls, TK_END, TK_DO, line);
+ return 0;
+ }
+ case TK_FOR: { /* stat -> forstat */
+ forstat(ls, line);
+ return 0;
+ }
+ case TK_REPEAT: { /* stat -> repeatstat */
+ repeatstat(ls, line);
+ return 0;
+ }
+ case TK_FUNCTION: {
+ funcstat(ls, line); /* stat -> funcstat */
+ return 0;
+ }
+ case TK_LOCAL: { /* stat -> localstat */
+ luaX_next(ls); /* skip LOCAL */
+ if (testnext(ls, TK_FUNCTION)) /* local function? */
+ localfunc(ls);
+ else
+ localstat(ls);
+ return 0;
+ }
+ case TK_RETURN: { /* stat -> retstat */
+ retstat(ls);
+ return 1; /* must be last statement */
+ }
+ case TK_BREAK: { /* stat -> breakstat */
+ luaX_next(ls); /* skip BREAK */
+ breakstat(ls);
+ return 1; /* must be last statement */
+ }
+ default: {
+ exprstat(ls);
+ return 0; /* to avoid warnings */
+ }
+ }
+}
+
+
+static void chunk (LexState *ls) {
+ /* chunk -> { stat [`;'] } */
+ int islast = 0;
+ enterlevel(ls);
+ while (!islast && !block_follow(ls->t.token)) {
+ islast = statement(ls);
+ testnext(ls, ';');
+ lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
+ ls->fs->freereg >= ls->fs->nactvar);
+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
+ }
+ leavelevel(ls);
+}
+
+/* }====================================================================== */
diff --git a/misc/liblua/lparser.h b/misc/liblua/lparser.h
new file mode 100644
index 0000000..18836af
--- /dev/null
+++ b/misc/liblua/lparser.h
@@ -0,0 +1,82 @@
+/*
+** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lua Parser
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lparser_h
+#define lparser_h
+
+#include "llimits.h"
+#include "lobject.h"
+#include "lzio.h"
+
+
+/*
+** Expression descriptor
+*/
+
+typedef enum {
+ VVOID, /* no value */
+ VNIL,
+ VTRUE,
+ VFALSE,
+ VK, /* info = index of constant in `k' */
+ VKNUM, /* nval = numerical value */
+ VLOCAL, /* info = local register */
+ VUPVAL, /* info = index of upvalue in `upvalues' */
+ VGLOBAL, /* info = index of table; aux = index of global name in `k' */
+ VINDEXED, /* info = table register; aux = index register (or `k') */
+ VJMP, /* info = instruction pc */
+ VRELOCABLE, /* info = instruction pc */
+ VNONRELOC, /* info = result register */
+ VCALL, /* info = instruction pc */
+ VVARARG /* info = instruction pc */
+} expkind;
+
+typedef struct expdesc {
+ expkind k;
+ union {
+ struct { int info, aux; } s;
+ lua_Number nval;
+ } u;
+ int t; /* patch list of `exit when true' */
+ int f; /* patch list of `exit when false' */
+} expdesc;
+
+
+typedef struct upvaldesc {
+ lu_byte k;
+ lu_byte info;
+} upvaldesc;
+
+
+struct BlockCnt; /* defined in lparser.c */
+
+
+/* state needed to generate code for a given function */
+typedef struct FuncState {
+ Proto *f; /* current function header */
+ Table *h; /* table to find (and reuse) elements in `k' */
+ struct FuncState *prev; /* enclosing function */
+ struct LexState *ls; /* lexical state */
+ struct lua_State *L; /* copy of the Lua state */
+ struct BlockCnt *bl; /* chain of current blocks */
+ int pc; /* next position to code (equivalent to `ncode') */
+ int lasttarget; /* `pc' of last `jump target' */
+ int jpc; /* list of pending jumps to `pc' */
+ int freereg; /* first free register */
+ int nk; /* number of elements in `k' */
+ int np; /* number of elements in `p' */
+ short nlocvars; /* number of elements in `locvars' */
+ lu_byte nactvar; /* number of active local variables */
+ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
+ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
+} FuncState;
+
+
+LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+ const char *name);
+
+
+#endif
diff --git a/misc/liblua/lstate.c b/misc/liblua/lstate.c
new file mode 100644
index 0000000..2bdbb62
--- /dev/null
+++ b/misc/liblua/lstate.c
@@ -0,0 +1,214 @@
+/*
+** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define lstate_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "llex.h"
+#include "lmem.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
+#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
+#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
+
+
+/*
+** Main thread combines a thread state and the global state
+*/
+typedef struct LG {
+ lua_State l;
+ global_State g;
+} LG;
+
+
+
+static void stack_init (lua_State *L1, lua_State *L) {
+ /* initialize CallInfo array */
+ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
+ L1->ci = L1->base_ci;
+ L1->size_ci = BASIC_CI_SIZE;
+ L1->end_ci = L1->base_ci + L1->size_ci - 1;
+ /* initialize stack array */
+ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
+ L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
+ L1->top = L1->stack;
+ L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
+ /* initialize first ci */
+ L1->ci->func = L1->top;
+ setnilvalue(L1->top++); /* `function' entry for this `ci' */
+ L1->base = L1->ci->base = L1->top;
+ L1->ci->top = L1->top + LUA_MINSTACK;
+}
+
+
+static void freestack (lua_State *L, lua_State *L1) {
+ luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
+ luaM_freearray(L, L1->stack, L1->stacksize, TValue);
+}
+
+
+/*
+** open parts that may cause memory-allocation errors
+*/
+static void f_luaopen (lua_State *L, void *ud) {
+ global_State *g = G(L);
+ UNUSED(ud);
+ stack_init(L, L); /* init stack */
+ sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
+ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
+ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
+ luaT_init(L);
+ luaX_init(L);
+ luaS_fix(luaS_newliteral(L, MEMERRMSG));
+ g->GCthreshold = 4*g->totalbytes;
+}
+
+
+static void preinit_state (lua_State *L, global_State *g) {
+ G(L) = g;
+ L->stack = NULL;
+ L->stacksize = 0;
+ L->errorJmp = NULL;
+ L->hook = NULL;
+ L->hookmask = 0;
+ L->basehookcount = 0;
+ L->allowhook = 1;
+ resethookcount(L);
+ L->openupval = NULL;
+ L->size_ci = 0;
+ L->nCcalls = L->baseCcalls = 0;
+ L->status = 0;
+ L->base_ci = L->ci = NULL;
+ L->savedpc = NULL;
+ L->errfunc = 0;
+ setnilvalue(gt(L));
+}
+
+
+static void close_state (lua_State *L) {
+ global_State *g = G(L);
+ luaF_close(L, L->stack); /* close all upvalues for this thread */
+ luaC_freeall(L); /* collect all objects */
+ lua_assert(g->rootgc == obj2gco(L));
+ lua_assert(g->strt.nuse == 0);
+ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
+ luaZ_freebuffer(L, &g->buff);
+ freestack(L, L);
+ lua_assert(g->totalbytes == sizeof(LG));
+ (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
+}
+
+
+lua_State *luaE_newthread (lua_State *L) {
+ lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
+ luaC_link(L, obj2gco(L1), LUA_TTHREAD);
+ preinit_state(L1, G(L));
+ stack_init(L1, L); /* init stack */
+ setobj2n(L, gt(L1), gt(L)); /* share table of globals */
+ L1->hookmask = L->hookmask;
+ L1->basehookcount = L->basehookcount;
+ L1->hook = L->hook;
+ resethookcount(L1);
+ lua_assert(iswhite(obj2gco(L1)));
+ return L1;
+}
+
+
+void luaE_freethread (lua_State *L, lua_State *L1) {
+ luaF_close(L1, L1->stack); /* close all upvalues for this thread */
+ lua_assert(L1->openupval == NULL);
+ luai_userstatefree(L1);
+ freestack(L, L1);
+ luaM_freemem(L, fromstate(L1), state_size(lua_State));
+}
+
+
+LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
+ int i;
+ lua_State *L;
+ global_State *g;
+ void *l = (*f)(ud, NULL, 0, state_size(LG));
+ if (l == NULL) return NULL;
+ L = tostate(l);
+ g = &((LG *)L)->g;
+ L->next = NULL;
+ L->tt = LUA_TTHREAD;
+ g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
+ L->marked = luaC_white(g);
+ set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
+ preinit_state(L, g);
+ g->frealloc = f;
+ g->ud = ud;
+ g->mainthread = L;
+ g->uvhead.u.l.prev = &g->uvhead;
+ g->uvhead.u.l.next = &g->uvhead;
+ g->GCthreshold = 0; /* mark it as unfinished state */
+ g->strt.size = 0;
+ g->strt.nuse = 0;
+ g->strt.hash = NULL;
+ setnilvalue(registry(L));
+ luaZ_initbuffer(L, &g->buff);
+ g->panic = NULL;
+ g->gcstate = GCSpause;
+ g->rootgc = obj2gco(L);
+ g->sweepstrgc = 0;
+ g->sweepgc = &g->rootgc;
+ g->gray = NULL;
+ g->grayagain = NULL;
+ g->weak = NULL;
+ g->tmudata = NULL;
+ g->totalbytes = sizeof(LG);
+ g->gcpause = LUAI_GCPAUSE;
+ g->gcstepmul = LUAI_GCMUL;
+ g->gcdept = 0;
+ for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
+ if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
+ /* memory allocation error: free partial state */
+ close_state(L);
+ L = NULL;
+ }
+ else
+ luai_userstateopen(L);
+ return L;
+}
+
+
+static void callallgcTM (lua_State *L, void *ud) {
+ UNUSED(ud);
+ luaC_callGCTM(L); /* call GC metamethods for all udata */
+}
+
+
+LUA_API void lua_close (lua_State *L) {
+ L = G(L)->mainthread; /* only the main thread can be closed */
+ lua_lock(L);
+ luaF_close(L, L->stack); /* close all upvalues for this thread */
+ luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
+ L->errfunc = 0; /* no error function during GC metamethods */
+ do { /* repeat until no more errors */
+ L->ci = L->base_ci;
+ L->base = L->top = L->ci->base;
+ L->nCcalls = L->baseCcalls = 0;
+ } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
+ lua_assert(G(L)->tmudata == NULL);
+ luai_userstateclose(L);
+ close_state(L);
+}
+
diff --git a/misc/liblua/lstate.h b/misc/liblua/lstate.h
new file mode 100644
index 0000000..3bc575b
--- /dev/null
+++ b/misc/liblua/lstate.h
@@ -0,0 +1,169 @@
+/*
+** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
+** Global State
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstate_h
+#define lstate_h
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "ltm.h"
+#include "lzio.h"
+
+
+
+struct lua_longjmp; /* defined in ldo.c */
+
+
+/* table of globals */
+#define gt(L) (&L->l_gt)
+
+/* registry */
+#define registry(L) (&G(L)->l_registry)
+
+
+/* extra stack space to handle TM calls and some other extras */
+#define EXTRA_STACK 5
+
+
+#define BASIC_CI_SIZE 8
+
+#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
+
+
+
+typedef struct stringtable {
+ GCObject **hash;
+ lu_int32 nuse; /* number of elements */
+ int size;
+} stringtable;
+
+
+/*
+** informations about a call
+*/
+typedef struct CallInfo {
+ StkId base; /* base for this function */
+ StkId func; /* function index in the stack */
+ StkId top; /* top for this function */
+ const Instruction *savedpc;
+ int nresults; /* expected number of results from this function */
+ int tailcalls; /* number of tail calls lost under this entry */
+} CallInfo;
+
+
+
+#define curr_func(L) (clvalue(L->ci->func))
+#define ci_func(ci) (clvalue((ci)->func))
+#define f_isLua(ci) (!ci_func(ci)->c.isC)
+#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
+
+
+/*
+** `global state', shared by all threads of this state
+*/
+typedef struct global_State {
+ stringtable strt; /* hash table for strings */
+ lua_Alloc frealloc; /* function to reallocate memory */
+ void *ud; /* auxiliary data to `frealloc' */
+ lu_byte currentwhite;
+ lu_byte gcstate; /* state of garbage collector */
+ int sweepstrgc; /* position of sweep in `strt' */
+ GCObject *rootgc; /* list of all collectable objects */
+ GCObject **sweepgc; /* position of sweep in `rootgc' */
+ GCObject *gray; /* list of gray objects */
+ GCObject *grayagain; /* list of objects to be traversed atomically */
+ GCObject *weak; /* list of weak tables (to be cleared) */
+ GCObject *tmudata; /* last element of list of userdata to be GC */
+ Mbuffer buff; /* temporary buffer for string concatentation */
+ lu_mem GCthreshold;
+ lu_mem totalbytes; /* number of bytes currently allocated */
+ lu_mem estimate; /* an estimate of number of bytes actually in use */
+ lu_mem gcdept; /* how much GC is `behind schedule' */
+ int gcpause; /* size of pause between successive GCs */
+ int gcstepmul; /* GC `granularity' */
+ lua_CFunction panic; /* to be called in unprotected errors */
+ TValue l_registry;
+ struct lua_State *mainthread;
+ UpVal uvhead; /* head of double-linked list of all open upvalues */
+ struct Table *mt[NUM_TAGS]; /* metatables for basic types */
+ TString *tmname[TM_N]; /* array with tag-method names */
+} global_State;
+
+
+/*
+** `per thread' state
+*/
+struct lua_State {
+ CommonHeader;
+ lu_byte status;
+ StkId top; /* first free slot in the stack */
+ StkId base; /* base of current function */
+ global_State *l_G;
+ CallInfo *ci; /* call info for current function */
+ const Instruction *savedpc; /* `savedpc' of current function */
+ StkId stack_last; /* last free slot in the stack */
+ StkId stack; /* stack base */
+ CallInfo *end_ci; /* points after end of ci array*/
+ CallInfo *base_ci; /* array of CallInfo's */
+ int stacksize;
+ int size_ci; /* size of array `base_ci' */
+ unsigned short nCcalls; /* number of nested C calls */
+ unsigned short baseCcalls; /* nested C calls when resuming coroutine */
+ lu_byte hookmask;
+ lu_byte allowhook;
+ int basehookcount;
+ int hookcount;
+ lua_Hook hook;
+ TValue l_gt; /* table of globals */
+ TValue env; /* temporary place for environments */
+ GCObject *openupval; /* list of open upvalues in this stack */
+ GCObject *gclist;
+ struct lua_longjmp *errorJmp; /* current error recover point */
+ ptrdiff_t errfunc; /* current error handling function (stack index) */
+};
+
+
+#define G(L) (L->l_G)
+
+
+/*
+** Union of all collectable objects
+*/
+union GCObject {
+ GCheader gch;
+ union TString ts;
+ union Udata u;
+ union Closure cl;
+ struct Table h;
+ struct Proto p;
+ struct UpVal uv;
+ struct lua_State th; /* thread */
+};
+
+
+/* macros to convert a GCObject into a specific value */
+#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
+#define gco2ts(o) (&rawgco2ts(o)->tsv)
+#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
+#define gco2u(o) (&rawgco2u(o)->uv)
+#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
+#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
+#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
+#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
+#define ngcotouv(o) \
+ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
+#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
+
+/* macro to convert any Lua object into a GCObject */
+#define obj2gco(v) (cast(GCObject *, (v)))
+
+
+LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
+LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
+
+#endif
+
diff --git a/misc/liblua/lstring.c b/misc/liblua/lstring.c
new file mode 100644
index 0000000..4911315
--- /dev/null
+++ b/misc/liblua/lstring.c
@@ -0,0 +1,111 @@
+/*
+** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
+** String table (keeps all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lstring_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+
+
+
+void luaS_resize (lua_State *L, int newsize) {
+ GCObject **newhash;
+ stringtable *tb;
+ int i;
+ if (G(L)->gcstate == GCSsweepstring)
+ return; /* cannot resize during GC traverse */
+ newhash = luaM_newvector(L, newsize, GCObject *);
+ tb = &G(L)->strt;
+ for (i=0; i<newsize; i++) newhash[i] = NULL;
+ /* rehash */
+ for (i=0; i<tb->size; i++) {
+ GCObject *p = tb->hash[i];
+ while (p) { /* for each node in the list */
+ GCObject *next = p->gch.next; /* save next */
+ unsigned int h = gco2ts(p)->hash;
+ int h1 = lmod(h, newsize); /* new position */
+ lua_assert(cast_int(h%newsize) == lmod(h, newsize));
+ p->gch.next = newhash[h1]; /* chain it */
+ newhash[h1] = p;
+ p = next;
+ }
+ }
+ luaM_freearray(L, tb->hash, tb->size, TString *);
+ tb->size = newsize;
+ tb->hash = newhash;
+}
+
+
+static TString *newlstr (lua_State *L, const char *str, size_t l,
+ unsigned int h) {
+ TString *ts;
+ stringtable *tb;
+ if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
+ luaM_toobig(L);
+ ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
+ ts->tsv.len = l;
+ ts->tsv.hash = h;
+ ts->tsv.marked = luaC_white(G(L));
+ ts->tsv.tt = LUA_TSTRING;
+ ts->tsv.reserved = 0;
+ memcpy(ts+1, str, l*sizeof(char));
+ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
+ tb = &G(L)->strt;
+ h = lmod(h, tb->size);
+ ts->tsv.next = tb->hash[h]; /* chain new entry */
+ tb->hash[h] = obj2gco(ts);
+ tb->nuse++;
+ if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
+ luaS_resize(L, tb->size*2); /* too crowded */
+ return ts;
+}
+
+
+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
+ GCObject *o;
+ unsigned int h = cast(unsigned int, l); /* seed */
+ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
+ size_t l1;
+ for (l1=l; l1>=step; l1-=step) /* compute hash */
+ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
+ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
+ o != NULL;
+ o = o->gch.next) {
+ TString *ts = rawgco2ts(o);
+ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
+ /* string may be dead */
+ if (isdead(G(L), o)) changewhite(o);
+ return ts;
+ }
+ }
+ return newlstr(L, str, l, h); /* not found */
+}
+
+
+Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
+ Udata *u;
+ if (s > MAX_SIZET - sizeof(Udata))
+ luaM_toobig(L);
+ u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
+ u->uv.marked = luaC_white(G(L)); /* is not finalized */
+ u->uv.tt = LUA_TUSERDATA;
+ u->uv.len = s;
+ u->uv.metatable = NULL;
+ u->uv.env = e;
+ /* chain it on udata list (after main thread) */
+ u->uv.next = G(L)->mainthread->next;
+ G(L)->mainthread->next = obj2gco(u);
+ return u;
+}
+
diff --git a/misc/liblua/lstring.h b/misc/liblua/lstring.h
new file mode 100644
index 0000000..73a2ff8
--- /dev/null
+++ b/misc/liblua/lstring.h
@@ -0,0 +1,31 @@
+/*
+** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
+** String table (keep all strings handled by Lua)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lstring_h
+#define lstring_h
+
+
+#include "lgc.h"
+#include "lobject.h"
+#include "lstate.h"
+
+
+#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
+
+#define sizeudata(u) (sizeof(union Udata)+(u)->len)
+
+#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
+#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
+ (sizeof(s)/sizeof(char))-1))
+
+#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
+
+LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
+LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+
+
+#endif
diff --git a/misc/liblua/lstrlib.c b/misc/liblua/lstrlib.c
new file mode 100644
index 0000000..b478e05
--- /dev/null
+++ b/misc/liblua/lstrlib.c
@@ -0,0 +1,869 @@
+/*
+** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
+** Standard library for string operations and pattern-matching
+** See Copyright Notice in lua.h
+*/
+
+
+#include <ctype.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lstrlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+/* macro to `unsign' a character */
+#define uchar(c) ((unsigned char)(c))
+
+
+
+static int str_len (lua_State *L) {
+ size_t l;
+ luaL_checklstring(L, 1, &l);
+ lua_pushinteger(L, l);
+ return 1;
+}
+
+
+static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
+ /* relative string position: negative means back from end */
+ if (pos < 0) pos += (ptrdiff_t)len + 1;
+ return (pos >= 0) ? pos : 0;
+}
+
+
+static int str_sub (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
+ ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
+ if (start < 1) start = 1;
+ if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
+ if (start <= end)
+ lua_pushlstring(L, s+start-1, end-start+1);
+ else lua_pushliteral(L, "");
+ return 1;
+}
+
+
+static int str_reverse (lua_State *L) {
+ size_t l;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ luaL_buffinit(L, &b);
+ while (l--) luaL_addchar(&b, s[l]);
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int str_lower (lua_State *L) {
+ size_t l;
+ size_t i;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ luaL_buffinit(L, &b);
+ for (i=0; i<l; i++)
+ luaL_addchar(&b, tolower(uchar(s[i])));
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int str_upper (lua_State *L) {
+ size_t l;
+ size_t i;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ luaL_buffinit(L, &b);
+ for (i=0; i<l; i++)
+ luaL_addchar(&b, toupper(uchar(s[i])));
+ luaL_pushresult(&b);
+ return 1;
+}
+
+static int str_rep (lua_State *L) {
+ size_t l;
+ luaL_Buffer b;
+ const char *s = luaL_checklstring(L, 1, &l);
+ int n = luaL_checkint(L, 2);
+ luaL_buffinit(L, &b);
+ while (n-- > 0)
+ luaL_addlstring(&b, s, l);
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int str_byte (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+ ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
+ ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
+ int n, i;
+ if (posi <= 0) posi = 1;
+ if ((size_t)pose > l) pose = l;
+ if (posi > pose) return 0; /* empty interval; return no values */
+ n = (int)(pose - posi + 1);
+ if (posi + n <= pose) /* overflow? */
+ luaL_error(L, "string slice too long");
+ luaL_checkstack(L, n, "string slice too long");
+ for (i=0; i<n; i++)
+ lua_pushinteger(L, uchar(s[posi+i-1]));
+ return n;
+}
+
+
+static int str_char (lua_State *L) {
+ int n = lua_gettop(L); /* number of arguments */
+ int i;
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ for (i=1; i<=n; i++) {
+ int c = luaL_checkint(L, i);
+ luaL_argcheck(L, uchar(c) == c, i, "invalid value");
+ luaL_addchar(&b, uchar(c));
+ }
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static int writer (lua_State *L, const void* b, size_t size, void* B) {
+ (void)L;
+ luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
+ return 0;
+}
+
+
+static int str_dump (lua_State *L) {
+ luaL_Buffer b;
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+ lua_settop(L, 1);
+ luaL_buffinit(L,&b);
+ if (lua_dump(L, writer, &b) != 0)
+ luaL_error(L, "unable to dump given function");
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+
+/*
+** {======================================================
+** PATTERN MATCHING
+** =======================================================
+*/
+
+
+#define CAP_UNFINISHED (-1)
+#define CAP_POSITION (-2)
+
+typedef struct MatchState {
+ const char *src_init; /* init of source string */
+ const char *src_end; /* end (`\0') of source string */
+ lua_State *L;
+ int level; /* total number of captures (finished or unfinished) */
+ struct {
+ const char *init;
+ ptrdiff_t len;
+ } capture[LUA_MAXCAPTURES];
+} MatchState;
+
+
+#define L_ESC '%'
+#define SPECIALS "^$*+?.([%-"
+
+
+static int check_capture (MatchState *ms, int l) {
+ l -= '1';
+ if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
+ return luaL_error(ms->L, "invalid capture index");
+ return l;
+}
+
+
+static int capture_to_close (MatchState *ms) {
+ int level = ms->level;
+ for (level--; level>=0; level--)
+ if (ms->capture[level].len == CAP_UNFINISHED) return level;
+ return luaL_error(ms->L, "invalid pattern capture");
+}
+
+
+static const char *classend (MatchState *ms, const char *p) {
+ switch (*p++) {
+ case L_ESC: {
+ if (*p == '\0')
+ luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
+ return p+1;
+ }
+ case '[': {
+ if (*p == '^') p++;
+ do { /* look for a `]' */
+ if (*p == '\0')
+ luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
+ if (*(p++) == L_ESC && *p != '\0')
+ p++; /* skip escapes (e.g. `%]') */
+ } while (*p != ']');
+ return p+1;
+ }
+ default: {
+ return p;
+ }
+ }
+}
+
+
+static int match_class (int c, int cl) {
+ int res;
+ switch (tolower(cl)) {
+ case 'a' : res = isalpha(c); break;
+ case 'c' : res = iscntrl(c); break;
+ case 'd' : res = isdigit(c); break;
+ case 'l' : res = islower(c); break;
+ case 'p' : res = ispunct(c); break;
+ case 's' : res = isspace(c); break;
+ case 'u' : res = isupper(c); break;
+ case 'w' : res = isalnum(c); break;
+ case 'x' : res = isxdigit(c); break;
+ case 'z' : res = (c == 0); break;
+ default: return (cl == c);
+ }
+ return (islower(cl) ? res : !res);
+}
+
+
+static int matchbracketclass (int c, const char *p, const char *ec) {
+ int sig = 1;
+ if (*(p+1) == '^') {
+ sig = 0;
+ p++; /* skip the `^' */
+ }
+ while (++p < ec) {
+ if (*p == L_ESC) {
+ p++;
+ if (match_class(c, uchar(*p)))
+ return sig;
+ }
+ else if ((*(p+1) == '-') && (p+2 < ec)) {
+ p+=2;
+ if (uchar(*(p-2)) <= c && c <= uchar(*p))
+ return sig;
+ }
+ else if (uchar(*p) == c) return sig;
+ }
+ return !sig;
+}
+
+
+static int singlematch (int c, const char *p, const char *ep) {
+ switch (*p) {
+ case '.': return 1; /* matches any char */
+ case L_ESC: return match_class(c, uchar(*(p+1)));
+ case '[': return matchbracketclass(c, p, ep-1);
+ default: return (uchar(*p) == c);
+ }
+}
+
+
+static const char *match (MatchState *ms, const char *s, const char *p);
+
+
+static const char *matchbalance (MatchState *ms, const char *s,
+ const char *p) {
+ if (*p == 0 || *(p+1) == 0)
+ luaL_error(ms->L, "unbalanced pattern");
+ if (*s != *p) return NULL;
+ else {
+ int b = *p;
+ int e = *(p+1);
+ int cont = 1;
+ while (++s < ms->src_end) {
+ if (*s == e) {
+ if (--cont == 0) return s+1;
+ }
+ else if (*s == b) cont++;
+ }
+ }
+ return NULL; /* string ends out of balance */
+}
+
+
+static const char *max_expand (MatchState *ms, const char *s,
+ const char *p, const char *ep) {
+ ptrdiff_t i = 0; /* counts maximum expand for item */
+ while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
+ i++;
+ /* keeps trying to match with the maximum repetitions */
+ while (i>=0) {
+ const char *res = match(ms, (s+i), ep+1);
+ if (res) return res;
+ i--; /* else didn't match; reduce 1 repetition to try again */
+ }
+ return NULL;
+}
+
+
+static const char *min_expand (MatchState *ms, const char *s,
+ const char *p, const char *ep) {
+ for (;;) {
+ const char *res = match(ms, s, ep+1);
+ if (res != NULL)
+ return res;
+ else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
+ s++; /* try with one more repetition */
+ else return NULL;
+ }
+}
+
+
+static const char *start_capture (MatchState *ms, const char *s,
+ const char *p, int what) {
+ const char *res;
+ int level = ms->level;
+ if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
+ ms->capture[level].init = s;
+ ms->capture[level].len = what;
+ ms->level = level+1;
+ if ((res=match(ms, s, p)) == NULL) /* match failed? */
+ ms->level--; /* undo capture */
+ return res;
+}
+
+
+static const char *end_capture (MatchState *ms, const char *s,
+ const char *p) {
+ int l = capture_to_close(ms);
+ const char *res;
+ ms->capture[l].len = s - ms->capture[l].init; /* close capture */
+ if ((res = match(ms, s, p)) == NULL) /* match failed? */
+ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
+ return res;
+}
+
+
+static const char *match_capture (MatchState *ms, const char *s, int l) {
+ size_t len;
+ l = check_capture(ms, l);
+ len = ms->capture[l].len;
+ if ((size_t)(ms->src_end-s) >= len &&
+ memcmp(ms->capture[l].init, s, len) == 0)
+ return s+len;
+ else return NULL;
+}
+
+
+static const char *match (MatchState *ms, const char *s, const char *p) {
+ init: /* using goto's to optimize tail recursion */
+ switch (*p) {
+ case '(': { /* start capture */
+ if (*(p+1) == ')') /* position capture? */
+ return start_capture(ms, s, p+2, CAP_POSITION);
+ else
+ return start_capture(ms, s, p+1, CAP_UNFINISHED);
+ }
+ case ')': { /* end capture */
+ return end_capture(ms, s, p+1);
+ }
+ case L_ESC: {
+ switch (*(p+1)) {
+ case 'b': { /* balanced string? */
+ s = matchbalance(ms, s, p+2);
+ if (s == NULL) return NULL;
+ p+=4; goto init; /* else return match(ms, s, p+4); */
+ }
+ case 'f': { /* frontier? */
+ const char *ep; char previous;
+ p += 2;
+ if (*p != '[')
+ luaL_error(ms->L, "missing " LUA_QL("[") " after "
+ LUA_QL("%%f") " in pattern");
+ ep = classend(ms, p); /* points to what is next */
+ previous = (s == ms->src_init) ? '\0' : *(s-1);
+ if (matchbracketclass(uchar(previous), p, ep-1) ||
+ !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
+ p=ep; goto init; /* else return match(ms, s, ep); */
+ }
+ default: {
+ if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
+ s = match_capture(ms, s, uchar(*(p+1)));
+ if (s == NULL) return NULL;
+ p+=2; goto init; /* else return match(ms, s, p+2) */
+ }
+ goto dflt; /* case default */
+ }
+ }
+ }
+ case '\0': { /* end of pattern */
+ return s; /* match succeeded */
+ }
+ case '$': {
+ if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
+ return (s == ms->src_end) ? s : NULL; /* check end of string */
+ else goto dflt;
+ }
+ default: dflt: { /* it is a pattern item */
+ const char *ep = classend(ms, p); /* points to what is next */
+ int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
+ switch (*ep) {
+ case '?': { /* optional */
+ const char *res;
+ if (m && ((res=match(ms, s+1, ep+1)) != NULL))
+ return res;
+ p=ep+1; goto init; /* else return match(ms, s, ep+1); */
+ }
+ case '*': { /* 0 or more repetitions */
+ return max_expand(ms, s, p, ep);
+ }
+ case '+': { /* 1 or more repetitions */
+ return (m ? max_expand(ms, s+1, p, ep) : NULL);
+ }
+ case '-': { /* 0 or more repetitions (minimum) */
+ return min_expand(ms, s, p, ep);
+ }
+ default: {
+ if (!m) return NULL;
+ s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
+ }
+ }
+ }
+ }
+}
+
+
+
+static const char *lmemfind (const char *s1, size_t l1,
+ const char *s2, size_t l2) {
+ if (l2 == 0) return s1; /* empty strings are everywhere */
+ else if (l2 > l1) return NULL; /* avoids a negative `l1' */
+ else {
+ const char *init; /* to search for a `*s2' inside `s1' */
+ l2--; /* 1st char will be checked by `memchr' */
+ l1 = l1-l2; /* `s2' cannot be found after that */
+ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
+ init++; /* 1st char is already checked */
+ if (memcmp(init, s2+1, l2) == 0)
+ return init-1;
+ else { /* correct `l1' and `s1' to try again */
+ l1 -= init-s1;
+ s1 = init;
+ }
+ }
+ return NULL; /* not found */
+ }
+}
+
+
+static void push_onecapture (MatchState *ms, int i, const char *s,
+ const char *e) {
+ if (i >= ms->level) {
+ if (i == 0) /* ms->level == 0, too */
+ lua_pushlstring(ms->L, s, e - s); /* add whole match */
+ else
+ luaL_error(ms->L, "invalid capture index");
+ }
+ else {
+ ptrdiff_t l = ms->capture[i].len;
+ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
+ if (l == CAP_POSITION)
+ lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
+ else
+ lua_pushlstring(ms->L, ms->capture[i].init, l);
+ }
+}
+
+
+static int push_captures (MatchState *ms, const char *s, const char *e) {
+ int i;
+ int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
+ luaL_checkstack(ms->L, nlevels, "too many captures");
+ for (i = 0; i < nlevels; i++)
+ push_onecapture(ms, i, s, e);
+ return nlevels; /* number of strings pushed */
+}
+
+
+static int str_find_aux (lua_State *L, int find) {
+ size_t l1, l2;
+ const char *s = luaL_checklstring(L, 1, &l1);
+ const char *p = luaL_checklstring(L, 2, &l2);
+ ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
+ if (init < 0) init = 0;
+ else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
+ if (find && (lua_toboolean(L, 4) || /* explicit request? */
+ strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
+ /* do a plain search */
+ const char *s2 = lmemfind(s+init, l1-init, p, l2);
+ if (s2) {
+ lua_pushinteger(L, s2-s+1);
+ lua_pushinteger(L, s2-s+l2);
+ return 2;
+ }
+ }
+ else {
+ MatchState ms;
+ int anchor = (*p == '^') ? (p++, 1) : 0;
+ const char *s1=s+init;
+ ms.L = L;
+ ms.src_init = s;
+ ms.src_end = s+l1;
+ do {
+ const char *res;
+ ms.level = 0;
+ if ((res=match(&ms, s1, p)) != NULL) {
+ if (find) {
+ lua_pushinteger(L, s1-s+1); /* start */
+ lua_pushinteger(L, res-s); /* end */
+ return push_captures(&ms, NULL, 0) + 2;
+ }
+ else
+ return push_captures(&ms, s1, res);
+ }
+ } while (s1++ < ms.src_end && !anchor);
+ }
+ lua_pushnil(L); /* not found */
+ return 1;
+}
+
+
+static int str_find (lua_State *L) {
+ return str_find_aux(L, 1);
+}
+
+
+static int str_match (lua_State *L) {
+ return str_find_aux(L, 0);
+}
+
+
+static int gmatch_aux (lua_State *L) {
+ MatchState ms;
+ size_t ls;
+ const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
+ const char *p = lua_tostring(L, lua_upvalueindex(2));
+ const char *src;
+ ms.L = L;
+ ms.src_init = s;
+ ms.src_end = s+ls;
+ for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
+ src <= ms.src_end;
+ src++) {
+ const char *e;
+ ms.level = 0;
+ if ((e = match(&ms, src, p)) != NULL) {
+ lua_Integer newstart = e-s;
+ if (e == src) newstart++; /* empty match? go at least one position */
+ lua_pushinteger(L, newstart);
+ lua_replace(L, lua_upvalueindex(3));
+ return push_captures(&ms, src, e);
+ }
+ }
+ return 0; /* not found */
+}
+
+
+static int gmatch (lua_State *L) {
+ luaL_checkstring(L, 1);
+ luaL_checkstring(L, 2);
+ lua_settop(L, 2);
+ lua_pushinteger(L, 0);
+ lua_pushcclosure(L, gmatch_aux, 3);
+ return 1;
+}
+
+
+static int gfind_nodef (lua_State *L) {
+ return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
+ LUA_QL("string.gmatch"));
+}
+
+
+static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
+ const char *e) {
+ size_t l, i;
+ const char *news = lua_tolstring(ms->L, 3, &l);
+ for (i = 0; i < l; i++) {
+ if (news[i] != L_ESC)
+ luaL_addchar(b, news[i]);
+ else {
+ i++; /* skip ESC */
+ if (!isdigit(uchar(news[i])))
+ luaL_addchar(b, news[i]);
+ else if (news[i] == '0')
+ luaL_addlstring(b, s, e - s);
+ else {
+ push_onecapture(ms, news[i] - '1', s, e);
+ luaL_addvalue(b); /* add capture to accumulated result */
+ }
+ }
+ }
+}
+
+
+static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
+ const char *e) {
+ lua_State *L = ms->L;
+ switch (lua_type(L, 3)) {
+ case LUA_TNUMBER:
+ case LUA_TSTRING: {
+ add_s(ms, b, s, e);
+ return;
+ }
+ case LUA_TFUNCTION: {
+ int n;
+ lua_pushvalue(L, 3);
+ n = push_captures(ms, s, e);
+ lua_call(L, n, 1);
+ break;
+ }
+ case LUA_TTABLE: {
+ push_onecapture(ms, 0, s, e);
+ lua_gettable(L, 3);
+ break;
+ }
+ }
+ if (!lua_toboolean(L, -1)) { /* nil or false? */
+ lua_pop(L, 1);
+ lua_pushlstring(L, s, e - s); /* keep original text */
+ }
+ else if (!lua_isstring(L, -1))
+ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
+ luaL_addvalue(b); /* add result to accumulator */
+}
+
+
+static int str_gsub (lua_State *L) {
+ size_t srcl;
+ const char *src = luaL_checklstring(L, 1, &srcl);
+ const char *p = luaL_checkstring(L, 2);
+ int tr = lua_type(L, 3);
+ int max_s = luaL_optint(L, 4, srcl+1);
+ int anchor = (*p == '^') ? (p++, 1) : 0;
+ int n = 0;
+ MatchState ms;
+ luaL_Buffer b;
+ luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
+ tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
+ "string/function/table expected");
+ luaL_buffinit(L, &b);
+ ms.L = L;
+ ms.src_init = src;
+ ms.src_end = src+srcl;
+ while (n < max_s) {
+ const char *e;
+ ms.level = 0;
+ e = match(&ms, src, p);
+ if (e) {
+ n++;
+ add_value(&ms, &b, src, e);
+ }
+ if (e && e>src) /* non empty match? */
+ src = e; /* skip it */
+ else if (src < ms.src_end)
+ luaL_addchar(&b, *src++);
+ else break;
+ if (anchor) break;
+ }
+ luaL_addlstring(&b, src, ms.src_end-src);
+ luaL_pushresult(&b);
+ lua_pushinteger(L, n); /* number of substitutions */
+ return 2;
+}
+
+/* }====================================================== */
+
+
+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
+#define MAX_ITEM 512
+/* valid flags in a format specification */
+#define FLAGS "-+ #0"
+/*
+** maximum size of each format specification (such as '%-099.99d')
+** (+10 accounts for %99.99x plus margin of error)
+*/
+#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
+
+
+static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ luaL_addchar(b, '"');
+ while (l--) {
+ switch (*s) {
+ case '"': case '\\': case '\n': {
+ luaL_addchar(b, '\\');
+ luaL_addchar(b, *s);
+ break;
+ }
+ case '\r': {
+ luaL_addlstring(b, "\\r", 2);
+ break;
+ }
+ case '\0': {
+ luaL_addlstring(b, "\\000", 4);
+ break;
+ }
+ default: {
+ luaL_addchar(b, *s);
+ break;
+ }
+ }
+ s++;
+ }
+ luaL_addchar(b, '"');
+}
+
+static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
+ const char *p = strfrmt;
+ while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
+ if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
+ luaL_error(L, "invalid format (repeated flags)");
+ if (isdigit(uchar(*p))) p++; /* skip width */
+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
+ if (*p == '.') {
+ p++;
+ if (isdigit(uchar(*p))) p++; /* skip precision */
+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
+ }
+ if (isdigit(uchar(*p)))
+ luaL_error(L, "invalid format (width or precision too long)");
+ *(form++) = '%';
+ strncpy(form, strfrmt, p - strfrmt + 1);
+ form += p - strfrmt + 1;
+ *form = '\0';
+ return p;
+}
+
+
+static void addintlen (char *form) {
+ size_t l = strlen(form);
+ char spec = form[l - 1];
+ strcpy(form + l - 1, LUA_INTFRMLEN);
+ form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
+ form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
+}
+
+
+static int str_format (lua_State *L) {
+ int arg = 1;
+ size_t sfl;
+ const char *strfrmt = luaL_checklstring(L, arg, &sfl);
+ const char *strfrmt_end = strfrmt+sfl;
+ luaL_Buffer b;
+ luaL_buffinit(L, &b);
+ while (strfrmt < strfrmt_end) {
+ if (*strfrmt != L_ESC)
+ luaL_addchar(&b, *strfrmt++);
+ else if (*++strfrmt == L_ESC)
+ luaL_addchar(&b, *strfrmt++); /* %% */
+ else { /* format item */
+ char form[MAX_FORMAT]; /* to store the format (`%...') */
+ char buff[MAX_ITEM]; /* to store the formatted item */
+ arg++;
+ strfrmt = scanformat(L, strfrmt, form);
+ switch (*strfrmt++) {
+ case 'c': {
+ sprintf(buff, form, (int)luaL_checknumber(L, arg));
+ break;
+ }
+ case 'd': case 'i': {
+ addintlen(form);
+ sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
+ break;
+ }
+ case 'o': case 'u': case 'x': case 'X': {
+ addintlen(form);
+ sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
+ break;
+ }
+ case 'e': case 'E': case 'f':
+ case 'g': case 'G': {
+ sprintf(buff, form, (double)luaL_checknumber(L, arg));
+ break;
+ }
+ case 'q': {
+ addquoted(L, &b, arg);
+ continue; /* skip the 'addsize' at the end */
+ }
+ case 's': {
+ size_t l;
+ const char *s = luaL_checklstring(L, arg, &l);
+ if (!strchr(form, '.') && l >= 100) {
+ /* no precision and string is too long to be formatted;
+ keep original string */
+ lua_pushvalue(L, arg);
+ luaL_addvalue(&b);
+ continue; /* skip the `addsize' at the end */
+ }
+ else {
+ sprintf(buff, form, s);
+ break;
+ }
+ }
+ default: { /* also treat cases `pnLlh' */
+ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
+ LUA_QL("format"), *(strfrmt - 1));
+ }
+ }
+ luaL_addlstring(&b, buff, strlen(buff));
+ }
+ }
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+static const luaL_Reg strlib[] = {
+ {"byte", str_byte},
+ {"char", str_char},
+ {"dump", str_dump},
+ {"find", str_find},
+ {"format", str_format},
+ {"gfind", gfind_nodef},
+ {"gmatch", gmatch},
+ {"gsub", str_gsub},
+ {"len", str_len},
+ {"lower", str_lower},
+ {"match", str_match},
+ {"rep", str_rep},
+ {"reverse", str_reverse},
+ {"sub", str_sub},
+ {"upper", str_upper},
+ {NULL, NULL}
+};
+
+
+static void createmetatable (lua_State *L) {
+ lua_createtable(L, 0, 1); /* create metatable for strings */
+ lua_pushliteral(L, ""); /* dummy string */
+ lua_pushvalue(L, -2);
+ lua_setmetatable(L, -2); /* set string metatable */
+ lua_pop(L, 1); /* pop dummy string */
+ lua_pushvalue(L, -2); /* string library... */
+ lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
+ lua_pop(L, 1); /* pop metatable */
+}
+
+
+/*
+** Open string library
+*/
+LUALIB_API int luaopen_string (lua_State *L) {
+ luaL_register(L, LUA_STRLIBNAME, strlib);
+#if defined(LUA_COMPAT_GFIND)
+ lua_getfield(L, -1, "gmatch");
+ lua_setfield(L, -2, "gfind");
+#endif
+ createmetatable(L);
+ return 1;
+}
+
diff --git a/misc/liblua/ltable.c b/misc/liblua/ltable.c
new file mode 100644
index 0000000..677b0e9
--- /dev/null
+++ b/misc/liblua/ltable.c
@@ -0,0 +1,588 @@
+/*
+** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+
+/*
+** Implementation of tables (aka arrays, objects, or hash tables).
+** Tables keep its elements in two parts: an array part and a hash part.
+** Non-negative integer keys are all candidates to be kept in the array
+** part. The actual size of the array is the largest `n' such that at
+** least half the slots between 0 and n are in use.
+** Hash uses a mix of chained scatter table with Brent's variation.
+** A main invariant of these tables is that, if an element is not
+** in its main position (i.e. the `original' position that its hash gives
+** to it), then the colliding element is in its own main position.
+** Hence even when the load factor reaches 100%, performance remains good.
+*/
+
+#include <math.h>
+#include <string.h>
+
+#define ltable_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lgc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "ltable.h"
+
+
+/*
+** max size of array part is 2^MAXBITS
+*/
+#if LUAI_BITSINT > 26
+#define MAXBITS 26
+#else
+#define MAXBITS (LUAI_BITSINT-2)
+#endif
+
+#define MAXASIZE (1 << MAXBITS)
+
+
+#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
+
+#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
+#define hashboolean(t,p) hashpow2(t, p)
+
+
+/*
+** for some types, it is better to avoid modulus by power of 2, as
+** they tend to have many 2 factors.
+*/
+#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
+
+
+#define hashpointer(t,p) hashmod(t, IntPoint(p))
+
+
+/*
+** number of ints inside a lua_Number
+*/
+#define numints cast_int(sizeof(lua_Number)/sizeof(int))
+
+
+
+#define dummynode (&dummynode_)
+
+static const Node dummynode_ = {
+ {{NULL}, LUA_TNIL}, /* value */
+ {{{NULL}, LUA_TNIL, NULL}} /* key */
+};
+
+
+/*
+** hash for lua_Numbers
+*/
+static Node *hashnum (const Table *t, lua_Number n) {
+ unsigned int a[numints];
+ int i;
+ if (luai_numeq(n, 0)) /* avoid problems with -0 */
+ return gnode(t, 0);
+ memcpy(a, &n, sizeof(a));
+ for (i = 1; i < numints; i++) a[0] += a[i];
+ return hashmod(t, a[0]);
+}
+
+
+
+/*
+** returns the `main' position of an element in a table (that is, the index
+** of its hash value)
+*/
+static Node *mainposition (const Table *t, const TValue *key) {
+ switch (ttype(key)) {
+ case LUA_TNUMBER:
+ return hashnum(t, nvalue(key));
+ case LUA_TSTRING:
+ return hashstr(t, rawtsvalue(key));
+ case LUA_TBOOLEAN:
+ return hashboolean(t, bvalue(key));
+ case LUA_TLIGHTUSERDATA:
+ return hashpointer(t, pvalue(key));
+ default:
+ return hashpointer(t, gcvalue(key));
+ }
+}
+
+
+/*
+** returns the index for `key' if `key' is an appropriate key to live in
+** the array part of the table, -1 otherwise.
+*/
+static int arrayindex (const TValue *key) {
+ if (ttisnumber(key)) {
+ lua_Number n = nvalue(key);
+ int k;
+ lua_number2int(k, n);
+ if (luai_numeq(cast_num(k), n))
+ return k;
+ }
+ return -1; /* `key' did not match some condition */
+}
+
+
+/*
+** returns the index of a `key' for table traversals. First goes all
+** elements in the array part, then elements in the hash part. The
+** beginning of a traversal is signalled by -1.
+*/
+static int findindex (lua_State *L, Table *t, StkId key) {
+ int i;
+ if (ttisnil(key)) return -1; /* first iteration */
+ i = arrayindex(key);
+ if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
+ return i-1; /* yes; that's the index (corrected to C) */
+ else {
+ Node *n = mainposition(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+ /* key may be dead already, but it is ok to use it in `next' */
+ if (luaO_rawequalObj(key2tval(n), key) ||
+ (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
+ gcvalue(gkey(n)) == gcvalue(key))) {
+ i = cast_int(n - gnode(t, 0)); /* key index in hash table */
+ /* hash elements are numbered after array ones */
+ return i + t->sizearray;
+ }
+ else n = gnext(n);
+ } while (n);
+ luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
+ return 0; /* to avoid warnings */
+ }
+}
+
+
+int luaH_next (lua_State *L, Table *t, StkId key) {
+ int i = findindex(L, t, key); /* find original element */
+ for (i++; i < t->sizearray; i++) { /* try first array part */
+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
+ setnvalue(key, cast_num(i+1));
+ setobj2s(L, key+1, &t->array[i]);
+ return 1;
+ }
+ }
+ for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
+ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
+ setobj2s(L, key, key2tval(gnode(t, i)));
+ setobj2s(L, key+1, gval(gnode(t, i)));
+ return 1;
+ }
+ }
+ return 0; /* no more elements */
+}
+
+
+/*
+** {=============================================================
+** Rehash
+** ==============================================================
+*/
+
+
+static int computesizes (int nums[], int *narray) {
+ int i;
+ int twotoi; /* 2^i */
+ int a = 0; /* number of elements smaller than 2^i */
+ int na = 0; /* number of elements to go to array part */
+ int n = 0; /* optimal size for array part */
+ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
+ if (nums[i] > 0) {
+ a += nums[i];
+ if (a > twotoi/2) { /* more than half elements present? */
+ n = twotoi; /* optimal size (till now) */
+ na = a; /* all elements smaller than n will go to array part */
+ }
+ }
+ if (a == *narray) break; /* all elements already counted */
+ }
+ *narray = n;
+ lua_assert(*narray/2 <= na && na <= *narray);
+ return na;
+}
+
+
+static int countint (const TValue *key, int *nums) {
+ int k = arrayindex(key);
+ if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
+ nums[ceillog2(k)]++; /* count as such */
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+static int numusearray (const Table *t, int *nums) {
+ int lg;
+ int ttlg; /* 2^lg */
+ int ause = 0; /* summation of `nums' */
+ int i = 1; /* count to traverse all array keys */
+ for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
+ int lc = 0; /* counter */
+ int lim = ttlg;
+ if (lim > t->sizearray) {
+ lim = t->sizearray; /* adjust upper limit */
+ if (i > lim)
+ break; /* no more elements to count */
+ }
+ /* count elements in range (2^(lg-1), 2^lg] */
+ for (; i <= lim; i++) {
+ if (!ttisnil(&t->array[i-1]))
+ lc++;
+ }
+ nums[lg] += lc;
+ ause += lc;
+ }
+ return ause;
+}
+
+
+static int numusehash (const Table *t, int *nums, int *pnasize) {
+ int totaluse = 0; /* total number of elements */
+ int ause = 0; /* summation of `nums' */
+ int i = sizenode(t);
+ while (i--) {
+ Node *n = &t->node[i];
+ if (!ttisnil(gval(n))) {
+ ause += countint(key2tval(n), nums);
+ totaluse++;
+ }
+ }
+ *pnasize += ause;
+ return totaluse;
+}
+
+
+static void setarrayvector (lua_State *L, Table *t, int size) {
+ int i;
+ luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
+ for (i=t->sizearray; i<size; i++)
+ setnilvalue(&t->array[i]);
+ t->sizearray = size;
+}
+
+
+static void setnodevector (lua_State *L, Table *t, int size) {
+ int lsize;
+ if (size == 0) { /* no elements to hash part? */
+ t->node = cast(Node *, dummynode); /* use common `dummynode' */
+ lsize = 0;
+ }
+ else {
+ int i;
+ lsize = ceillog2(size);
+ if (lsize > MAXBITS)
+ luaG_runerror(L, "table overflow");
+ size = twoto(lsize);
+ t->node = luaM_newvector(L, size, Node);
+ for (i=0; i<size; i++) {
+ Node *n = gnode(t, i);
+ gnext(n) = NULL;
+ setnilvalue(gkey(n));
+ setnilvalue(gval(n));
+ }
+ }
+ t->lsizenode = cast_byte(lsize);
+ t->lastfree = gnode(t, size); /* all positions are free */
+}
+
+
+static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
+ int i;
+ int oldasize = t->sizearray;
+ int oldhsize = t->lsizenode;
+ Node *nold = t->node; /* save old hash ... */
+ if (nasize > oldasize) /* array part must grow? */
+ setarrayvector(L, t, nasize);
+ /* create new hash part with appropriate size */
+ setnodevector(L, t, nhsize);
+ if (nasize < oldasize) { /* array part must shrink? */
+ t->sizearray = nasize;
+ /* re-insert elements from vanishing slice */
+ for (i=nasize; i<oldasize; i++) {
+ if (!ttisnil(&t->array[i]))
+ setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
+ }
+ /* shrink array */
+ luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
+ }
+ /* re-insert elements from hash part */
+ for (i = twoto(oldhsize) - 1; i >= 0; i--) {
+ Node *old = nold+i;
+ if (!ttisnil(gval(old)))
+ setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
+ }
+ if (nold != dummynode)
+ luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
+}
+
+
+void luaH_resizearray (lua_State *L, Table *t, int nasize) {
+ int nsize = (t->node == dummynode) ? 0 : sizenode(t);
+ resize(L, t, nasize, nsize);
+}
+
+
+static void rehash (lua_State *L, Table *t, const TValue *ek) {
+ int nasize, na;
+ int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
+ int i;
+ int totaluse;
+ for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
+ nasize = numusearray(t, nums); /* count keys in array part */
+ totaluse = nasize; /* all those keys are integer keys */
+ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
+ /* count extra key */
+ nasize += countint(ek, nums);
+ totaluse++;
+ /* compute new size for array part */
+ na = computesizes(nums, &nasize);
+ /* resize the table to new computed sizes */
+ resize(L, t, nasize, totaluse - na);
+}
+
+
+
+/*
+** }=============================================================
+*/
+
+
+Table *luaH_new (lua_State *L, int narray, int nhash) {
+ Table *t = luaM_new(L, Table);
+ luaC_link(L, obj2gco(t), LUA_TTABLE);
+ t->metatable = NULL;
+ t->flags = cast_byte(~0);
+ /* temporary values (kept only if some malloc fails) */
+ t->array = NULL;
+ t->sizearray = 0;
+ t->lsizenode = 0;
+ t->node = cast(Node *, dummynode);
+ setarrayvector(L, t, narray);
+ setnodevector(L, t, nhash);
+ return t;
+}
+
+
+void luaH_free (lua_State *L, Table *t) {
+ if (t->node != dummynode)
+ luaM_freearray(L, t->node, sizenode(t), Node);
+ luaM_freearray(L, t->array, t->sizearray, TValue);
+ luaM_free(L, t);
+}
+
+
+static Node *getfreepos (Table *t) {
+ while (t->lastfree-- > t->node) {
+ if (ttisnil(gkey(t->lastfree)))
+ return t->lastfree;
+ }
+ return NULL; /* could not find a free place */
+}
+
+
+
+/*
+** inserts a new key into a hash table; first, check whether key's main
+** position is free. If not, check whether colliding node is in its main
+** position or not: if it is not, move colliding node to an empty place and
+** put new key in its main position; otherwise (colliding node is in its main
+** position), new key goes to an empty position.
+*/
+static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
+ Node *mp = mainposition(t, key);
+ if (!ttisnil(gval(mp)) || mp == dummynode) {
+ Node *othern;
+ Node *n = getfreepos(t); /* get a free place */
+ if (n == NULL) { /* cannot find a free place? */
+ rehash(L, t, key); /* grow table */
+ return luaH_set(L, t, key); /* re-insert key into grown table */
+ }
+ lua_assert(n != dummynode);
+ othern = mainposition(t, key2tval(mp));
+ if (othern != mp) { /* is colliding node out of its main position? */
+ /* yes; move colliding node into free position */
+ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
+ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
+ gnext(mp) = NULL; /* now `mp' is free */
+ setnilvalue(gval(mp));
+ }
+ else { /* colliding node is in its own main position */
+ /* new node will go into free position */
+ gnext(n) = gnext(mp); /* chain new position */
+ gnext(mp) = n;
+ mp = n;
+ }
+ }
+ gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
+ luaC_barriert(L, t, key);
+ lua_assert(ttisnil(gval(mp)));
+ return gval(mp);
+}
+
+
+/*
+** search function for integers
+*/
+const TValue *luaH_getnum (Table *t, int key) {
+ /* (1 <= key && key <= t->sizearray) */
+ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
+ return &t->array[key-1];
+ else {
+ lua_Number nk = cast_num(key);
+ Node *n = hashnum(t, nk);
+ do { /* check whether `key' is somewhere in the chain */
+ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
+ return gval(n); /* that's it */
+ else n = gnext(n);
+ } while (n);
+ return luaO_nilobject;
+ }
+}
+
+
+/*
+** search function for strings
+*/
+const TValue *luaH_getstr (Table *t, TString *key) {
+ Node *n = hashstr(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+ if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
+ return gval(n); /* that's it */
+ else n = gnext(n);
+ } while (n);
+ return luaO_nilobject;
+}
+
+
+/*
+** main search function
+*/
+const TValue *luaH_get (Table *t, const TValue *key) {
+ switch (ttype(key)) {
+ case LUA_TNIL: return luaO_nilobject;
+ case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
+ case LUA_TNUMBER: {
+ int k;
+ lua_Number n = nvalue(key);
+ lua_number2int(k, n);
+ if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
+ return luaH_getnum(t, k); /* use specialized version */
+ /* else go through */
+ }
+ default: {
+ Node *n = mainposition(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+ if (luaO_rawequalObj(key2tval(n), key))
+ return gval(n); /* that's it */
+ else n = gnext(n);
+ } while (n);
+ return luaO_nilobject;
+ }
+ }
+}
+
+
+TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
+ const TValue *p = luaH_get(t, key);
+ t->flags = 0;
+ if (p != luaO_nilobject)
+ return cast(TValue *, p);
+ else {
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+ else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
+ luaG_runerror(L, "table index is NaN");
+ return newkey(L, t, key);
+ }
+}
+
+
+TValue *luaH_setnum (lua_State *L, Table *t, int key) {
+ const TValue *p = luaH_getnum(t, key);
+ if (p != luaO_nilobject)
+ return cast(TValue *, p);
+ else {
+ TValue k;
+ setnvalue(&k, cast_num(key));
+ return newkey(L, t, &k);
+ }
+}
+
+
+TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
+ const TValue *p = luaH_getstr(t, key);
+ if (p != luaO_nilobject)
+ return cast(TValue *, p);
+ else {
+ TValue k;
+ setsvalue(L, &k, key);
+ return newkey(L, t, &k);
+ }
+}
+
+
+static int unbound_search (Table *t, unsigned int j) {
+ unsigned int i = j; /* i is zero or a present index */
+ j++;
+ /* find `i' and `j' such that i is present and j is not */
+ while (!ttisnil(luaH_getnum(t, j))) {
+ i = j;
+ j *= 2;
+ if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
+ /* table was built with bad purposes: resort to linear search */
+ i = 1;
+ while (!ttisnil(luaH_getnum(t, i))) i++;
+ return i - 1;
+ }
+ }
+ /* now do a binary search between them */
+ while (j - i > 1) {
+ unsigned int m = (i+j)/2;
+ if (ttisnil(luaH_getnum(t, m))) j = m;
+ else i = m;
+ }
+ return i;
+}
+
+
+/*
+** Try to find a boundary in table `t'. A `boundary' is an integer index
+** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
+*/
+int luaH_getn (Table *t) {
+ unsigned int j = t->sizearray;
+ if (j > 0 && ttisnil(&t->array[j - 1])) {
+ /* there is a boundary in the array part: (binary) search for it */
+ unsigned int i = 0;
+ while (j - i > 1) {
+ unsigned int m = (i+j)/2;
+ if (ttisnil(&t->array[m - 1])) j = m;
+ else i = m;
+ }
+ return i;
+ }
+ /* else must find a boundary in hash part */
+ else if (t->node == dummynode) /* hash part is empty? */
+ return j; /* that is easy... */
+ else return unbound_search(t, j);
+}
+
+
+
+#if defined(LUA_DEBUG)
+
+Node *luaH_mainposition (const Table *t, const TValue *key) {
+ return mainposition(t, key);
+}
+
+int luaH_isdummy (Node *n) { return n == dummynode; }
+
+#endif
diff --git a/misc/liblua/ltable.h b/misc/liblua/ltable.h
new file mode 100644
index 0000000..f5b9d5e
--- /dev/null
+++ b/misc/liblua/ltable.h
@@ -0,0 +1,40 @@
+/*
+** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lua tables (hash)
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltable_h
+#define ltable_h
+
+#include "lobject.h"
+
+
+#define gnode(t,i) (&(t)->node[i])
+#define gkey(n) (&(n)->i_key.nk)
+#define gval(n) (&(n)->i_val)
+#define gnext(n) ((n)->i_key.nk.next)
+
+#define key2tval(n) (&(n)->i_key.tvk)
+
+
+LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
+LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
+LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
+LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
+LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
+LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
+LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
+LUAI_FUNC void luaH_free (lua_State *L, Table *t);
+LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
+LUAI_FUNC int luaH_getn (Table *t);
+
+
+#if defined(LUA_DEBUG)
+LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
+LUAI_FUNC int luaH_isdummy (Node *n);
+#endif
+
+
+#endif
diff --git a/misc/liblua/ltablib.c b/misc/liblua/ltablib.c
new file mode 100644
index 0000000..b6d9cb4
--- /dev/null
+++ b/misc/liblua/ltablib.c
@@ -0,0 +1,287 @@
+/*
+** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
+** Library for Table Manipulation
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stddef.h>
+
+#define ltablib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+
+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
+
+
+static int foreachi (lua_State *L) {
+ int i;
+ int n = aux_getn(L, 1);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ for (i=1; i <= n; i++) {
+ lua_pushvalue(L, 2); /* function */
+ lua_pushinteger(L, i); /* 1st argument */
+ lua_rawgeti(L, 1, i); /* 2nd argument */
+ lua_call(L, 2, 1);
+ if (!lua_isnil(L, -1))
+ return 1;
+ lua_pop(L, 1); /* remove nil result */
+ }
+ return 0;
+}
+
+
+static int foreach (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, 1)) {
+ lua_pushvalue(L, 2); /* function */
+ lua_pushvalue(L, -3); /* key */
+ lua_pushvalue(L, -3); /* value */
+ lua_call(L, 2, 1);
+ if (!lua_isnil(L, -1))
+ return 1;
+ lua_pop(L, 2); /* remove value and result */
+ }
+ return 0;
+}
+
+
+static int maxn (lua_State *L) {
+ lua_Number max = 0;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ lua_pushnil(L); /* first key */
+ while (lua_next(L, 1)) {
+ lua_pop(L, 1); /* remove value */
+ if (lua_type(L, -1) == LUA_TNUMBER) {
+ lua_Number v = lua_tonumber(L, -1);
+ if (v > max) max = v;
+ }
+ }
+ lua_pushnumber(L, max);
+ return 1;
+}
+
+
+static int getn (lua_State *L) {
+ lua_pushinteger(L, aux_getn(L, 1));
+ return 1;
+}
+
+
+static int setn (lua_State *L) {
+ luaL_checktype(L, 1, LUA_TTABLE);
+#ifndef luaL_setn
+ luaL_setn(L, 1, luaL_checkint(L, 2));
+#else
+ luaL_error(L, LUA_QL("setn") " is obsolete");
+#endif
+ lua_pushvalue(L, 1);
+ return 1;
+}
+
+
+static int tinsert (lua_State *L) {
+ int e = aux_getn(L, 1) + 1; /* first empty element */
+ int pos; /* where to insert new element */
+ switch (lua_gettop(L)) {
+ case 2: { /* called with only 2 arguments */
+ pos = e; /* insert new element at the end */
+ break;
+ }
+ case 3: {
+ int i;
+ pos = luaL_checkint(L, 2); /* 2nd argument is the position */
+ if (pos > e) e = pos; /* `grow' array if necessary */
+ for (i = e; i > pos; i--) { /* move up elements */
+ lua_rawgeti(L, 1, i-1);
+ lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
+ }
+ break;
+ }
+ default: {
+ return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
+ }
+ }
+ luaL_setn(L, 1, e); /* new size */
+ lua_rawseti(L, 1, pos); /* t[pos] = v */
+ return 0;
+}
+
+
+static int tremove (lua_State *L) {
+ int e = aux_getn(L, 1);
+ int pos = luaL_optint(L, 2, e);
+ if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
+ return 0; /* nothing to remove */
+ luaL_setn(L, 1, e - 1); /* t.n = n-1 */
+ lua_rawgeti(L, 1, pos); /* result = t[pos] */
+ for ( ;pos<e; pos++) {
+ lua_rawgeti(L, 1, pos+1);
+ lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
+ }
+ lua_pushnil(L);
+ lua_rawseti(L, 1, e); /* t[e] = nil */
+ return 1;
+}
+
+
+static void addfield (lua_State *L, luaL_Buffer *b, int i) {
+ lua_rawgeti(L, 1, i);
+ if (!lua_isstring(L, -1))
+ luaL_error(L, "invalid value (%s) at index %d in table for "
+ LUA_QL("concat"), luaL_typename(L, -1), i);
+ luaL_addvalue(b);
+}
+
+
+static int tconcat (lua_State *L) {
+ luaL_Buffer b;
+ size_t lsep;
+ int i, last;
+ const char *sep = luaL_optlstring(L, 2, "", &lsep);
+ luaL_checktype(L, 1, LUA_TTABLE);
+ i = luaL_optint(L, 3, 1);
+ last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
+ luaL_buffinit(L, &b);
+ for (; i < last; i++) {
+ addfield(L, &b, i);
+ luaL_addlstring(&b, sep, lsep);
+ }
+ if (i == last) /* add last value (if interval was not empty) */
+ addfield(L, &b, i);
+ luaL_pushresult(&b);
+ return 1;
+}
+
+
+
+/*
+** {======================================================
+** Quicksort
+** (based on `Algorithms in MODULA-3', Robert Sedgewick;
+** Addison-Wesley, 1993.)
+*/
+
+
+static void set2 (lua_State *L, int i, int j) {
+ lua_rawseti(L, 1, i);
+ lua_rawseti(L, 1, j);
+}
+
+static int sort_comp (lua_State *L, int a, int b) {
+ if (!lua_isnil(L, 2)) { /* function? */
+ int res;
+ lua_pushvalue(L, 2);
+ lua_pushvalue(L, a-1); /* -1 to compensate function */
+ lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
+ lua_call(L, 2, 1);
+ res = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return res;
+ }
+ else /* a < b? */
+ return lua_lessthan(L, a, b);
+}
+
+static void auxsort (lua_State *L, int l, int u) {
+ while (l < u) { /* for tail recursion */
+ int i, j;
+ /* sort elements a[l], a[(l+u)/2] and a[u] */
+ lua_rawgeti(L, 1, l);
+ lua_rawgeti(L, 1, u);
+ if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
+ set2(L, l, u); /* swap a[l] - a[u] */
+ else
+ lua_pop(L, 2);
+ if (u-l == 1) break; /* only 2 elements */
+ i = (l+u)/2;
+ lua_rawgeti(L, 1, i);
+ lua_rawgeti(L, 1, l);
+ if (sort_comp(L, -2, -1)) /* a[i]<a[l]? */
+ set2(L, i, l);
+ else {
+ lua_pop(L, 1); /* remove a[l] */
+ lua_rawgeti(L, 1, u);
+ if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
+ set2(L, i, u);
+ else
+ lua_pop(L, 2);
+ }
+ if (u-l == 2) break; /* only 3 elements */
+ lua_rawgeti(L, 1, i); /* Pivot */
+ lua_pushvalue(L, -1);
+ lua_rawgeti(L, 1, u-1);
+ set2(L, i, u-1);
+ /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
+ i = l; j = u-1;
+ for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
+ /* repeat ++i until a[i] >= P */
+ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
+ if (i>u) luaL_error(L, "invalid order function for sorting");
+ lua_pop(L, 1); /* remove a[i] */
+ }
+ /* repeat --j until a[j] <= P */
+ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
+ if (j<l) luaL_error(L, "invalid order function for sorting");
+ lua_pop(L, 1); /* remove a[j] */
+ }
+ if (j<i) {
+ lua_pop(L, 3); /* pop pivot, a[i], a[j] */
+ break;
+ }
+ set2(L, i, j);
+ }
+ lua_rawgeti(L, 1, u-1);
+ lua_rawgeti(L, 1, i);
+ set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
+ /* a[l..i-1] <= a[i] == P <= a[i+1..u] */
+ /* adjust so that smaller half is in [j..i] and larger one in [l..u] */
+ if (i-l < u-i) {
+ j=l; i=i-1; l=i+2;
+ }
+ else {
+ j=i+1; i=u; u=j-2;
+ }
+ auxsort(L, j, i); /* call recursively the smaller one */
+ } /* repeat the routine for the larger one */
+}
+
+static int sort (lua_State *L) {
+ int n = aux_getn(L, 1);
+ luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */
+ if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_settop(L, 2); /* make sure there is two arguments */
+ auxsort(L, 1, n);
+ return 0;
+}
+
+/* }====================================================== */
+
+
+static const luaL_Reg tab_funcs[] = {
+ {"concat", tconcat},
+ {"foreach", foreach},
+ {"foreachi", foreachi},
+ {"getn", getn},
+ {"maxn", maxn},
+ {"insert", tinsert},
+ {"remove", tremove},
+ {"setn", setn},
+ {"sort", sort},
+ {NULL, NULL}
+};
+
+
+LUALIB_API int luaopen_table (lua_State *L) {
+ luaL_register(L, LUA_TABLIBNAME, tab_funcs);
+ return 1;
+}
+
diff --git a/misc/liblua/ltm.c b/misc/liblua/ltm.c
new file mode 100644
index 0000000..c27f0f6
--- /dev/null
+++ b/misc/liblua/ltm.c
@@ -0,0 +1,75 @@
+/*
+** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define ltm_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+
+
+
+const char *const luaT_typenames[] = {
+ "nil", "boolean", "userdata", "number",
+ "string", "table", "function", "userdata", "thread",
+ "proto", "upval"
+};
+
+
+void luaT_init (lua_State *L) {
+ static const char *const luaT_eventname[] = { /* ORDER TM */
+ "__index", "__newindex",
+ "__gc", "__mode", "__eq",
+ "__add", "__sub", "__mul", "__div", "__mod",
+ "__pow", "__unm", "__len", "__lt", "__le",
+ "__concat", "__call"
+ };
+ int i;
+ for (i=0; i<TM_N; i++) {
+ G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+ luaS_fix(G(L)->tmname[i]); /* never collect these names */
+ }
+}
+
+
+/*
+** function to be used with macro "fasttm": optimized for absence of
+** tag methods
+*/
+const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
+ const TValue *tm = luaH_getstr(events, ename);
+ lua_assert(event <= TM_EQ);
+ if (ttisnil(tm)) { /* no tag method? */
+ events->flags |= cast_byte(1u<<event); /* cache this fact */
+ return NULL;
+ }
+ else return tm;
+}
+
+
+const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
+ Table *mt;
+ switch (ttype(o)) {
+ case LUA_TTABLE:
+ mt = hvalue(o)->metatable;
+ break;
+ case LUA_TUSERDATA:
+ mt = uvalue(o)->metatable;
+ break;
+ default:
+ mt = G(L)->mt[ttype(o)];
+ }
+ return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
+}
+
diff --git a/misc/liblua/ltm.h b/misc/liblua/ltm.h
new file mode 100644
index 0000000..64343b7
--- /dev/null
+++ b/misc/liblua/ltm.h
@@ -0,0 +1,54 @@
+/*
+** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
+** Tag methods
+** See Copyright Notice in lua.h
+*/
+
+#ifndef ltm_h
+#define ltm_h
+
+
+#include "lobject.h"
+
+
+/*
+* WARNING: if you change the order of this enumeration,
+* grep "ORDER TM"
+*/
+typedef enum {
+ TM_INDEX,
+ TM_NEWINDEX,
+ TM_GC,
+ TM_MODE,
+ TM_EQ, /* last tag method with `fast' access */
+ TM_ADD,
+ TM_SUB,
+ TM_MUL,
+ TM_DIV,
+ TM_MOD,
+ TM_POW,
+ TM_UNM,
+ TM_LEN,
+ TM_LT,
+ TM_LE,
+ TM_CONCAT,
+ TM_CALL,
+ TM_N /* number of elements in the enum */
+} TMS;
+
+
+
+#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
+ ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
+
+#define fasttm(l,et,e) gfasttm(G(l), et, e)
+
+LUAI_DATA const char *const luaT_typenames[];
+
+
+LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
+LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
+ TMS event);
+LUAI_FUNC void luaT_init (lua_State *L);
+
+#endif
diff --git a/misc/liblua/lua.h b/misc/liblua/lua.h
new file mode 100644
index 0000000..b796878
--- /dev/null
+++ b/misc/liblua/lua.h
@@ -0,0 +1,388 @@
+/*
+** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
+** Lua - An Extensible Extension Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#include "luaconf.h"
+
+
+#define LUA_VERSION "Lua 5.1"
+#define LUA_RELEASE "Lua 5.1.4"
+#define LUA_VERSION_NUM 501
+#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+
+
+/* mark for precompiled code (`<esc>Lua') */
+#define LUA_SIGNATURE "\033Lua"
+
+/* option for multiple returns in `lua_pcall' and `lua_call' */
+#define LUA_MULTRET (-1)
+
+
+/*
+** pseudo-indices
+*/
+#define LUA_REGISTRYINDEX (-10000)
+#define LUA_ENVIRONINDEX (-10001)
+#define LUA_GLOBALSINDEX (-10002)
+#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
+
+
+/* thread status; 0 is OK */
+#define LUA_YIELD 1
+#define LUA_ERRRUN 2
+#define LUA_ERRSYNTAX 3
+#define LUA_ERRMEM 4
+#define LUA_ERRERR 5
+
+
+typedef struct lua_State lua_State;
+
+typedef int (*lua_CFunction) (lua_State *L);
+
+
+/*
+** functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
+
+
+/*
+** prototype for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE (-1)
+
+#define LUA_TNIL 0
+#define LUA_TBOOLEAN 1
+#define LUA_TLIGHTUSERDATA 2
+#define LUA_TNUMBER 3
+#define LUA_TSTRING 4
+#define LUA_TTABLE 5
+#define LUA_TFUNCTION 6
+#define LUA_TUSERDATA 7
+#define LUA_TTHREAD 8
+
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK 20
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
+
+/* type of numbers in Lua */
+typedef LUA_NUMBER lua_Number;
+
+
+/* type for integer functions */
+typedef LUA_INTEGER lua_Integer;
+
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
+
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int (lua_gettop) (lua_State *L);
+LUA_API void (lua_settop) (lua_State *L, int idx);
+LUA_API void (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void (lua_remove) (lua_State *L, int idx);
+LUA_API void (lua_insert) (lua_State *L, int idx);
+LUA_API void (lua_replace) (lua_State *L, int idx);
+LUA_API int (lua_checkstack) (lua_State *L, int sz);
+
+LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int (lua_isnumber) (lua_State *L, int idx);
+LUA_API int (lua_isstring) (lua_State *L, int idx);
+LUA_API int (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int (lua_type) (lua_State *L, int idx);
+LUA_API const char *(lua_typename) (lua_State *L, int tp);
+
+LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
+
+LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
+LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
+LUA_API int (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+LUA_API size_t (lua_objlen) (lua_State *L, int idx);
+LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void *(lua_topointer) (lua_State *L, int idx);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void (lua_pushnil) (lua_State *L);
+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
+LUA_API void (lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+ va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void (lua_pushboolean) (lua_State *L, int b);
+LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int (lua_pushthread) (lua_State *L);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API void (lua_gettable) (lua_State *L, int idx);
+LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_rawget) (lua_State *L, int idx);
+LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API void (lua_getfenv) (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void (lua_settable) (lua_State *L, int idx);
+LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_rawset) (lua_State *L, int idx);
+LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API int (lua_setfenv) (lua_State *L, int idx);
+
+
+/*
+** `load' and `call' functions (load and run Lua code)
+*/
+LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
+LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
+LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
+LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+ const char *chunkname);
+
+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int (lua_yield) (lua_State *L, int nresults);
+LUA_API int (lua_resume) (lua_State *L, int narg);
+LUA_API int (lua_status) (lua_State *L);
+
+/*
+** garbage-collection function and options
+*/
+
+#define LUA_GCSTOP 0
+#define LUA_GCRESTART 1
+#define LUA_GCCOLLECT 2
+#define LUA_GCCOUNT 3
+#define LUA_GCCOUNTB 4
+#define LUA_GCSTEP 5
+#define LUA_GCSETPAUSE 6
+#define LUA_GCSETSTEPMUL 7
+
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
+
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API int (lua_error) (lua_State *L);
+
+LUA_API int (lua_next) (lua_State *L, int idx);
+
+LUA_API void (lua_concat) (lua_State *L, int n);
+
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+
+
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_pop(L,n) lua_settop(L, -(n)-1)
+
+#define lua_newtable(L) lua_createtable(L, 0, 0)
+
+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+
+#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
+
+#define lua_strlen(L,i) lua_objlen(L, (i))
+
+#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
+#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
+#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
+#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
+#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
+#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
+#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
+
+#define lua_pushliteral(L, s) \
+ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+
+#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
+#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
+
+#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
+
+
+
+/*
+** compatibility macros and functions
+*/
+
+#define lua_open() luaL_newstate()
+
+#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
+
+#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
+
+#define lua_Chunkreader lua_Reader
+#define lua_Chunkwriter lua_Writer
+
+
+/* hack */
+LUA_API void lua_setlevel (lua_State *from, lua_State *to);
+
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL 0
+#define LUA_HOOKRET 1
+#define LUA_HOOKLINE 2
+#define LUA_HOOKCOUNT 3
+#define LUA_HOOKTAILRET 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL (1 << LUA_HOOKCALL)
+#define LUA_MASKRET (1 << LUA_HOOKRET)
+#define LUA_MASKLINE (1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug; /* activation record */
+
+
+/* Functions to be called by the debuger in specific events */
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+
+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook lua_gethook (lua_State *L);
+LUA_API int lua_gethookmask (lua_State *L);
+LUA_API int lua_gethookcount (lua_State *L);
+
+
+struct lua_Debug {
+ int event;
+ const char *name; /* (n) */
+ const char *namewhat; /* (n) `global', `local', `field', `method' */
+ const char *what; /* (S) `Lua', `C', `main', `tail' */
+ const char *source; /* (S) */
+ int currentline; /* (l) */
+ int nups; /* (u) number of upvalues */
+ int linedefined; /* (S) */
+ int lastlinedefined; /* (S) */
+ char short_src[LUA_IDSIZE]; /* (S) */
+ /* private part */
+ int i_ci; /* active function */
+};
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif
diff --git a/misc/liblua/luaconf.h b/misc/liblua/luaconf.h
new file mode 100644
index 0000000..e2cb261
--- /dev/null
+++ b/misc/liblua/luaconf.h
@@ -0,0 +1,763 @@
+/*
+** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lconfig_h
+#define lconfig_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ==================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+@@ LUA_ANSI controls the use of non-ansi features.
+** CHANGE it (define it) if you want Lua to avoid the use of any
+** non-ansi feature or library.
+*/
+#if defined(__STRICT_ANSI__)
+#define LUA_ANSI
+#endif
+
+
+#if !defined(LUA_ANSI) && defined(_WIN32)
+#define LUA_WIN
+#endif
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+#define LUA_USE_READLINE /* needs some extra libraries */
+#endif
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_DL_DYLD /* does not need extra library */
+#endif
+
+
+
+/*
+@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
+@* Interfaces Extension (XSI).
+** CHANGE it (define it) if your system is XSI compatible.
+*/
+#if defined(LUA_USE_POSIX)
+#define LUA_USE_MKSTEMP
+#define LUA_USE_ISATTY
+#define LUA_USE_POPEN
+#define LUA_USE_ULONGJMP
+#endif
+
+
+/*
+@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
+@* Lua check to set its paths.
+@@ LUA_INIT is the name of the environment variable that Lua
+@* checks for initialization code.
+** CHANGE them if you want different names.
+*/
+#define LUA_PATH "LUA_PATH"
+#define LUA_CPATH "LUA_CPATH"
+#define LUA_INIT "LUA_INIT"
+
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+@* Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+@* C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#if defined(_WIN32)
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR "!\\lua\\"
+#define LUA_CDIR "!\\"
+#define LUA_PATH_DEFAULT \
+ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+ ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
+
+#else
+#define LUA_ROOT "/usr/local/"
+#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
+#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
+#define LUA_PATH_DEFAULT \
+ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
+#define LUA_CPATH_DEFAULT \
+ "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
+#endif
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP "\\"
+#else
+#define LUA_DIRSEP "/"
+#endif
+
+
+/*
+@@ LUA_PATHSEP is the character that separates templates in a path.
+@@ LUA_PATH_MARK is the string that marks the substitution points in a
+@* template.
+@@ LUA_EXECDIR in a Windows path is replaced by the executable's
+@* directory.
+@@ LUA_IGMARK is a mark to ignore all before it when bulding the
+@* luaopen_ function name.
+** CHANGE them if for some reason your system cannot use those
+** characters. (E.g., if one of those characters is a common character
+** in file/directory names.) Probably you do not need to change them.
+*/
+#define LUA_PATHSEP ";"
+#define LUA_PATH_MARK "?"
+#define LUA_EXECDIR "!"
+#define LUA_IGMARK "-"
+
+
+/*
+@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
+** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
+** machines, ptrdiff_t gives a good choice between int or long.)
+*/
+#define LUA_INTEGER ptrdiff_t
+
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all standard library functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL)
+
+#if defined(LUA_CORE) || defined(LUA_LIB)
+#define LUA_API __declspec(dllexport)
+#else
+#define LUA_API __declspec(dllimport)
+#endif
+
+#else
+
+#define LUA_API extern
+
+#endif
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API LUA_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+@* exported to outside modules.
+@@ LUAI_DATA is a mark for all extern (const) variables that are not to
+@* be exported to outside modules.
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library.
+*/
+#if defined(luaall_c)
+#define LUAI_FUNC static
+#define LUAI_DATA /* empty */
+
+#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__)
+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
+#define LUAI_DATA LUAI_FUNC
+
+#else
+#define LUAI_FUNC extern
+#define LUAI_DATA extern
+#endif
+
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** CHANGE it if you want a different appearance.
+*/
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@* of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE 60
+
+
+/*
+** {==================================================================
+** Stand-alone configuration
+** ===================================================================
+*/
+
+#if defined(lua_c) || defined(luaall_c)
+
+/*
+@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
+@* is, whether we're running lua interactively).
+** CHANGE it if you have a better definition for non-POSIX/non-Windows
+** systems.
+*/
+#if defined(LUA_USE_ISATTY)
+#include <unistd.h>
+#define lua_stdin_is_tty() isatty(0)
+#elif defined(LUA_WIN)
+#include <io.h>
+#include <stdio.h>
+#define lua_stdin_is_tty() _isatty(_fileno(stdin))
+#else
+#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
+#endif
+
+
+/*
+@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
+@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
+** CHANGE them if you want different prompts. (You can also change the
+** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
+*/
+#define LUA_PROMPT "> "
+#define LUA_PROMPT2 ">> "
+
+
+/*
+@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
+** CHANGE it if your stand-alone interpreter has a different name and
+** your system is not able to detect that name automatically.
+*/
+#define LUA_PROGNAME "lua"
+
+
+/*
+@@ LUA_MAXINPUT is the maximum length for an input line in the
+@* stand-alone interpreter.
+** CHANGE it if you need longer lines.
+*/
+#define LUA_MAXINPUT 512
+
+
+/*
+@@ lua_readline defines how to show a prompt and then read a line from
+@* the standard input.
+@@ lua_saveline defines how to "save" a read line in a "history".
+@@ lua_freeline defines how to free a line read by lua_readline.
+** CHANGE them if you want to improve this functionality (e.g., by using
+** GNU readline and history facilities).
+*/
+#if defined(LUA_USE_READLINE)
+#include <stdio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
+#define lua_saveline(L,idx) \
+ if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
+ add_history(lua_tostring(L, idx)); /* add it to history */
+#define lua_freeline(L,b) ((void)L, free(b))
+#else
+#define lua_readline(L,b,p) \
+ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
+ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
+#define lua_saveline(L,idx) { (void)L; (void)idx; }
+#define lua_freeline(L,b) { (void)L; (void)b; }
+#endif
+
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
+@* as a percentage.
+** CHANGE it if you want the GC to run faster or slower (higher values
+** mean larger pauses which mean slower collection.) You can also change
+** this value dynamically.
+*/
+#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
+
+
+/*
+@@ LUAI_GCMUL defines the default speed of garbage collection relative to
+@* memory allocation as a percentage.
+** CHANGE it if you want to change the granularity of the garbage
+** collection. (Higher values mean coarser collections. 0 represents
+** infinity, where each step performs a full collection.) You can also
+** change this value dynamically.
+*/
+#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
+
+
+
+/*
+@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
+** CHANGE it (define it) if you want exact compatibility with the
+** behavior of setn/getn in Lua 5.0.
+*/
+#undef LUA_COMPAT_GETN
+
+/*
+@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
+** CHANGE it to undefined as soon as you do not need a global 'loadlib'
+** function (the function is still available as 'package.loadlib').
+*/
+#undef LUA_COMPAT_LOADLIB
+
+/*
+@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
+** CHANGE it to undefined as soon as your programs use only '...' to
+** access vararg parameters (instead of the old 'arg' table).
+*/
+#define LUA_COMPAT_VARARG
+
+/*
+@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
+** CHANGE it to undefined as soon as your programs use 'math.fmod' or
+** the new '%' operator instead of 'math.mod'.
+*/
+#define LUA_COMPAT_MOD
+
+/*
+@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
+@* facility.
+** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
+** off the advisory error when nesting [[...]].
+*/
+#define LUA_COMPAT_LSTR 1
+
+/*
+@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
+** CHANGE it to undefined as soon as you rename 'string.gfind' to
+** 'string.gmatch'.
+*/
+#define LUA_COMPAT_GFIND
+
+/*
+@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
+@* behavior.
+** CHANGE it to undefined as soon as you replace to 'luaL_register'
+** your uses of 'luaL_openlib'
+*/
+#define LUA_COMPAT_OPENLIB
+
+
+
+/*
+@@ luai_apicheck is the assert macro used by the Lua-C API.
+** CHANGE luai_apicheck if you want Lua to perform some checks in the
+** parameters it gets from API calls. This may slow down the interpreter
+** a bit, but may be quite useful when debugging C code that interfaces
+** with Lua. A useful redefinition is to use assert.h.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(L,o) { (void)L; assert(o); }
+#else
+#define luai_apicheck(L,o) { (void)L; }
+#endif
+
+
+/*
+@@ LUAI_BITSINT defines the number of bits in an int.
+** CHANGE here if Lua cannot automatically detect the number of bits of
+** your machine. Probably you do not need to change this.
+*/
+/* avoid overflows in comparison */
+#if INT_MAX-20 < 32760
+#define LUAI_BITSINT 16
+#elif INT_MAX > 2147483640L
+/* int has at least 32 bits */
+#define LUAI_BITSINT 32
+#else
+#error "you must define LUA_BITSINT with number of bits in an integer"
+#endif
+
+
+/*
+@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
+@@ LUAI_INT32 is an signed integer with at least 32 bits.
+@@ LUAI_UMEM is an unsigned integer big enough to count the total
+@* memory used by Lua.
+@@ LUAI_MEM is a signed integer big enough to count the total memory
+@* used by Lua.
+** CHANGE here if for some weird reason the default definitions are not
+** good enough for your machine. (The definitions in the 'else'
+** part always works, but may waste space on machines with 64-bit
+** longs.) Probably you do not need to change this.
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_UINT32 unsigned int
+#define LUAI_INT32 int
+#define LUAI_MAXINT32 INT_MAX
+#define LUAI_UMEM size_t
+#define LUAI_MEM ptrdiff_t
+#else
+/* 16-bit ints */
+#define LUAI_UINT32 unsigned long
+#define LUAI_INT32 long
+#define LUAI_MAXINT32 LONG_MAX
+#define LUAI_UMEM unsigned long
+#define LUAI_MEM long
+#endif
+
+
+/*
+@@ LUAI_MAXCALLS limits the number of nested calls.
+** CHANGE it if you need really deep recursive calls. This limit is
+** arbitrary; its only purpose is to stop infinite recursion before
+** exhausting memory.
+*/
+#define LUAI_MAXCALLS 20000
+
+
+/*
+@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
+@* can use.
+** CHANGE it if you need lots of (Lua) stack space for your C
+** functions. This limit is arbitrary; its only purpose is to stop C
+** functions to consume unlimited stack space. (must be smaller than
+** -LUA_REGISTRYINDEX)
+*/
+#define LUAI_MAXCSTACK 8000
+
+
+
+/*
+** {==================================================================
+** CHANGE (to smaller values) the following definitions if your system
+** has a small C stack. (Or you may want to change them to larger
+** values if your system has a large C stack and these limits are
+** too rigid for you.) Some of these constants control the size of
+** stack-allocated arrays used by the compiler or the interpreter, while
+** others limit the maximum number of recursive calls that the compiler
+** or the interpreter can perform. Values too large may cause a C stack
+** overflow for some forms of deep constructs.
+** ===================================================================
+*/
+
+
+/*
+@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
+@* syntactical nested non-terminals in a program.
+*/
+#define LUAI_MAXCCALLS 200
+
+
+/*
+@@ LUAI_MAXVARS is the maximum number of local variables per function
+@* (must be smaller than 250).
+*/
+#define LUAI_MAXVARS 200
+
+
+/*
+@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
+@* (must be smaller than 250).
+*/
+#define LUAI_MAXUPVALUES 60
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+*/
+#define LUAL_BUFFERSIZE BUFSIZ
+
+/* }================================================================== */
+
+
+
+
+/*
+** {==================================================================
+@@ LUA_NUMBER is the type of numbers in Lua.
+** CHANGE the following definitions only if you want to build Lua
+** with a number type different from double. You may also need to
+** change lua_number2int & lua_number2integer.
+** ===================================================================
+*/
+
+#define LUA_NUMBER_DOUBLE
+#define LUA_NUMBER double
+
+/*
+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@* over a number.
+*/
+#define LUAI_UACNUMBER double
+
+
+/*
+@@ LUA_NUMBER_SCAN is the format for reading numbers.
+@@ LUA_NUMBER_FMT is the format for writing numbers.
+@@ lua_number2str converts a number to a string.
+@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
+@@ lua_str2number converts a string to a number.
+*/
+#define LUA_NUMBER_SCAN "%lf"
+#define LUA_NUMBER_FMT "%.14g"
+#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+#define lua_str2number(s,p) strtod((s), (p))
+
+
+/*
+@@ The luai_num* macros define the primitive operations over numbers.
+*/
+#if defined(LUA_CORE)
+#include <math.h>
+#define luai_numadd(a,b) ((a)+(b))
+#define luai_numsub(a,b) ((a)-(b))
+#define luai_nummul(a,b) ((a)*(b))
+#define luai_numdiv(a,b) ((a)/(b))
+#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
+#define luai_numpow(a,b) (pow(a,b))
+#define luai_numunm(a) (-(a))
+#define luai_numeq(a,b) ((a)==(b))
+#define luai_numlt(a,b) ((a)<(b))
+#define luai_numle(a,b) ((a)<=(b))
+#define luai_numisnan(a) (!luai_numeq((a), (a)))
+#endif
+
+
+/*
+@@ lua_number2int is a macro to convert lua_Number to int.
+@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
+** CHANGE them if you know a faster way to convert a lua_Number to
+** int (with any rounding method and without throwing errors) in your
+** system. In Pentium machines, a naive typecast from double to int
+** in C is extremely slow, so any alternative is worth trying.
+*/
+
+/* On a Pentium, resort to a trick */
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
+ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
+
+/* On a Microsoft compiler, use assembler */
+#if defined(_MSC_VER)
+
+#define lua_number2int(i,d) __asm fld d __asm fistp i
+#define lua_number2integer(i,n) lua_number2int(i, n)
+
+/* the next trick should work on any Pentium, but sometimes clashes
+ with a DirectX idiosyncrasy */
+#else
+
+union luai_Cast { double l_d; long l_l; };
+#define lua_number2int(i,d) \
+ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
+#define lua_number2integer(i,n) lua_number2int(i, n)
+
+#endif
+
+
+/* this option always works, but may be slow */
+#else
+#define lua_number2int(i,d) ((i)=(int)(d))
+#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
+
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
+** CHANGE it if your system requires alignments larger than double. (For
+** instance, if your system supports long doubles and they must be
+** aligned in 16-byte boundaries, then you should add long double in the
+** union.) Probably you do not need to change this.
+*/
+#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
+
+
+/*
+@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
+** CHANGE them if you prefer to use longjmp/setjmp even with C++
+** or if want/don't to use _longjmp/_setjmp instead of regular
+** longjmp/setjmp. By default, Lua handles errors with exceptions when
+** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
+** and with longjmp/setjmp otherwise.
+*/
+#if defined(__cplusplus)
+/* C++ exceptions */
+#define LUAI_THROW(L,c) throw(c)
+#define LUAI_TRY(L,c,a) try { a } catch(...) \
+ { if ((c)->status == 0) (c)->status = -1; }
+#define luai_jmpbuf int /* dummy variable */
+
+#elif defined(LUA_USE_ULONGJMP)
+/* in Unix, try _longjmp/_setjmp (more efficient) */
+#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
+#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
+#define luai_jmpbuf jmp_buf
+
+#else
+/* default handling with long jumps */
+#define LUAI_THROW(L,c) longjmp((c)->b, 1)
+#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
+#define luai_jmpbuf jmp_buf
+
+#endif
+
+
+/*
+@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
+@* can do during pattern-matching.
+** CHANGE it if you need more captures. This limit is arbitrary.
+*/
+#define LUA_MAXCAPTURES 32
+
+
+/*
+@@ lua_tmpnam is the function that the OS library uses to create a
+@* temporary name.
+@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
+** CHANGE them if you have an alternative to tmpnam (which is considered
+** insecure) or if you want the original tmpnam anyway. By default, Lua
+** uses tmpnam except when POSIX is available, where it uses mkstemp.
+*/
+#if defined(loslib_c) || defined(luaall_c)
+
+#if defined(LUA_USE_MKSTEMP)
+#include <unistd.h>
+#define LUA_TMPNAMBUFSIZE 32
+#define lua_tmpnam(b,e) { \
+ strcpy(b, "/tmp/lua_XXXXXX"); \
+ e = mkstemp(b); \
+ if (e != -1) close(e); \
+ e = (e == -1); }
+
+#else
+#define LUA_TMPNAMBUFSIZE L_tmpnam
+#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
+#endif
+
+#endif
+
+
+/*
+@@ lua_popen spawns a new process connected to the current one through
+@* the file streams.
+** CHANGE it if you have a way to implement it in your system.
+*/
+#if defined(LUA_USE_POPEN)
+
+#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
+#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
+
+#elif defined(LUA_WIN)
+
+#define lua_popen(L,c,m) ((void)L, _popen(c,m))
+#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
+
+#else
+
+#define lua_popen(L,c,m) ((void)((void)c, m), \
+ luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
+#define lua_pclose(L,file) ((void)((void)L, file), 0)
+
+#endif
+
+/*
+@@ LUA_DL_* define which dynamic-library system Lua should use.
+** CHANGE here if Lua has problems choosing the appropriate
+** dynamic-library system for your platform (either Windows' DLL, Mac's
+** dyld, or Unix's dlopen). If your system is some kind of Unix, there
+** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
+** it. To use dlopen you also need to adapt the src/Makefile (probably
+** adding -ldl to the linker options), so Lua does not select it
+** automatically. (When you change the makefile to add -ldl, you must
+** also add -DLUA_USE_DLOPEN.)
+** If you do not want any kind of dynamic library, undefine all these
+** options.
+** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
+*/
+#if defined(LUA_USE_DLOPEN)
+#define LUA_DL_DLOPEN
+#endif
+
+#if defined(LUA_WIN)
+#define LUA_DL_DLL
+#endif
+
+
+/*
+@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
+@* (the data goes just *before* the lua_State pointer).
+** CHANGE (define) this if you really need that. This value must be
+** a multiple of the maximum alignment required for your machine.
+*/
+#define LUAI_EXTRASPACE 0
+
+
+/*
+@@ luai_userstate* allow user-specific actions on threads.
+** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
+** extra when a thread is created/deleted/resumed/yielded.
+*/
+#define luai_userstateopen(L) ((void)L)
+#define luai_userstateclose(L) ((void)L)
+#define luai_userstatethread(L,L1) ((void)L)
+#define luai_userstatefree(L) ((void)L)
+#define luai_userstateresume(L,n) ((void)L)
+#define luai_userstateyield(L,n) ((void)L)
+
+
+/*
+@@ LUA_INTFRMLEN is the length modifier for integer conversions
+@* in 'string.format'.
+@@ LUA_INTFRM_T is the integer type correspoding to the previous length
+@* modifier.
+** CHANGE them if your system supports long long or does not support long.
+*/
+
+#if defined(LUA_USELONGLONG)
+
+#define LUA_INTFRMLEN "ll"
+#define LUA_INTFRM_T long long
+
+#else
+
+#define LUA_INTFRMLEN "l"
+#define LUA_INTFRM_T long
+
+#endif
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+#endif
+
diff --git a/misc/liblua/lualib.h b/misc/liblua/lualib.h
new file mode 100644
index 0000000..e9ff9ba
--- /dev/null
+++ b/misc/liblua/lualib.h
@@ -0,0 +1,53 @@
+/*
+** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+
+/* Key to file-handle type */
+#define LUA_FILEHANDLE "FILE*"
+
+
+#define LUA_COLIBNAME "coroutine"
+LUALIB_API int (luaopen_base) (lua_State *L);
+
+#define LUA_TABLIBNAME "table"
+LUALIB_API int (luaopen_table) (lua_State *L);
+
+#define LUA_IOLIBNAME "io"
+LUALIB_API int (luaopen_io) (lua_State *L);
+
+#define LUA_OSLIBNAME "os"
+LUALIB_API int (luaopen_os) (lua_State *L);
+
+#define LUA_STRLIBNAME "string"
+LUALIB_API int (luaopen_string) (lua_State *L);
+
+#define LUA_MATHLIBNAME "math"
+LUALIB_API int (luaopen_math) (lua_State *L);
+
+#define LUA_DBLIBNAME "debug"
+LUALIB_API int (luaopen_debug) (lua_State *L);
+
+#define LUA_LOADLIBNAME "package"
+LUALIB_API int (luaopen_package) (lua_State *L);
+
+
+/* open all previous libraries */
+LUALIB_API void (luaL_openlibs) (lua_State *L);
+
+
+
+#ifndef lua_assert
+#define lua_assert(x) ((void)0)
+#endif
+
+
+#endif
diff --git a/misc/liblua/lundump.c b/misc/liblua/lundump.c
new file mode 100644
index 0000000..8010a45
--- /dev/null
+++ b/misc/liblua/lundump.c
@@ -0,0 +1,227 @@
+/*
+** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
+** load precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#include <string.h>
+
+#define lundump_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstring.h"
+#include "lundump.h"
+#include "lzio.h"
+
+typedef struct {
+ lua_State* L;
+ ZIO* Z;
+ Mbuffer* b;
+ const char* name;
+} LoadState;
+
+#ifdef LUAC_TRUST_BINARIES
+#define IF(c,s)
+#define error(S,s)
+#else
+#define IF(c,s) if (c) error(S,s)
+
+static void error(LoadState* S, const char* why)
+{
+ luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
+ luaD_throw(S->L,LUA_ERRSYNTAX);
+}
+#endif
+
+#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
+#define LoadByte(S) (lu_byte)LoadChar(S)
+#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
+#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
+
+static void LoadBlock(LoadState* S, void* b, size_t size)
+{
+ size_t r=luaZ_read(S->Z,b,size);
+ IF (r!=0, "unexpected end");
+}
+
+static int LoadChar(LoadState* S)
+{
+ char x;
+ LoadVar(S,x);
+ return x;
+}
+
+static int LoadInt(LoadState* S)
+{
+ int x;
+ LoadVar(S,x);
+ IF (x<0, "bad integer");
+ return x;
+}
+
+static lua_Number LoadNumber(LoadState* S)
+{
+ lua_Number x;
+ LoadVar(S,x);
+ return x;
+}
+
+static TString* LoadString(LoadState* S)
+{
+ size_t size;
+ LoadVar(S,size);
+ if (size==0)
+ return NULL;
+ else
+ {
+ char* s=luaZ_openspace(S->L,S->b,size);
+ LoadBlock(S,s,size);
+ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
+ }
+}
+
+static void LoadCode(LoadState* S, Proto* f)
+{
+ int n=LoadInt(S);
+ f->code=luaM_newvector(S->L,n,Instruction);
+ f->sizecode=n;
+ LoadVector(S,f->code,n,sizeof(Instruction));
+}
+
+static Proto* LoadFunction(LoadState* S, TString* p);
+
+static void LoadConstants(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->k=luaM_newvector(S->L,n,TValue);
+ f->sizek=n;
+ for (i=0; i<n; i++) setnilvalue(&f->k[i]);
+ for (i=0; i<n; i++)
+ {
+ TValue* o=&f->k[i];
+ int t=LoadChar(S);
+ switch (t)
+ {
+ case LUA_TNIL:
+ setnilvalue(o);
+ break;
+ case LUA_TBOOLEAN:
+ setbvalue(o,LoadChar(S)!=0);
+ break;
+ case LUA_TNUMBER:
+ setnvalue(o,LoadNumber(S));
+ break;
+ case LUA_TSTRING:
+ setsvalue2n(S->L,o,LoadString(S));
+ break;
+ default:
+ error(S,"bad constant");
+ break;
+ }
+ }
+ n=LoadInt(S);
+ f->p=luaM_newvector(S->L,n,Proto*);
+ f->sizep=n;
+ for (i=0; i<n; i++) f->p[i]=NULL;
+ for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
+}
+
+static void LoadDebug(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->lineinfo=luaM_newvector(S->L,n,int);
+ f->sizelineinfo=n;
+ LoadVector(S,f->lineinfo,n,sizeof(int));
+ n=LoadInt(S);
+ f->locvars=luaM_newvector(S->L,n,LocVar);
+ f->sizelocvars=n;
+ for (i=0; i<n; i++) f->locvars[i].varname=NULL;
+ for (i=0; i<n; i++)
+ {
+ f->locvars[i].varname=LoadString(S);
+ f->locvars[i].startpc=LoadInt(S);
+ f->locvars[i].endpc=LoadInt(S);
+ }
+ n=LoadInt(S);
+ f->upvalues=luaM_newvector(S->L,n,TString*);
+ f->sizeupvalues=n;
+ for (i=0; i<n; i++) f->upvalues[i]=NULL;
+ for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
+}
+
+static Proto* LoadFunction(LoadState* S, TString* p)
+{
+ Proto* f;
+ if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
+ f=luaF_newproto(S->L);
+ setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
+ f->source=LoadString(S); if (f->source==NULL) f->source=p;
+ f->linedefined=LoadInt(S);
+ f->lastlinedefined=LoadInt(S);
+ f->nups=LoadByte(S);
+ f->numparams=LoadByte(S);
+ f->is_vararg=LoadByte(S);
+ f->maxstacksize=LoadByte(S);
+ LoadCode(S,f);
+ LoadConstants(S,f);
+ LoadDebug(S,f);
+ IF (!luaG_checkcode(f), "bad code");
+ S->L->top--;
+ S->L->nCcalls--;
+ return f;
+}
+
+static void LoadHeader(LoadState* S)
+{
+ char h[LUAC_HEADERSIZE];
+ char s[LUAC_HEADERSIZE];
+ luaU_header(h);
+ LoadBlock(S,s,LUAC_HEADERSIZE);
+ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
+}
+
+/*
+** load precompiled chunk
+*/
+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
+{
+ LoadState S;
+ if (*name=='@' || *name=='=')
+ S.name=name+1;
+ else if (*name==LUA_SIGNATURE[0])
+ S.name="binary string";
+ else
+ S.name=name;
+ S.L=L;
+ S.Z=Z;
+ S.b=buff;
+ LoadHeader(&S);
+ return LoadFunction(&S,luaS_newliteral(L,"=?"));
+}
+
+/*
+* make header
+*/
+void luaU_header (char* h)
+{
+ int x=1;
+ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
+ h+=sizeof(LUA_SIGNATURE)-1;
+ *h++=(char)LUAC_VERSION;
+ *h++=(char)LUAC_FORMAT;
+ *h++=(char)*(char*)&x; /* endianness */
+ *h++=(char)sizeof(int);
+ *h++=(char)sizeof(size_t);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+ *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
+}
diff --git a/misc/liblua/lundump.h b/misc/liblua/lundump.h
new file mode 100644
index 0000000..c80189d
--- /dev/null
+++ b/misc/liblua/lundump.h
@@ -0,0 +1,36 @@
+/*
+** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
+** load precompiled Lua chunks
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lundump_h
+#define lundump_h
+
+#include "lobject.h"
+#include "lzio.h"
+
+/* load one chunk; from lundump.c */
+LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
+
+/* make header; from lundump.c */
+LUAI_FUNC void luaU_header (char* h);
+
+/* dump one chunk; from ldump.c */
+LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
+
+#ifdef luac_c
+/* print one chunk; from print.c */
+LUAI_FUNC void luaU_print (const Proto* f, int full);
+#endif
+
+/* for header of binary files -- this is Lua 5.1 */
+#define LUAC_VERSION 0x51
+
+/* for header of binary files -- this is the official format */
+#define LUAC_FORMAT 0
+
+/* size of header of binary files */
+#define LUAC_HEADERSIZE 12
+
+#endif
diff --git a/misc/liblua/lvm.c b/misc/liblua/lvm.c
new file mode 100644
index 0000000..c7c0e57
--- /dev/null
+++ b/misc/liblua/lvm.c
@@ -0,0 +1,763 @@
+/*
+** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lvm_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldebug.h"
+#include "ldo.h"
+#include "lfunc.h"
+#include "lgc.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "ltable.h"
+#include "ltm.h"
+#include "lvm.h"
+
+
+
+/* limit for table tag-method chains (to avoid loops) */
+#define MAXTAGLOOP 100
+
+
+const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
+ lua_Number num;
+ if (ttisnumber(obj)) return obj;
+ if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
+ setnvalue(n, num);
+ return n;
+ }
+ else
+ return NULL;
+}
+
+
+int luaV_tostring (lua_State *L, StkId obj) {
+ if (!ttisnumber(obj))
+ return 0;
+ else {
+ char s[LUAI_MAXNUMBER2STR];
+ lua_Number n = nvalue(obj);
+ lua_number2str(s, n);
+ setsvalue2s(L, obj, luaS_new(L, s));
+ return 1;
+ }
+}
+
+
+static void traceexec (lua_State *L, const Instruction *pc) {
+ lu_byte mask = L->hookmask;
+ const Instruction *oldpc = L->savedpc;
+ L->savedpc = pc;
+ if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
+ resethookcount(L);
+ luaD_callhook(L, LUA_HOOKCOUNT, -1);
+ }
+ if (mask & LUA_MASKLINE) {
+ Proto *p = ci_func(L->ci)->l.p;
+ int npc = pcRel(pc, p);
+ int newline = getline(p, npc);
+ /* call linehook when enter a new function, when jump back (loop),
+ or when enter a new line */
+ if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
+ luaD_callhook(L, LUA_HOOKLINE, newline);
+ }
+}
+
+
+static void callTMres (lua_State *L, StkId res, const TValue *f,
+ const TValue *p1, const TValue *p2) {
+ ptrdiff_t result = savestack(L, res);
+ setobj2s(L, L->top, f); /* push function */
+ setobj2s(L, L->top+1, p1); /* 1st argument */
+ setobj2s(L, L->top+2, p2); /* 2nd argument */
+ luaD_checkstack(L, 3);
+ L->top += 3;
+ luaD_call(L, L->top - 3, 1);
+ res = restorestack(L, result);
+ L->top--;
+ setobjs2s(L, res, L->top);
+}
+
+
+
+static void callTM (lua_State *L, const TValue *f, const TValue *p1,
+ const TValue *p2, const TValue *p3) {
+ setobj2s(L, L->top, f); /* push function */
+ setobj2s(L, L->top+1, p1); /* 1st argument */
+ setobj2s(L, L->top+2, p2); /* 2nd argument */
+ setobj2s(L, L->top+3, p3); /* 3th argument */
+ luaD_checkstack(L, 4);
+ L->top += 4;
+ luaD_call(L, L->top - 4, 0);
+}
+
+
+void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+ int loop;
+ for (loop = 0; loop < MAXTAGLOOP; loop++) {
+ const TValue *tm;
+ if (ttistable(t)) { /* `t' is a table? */
+ Table *h = hvalue(t);
+ const TValue *res = luaH_get(h, key); /* do a primitive get */
+ if (!ttisnil(res) || /* result is no nil? */
+ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
+ setobj2s(L, val, res);
+ return;
+ }
+ /* else will try the tag method */
+ }
+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
+ luaG_typeerror(L, t, "index");
+ if (ttisfunction(tm)) {
+ callTMres(L, val, tm, t, key);
+ return;
+ }
+ t = tm; /* else repeat with `tm' */
+ }
+ luaG_runerror(L, "loop in gettable");
+}
+
+
+void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
+ int loop;
+ for (loop = 0; loop < MAXTAGLOOP; loop++) {
+ const TValue *tm;
+ if (ttistable(t)) { /* `t' is a table? */
+ Table *h = hvalue(t);
+ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
+ if (!ttisnil(oldval) || /* result is no nil? */
+ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
+ setobj2t(L, oldval, val);
+ luaC_barriert(L, h, val);
+ return;
+ }
+ /* else will try the tag method */
+ }
+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+ luaG_typeerror(L, t, "index");
+ if (ttisfunction(tm)) {
+ callTM(L, tm, t, key, val);
+ return;
+ }
+ t = tm; /* else repeat with `tm' */
+ }
+ luaG_runerror(L, "loop in settable");
+}
+
+
+static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
+ StkId res, TMS event) {
+ const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
+ if (ttisnil(tm))
+ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
+ if (ttisnil(tm)) return 0;
+ callTMres(L, res, tm, p1, p2);
+ return 1;
+}
+
+
+static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
+ TMS event) {
+ const TValue *tm1 = fasttm(L, mt1, event);
+ const TValue *tm2;
+ if (tm1 == NULL) return NULL; /* no metamethod */
+ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
+ tm2 = fasttm(L, mt2, event);
+ if (tm2 == NULL) return NULL; /* no metamethod */
+ if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
+ return tm1;
+ return NULL;
+}
+
+
+static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
+ TMS event) {
+ const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
+ const TValue *tm2;
+ if (ttisnil(tm1)) return -1; /* no metamethod? */
+ tm2 = luaT_gettmbyobj(L, p2, event);
+ if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
+ return -1;
+ callTMres(L, L->top, tm1, p1, p2);
+ return !l_isfalse(L->top);
+}
+
+
+static int l_strcmp (const TString *ls, const TString *rs) {
+ const char *l = getstr(ls);
+ size_t ll = ls->tsv.len;
+ const char *r = getstr(rs);
+ size_t lr = rs->tsv.len;
+ for (;;) {
+ int temp = strcoll(l, r);
+ if (temp != 0) return temp;
+ else { /* strings are equal up to a `\0' */
+ size_t len = strlen(l); /* index of first `\0' in both strings */
+ if (len == lr) /* r is finished? */
+ return (len == ll) ? 0 : 1;
+ else if (len == ll) /* l is finished? */
+ return -1; /* l is smaller than r (because r is not finished) */
+ /* both strings longer than `len'; go on comparing (after the `\0') */
+ len++;
+ l += len; ll -= len; r += len; lr -= len;
+ }
+ }
+}
+
+
+int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+ if (ttype(l) != ttype(r))
+ return luaG_ordererror(L, l, r);
+ else if (ttisnumber(l))
+ return luai_numlt(nvalue(l), nvalue(r));
+ else if (ttisstring(l))
+ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+ else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
+ return res;
+ return luaG_ordererror(L, l, r);
+}
+
+
+static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+ if (ttype(l) != ttype(r))
+ return luaG_ordererror(L, l, r);
+ else if (ttisnumber(l))
+ return luai_numle(nvalue(l), nvalue(r));
+ else if (ttisstring(l))
+ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+ else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ return res;
+ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
+ return !res;
+ return luaG_ordererror(L, l, r);
+}
+
+
+int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
+ const TValue *tm;
+ lua_assert(ttype(t1) == ttype(t2));
+ switch (ttype(t1)) {
+ case LUA_TNIL: return 1;
+ case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+ case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
+ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+ case LUA_TUSERDATA: {
+ if (uvalue(t1) == uvalue(t2)) return 1;
+ tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
+ TM_EQ);
+ break; /* will try TM */
+ }
+ case LUA_TTABLE: {
+ if (hvalue(t1) == hvalue(t2)) return 1;
+ tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+ default: return gcvalue(t1) == gcvalue(t2);
+ }
+ if (tm == NULL) return 0; /* no TM? */
+ callTMres(L, L->top, tm, t1, t2); /* call TM */
+ return !l_isfalse(L->top);
+}
+
+
+void luaV_concat (lua_State *L, int total, int last) {
+ do {
+ StkId top = L->base + last + 1;
+ int n = 2; /* number of elements handled in this pass (at least 2) */
+ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
+ if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
+ luaG_concaterror(L, top-2, top-1);
+ } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
+ (void)tostring(L, top - 2); /* result is first op (as string) */
+ else {
+ /* at least two string values; get as many as possible */
+ size_t tl = tsvalue(top-1)->len;
+ char *buffer;
+ int i;
+ /* collect total length */
+ for (n = 1; n < total && tostring(L, top-n-1); n++) {
+ size_t l = tsvalue(top-n-1)->len;
+ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
+ tl += l;
+ }
+ buffer = luaZ_openspace(L, &G(L)->buff, tl);
+ tl = 0;
+ for (i=n; i>0; i--) { /* concat all strings */
+ size_t l = tsvalue(top-i)->len;
+ memcpy(buffer+tl, svalue(top-i), l);
+ tl += l;
+ }
+ setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
+ }
+ total -= n-1; /* got `n' strings to create 1 new */
+ last -= n-1;
+ } while (total > 1); /* repeat until only 1 result left */
+}
+
+
+static void Arith (lua_State *L, StkId ra, const TValue *rb,
+ const TValue *rc, TMS op) {
+ TValue tempb, tempc;
+ const TValue *b, *c;
+ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
+ (c = luaV_tonumber(rc, &tempc)) != NULL) {
+ lua_Number nb = nvalue(b), nc = nvalue(c);
+ switch (op) {
+ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
+ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
+ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
+ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
+ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
+ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
+ case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
+ default: lua_assert(0); break;
+ }
+ }
+ else if (!call_binTM(L, rb, rc, ra, op))
+ luaG_aritherror(L, rb, rc);
+}
+
+
+
+/*
+** some macros for common tasks in `luaV_execute'
+*/
+
+#define runtime_check(L, c) { if (!(c)) break; }
+
+#define RA(i) (base+GETARG_A(i))
+/* to be used after possible stack reallocation */
+#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
+#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
+#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
+ ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
+#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
+ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
+#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
+
+
+#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
+
+
+#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
+
+
+#define arith_op(op,tm) { \
+ TValue *rb = RKB(i); \
+ TValue *rc = RKC(i); \
+ if (ttisnumber(rb) && ttisnumber(rc)) { \
+ lua_Number nb = nvalue(rb), nc = nvalue(rc); \
+ setnvalue(ra, op(nb, nc)); \
+ } \
+ else \
+ Protect(Arith(L, ra, rb, rc, tm)); \
+ }
+
+
+
+void luaV_execute (lua_State *L, int nexeccalls) {
+ LClosure *cl;
+ StkId base;
+ TValue *k;
+ const Instruction *pc;
+ reentry: /* entry point */
+ lua_assert(isLua(L->ci));
+ pc = L->savedpc;
+ cl = &clvalue(L->ci->func)->l;
+ base = L->base;
+ k = cl->p->k;
+ /* main loop of interpreter */
+ for (;;) {
+ const Instruction i = *pc++;
+ StkId ra;
+ if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
+ (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
+ traceexec(L, pc);
+ if (L->status == LUA_YIELD) { /* did hook yield? */
+ L->savedpc = pc - 1;
+ return;
+ }
+ base = L->base;
+ }
+ /* warning!! several calls may realloc the stack and invalidate `ra' */
+ ra = RA(i);
+ lua_assert(base == L->base && L->base == L->ci->base);
+ lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
+ lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
+ switch (GET_OPCODE(i)) {
+ case OP_MOVE: {
+ setobjs2s(L, ra, RB(i));
+ continue;
+ }
+ case OP_LOADK: {
+ setobj2s(L, ra, KBx(i));
+ continue;
+ }
+ case OP_LOADBOOL: {
+ setbvalue(ra, GETARG_B(i));
+ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
+ continue;
+ }
+ case OP_LOADNIL: {
+ TValue *rb = RB(i);
+ do {
+ setnilvalue(rb--);
+ } while (rb >= ra);
+ continue;
+ }
+ case OP_GETUPVAL: {
+ int b = GETARG_B(i);
+ setobj2s(L, ra, cl->upvals[b]->v);
+ continue;
+ }
+ case OP_GETGLOBAL: {
+ TValue g;
+ TValue *rb = KBx(i);
+ sethvalue(L, &g, cl->env);
+ lua_assert(ttisstring(rb));
+ Protect(luaV_gettable(L, &g, rb, ra));
+ continue;
+ }
+ case OP_GETTABLE: {
+ Protect(luaV_gettable(L, RB(i), RKC(i), ra));
+ continue;
+ }
+ case OP_SETGLOBAL: {
+ TValue g;
+ sethvalue(L, &g, cl->env);
+ lua_assert(ttisstring(KBx(i)));
+ Protect(luaV_settable(L, &g, KBx(i), ra));
+ continue;
+ }
+ case OP_SETUPVAL: {
+ UpVal *uv = cl->upvals[GETARG_B(i)];
+ setobj(L, uv->v, ra);
+ luaC_barrier(L, uv, ra);
+ continue;
+ }
+ case OP_SETTABLE: {
+ Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
+ continue;
+ }
+ case OP_NEWTABLE: {
+ int b = GETARG_B(i);
+ int c = GETARG_C(i);
+ sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
+ Protect(luaC_checkGC(L));
+ continue;
+ }
+ case OP_SELF: {
+ StkId rb = RB(i);
+ setobjs2s(L, ra+1, rb);
+ Protect(luaV_gettable(L, rb, RKC(i), ra));
+ continue;
+ }
+ case OP_ADD: {
+ arith_op(luai_numadd, TM_ADD);
+ continue;
+ }
+ case OP_SUB: {
+ arith_op(luai_numsub, TM_SUB);
+ continue;
+ }
+ case OP_MUL: {
+ arith_op(luai_nummul, TM_MUL);
+ continue;
+ }
+ case OP_DIV: {
+ arith_op(luai_numdiv, TM_DIV);
+ continue;
+ }
+ case OP_MOD: {
+ arith_op(luai_nummod, TM_MOD);
+ continue;
+ }
+ case OP_POW: {
+ arith_op(luai_numpow, TM_POW);
+ continue;
+ }
+ case OP_UNM: {
+ TValue *rb = RB(i);
+ if (ttisnumber(rb)) {
+ lua_Number nb = nvalue(rb);
+ setnvalue(ra, luai_numunm(nb));
+ }
+ else {
+ Protect(Arith(L, ra, rb, rb, TM_UNM));
+ }
+ continue;
+ }
+ case OP_NOT: {
+ int res = l_isfalse(RB(i)); /* next assignment may change this value */
+ setbvalue(ra, res);
+ continue;
+ }
+ case OP_LEN: {
+ const TValue *rb = RB(i);
+ switch (ttype(rb)) {
+ case LUA_TTABLE: {
+ setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
+ break;
+ }
+ case LUA_TSTRING: {
+ setnvalue(ra, cast_num(tsvalue(rb)->len));
+ break;
+ }
+ default: { /* try metamethod */
+ Protect(
+ if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
+ luaG_typeerror(L, rb, "get length of");
+ )
+ }
+ }
+ continue;
+ }
+ case OP_CONCAT: {
+ int b = GETARG_B(i);
+ int c = GETARG_C(i);
+ Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
+ setobjs2s(L, RA(i), base+b);
+ continue;
+ }
+ case OP_JMP: {
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+ case OP_EQ: {
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ Protect(
+ if (equalobj(L, rb, rc) == GETARG_A(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+ )
+ pc++;
+ continue;
+ }
+ case OP_LT: {
+ Protect(
+ if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+ )
+ pc++;
+ continue;
+ }
+ case OP_LE: {
+ Protect(
+ if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+ )
+ pc++;
+ continue;
+ }
+ case OP_TEST: {
+ if (l_isfalse(ra) != GETARG_C(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+ pc++;
+ continue;
+ }
+ case OP_TESTSET: {
+ TValue *rb = RB(i);
+ if (l_isfalse(rb) != GETARG_C(i)) {
+ setobjs2s(L, ra, rb);
+ dojump(L, pc, GETARG_sBx(*pc));
+ }
+ pc++;
+ continue;
+ }
+ case OP_CALL: {
+ int b = GETARG_B(i);
+ int nresults = GETARG_C(i) - 1;
+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
+ L->savedpc = pc;
+ switch (luaD_precall(L, ra, nresults)) {
+ case PCRLUA: {
+ nexeccalls++;
+ goto reentry; /* restart luaV_execute over new Lua function */
+ }
+ case PCRC: {
+ /* it was a C function (`precall' called it); adjust results */
+ if (nresults >= 0) L->top = L->ci->top;
+ base = L->base;
+ continue;
+ }
+ default: {
+ return; /* yield */
+ }
+ }
+ }
+ case OP_TAILCALL: {
+ int b = GETARG_B(i);
+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
+ L->savedpc = pc;
+ lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
+ switch (luaD_precall(L, ra, LUA_MULTRET)) {
+ case PCRLUA: {
+ /* tail call: put new frame in place of previous one */
+ CallInfo *ci = L->ci - 1; /* previous frame */
+ int aux;
+ StkId func = ci->func;
+ StkId pfunc = (ci+1)->func; /* previous function index */
+ if (L->openupval) luaF_close(L, ci->base);
+ L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
+ for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
+ setobjs2s(L, func+aux, pfunc+aux);
+ ci->top = L->top = func+aux; /* correct top */
+ lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
+ ci->savedpc = L->savedpc;
+ ci->tailcalls++; /* one more call lost */
+ L->ci--; /* remove new frame */
+ goto reentry;
+ }
+ case PCRC: { /* it was a C function (`precall' called it) */
+ base = L->base;
+ continue;
+ }
+ default: {
+ return; /* yield */
+ }
+ }
+ }
+ case OP_RETURN: {
+ int b = GETARG_B(i);
+ if (b != 0) L->top = ra+b-1;
+ if (L->openupval) luaF_close(L, base);
+ L->savedpc = pc;
+ b = luaD_poscall(L, ra);
+ if (--nexeccalls == 0) /* was previous function running `here'? */
+ return; /* no: return */
+ else { /* yes: continue its execution */
+ if (b) L->top = L->ci->top;
+ lua_assert(isLua(L->ci));
+ lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
+ goto reentry;
+ }
+ }
+ case OP_FORLOOP: {
+ lua_Number step = nvalue(ra+2);
+ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
+ lua_Number limit = nvalue(ra+1);
+ if (luai_numlt(0, step) ? luai_numle(idx, limit)
+ : luai_numle(limit, idx)) {
+ dojump(L, pc, GETARG_sBx(i)); /* jump back */
+ setnvalue(ra, idx); /* update internal index... */
+ setnvalue(ra+3, idx); /* ...and external index */
+ }
+ continue;
+ }
+ case OP_FORPREP: {
+ const TValue *init = ra;
+ const TValue *plimit = ra+1;
+ const TValue *pstep = ra+2;
+ L->savedpc = pc; /* next steps may throw errors */
+ if (!tonumber(init, ra))
+ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ else if (!tonumber(plimit, ra+1))
+ luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ else if (!tonumber(pstep, ra+2))
+ luaG_runerror(L, LUA_QL("for") " step must be a number");
+ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+ case OP_TFORLOOP: {
+ StkId cb = ra + 3; /* call base */
+ setobjs2s(L, cb+2, ra+2);
+ setobjs2s(L, cb+1, ra+1);
+ setobjs2s(L, cb, ra);
+ L->top = cb+3; /* func. + 2 args (state and index) */
+ Protect(luaD_call(L, cb, GETARG_C(i)));
+ L->top = L->ci->top;
+ cb = RA(i) + 3; /* previous call may change the stack */
+ if (!ttisnil(cb)) { /* continue loop? */
+ setobjs2s(L, cb-1, cb); /* save control variable */
+ dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
+ }
+ pc++;
+ continue;
+ }
+ case OP_SETLIST: {
+ int n = GETARG_B(i);
+ int c = GETARG_C(i);
+ int last;
+ Table *h;
+ if (n == 0) {
+ n = cast_int(L->top - ra) - 1;
+ L->top = L->ci->top;
+ }
+ if (c == 0) c = cast_int(*pc++);
+ runtime_check(L, ttistable(ra));
+ h = hvalue(ra);
+ last = ((c-1)*LFIELDS_PER_FLUSH) + n;
+ if (last > h->sizearray) /* needs more space? */
+ luaH_resizearray(L, h, last); /* pre-alloc it at once */
+ for (; n > 0; n--) {
+ TValue *val = ra+n;
+ setobj2t(L, luaH_setnum(L, h, last--), val);
+ luaC_barriert(L, h, val);
+ }
+ continue;
+ }
+ case OP_CLOSE: {
+ luaF_close(L, ra);
+ continue;
+ }
+ case OP_CLOSURE: {
+ Proto *p;
+ Closure *ncl;
+ int nup, j;
+ p = cl->p->p[GETARG_Bx(i)];
+ nup = p->nups;
+ ncl = luaF_newLclosure(L, nup, cl->env);
+ ncl->l.p = p;
+ for (j=0; j<nup; j++, pc++) {
+ if (GET_OPCODE(*pc) == OP_GETUPVAL)
+ ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
+ else {
+ lua_assert(GET_OPCODE(*pc) == OP_MOVE);
+ ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
+ }
+ }
+ setclvalue(L, ra, ncl);
+ Protect(luaC_checkGC(L));
+ continue;
+ }
+ case OP_VARARG: {
+ int b = GETARG_B(i) - 1;
+ int j;
+ CallInfo *ci = L->ci;
+ int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
+ if (b == LUA_MULTRET) {
+ Protect(luaD_checkstack(L, n));
+ ra = RA(i); /* previous call may change the stack */
+ b = n;
+ L->top = ra + n;
+ }
+ for (j = 0; j < b; j++) {
+ if (j < n) {
+ setobjs2s(L, ra + j, ci->base - n + j);
+ }
+ else {
+ setnilvalue(ra + j);
+ }
+ }
+ continue;
+ }
+ }
+ }
+}
+
diff --git a/misc/liblua/lvm.h b/misc/liblua/lvm.h
new file mode 100644
index 0000000..bfe4f56
--- /dev/null
+++ b/misc/liblua/lvm.h
@@ -0,0 +1,36 @@
+/*
+** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
+** Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lvm_h
+#define lvm_h
+
+
+#include "ldo.h"
+#include "lobject.h"
+#include "ltm.h"
+
+
+#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
+
+#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
+ (((o) = luaV_tonumber(o,n)) != NULL))
+
+#define equalobj(L,o1,o2) \
+ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
+
+
+LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
+LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
+LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
+LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
+ StkId val);
+LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
+ StkId val);
+LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
+LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
+
+#endif
diff --git a/misc/liblua/lzio.c b/misc/liblua/lzio.c
new file mode 100644
index 0000000..293edd5
--- /dev/null
+++ b/misc/liblua/lzio.c
@@ -0,0 +1,82 @@
+/*
+** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
+** a generic input stream interface
+** See Copyright Notice in lua.h
+*/
+
+
+#include <string.h>
+
+#define lzio_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "llimits.h"
+#include "lmem.h"
+#include "lstate.h"
+#include "lzio.h"
+
+
+int luaZ_fill (ZIO *z) {
+ size_t size;
+ lua_State *L = z->L;
+ const char *buff;
+ lua_unlock(L);
+ buff = z->reader(L, z->data, &size);
+ lua_lock(L);
+ if (buff == NULL || size == 0) return EOZ;
+ z->n = size - 1;
+ z->p = buff;
+ return char2int(*(z->p++));
+}
+
+
+int luaZ_lookahead (ZIO *z) {
+ if (z->n == 0) {
+ if (luaZ_fill(z) == EOZ)
+ return EOZ;
+ else {
+ z->n++; /* luaZ_fill removed first byte; put back it */
+ z->p--;
+ }
+ }
+ return char2int(*z->p);
+}
+
+
+void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
+ z->L = L;
+ z->reader = reader;
+ z->data = data;
+ z->n = 0;
+ z->p = NULL;
+}
+
+
+/* --------------------------------------------------------------- read --- */
+size_t luaZ_read (ZIO *z, void *b, size_t n) {
+ while (n) {
+ size_t m;
+ if (luaZ_lookahead(z) == EOZ)
+ return n; /* return number of missing bytes */
+ m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
+ memcpy(b, z->p, m);
+ z->n -= m;
+ z->p += m;
+ b = (char *)b + m;
+ n -= m;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
+ if (n > buff->buffsize) {
+ if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
+ luaZ_resizebuffer(L, buff, n);
+ }
+ return buff->buffer;
+}
+
+
diff --git a/misc/liblua/lzio.h b/misc/liblua/lzio.h
new file mode 100644
index 0000000..51d695d
--- /dev/null
+++ b/misc/liblua/lzio.h
@@ -0,0 +1,67 @@
+/*
+** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
+** Buffered streams
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lzio_h
+#define lzio_h
+
+#include "lua.h"
+
+#include "lmem.h"
+
+
+#define EOZ (-1) /* end of stream */
+
+typedef struct Zio ZIO;
+
+#define char2int(c) cast(int, cast(unsigned char, (c)))
+
+#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
+
+typedef struct Mbuffer {
+ char *buffer;
+ size_t n;
+ size_t buffsize;
+} Mbuffer;
+
+#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
+
+#define luaZ_buffer(buff) ((buff)->buffer)
+#define luaZ_sizebuffer(buff) ((buff)->buffsize)
+#define luaZ_bufflen(buff) ((buff)->n)
+
+#define luaZ_resetbuffer(buff) ((buff)->n = 0)
+
+
+#define luaZ_resizebuffer(L, buff, size) \
+ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
+ (buff)->buffsize = size)
+
+#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
+
+
+LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
+LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
+ void *data);
+LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
+LUAI_FUNC int luaZ_lookahead (ZIO *z);
+
+
+
+/* --------- Private Part ------------------ */
+
+struct Zio {
+ size_t n; /* bytes still unread */
+ const char *p; /* current position in buffer */
+ lua_Reader reader;
+ void* data; /* additional data */
+ lua_State *L; /* Lua state (for reader) */
+};
+
+
+LUAI_FUNC int luaZ_fill (ZIO *z);
+
+#endif
diff --git a/misc/liblua/print.c b/misc/liblua/print.c
new file mode 100644
index 0000000..e240cfc
--- /dev/null
+++ b/misc/liblua/print.c
@@ -0,0 +1,227 @@
+/*
+** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
+** print bytecodes
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdio.h>
+
+#define luac_c
+#define LUA_CORE
+
+#include "ldebug.h"
+#include "lobject.h"
+#include "lopcodes.h"
+#include "lundump.h"
+
+#define PrintFunction luaU_print
+
+#define Sizeof(x) ((int)sizeof(x))
+#define VOID(p) ((const void*)(p))
+
+static void PrintString(const TString* ts)
+{
+ const char* s=getstr(ts);
+ size_t i,n=ts->tsv.len;
+ putchar('"');
+ for (i=0; i<n; i++)
+ {
+ int c=s[i];
+ switch (c)
+ {
+ case '"': printf("\\\""); break;
+ case '\\': printf("\\\\"); break;
+ case '\a': printf("\\a"); break;
+ case '\b': printf("\\b"); break;
+ case '\f': printf("\\f"); break;
+ case '\n': printf("\\n"); break;
+ case '\r': printf("\\r"); break;
+ case '\t': printf("\\t"); break;
+ case '\v': printf("\\v"); break;
+ default: if (isprint((unsigned char)c))
+ putchar(c);
+ else
+ printf("\\%03u",(unsigned char)c);
+ }
+ }
+ putchar('"');
+}
+
+static void PrintConstant(const Proto* f, int i)
+{
+ const TValue* o=&f->k[i];
+ switch (ttype(o))
+ {
+ case LUA_TNIL:
+ printf("nil");
+ break;
+ case LUA_TBOOLEAN:
+ printf(bvalue(o) ? "true" : "false");
+ break;
+ case LUA_TNUMBER:
+ printf(LUA_NUMBER_FMT,nvalue(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(rawtsvalue(o));
+ break;
+ default: /* cannot happen */
+ printf("? type=%d",ttype(o));
+ break;
+ }
+}
+
+static void PrintCode(const Proto* f)
+{
+ const Instruction* code=f->code;
+ int pc,n=f->sizecode;
+ for (pc=0; pc<n; pc++)
+ {
+ Instruction i=code[pc];
+ OpCode o=GET_OPCODE(i);
+ int a=GETARG_A(i);
+ int b=GETARG_B(i);
+ int c=GETARG_C(i);
+ int bx=GETARG_Bx(i);
+ int sbx=GETARG_sBx(i);
+ int line=getline(f,pc);
+ printf("\t%d\t",pc+1);
+ if (line>0) printf("[%d]\t",line); else printf("[-]\t");
+ printf("%-9s\t",luaP_opnames[o]);
+ switch (getOpMode(o))
+ {
+ case iABC:
+ printf("%d",a);
+ if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
+ if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
+ break;
+ case iABx:
+ if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
+ break;
+ case iAsBx:
+ if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
+ break;
+ }
+ switch (o)
+ {
+ case OP_LOADK:
+ printf("\t; "); PrintConstant(f,bx);
+ break;
+ case OP_GETUPVAL:
+ case OP_SETUPVAL:
+ printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
+ break;
+ case OP_GETGLOBAL:
+ case OP_SETGLOBAL:
+ printf("\t; %s",svalue(&f->k[bx]));
+ break;
+ case OP_GETTABLE:
+ case OP_SELF:
+ if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
+ break;
+ case OP_SETTABLE:
+ case OP_ADD:
+ case OP_SUB:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_POW:
+ case OP_EQ:
+ case OP_LT:
+ case OP_LE:
+ if (ISK(b) || ISK(c))
+ {
+ printf("\t; ");
+ if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
+ printf(" ");
+ if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
+ }
+ break;
+ case OP_JMP:
+ case OP_FORLOOP:
+ case OP_FORPREP:
+ printf("\t; to %d",sbx+pc+2);
+ break;
+ case OP_CLOSURE:
+ printf("\t; %p",VOID(f->p[bx]));
+ break;
+ case OP_SETLIST:
+ if (c==0) printf("\t; %d",(int)code[++pc]);
+ else printf("\t; %d",c);
+ break;
+ default:
+ break;
+ }
+ printf("\n");
+ }
+}
+
+#define SS(x) (x==1)?"":"s"
+#define S(x) x,SS(x)
+
+static void PrintHeader(const Proto* f)
+{
+ const char* s=getstr(f->source);
+ if (*s=='@' || *s=='=')
+ s++;
+ else if (*s==LUA_SIGNATURE[0])
+ s="(bstring)";
+ else
+ s="(string)";
+ printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
+ (f->linedefined==0)?"main":"function",s,
+ f->linedefined,f->lastlinedefined,
+ S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
+ printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
+ f->numparams,f->is_vararg?"+":"",SS(f->numparams),
+ S(f->maxstacksize),S(f->nups));
+ printf("%d local%s, %d constant%s, %d function%s\n",
+ S(f->sizelocvars),S(f->sizek),S(f->sizep));
+}
+
+static void PrintConstants(const Proto* f)
+{
+ int i,n=f->sizek;
+ printf("constants (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t",i+1);
+ PrintConstant(f,i);
+ printf("\n");
+ }
+}
+
+static void PrintLocals(const Proto* f)
+{
+ int i,n=f->sizelocvars;
+ printf("locals (%d) for %p:\n",n,VOID(f));
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\t%d\t%d\n",
+ i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
+ }
+}
+
+static void PrintUpvalues(const Proto* f)
+{
+ int i,n=f->sizeupvalues;
+ printf("upvalues (%d) for %p:\n",n,VOID(f));
+ if (f->upvalues==NULL) return;
+ for (i=0; i<n; i++)
+ {
+ printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
+ }
+}
+
+void PrintFunction(const Proto* f, int full)
+{
+ int i,n=f->sizep;
+ PrintHeader(f);
+ PrintCode(f);
+ if (full)
+ {
+ PrintConstants(f);
+ PrintLocals(f);
+ PrintUpvalues(f);
+ }
+ for (i=0; i<n; i++) PrintFunction(f->p[i],full);
+}
diff --git a/misc/libopenalbridge/CMakeLists.txt b/misc/libopenalbridge/CMakeLists.txt
deleted file mode 100644
index 1ffae10..0000000
--- a/misc/libopenalbridge/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-find_package(OpenAL REQUIRED)
-find_package(OggVorbis REQUIRED)
-include_directories(${OPENAL_INCLUDE_DIR})
-include_directories(${OGGVORBIS_INCLUDE_DIRS})
-
-#set destination directory for library
-set(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH})
-
-#list of source files for libraries
-set(openal_src openalbridge.c loaders.c wrappers.c commands.c)
-
-#build a static library for human systems
-set (build_type STATIC)
-
-#visualstudio and windows in general don't like static linking, so we're building the library in shared mode
-if(WIN32)
-#workaround for visualstudio (wants headers in the source list)
- set(openal_src *.h ${openal_src})
-#deps for the shared library
- link_libraries(${VORBISFILE_LIBRARY})
- link_libraries(${VORBIS_LIBRARY})
- link_libraries(${OGG_LIBRARY})
- link_libraries(${OPENAL_LIBRARY})
-#build a shared library
- set (build_type SHARED)
-endif()
-
-#compiles and links actual library
-add_library (openalbridge ${build_type} ${openal_src})
-
-if(WIN32)
-if(MSVC)
- SET_TARGET_PROPERTIES(openalbridge PROPERTIES LINK_FLAGS /DEF:openalbridge.def)
-endif(MSVC)
-#install it in the executable directory
- install(TARGETS openalbridge DESTINATION bin)
-endif(WIN32)
-
-#type make openalbridge_test to get a small executable test
-add_executable(openalbridge_test "${hedgewars_SOURCE_DIR}/misc/libopenalbridge/tester.c")
-target_link_libraries(openalbridge_test openalbridge ${OPENAL_LIBRARY} ${OGGVORBIS_LIBRARIES})
-
diff --git a/misc/libopenalbridge/commands.c b/misc/libopenalbridge/commands.c
deleted file mode 100644
index ca3e589..0000000
--- a/misc/libopenalbridge/commands.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * commands.c
- * Hedgewars
- *
- * Created by Vittorio on 13/06/10.
- * Copyright 2010 __MyCompanyName__. All rights reserved.
- *
- */
-
-#include "commands.h"
-#include "wrappers.h"
-
-ALfloat old_gain;
-extern ALuint *Sources;
-extern ALuint cache_size, cache_index, sources_number;
-extern ALboolean instances_number;
-extern al_sound_t *the_sounds;
-
-void openal_pausesound (uint32_t index) {
- if (openal_ready() == AL_TRUE && index < cache_size)
- alSourcePause(Sources[the_sounds[index].source_index]);
-}
-
-
-void openal_stopsound (uint32_t index) {
- if (openal_ready() == AL_TRUE && index < cache_size)
- alSourceStop(Sources[the_sounds[index].source_index]);
-}
-
-
-void openal_playsound (unsigned int index) {
- ALboolean needsSource = AL_TRUE;
- ALfloat SourcePosition[] = { 0.0, 0.0, 0.0 };
- ALfloat SourceVelocity[] = { 0.0, 0.0, 0.0 };
- ALint state;
- int i, j;
-
- if (openal_ready() == AL_TRUE && index < cache_size) {
- // check if sound has already a source
- if (the_sounds[index].source_index != -1) {
- // it has a source, check it's not playing
- alGetSourcei(Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
- if (state != AL_PLAYING && state != AL_PAUSED) {
- // it is not being played, so we can use it safely
- needsSource = AL_FALSE;
- }
- // else it is being played, so we have to allocate a new source for this buffer
- }
-
- if (needsSource) {
-#ifdef DEBUG
- fprintf(stderr,"(Bridge Debug) - looking for a source for sound %d\n", index);
-#endif
- for (i = 0; i < sources_number; i++) {
- // let's iterate on Sources until we find a source that is not playing
- alGetSourcei(Sources[i], AL_SOURCE_STATE, &state);
- if (state != AL_PLAYING && state != AL_PAUSED) {
- // let's iterate on the_sounds until we find the sound using that source
- for (j = 0; j < cache_size; j++) {
- if (the_sounds[j].source_index == i) {
- the_sounds[j].source_index = -1;
- break;
- }
- }
- // here we know that no-one is using that source so we can use it
- break;
- }
- }
-
- if (i == sources_number) {
- // this means all sources are busy
- }
-
- // set source properties that it will use when it's in playback
- alSourcei (Sources[i], AL_BUFFER, the_sounds[index].buffer);
- alSourcef (Sources[i], AL_PITCH, 1.0f);
- alSourcef (Sources[i], AL_GAIN, 1.0f);
- alSourcefv(Sources[i], AL_POSITION, SourcePosition);
- alSourcefv(Sources[i], AL_VELOCITY, SourceVelocity);
- alSourcei (Sources[i], AL_LOOPING, 0);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge ERROR) - failed to set Source properties\n");
- return;
- }
- the_sounds[index].source_index = i;
- }
-
- alSourcePlay(Sources[the_sounds[index].source_index]);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index);
- return;
- }
- }
-}
-
-void openal_toggleloop (uint32_t index) {
- ALint loop;
-
- if (openal_ready() == AL_TRUE && index < cache_size) {
- alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop);
- alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001);
- }
-}
-
-
-void openal_setvolume (uint32_t index, float gain) {
- if (openal_ready() == AL_TRUE && index < cache_size)
- alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain);
-}
-
-
-void openal_setglobalvolume (float gain) {
- if (openal_ready() == AL_TRUE)
- alListenerf (AL_GAIN, gain);
-}
-
-void openal_togglemute () {
- ALfloat gain;
-
- if (openal_ready() == AL_TRUE) {
- alGetListenerf (AL_GAIN, &gain);
- if (gain > 0) {
- old_gain = gain;
- gain = 0;
- } else
- gain = old_gain;
-
- alListenerf (AL_GAIN, gain);
- }
-}
-
-// Fade in or out by calling a helper thread
-void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) {
-#ifndef _WIN32
- pthread_t thread;
-#else
- HANDLE Thread;
-#endif
- fade_t *fade;
-
- if (openal_ready() == AL_TRUE && index < cache_size) {
- fade = (fade_t*) Malloc(sizeof(fade_t));
- fade->index = index;
- fade->quantity = quantity;
- fade->type = direction;
-
-#ifndef _WIN32
- pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade);
- pthread_detach(thread);
-#else
- Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade);
-#endif
- }
-}
-
-void openal_setposition (uint32_t index, float x, float y, float z) {
- if (openal_ready() == AL_TRUE && index < cache_size)
- alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);;
-}
-
-void helper_fade(void *tmp) {
- ALfloat gain;
- ALfloat target_gain;
- fade_t *fade;
- uint32_t index;
- uint16_t quantity;
- al_fade_t type;
-
- fade = tmp;
- index = fade->index;
- quantity = fade->quantity;
- type = fade->type;
- free (fade);
-
- if (type == AL_FADE_IN) {
-#ifdef DEBUG
- fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity);
-#endif
-
- // save the volume desired after the fade
- alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
- if (target_gain > 1.0f || target_gain <= 0.0f)
- target_gain = 1.0f;
-
- for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) {
-#ifdef TRACE
- fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain);
-#endif
- alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
- usleep(10000);
- }
- } else {
- alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain);
-
- for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) {
-#ifdef TRACE
- fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain);
-#endif
- alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain);
- usleep(10000);
- }
-
- if (AL_NO_ERROR != alGetError())
- fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n");
-
- // stop that sound and reset its volume
- alSourceStop (Sources[the_sounds[index].source_index]);
- alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain);
- }
-
- if (AL_NO_ERROR != alGetError())
- fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n");
-
-#ifndef _WIN32
- pthread_exit(NULL);
-#else
- _endthread();
-#endif
-}
-
diff --git a/misc/libopenalbridge/commands.h b/misc/libopenalbridge/commands.h
deleted file mode 100644
index 86e3c3c..0000000
--- a/misc/libopenalbridge/commands.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * commands.h
- * Hedgewars
- *
- * Created by Vittorio on 13/06/10.
- * Copyright 2010 __MyCompanyName__. All rights reserved.
- *
- */
-
-#ifndef _OALB_COMMANDS_H
-#define _OALB_COMMANDS_H
-
-#include "openalbridge_t.h"
-#include "openalbridge.h"
-
-
-#define openal_fadein(x,y) openal_fade(x,y,AL_FADE_IN)
-#define openal_fadeout(x,y) openal_fade(x,y,AL_FADE_OUT)
-#define openal_playsound_loop(x,y) openal_playsound(x) \
- if (y != 0) \
- openal_toggleloop(x);
-#ifdef __CPLUSPLUS
-extern "C" {
-#endif
-
- // play, pause, stop a single sound source
- void openal_pausesound (unsigned int index);
- void openal_stopsound (unsigned int index);
-
- // play a sound and set whether it should loop or not (0/1)
- void openal_playsound (unsigned int index);
-
- void openal_freesound (unsigned int index);
-
- // set or unset the looping property for a sound source
- void openal_toggleloop (unsigned int index);
-
- // set position and volume of a sound source
- void openal_setposition (unsigned int index, float x, float y, float z);
- void openal_setvolume (unsigned int index, float gain);
-
- // set volume for all sounds (gain interval is [0-1])
- void openal_setglobalvolume (float gain);
-
- // mute or unmute all sounds
- void openal_togglemute (void);
-
- // fade effect,
- void openal_fade (unsigned int index, unsigned short int quantity, al_fade_t direction);
-
-#ifdef __CPLUSPLUS
-}
-#endif
-
-#endif /*_OALB_COMMANDS_H*/
diff --git a/misc/libopenalbridge/globals.h b/misc/libopenalbridge/globals.h
deleted file mode 100644
index 9c43928..0000000
--- a/misc/libopenalbridge/globals.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef _OALB_GLOBALS_H
-#define _OALB_GLOBALS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "al.h"
-
-#ifndef _WIN32
-#include <pthread.h>
-#include <syslog.h>
-#else
-#include <process.h>
-#endif
-
-
-// 1.0 02/03/10 - Defines cross-platform sleep, usleep, etc. [Wu Yongwei]
-#ifndef _SLEEP_H
-#define _SLEEP_H
-#ifdef _WIN32
-# if defined(_NEED_SLEEP_ONLY) && (defined(_MSC_VER) || defined(__MINGW32__))
-# include <stdlib.h>
-# define sleep(t) _sleep((t) * 1000)
-# else
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-# define sleep(t) Sleep((t) * 1000)
-# endif
-# ifndef _NEED_SLEEP_ONLY
-# define msleep(t) Sleep(t)
-# define usleep(t) Sleep((t) / 1000)
-# endif
-#else
-# include <unistd.h>
-# ifndef _NEED_SLEEP_ONLY
-# define msleep(t) usleep((t) * 1000)
-# endif
-#endif
-#endif // _SLEEP_H
-
-
-// check compiler requirements
-#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
-#warning __BIG_ENDIAN__ or __LITTLE_ENDIAN__ not found, going to set __LITTLE_ENDIAN__ as default
-#define __LITTLE_ENDIAN__ 1
-#endif
-
-/* use byteswap macros from the host system, hopefully optimized ones ;-)
- * or define our own version, simple, stupid, straight-forward... */
-#ifdef HAVE_BYTESWAP_H
-#include <byteswap.h>
-#else
-#define bswap_16(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
-#define bswap_32(x) (((x & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | \
- ((x & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) )
-#endif /* HAVE_BYTESWAP_H */
-
-/* swap numbers accordingly to architecture automatically */
-#ifdef __LITTLE_ENDIAN__
-#define ENDIAN_LITTLE_32(x) x
-#define ENDIAN_BIG_32(x) bswap_32(x)
-#define ENDIAN_LITTLE_16(x) x
-#define ENDIAN_BIG_16(x) bswap_16(x)
-#elif __BIG_ENDIAN__
-#define ENDIAN_LITTLE_32(x) bswap_32(x)
-#define ENDIAN_BIG_32(x) x
-#define ENDIAN_LITTLE_16(x) bswap_16(x)
-#define ENDIAN_BIG_16(x) x
-#endif
-
-/* file format defines */
-#define OGG_FILE_FORMAT 0x4F676753
-#define WAV_FILE_FORMAT 0x52494646
-#define WAV_HEADER_SUBCHUNK2ID 0x64617461
-
-
-#endif /*_OALB_GLOBALS_H*/
diff --git a/misc/libopenalbridge/loaders.c b/misc/libopenalbridge/loaders.c
deleted file mode 100644
index 9c357e7..0000000
--- a/misc/libopenalbridge/loaders.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
-* OpenAL Bridge - a simple portable library for OpenAL interface
-* Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser 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 "loaders.h"
-#include "wrappers.h"
-#include "vorbis/vorbisfile.h"
-#include "openalbridge_t.h"
-
-
-int load_wavpcm (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq) {
- WAV_header_t WAVHeader;
- FILE *wavfile;
- int32_t t;
- uint32_t n = 0;
- uint8_t sub0, sub1, sub2, sub3;
-
- wavfile = Fopen(filename, "rb");
-
- fread(&WAVHeader.ChunkID, sizeof(uint32_t), 1, wavfile); /*RIFF*/
- fread(&WAVHeader.ChunkSize, sizeof(uint32_t), 1, wavfile);
- fread(&WAVHeader.Format, sizeof(uint32_t), 1, wavfile); /*WAVE*/
-
-#ifdef DEBUG
- fprintf(stderr, "ChunkID: %X\n", ENDIAN_BIG_32(WAVHeader.ChunkID));
- fprintf(stderr, "ChunkSize: %d\n", ENDIAN_LITTLE_32(WAVHeader.ChunkSize));
- fprintf(stderr, "Format: %X\n", ENDIAN_BIG_32(WAVHeader.Format));
-#endif
-
- fread(&WAVHeader.Subchunk1ID, sizeof(uint32_t), 1, wavfile); /*fmt */
- fread(&WAVHeader.Subchunk1Size, sizeof(uint32_t), 1, wavfile);
- fread(&WAVHeader.AudioFormat, sizeof(uint16_t), 1, wavfile);
- fread(&WAVHeader.NumChannels, sizeof(uint16_t), 1, wavfile);
- fread(&WAVHeader.SampleRate, sizeof(uint32_t), 1, wavfile);
- fread(&WAVHeader.ByteRate, sizeof(uint32_t), 1, wavfile);
- fread(&WAVHeader.BlockAlign, sizeof(uint16_t), 1, wavfile);
- fread(&WAVHeader.BitsPerSample, sizeof(uint16_t), 1, wavfile);
-
-#ifdef DEBUG
- fprintf(stderr, "Subchunk1ID: %X\n", ENDIAN_BIG_32(WAVHeader.Subchunk1ID));
- fprintf(stderr, "Subchunk1Size: %d\n", ENDIAN_LITTLE_32(WAVHeader.Subchunk1Size));
- fprintf(stderr, "AudioFormat: %d\n", ENDIAN_LITTLE_16(WAVHeader.AudioFormat));
- fprintf(stderr, "NumChannels: %d\n", ENDIAN_LITTLE_16(WAVHeader.NumChannels));
- fprintf(stderr, "SampleRate: %d\n", ENDIAN_LITTLE_32(WAVHeader.SampleRate));
- fprintf(stderr, "ByteRate: %d\n", ENDIAN_LITTLE_32(WAVHeader.ByteRate));
- fprintf(stderr, "BlockAlign: %d\n", ENDIAN_LITTLE_16(WAVHeader.BlockAlign));
- fprintf(stderr, "BitsPerSample: %d\n", ENDIAN_LITTLE_16(WAVHeader.BitsPerSample));
-#endif
-
- /*remove useless header chunks by looking for the WAV_HEADER_SUBCHUNK2ID integer */
- do {
- t = fread(&sub0, sizeof(uint8_t), 1, wavfile);
- if(sub0 == 0x64) {
- t = fread(&sub1, sizeof(uint8_t), 1, wavfile);
- if(sub1 == 0x61) {
- t = fread(&sub2, sizeof(uint8_t), 1, wavfile);
- if(sub2 == 0x74) {
- t = fread(&sub3, sizeof(uint8_t), 1, wavfile);
- if(sub3 == 0x61) {
- WAVHeader.Subchunk2ID = WAV_HEADER_SUBCHUNK2ID;
- break;
- }
- }
- }
- }
-
- if (t <= 0) {
- // eof
- fprintf(stderr,"(Bridge Error) - wrong WAV header\n");
- return -1;
- }
- } while (1);
-
- fread(&WAVHeader.Subchunk2Size, sizeof(uint32_t), 1, wavfile);
-
-#ifdef DEBUG
- fprintf(stderr, "Subchunk2ID: %X\n", ENDIAN_LITTLE_32(WAVHeader.Subchunk2ID));
- fprintf(stderr, "Subchunk2Size: %d\n", ENDIAN_LITTLE_32(WAVHeader.Subchunk2Size));
-#endif
-
- *data = (char*) Malloc (sizeof(char) * ENDIAN_LITTLE_32(WAVHeader.Subchunk2Size));
-
- /*read the actual sound data*/
- do {
- n += fread(&((*data)[n]), sizeof(uint8_t), 4, wavfile);
- } while (n < ENDIAN_LITTLE_32(WAVHeader.Subchunk2Size));
-
- fclose(wavfile);
-
-#ifdef DEBUG
- fprintf(stderr,"(Bridge Info) - WAV data loaded\n");
-#endif
-
- /*set parameters for OpenAL*/
- /*Valid formats are AL_FORMAT_MONO8, AL_FORMAT_MONO16, AL_FORMAT_STEREO8, and AL_FORMAT_STEREO16*/
- if (ENDIAN_LITTLE_16(WAVHeader.NumChannels) == 1) {
- if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 8)
- *format = AL_FORMAT_MONO8;
- else {
- if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 16)
- *format = AL_FORMAT_MONO16;
- else {
- fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]\n");
- return -2;
- }
- }
- } else {
- if (ENDIAN_LITTLE_16(WAVHeader.NumChannels) == 2) {
- if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 8)
- *format = AL_FORMAT_STEREO8;
- else {
- if (ENDIAN_LITTLE_16(WAVHeader.BitsPerSample) == 16)
- *format = AL_FORMAT_STEREO16;
- else {
- fprintf(stderr,"(Bridge Error) - wrong WAV header [bitsample value]\n");
- return -2;
- }
- }
- } else {
- fprintf(stderr,"(Bridge Error) - wrong WAV header [format value]\n");
- return -2;
- }
- }
-
- *bitsize = ENDIAN_LITTLE_32(WAVHeader.Subchunk2Size);
- *freq = ENDIAN_LITTLE_32(WAVHeader.SampleRate);
- return 0;
-}
-
-
-int load_oggvorbis (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq) {
- /*implementation inspired from http://www.devmaster.net/forums/showthread.php?t=1153 */
-
- /*ogg handle*/
- FILE *oggFile;
- /*stream handle*/
- OggVorbis_File oggStream;
- /*some formatting data*/
- vorbis_info *vorbisInfo;
- /*length of the decoded data*/
- int64_t pcm_length;
- /*other vars*/
- int section, result, size, endianness;
-#ifdef DEBUG
- int i;
- /*other less useful data*/
- vorbis_comment *vorbisComment;
-#endif
-
- oggFile = Fopen(filename, "rb");
- result = ov_open_callbacks(oggFile, &oggStream, NULL, 0, OV_CALLBACKS_DEFAULT);
- if (result < 0) {
- fprintf(stderr,"(Bridge Error) - ov_open_callbacks() failed with %X\n", result);
- ov_clear(&oggStream);
- return -1;
- }
-
- /*load OGG header and determine the decoded data size*/
- vorbisInfo = ov_info(&oggStream, -1);
- pcm_length = ov_pcm_total(&oggStream, -1) << vorbisInfo->channels;
-
-#ifdef DEBUG
- vorbisComment = ov_comment(&oggStream, -1);
- fprintf(stderr, "Version: %d\n", vorbisInfo->version);
- fprintf(stderr, "Channels: %d\n", vorbisInfo->channels);
- fprintf(stderr, "Rate (Hz): %ld\n", vorbisInfo->rate);
- fprintf(stderr, "Bitrate Upper: %ld\n", vorbisInfo->bitrate_upper);
- fprintf(stderr, "Bitrate Nominal: %ld\n", vorbisInfo->bitrate_nominal);
- fprintf(stderr, "Bitrate Lower: %ld\n", vorbisInfo->bitrate_lower);
- fprintf(stderr, "Bitrate Windows: %ld\n", vorbisInfo->bitrate_window);
- fprintf(stderr, "Vendor: %s\n", vorbisComment->vendor);
- fprintf(stderr, "PCM data size: %lld\n", pcm_length);
- fprintf(stderr, "# comment: %d\n", vorbisComment->comments);
- for (i = 0; i < vorbisComment->comments; i++)
- fprintf(stderr, "\tComment %d: %s\n", i, vorbisComment->user_comments[i]);
-#endif
-
- /*allocates enough room for the decoded data*/
- *data = (char*) Malloc (sizeof(char) * pcm_length);
-
- /*there *should* not be ogg at 8 bits*/
- if (vorbisInfo->channels == 1)
- *format = AL_FORMAT_MONO16;
- else {
- if (vorbisInfo->channels == 2)
- *format = AL_FORMAT_STEREO16;
- else {
- fprintf(stderr,"(Bridge Error) - wrong OGG header [channel %d]\n", vorbisInfo->channels);
- ov_clear(&oggStream);
- return -2;
- }
- }
-
- size = 0;
-#ifdef __LITTLE_ENDIAN__
- endianness = 0;
-#elif __BIG_ENDIAN__
- endianness = 1;
-#endif
- while (size < pcm_length) {
- /*ov_read decodes the ogg stream and storse the pcm in data*/
- result = ov_read (&oggStream, *data + size, pcm_length - size, endianness, 2, 1, §ion);
- if (result > 0) {
- size += result;
- } else {
- if (result == 0)
- break;
- else {
- fprintf(stderr,"(Bridge Error) - End of file from OGG stream\n");
- ov_clear(&oggStream);
- return -3;
- }
- }
- }
-
- /*set the last fields*/
- *bitsize = size;
- *freq = vorbisInfo->rate;
-
- /*cleaning time (ov_clear also closes file handler)*/
- ov_clear(&oggStream);
-
- return 0;
-}
diff --git a/misc/libopenalbridge/loaders.h b/misc/libopenalbridge/loaders.h
deleted file mode 100644
index 75311f1..0000000
--- a/misc/libopenalbridge/loaders.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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 "globals.h"
-
-#ifndef _OALB_LOADERS_H
-#define _OALB_LOADERS_H
-
-int load_wavpcm (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq);
-int load_oggvorbis (const char *filename, ALenum *format, char **data, ALsizei *bitsize, ALsizei *freq);
-
-#endif /*_OALB_LOADERS_H*/
diff --git a/misc/libopenalbridge/openalbridge.c b/misc/libopenalbridge/openalbridge.c
deleted file mode 100644
index 9059e18..0000000
--- a/misc/libopenalbridge/openalbridge.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
-* OpenAL Bridge - a simple portable library for OpenAL interface
-* Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser 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 "openalbridge.h"
-#include "globals.h"
-#include "al.h"
-#include "alc.h"
-#include "wrappers.h"
-#include "loaders.h"
-#include "string.h"
-
-// Sources are points emitting sound, their number is limited, but a single source can play many buffers
-// Buffers hold sound data and are unlimited
-ALuint *Sources;
-ALuint cache_size, cache_index, sources_number;
-ALboolean instances_number;
-al_sound_t *the_sounds;
-ALint cache_pointer;
-
-// Initialize an OpenAL contex and allocate memory space for data and buffers
-// It can be called twice to increase the cache size
-int openal_init (void) {
- ALCcontext *context;
- ALCdevice *device;
- int i;
-
- // reuse old context and resize the existing
- if (openal_ready() == AL_TRUE) {
- fprintf(stderr,"(Bridge Info) - already initialized\n");
- instances_number++;
- return AL_TRUE;
- }
-
- cache_pointer = 0;
- instances_number++;
-
- // initial memory size
- cache_size = 50;
-
- // open hardware device if present
- device = alcOpenDevice(NULL);
- sources_number = 16;
- if (device == NULL) {
- fprintf(stderr,"(Bridge Warning) - failed to open sound device, using software renderer\n");
- device = alcOpenDevice("Generic Software");
- sources_number = 32;
- if (device == NULL) {
- fprintf(stderr,"(Bridge ERROR) - failed to start software renderer, sound will be disabled\n");
- return -1;
- }
- }
-
- fprintf(stderr,"(Bridge Info) - output device: %s\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
-
- context = alcCreateContext(device, NULL);
- alcMakeContextCurrent(context);
- alcProcessContext(context);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge ERROR) - Failed to create a new contex\n");
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- alcCloseDevice(device);
- return -2;
- }
-
- Sources = (ALuint *)Malloc (sizeof(ALuint) * sources_number);
- alGenSources(sources_number, Sources);
-
- // set the listener gain, position (on xyz axes), velocity (one value for each axe) and orientation
- // Position, Velocity and Orientation of the listener
- ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
- ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
- ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
-
- alListenerf (AL_GAIN, 1.0f );
- alListenerfv(AL_POSITION, ListenerPos);
- alListenerfv(AL_VELOCITY, ListenerVel);
- alListenerfv(AL_ORIENTATION, ListenerOri);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge ERROR) - Failed to set Listener properties\n");
- return -3;
- }
-
- the_sounds = (al_sound_t *)Malloc (sizeof(al_sound_t) * cache_size);
- for (i = 0; i < cache_size; i++)
- the_sounds[i] = new_sound_el();
-
- alGetError();
- return AL_TRUE;
-}
-
-
-// Stop all sounds, deallocate all memory and close OpenAL context
-void openal_close (void) {
- ALCcontext *context;
- ALCdevice *device;
- int i;
-
- if (instances_number == 0) {
- fprintf(stderr,"(Bridge Warning) - OpenAL not initialized\n");
- return;
- }
-
- instances_number--;
- if (instances_number > 0) {
- // release memory only when last session ends
- return;
- }
-
- for (i = 0; i < cache_size; i++) {
- openal_unloadfile(i);
- }
- free(the_sounds);
-
- alSourceStopv (sources_number, Sources);
- alDeleteSources (sources_number, Sources);
-
- free(Sources);
-
- context = alcGetCurrentContext();
- device = alcGetContextsDevice(context);
-
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- alcCloseDevice(device);
-
- fprintf(stderr,"(Bridge Info) - closed\n");
-
- return;
-}
-
-
-ALboolean openal_ready (void) {
- if (instances_number >= 1)
- return AL_TRUE;
- else
- return AL_FALSE;
-}
-
-
-// Open a file, load into memory and allocate the Source buffer for playing
-int openal_loadfile (const char *filename){
- ALenum format, error;
- ALsizei bitsize, freq;
- uint32_t fileformat;
- al_sound_t sound_data;
- int len, i, index = -1;
- char *data;
- FILE *fp;
-
- if (openal_ready() == AL_FALSE) {
- fprintf(stderr,"(Bridge Warning) - not initialized\n");
- return -1;
- }
-
- // if this sound is already loaded return the index from the_sounds
- len = strlen(filename);
- for (i = 0; i < cache_size; i++) {
- if (the_sounds[i].filename != NULL && strncmp(the_sounds[i].filename, filename, len) == 0) {
-#ifdef DEBUG
- fprintf(stderr,"(Bridge Debug) - sound %d is already loaded\n", i);
-#endif
- return i;
- }
- // if we don't have memory available search for a free element
- if (cache_pointer >= cache_size)
- if (the_sounds[i].is_used == AL_FALSE)
- index = i;
- }
-
- if (index == -1 && cache_pointer >= cache_size) {
- fprintf(stderr,"(Bridge Info) - No free spots found; doubling cache size\n", filename);
- cache_size *= 2;
- the_sounds = (al_sound_t *)Realloc (the_sounds, sizeof(al_sound_t) * cache_size);
- for (i = cache_size - 50; i < cache_size; i++)
- the_sounds[i] = new_sound_el();
- } else
- index = ++cache_pointer;
-
-
- // detect the file format, as written in the first 4 bytes of the header
- fp = Fopen (filename, "rb");
- if (fp == NULL) {
- fprintf(stderr,"(Bridge ERROR) - File %s not loaded\n", filename);
- return -3;
- }
-
- error = fread (&fileformat, sizeof(uint32_t), 1, fp);
- fclose (fp);
- if (error < 0) {
- fprintf(stderr,"(Bridge ERROR) - File %s is too short\n", filename);
- return -4;
- }
-
- switch (ENDIAN_BIG_32(fileformat)) {
- case OGG_FILE_FORMAT:
- error = load_oggvorbis (filename, &format, &data, &bitsize, &freq);
- break;
- case WAV_FILE_FORMAT:
- error = load_wavpcm (filename, &format, &data, &bitsize, &freq);
- break;
- default:
- fprintf(stderr,"(Bridge ERROR) - File format (%08X) not supported\n", ENDIAN_BIG_32(fileformat));
- return -5;
- break;
- }
-
- if (error != 0) {
- fprintf(stderr,"(Bridge ERROR) - error loading file %s\n", filename);
- if(data)
- free(data);
- return -6;
- }
-
- // alGenBuffers happens here
- sound_data = init_sound_el(filename);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge ERROR) - Failed to allocate memory for buffer %d\n", index);
- free(data);
- return -5;
- }
-
- // copy pcm data in one buffer and free it
- alBufferData(sound_data.buffer, format, data, bitsize, freq);
- free(data);
-
- if (AL_NO_ERROR != alGetError()) {
- fprintf(stderr,"(Bridge ERROR) - Failed to write data to buffer %d\n", index);
- return -8;
- }
-
- // clear any AL errors beforehand
- alGetError();
-
- fprintf(stderr,"(Bridge Info) - successfully loaded %s\n", filename);
-
- // returns the index of the source you just loaded, increments it and exits
- the_sounds[index] = sound_data;
- return index;
-}
-
-
-void openal_unloadfile (uint32_t index) {
- ALint state;
-
- if (openal_ready() == AL_TRUE && index < cache_size && the_sounds[index].is_used == AL_TRUE) {
- alGetSourcei (Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state);
- if (state == AL_PLAYING || state == AL_PAUSED)
- openal_stopsound(index);
-
- // free memory and
- alDeleteBuffers (1, &the_sounds[index].buffer);
- the_sounds[index] = new_sound_el();
- }
-}
diff --git a/misc/libopenalbridge/openalbridge.def b/misc/libopenalbridge/openalbridge.def
deleted file mode 100644
index 9a922a2..0000000
--- a/misc/libopenalbridge/openalbridge.def
+++ /dev/null
@@ -1,20 +0,0 @@
-LIBRARY "openalbridge"
-EXPORTS
- openal_init
- openal_close
- openal_ready
- openal_loadfile
- openal_playsound
- openal_pausesound
- openal_stopsound
- openal_playsound_loop
- openal_stopsound_free
- openal_freesound
- openal_toggleloop
- openal_setvolume
- openal_setglobalvolume
- openal_togglemute
- openal_fade
- openal_fadein
- openal_fadeout
-
diff --git a/misc/libopenalbridge/openalbridge.h b/misc/libopenalbridge/openalbridge.h
deleted file mode 100644
index 833bcf7..0000000
--- a/misc/libopenalbridge/openalbridge.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef _OALB_INTERFACE_H
-#define _OALB_INTERFACE_H
-
-#include "openalbridge_t.h"
-#include "commands.h"
-
-#ifdef __CPLUSPLUS
-extern "C" {
-#endif
-
- // init audio context and allocate memory
- int openal_init (void);
-
- // close audio subsytem and free memory
- void openal_close (void);
-
- // check if openal_init has been called
- char openal_ready (void);
-
- // load an audio file into memory and map it to abuffer
- int openal_loadfile (const char *filename);
-
- // unloads data from memory and marks a free spot
- void openal_unloadfile (unsigned int index);
-
- /******* other functions continue in commands.h *******/
-
-#ifdef __CPLUSPLUS
-}
-#endif
-
-#endif /*_OALB_INTERFACE_H*/
diff --git a/misc/libopenalbridge/openalbridge_t.h b/misc/libopenalbridge/openalbridge_t.h
deleted file mode 100644
index e6f53ef..0000000
--- a/misc/libopenalbridge/openalbridge_t.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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 <stdint.h>
-#include "al.h"
-
-#ifndef _OALB_INTERFACE_TYPES_H
-#define _OALB_INTERFACE_TYPES_H
-
-enum al_fade_enum {AL_FADE_IN, AL_FADE_OUT};
-typedef enum al_fade_enum al_fade_t;
-
-
-// data type to handle which source source is playing what
-#pragma pack(1)
-typedef struct _al_sound_t {
- const char *filename; // name of the sound file
- ALuint buffer; // actual sound content
- uint32_t source_index; // index of the associated source
- ALboolean is_used; // tells if the element can be overwritten
-} al_sound_t;
-#pragma pack()
-
-
-// data type for passing data between threads
-#pragma pack(1)
-typedef struct _fade_t {
- uint32_t index;
- uint16_t quantity;
- al_fade_t type;
-} fade_t;
-#pragma pack()
-
-
-// data type for WAV header
-#pragma pack(1)
-typedef struct _WAV_header_t {
- uint32_t ChunkID;
- uint32_t ChunkSize;
- uint32_t Format;
- uint32_t Subchunk1ID;
- uint32_t Subchunk1Size;
- uint16_t AudioFormat;
- uint16_t NumChannels;
- uint32_t SampleRate;
- uint32_t ByteRate;
- uint16_t BlockAlign;
- uint16_t BitsPerSample;
- uint32_t Subchunk2ID;
- uint32_t Subchunk2Size;
-} WAV_header_t;
-#pragma pack()
-
-
-#ifdef __CPLUSPLUS
-}
-#endif
-
-#endif /*_OALB_INTERFACE_TYPES_H*/
diff --git a/misc/libopenalbridge/tester.c b/misc/libopenalbridge/tester.c
deleted file mode 100644
index 9fbb788..0000000
--- a/misc/libopenalbridge/tester.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-#include "openalbridge.h"
-
-int main (int argc, int **argv) {
-
- openal_init();
-
- openal_close();
-
- return 0;
-}
diff --git a/misc/libopenalbridge/wrappers.c b/misc/libopenalbridge/wrappers.c
deleted file mode 100644
index 9b6a21c..0000000
--- a/misc/libopenalbridge/wrappers.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-* OpenAL Bridge - a simple portable library for OpenAL interface
-* Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser 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 "wrappers.h"
-#include "openalbridge_t.h"
-
-
-void *Malloc (size_t nbytes) {
- void *aptr;
-
- if ((aptr = malloc(nbytes)) == NULL) {
- fprintf(stderr,"(Bridge FATAL) - not enough memory\n");
- abort();
- }
-
- return aptr;
-}
-
-
-void *Realloc (void *aptr, size_t nbytes) {
- aptr = realloc(aptr, nbytes);
-
- if (aptr == NULL) {
- fprintf(stderr,"(Bridge FATAL) - not enough memory\n");
- abort();
- }
-
- return aptr;
-}
-
-
-FILE *Fopen (const char *fname, char *mode) {
- FILE *fp;
-
- fp = fopen(fname,mode);
- if (fp == NULL)
- fprintf(stderr,"(Bridge Error) - can't open file %s in mode '%s'\n", fname, mode);
-
- return fp;
-}
-
-
-al_sound_t new_sound_el (void) {
- al_sound_t sound;
-
- sound.filename = NULL;
- sound.buffer = -1;
- sound.source_index = -1;
- sound.is_used = AL_FALSE;
-
- return sound;
-}
-
-al_sound_t init_sound_el (const char *str) {
- al_sound_t sound;
-
- sound.filename = str;
- sound.source_index = -1;
- sound.is_used = AL_TRUE;
- alGenBuffers(1, &sound.buffer);
-
- return sound;
-}
diff --git a/misc/libopenalbridge/wrappers.h b/misc/libopenalbridge/wrappers.h
deleted file mode 100644
index ab122d5..0000000
--- a/misc/libopenalbridge/wrappers.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * OpenAL Bridge - a simple portable library for OpenAL interface
- * Copyright (c) 2009 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#ifndef _OALB_WRAPPERS_H
-#define _OALB_WRAPPERS_H
-
-#include "globals.h"
-#include "openalbridge_t.h"
-
-void *Malloc (size_t nbytes);
-void *Realloc (void *aptr, size_t nbytes);
-FILE *Fopen (const char *fname, char *mode);
-void helper_fade (void *tmp);
-al_sound_t new_sound_el (void);
-al_sound_t init_sound_el (const char *str);
-
-#endif /*_OALB_WRAPPERS_H*/
diff --git a/misc/libphysfs/Android.mk b/misc/libphysfs/Android.mk
new file mode 100644
index 0000000..cb82f55
--- /dev/null
+++ b/misc/libphysfs/Android.mk
@@ -0,0 +1,27 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := physfs
+
+LOCAL_CFLAGS := -O2 -DPHYSFS_NO_CDROM_SUPPORT
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+
+LOCAL_SRC_FILES := physfs.c \
+ physfs_byteorder.c \
+ physfs_unicode.c \
+ platform_posix.c \
+ platform_unix.c \
+ platform_macosx.c \
+ platform_windows.c \
+ archiver_dir.c \
+ archiver_grp.c \
+ archiver_hog.c \
+ archiver_lzma.c \
+ archiver_mvl.c \
+ archiver_qpak.c \
+ archiver_wad.c \
+ archiver_zip.c \
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/misc/libphysfs/CMakeLists.txt b/misc/libphysfs/CMakeLists.txt
new file mode 100644
index 0000000..5130b5b
--- /dev/null
+++ b/misc/libphysfs/CMakeLists.txt
@@ -0,0 +1,290 @@
+# PhysicsFS; a portable, flexible file i/o abstraction.
+# Copyright (C) 2007 Ryan C. Gordon.
+#
+# Please see the file LICENSE.txt in the source's root directory.
+
+## lines starting with '##' are lines overridden/modified/added by Hedgewars configuration
+##CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
+##PROJECT(PhysicsFS)
+set(PHYSFS_VERSION 2.1.0)
+
+# Increment this if/when we break backwards compatibility.
+set(PHYSFS_SOVERSION 1)
+
+# I hate that they define "WIN32" ... we're about to move to Win64...I hope!
+if(WIN32 AND NOT WINDOWS)
+ set(WINDOWS TRUE)
+endif(WIN32 AND NOT WINDOWS)
+
+# Bleh, let's do it for "APPLE" too.
+if(APPLE AND NOT MACOSX)
+ set(MACOSX TRUE)
+endif(APPLE AND NOT MACOSX)
+
+# For now, Haiku and BeOS are the same, as far as the build system cares.
+if(HAIKU AND NOT BEOS)
+ set(BEOS TRUE)
+endif(HAIKU AND NOT BEOS)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set(SOLARIS TRUE)
+endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+
+include(CheckIncludeFile)
+include(CheckLibraryExists)
+include(CheckCSourceCompiles)
+
+
+if(MACOSX)
+ # Fallback to older OS X on PowerPC to support wider range of systems...
+ if(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
+ add_definitions(-DMAC_OS_X_VERSION_MIN_REQUIRED=1020)
+ set(OTHER_LDFLAGS ${OTHER_LDFLAGS} " -mmacosx-version-min=10.2")
+ endif(CMAKE_OSX_ARCHITECTURES MATCHES ppc)
+
+ # Need these everywhere...
+ add_definitions(-fno-common)
+ find_library(iokit_framework NAMES IOKit)
+ list(APPEND OTHER_LDFLAGS ${iokit_framework})
+endif(MACOSX)
+
+# Add some gcc-specific command lines.
+if(CMAKE_COMPILER_IS_GNUCC)
+ # Always build with debug symbols...you can strip it later.
+ add_definitions(-g -pipe -Werror -fsigned-char)
+
+ # Stupid BeOS generates warnings in the system headers.
+ if(NOT BEOS)
+ add_definitions(-Wall)
+ endif(NOT BEOS)
+
+ CHECK_C_SOURCE_COMPILES("
+ #if ((defined(__GNUC__)) && (__GNUC__ >= 4))
+ int main(int argc, char **argv) { int is_gcc4 = 1; return 0; }
+ #else
+ #error This is not gcc4.
+ #endif
+ " PHYSFS_IS_GCC4)
+
+ if(PHYSFS_IS_GCC4)
+ # Not supported on several operating systems at this time.
+ if(NOT SOLARIS AND NOT WINDOWS)
+ add_definitions(-fvisibility=hidden)
+ endif(NOT SOLARIS AND NOT WINDOWS)
+ endif(PHYSFS_IS_GCC4)
+
+ # Don't use -rpath.
+ set(CMAKE_SKIP_RPATH ON CACHE BOOL "Skip RPATH" FORCE)
+endif(CMAKE_COMPILER_IS_GNUCC)
+
+if(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
+ add_definitions(-erroff=E_EMPTY_TRANSLATION_UNIT)
+ add_definitions(-xldscope=hidden)
+endif(CMAKE_C_COMPILER_ID STREQUAL "SunPro")
+
+if(MSVC)
+ # VS.NET 8.0 got really really anal about strcpy, etc, which even if we
+ # cleaned up our code, zlib, etc still use...so disable the warning.
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
+endif(MSVC)
+
+
+if(BEOS)
+ # We add this explicitly, since we don't want CMake to think this
+ # is a C++ project unless we're on BeOS.
+ set(PHYSFS_BEOS_SRCS src/platform_beos.cpp)
+ find_library(BE_LIBRARY be)
+ find_library(ROOT_LIBRARY root)
+ set(optional_library_libs ${optional_library_libs} ${BE_LIBRARY} ${ROOT_LIBRARY})
+endif(BEOS)
+
+
+# Almost everything is "compiled" here, but things that don't apply to the
+# build are #ifdef'd out. This is to make it easy to embed PhysicsFS into
+# another project or bring up a new build system: just compile all the source
+# code and #define the things you want.
+set(PHYSFS_SRCS
+ physfs.c
+ physfs_byteorder.c
+ physfs_unicode.c
+ platform_posix.c
+ platform_unix.c
+ platform_macosx.c
+ platform_windows.c
+ archiver_dir.c
+ archiver_unpacked.c
+ archiver_grp.c
+ archiver_hog.c
+ archiver_lzma.c
+ archiver_mvl.c
+ archiver_qpak.c
+ archiver_wad.c
+ archiver_zip.c
+ archiver_iso9660.c
+ ${PHYSFS_BEOS_SRCS}
+)
+
+
+# platform layers ...
+
+if(UNIX)
+ if(BEOS)
+ set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
+ set(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
+ set(HAVE_PTHREAD_H TRUE)
+ else(BEOS)
+ CHECK_INCLUDE_FILE(sys/ucred.h HAVE_UCRED_H)
+ if(HAVE_UCRED_H)
+ add_definitions(-DPHYSFS_HAVE_SYS_UCRED_H=1)
+ set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
+ endif(HAVE_UCRED_H)
+
+ CHECK_INCLUDE_FILE(mntent.h HAVE_MNTENT_H)
+ if(HAVE_MNTENT_H)
+ add_definitions(-DPHYSFS_HAVE_MNTENT_H=1)
+ set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
+ endif(HAVE_MNTENT_H)
+
+ # !!! FIXME: Solaris fails this, because mnttab.h implicitly
+ # !!! FIXME: depends on other system headers. :(
+ #CHECK_INCLUDE_FILE(sys/mnttab.h HAVE_SYS_MNTTAB_H)
+ CHECK_C_SOURCE_COMPILES("
+ #include <stdio.h>
+ #include <sys/mnttab.h>
+ int main(int argc, char **argv) { return 0; }
+ " HAVE_SYS_MNTTAB_H)
+
+ if(HAVE_SYS_MNTTAB_H)
+ add_definitions(-DPHYSFS_HAVE_SYS_MNTTAB_H=1)
+ set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
+ endif(HAVE_SYS_MNTTAB_H)
+
+ CHECK_INCLUDE_FILE(pthread.h HAVE_PTHREAD_H)
+ if(HAVE_PTHREAD_H)
+ set(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
+ endif(HAVE_PTHREAD_H)
+ endif(BEOS)
+endif(UNIX)
+
+if(WINDOWS)
+ set(PHYSFS_HAVE_CDROM_SUPPORT TRUE)
+ set(PHYSFS_HAVE_THREAD_SUPPORT TRUE)
+endif(WINDOWS)
+
+if(NOT PHYSFS_HAVE_CDROM_SUPPORT)
+ add_definitions(-DPHYSFS_NO_CDROM_SUPPORT=1)
+ message(WARNING " ***")
+ message(WARNING " *** There is no CD-ROM support in this build!")
+ message(WARNING " *** PhysicsFS will just pretend there are no discs.")
+ message(WARNING " *** This may be fine, depending on how PhysicsFS is used,")
+ message(WARNING " *** but is this what you REALLY wanted?")
+ message(WARNING " *** (Maybe fix CMakeLists.txt, or write a platform driver?)")
+ message(WARNING " ***")
+endif(NOT PHYSFS_HAVE_CDROM_SUPPORT)
+
+if(PHYSFS_HAVE_THREAD_SUPPORT)
+ add_definitions(-D_REENTRANT -D_THREAD_SAFE)
+else(PHYSFS_HAVE_THREAD_SUPPORT)
+ add_definitions(-DPHYSFS_NO_THREAD_SUPPORT=1)
+ message(WARNING " ***")
+ message(WARNING " *** There is no thread support in this build!")
+ message(WARNING " *** PhysicsFS will NOT be reentrant!")
+ message(WARNING " *** This may be fine, depending on how PhysicsFS is used,")
+ message(WARNING " *** but is this what you REALLY wanted?")
+ message(WARNING " *** (Maybe fix CMakeLists.txt, or write a platform driver?)")
+ message(WARNING " ***")
+endif(PHYSFS_HAVE_THREAD_SUPPORT)
+
+
+# Archivers ...
+
+option(PHYSFS_ARCHIVE_ZIP "Enable ZIP support" TRUE)
+if(PHYSFS_ARCHIVE_ZIP)
+ add_definitions(-DPHYSFS_SUPPORTS_ZIP=1)
+ set(PHYSFS_FEATURES "ZIP")
+endif(PHYSFS_ARCHIVE_ZIP)
+
+#option(PHYSFS_ARCHIVE_GRP "Enable Build Engine GRP support" TRUE)
+#if(PHYSFS_ARCHIVE_GRP)
+# add_definitions(-DPHYSFS_SUPPORTS_GRP=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} GRP")
+#endif(PHYSFS_ARCHIVE_GRP)
+
+#option(PHYSFS_ARCHIVE_WAD "Enable Doom WAD support" TRUE)
+#if(PHYSFS_ARCHIVE_WAD)
+# add_definitions(-DPHYSFS_SUPPORTS_WAD=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} WAD")
+#endif(PHYSFS_ARCHIVE_WAD)
+
+#option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
+#if(PHYSFS_ARCHIVE_HOG)
+# add_definitions(-DPHYSFS_SUPPORTS_HOG=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} HOG")
+#endif(PHYSFS_ARCHIVE_HOG)
+
+#option(PHYSFS_ARCHIVE_MVL "Enable Descent I/II MVL support" TRUE)
+#if(PHYSFS_ARCHIVE_MVL)
+# add_definitions(-DPHYSFS_SUPPORTS_MVL=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} MVL")
+#endif(PHYSFS_ARCHIVE_MVL)
+
+#option(PHYSFS_ARCHIVE_QPAK "Enable Quake I/II QPAK support" TRUE)
+#if(PHYSFS_ARCHIVE_QPAK)
+# add_definitions(-DPHYSFS_SUPPORTS_QPAK=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} QPAK")
+#endif(PHYSFS_ARCHIVE_QPAK)
+
+#option(PHYSFS_ARCHIVE_ISO9660 "Enable ISO9660 support" TRUE)
+#if(PHYSFS_ARCHIVE_ISO9660)
+# add_definitions(-DPHYSFS_SUPPORTS_ISO9660=1)
+# set(PHYSFS_FEATURES "${PHYSFS_FEATURES} CD-ROM")
+#endif(PHYSFS_ARCHIVE_ISO9660)
+
+
+##as needed by Hedgewars configuration
+if(WINDOWS)
+ option(PHYSFS_BUILD_STATIC "Build static library" FALSE)
+ option(PHYSFS_BUILD_SHARED "Build shared library" TRUE)
+ list(APPEND OTHER_LDFLAGS ${SDL_LIBRARY})
+else(WINDOWS)
+ option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
+ option(PHYSFS_BUILD_SHARED "Build shared library" FALSE)
+endif(WINDOWS)
+
+if(PHYSFS_BUILD_STATIC)
+ add_library(physfs STATIC ${PHYSFS_SRCS})
+ set_target_properties(physfs PROPERTIES OUTPUT_NAME ${physfs_output_name}) ##
+ set(lib_prefix ${CMAKE_STATIC_LIBRARY_PREFIX}) ##
+ set(lib_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX}) ##
+endif(PHYSFS_BUILD_STATIC)
+
+if(PHYSFS_BUILD_SHARED)
+ add_library(physfs SHARED ${PHYSFS_SRCS})
+ set_target_properties(physfs PROPERTIES VERSION ${PHYSFS_VERSION})
+ set_target_properties(physfs PROPERTIES SOVERSION ${PHYSFS_SOVERSION})
+ set_target_properties(physfs PROPERTIES OUTPUT_NAME ${physfs_output_name}) ##
+ target_link_libraries(physfs ${optional_library_libs} ${OTHER_LDFLAGS})
+ install(TARGETS physfs RUNTIME DESTINATION ${target_library_install_dir}) ##
+ set(lib_prefix ${CMAKE_SHARED_LIBRARY_PREFIX}) ##
+ set(lib_suffix ${CMAKE_SHARED_LIBRARY_SUFFIX}) ##
+endif(PHYSFS_BUILD_SHARED)
+
+if(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
+ message(FATAL "Both shared and static libraries are disabled!")
+endif(NOT PHYSFS_BUILD_SHARED AND NOT PHYSFS_BUILD_STATIC)
+
+# CMake FAQ says I need this...
+if(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
+ set_target_properties(physfs PROPERTIES CLEAN_DIRECT_OUTPUT 1)
+endif(PHYSFS_BUILD_SHARED AND PHYSFS_BUILD_STATIC)
+
+## added standard variables emulating the FindPhysFS.cmake ones (FORCE or cmake won't pick 'em)
+set(PHYSFS_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/misc/libphysfs/ CACHE STRING "" FORCE)
+set(PHYSFS_LIBRARY ${LIBRARY_OUTPUT_PATH}/${lib_prefix}${physfs_output_name}${lib_suffix} CACHE STRING "" FORCE)
+
+
+## removed install, language bindings and test program
+## simplified configuration output
+
+#message(STATUS "PhysFS will be built with ${PHYSFS_FEATURES} support")
+
diff --git a/misc/libphysfs/Xcode/Physfs.xcodeproj/project.pbxproj b/misc/libphysfs/Xcode/Physfs.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5f97bdf
--- /dev/null
+++ b/misc/libphysfs/Xcode/Physfs.xcodeproj/project.pbxproj
@@ -0,0 +1,326 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 617D78F916D932900091D4D6 /* archiver_dir.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78E816D932900091D4D6 /* archiver_dir.c */; };
+ 617D78FA16D932900091D4D6 /* archiver_grp.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78E916D932900091D4D6 /* archiver_grp.c */; };
+ 617D78FB16D932900091D4D6 /* archiver_hog.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78EA16D932900091D4D6 /* archiver_hog.c */; };
+ 617D78FC16D932900091D4D6 /* archiver_iso9660.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78EB16D932900091D4D6 /* archiver_iso9660.c */; };
+ 617D78FD16D932900091D4D6 /* archiver_lzma.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78EC16D932900091D4D6 /* archiver_lzma.c */; };
+ 617D78FE16D932900091D4D6 /* archiver_mvl.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78ED16D932900091D4D6 /* archiver_mvl.c */; };
+ 617D78FF16D932900091D4D6 /* archiver_qpak.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78EE16D932900091D4D6 /* archiver_qpak.c */; };
+ 617D790016D932900091D4D6 /* archiver_unpacked.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78EF16D932900091D4D6 /* archiver_unpacked.c */; };
+ 617D790116D932900091D4D6 /* archiver_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F016D932900091D4D6 /* archiver_wad.c */; };
+ 617D790216D932900091D4D6 /* archiver_zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F116D932900091D4D6 /* archiver_zip.c */; };
+ 617D790316D932900091D4D6 /* physfs_byteorder.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F216D932900091D4D6 /* physfs_byteorder.c */; };
+ 617D790416D932900091D4D6 /* physfs_unicode.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F316D932900091D4D6 /* physfs_unicode.c */; };
+ 617D790516D932900091D4D6 /* physfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F416D932900091D4D6 /* physfs.c */; };
+ 617D790616D932900091D4D6 /* platform_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F516D932900091D4D6 /* platform_macosx.c */; };
+ 617D790716D932900091D4D6 /* platform_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F616D932900091D4D6 /* platform_posix.c */; };
+ 617D790816D932900091D4D6 /* platform_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F716D932900091D4D6 /* platform_unix.c */; };
+ 617D790916D932900091D4D6 /* platform_windows.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D78F816D932900091D4D6 /* platform_windows.c */; };
+ 617D790F16D932BC0091D4D6 /* physfs_casefolding.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D790A16D932BC0091D4D6 /* physfs_casefolding.h */; };
+ 617D791016D932BC0091D4D6 /* physfs_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D790B16D932BC0091D4D6 /* physfs_internal.h */; };
+ 617D791116D932BC0091D4D6 /* physfs_miniz.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D790C16D932BC0091D4D6 /* physfs_miniz.h */; };
+ 617D791216D932BC0091D4D6 /* physfs_platforms.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D790D16D932BC0091D4D6 /* physfs_platforms.h */; };
+ 617D791316D932BC0091D4D6 /* physfs.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D790E16D932BC0091D4D6 /* physfs.h */; };
+ AA747D9F0F9514B9006C5449 /* Physfs_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Physfs_Prefix.pch */; };
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 617D78E716D932600091D4D6 /* libPhysfs.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPhysfs.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 617D78E816D932900091D4D6 /* archiver_dir.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_dir.c; path = ../archiver_dir.c; sourceTree = SOURCE_ROOT; };
+ 617D78E916D932900091D4D6 /* archiver_grp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_grp.c; path = ../archiver_grp.c; sourceTree = SOURCE_ROOT; };
+ 617D78EA16D932900091D4D6 /* archiver_hog.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_hog.c; path = ../archiver_hog.c; sourceTree = SOURCE_ROOT; };
+ 617D78EB16D932900091D4D6 /* archiver_iso9660.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_iso9660.c; path = ../archiver_iso9660.c; sourceTree = SOURCE_ROOT; };
+ 617D78EC16D932900091D4D6 /* archiver_lzma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_lzma.c; path = ../archiver_lzma.c; sourceTree = SOURCE_ROOT; };
+ 617D78ED16D932900091D4D6 /* archiver_mvl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_mvl.c; path = ../archiver_mvl.c; sourceTree = SOURCE_ROOT; };
+ 617D78EE16D932900091D4D6 /* archiver_qpak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_qpak.c; path = ../archiver_qpak.c; sourceTree = SOURCE_ROOT; };
+ 617D78EF16D932900091D4D6 /* archiver_unpacked.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_unpacked.c; path = ../archiver_unpacked.c; sourceTree = SOURCE_ROOT; };
+ 617D78F016D932900091D4D6 /* archiver_wad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_wad.c; path = ../archiver_wad.c; sourceTree = SOURCE_ROOT; };
+ 617D78F116D932900091D4D6 /* archiver_zip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = archiver_zip.c; path = ../archiver_zip.c; sourceTree = SOURCE_ROOT; };
+ 617D78F216D932900091D4D6 /* physfs_byteorder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = physfs_byteorder.c; path = ../physfs_byteorder.c; sourceTree = SOURCE_ROOT; };
+ 617D78F316D932900091D4D6 /* physfs_unicode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = physfs_unicode.c; path = ../physfs_unicode.c; sourceTree = SOURCE_ROOT; };
+ 617D78F416D932900091D4D6 /* physfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = physfs.c; path = ../physfs.c; sourceTree = SOURCE_ROOT; };
+ 617D78F516D932900091D4D6 /* platform_macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = platform_macosx.c; path = ../platform_macosx.c; sourceTree = SOURCE_ROOT; };
+ 617D78F616D932900091D4D6 /* platform_posix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = platform_posix.c; path = ../platform_posix.c; sourceTree = SOURCE_ROOT; };
+ 617D78F716D932900091D4D6 /* platform_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = platform_unix.c; path = ../platform_unix.c; sourceTree = SOURCE_ROOT; };
+ 617D78F816D932900091D4D6 /* platform_windows.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = platform_windows.c; path = ../platform_windows.c; sourceTree = SOURCE_ROOT; };
+ 617D790A16D932BC0091D4D6 /* physfs_casefolding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfs_casefolding.h; path = ../physfs_casefolding.h; sourceTree = SOURCE_ROOT; };
+ 617D790B16D932BC0091D4D6 /* physfs_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfs_internal.h; path = ../physfs_internal.h; sourceTree = SOURCE_ROOT; };
+ 617D790C16D932BC0091D4D6 /* physfs_miniz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfs_miniz.h; path = ../physfs_miniz.h; sourceTree = SOURCE_ROOT; };
+ 617D790D16D932BC0091D4D6 /* physfs_platforms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfs_platforms.h; path = ../physfs_platforms.h; sourceTree = SOURCE_ROOT; };
+ 617D790E16D932BC0091D4D6 /* physfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfs.h; path = ../physfs.h; sourceTree = SOURCE_ROOT; };
+ AA747D9E0F9514B9006C5449 /* Physfs_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Physfs_Prefix.pch; sourceTree = SOURCE_ROOT; };
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D2AAC07C0554694100DB518D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DFFF38A50411DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 617D78E716D932600091D4D6 /* libPhysfs.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* Physfs */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AEFE84172EC02AAC07 /* Sources */,
+ 32C88DFF0371C24200C91783 /* Other Sources */,
+ 0867D69AFE84028FC02AAC07 /* Frameworks */,
+ 034768DFFF38A50411DB9C8B /* Products */,
+ );
+ name = Physfs;
+ sourceTree = "<group>";
+ };
+ 0867D69AFE84028FC02AAC07 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 08FB77AEFE84172EC02AAC07 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 617D790A16D932BC0091D4D6 /* physfs_casefolding.h */,
+ 617D790B16D932BC0091D4D6 /* physfs_internal.h */,
+ 617D790C16D932BC0091D4D6 /* physfs_miniz.h */,
+ 617D790D16D932BC0091D4D6 /* physfs_platforms.h */,
+ 617D790E16D932BC0091D4D6 /* physfs.h */,
+ 617D78E816D932900091D4D6 /* archiver_dir.c */,
+ 617D78E916D932900091D4D6 /* archiver_grp.c */,
+ 617D78EA16D932900091D4D6 /* archiver_hog.c */,
+ 617D78EB16D932900091D4D6 /* archiver_iso9660.c */,
+ 617D78EC16D932900091D4D6 /* archiver_lzma.c */,
+ 617D78ED16D932900091D4D6 /* archiver_mvl.c */,
+ 617D78EE16D932900091D4D6 /* archiver_qpak.c */,
+ 617D78EF16D932900091D4D6 /* archiver_unpacked.c */,
+ 617D78F016D932900091D4D6 /* archiver_wad.c */,
+ 617D78F116D932900091D4D6 /* archiver_zip.c */,
+ 617D78F216D932900091D4D6 /* physfs_byteorder.c */,
+ 617D78F316D932900091D4D6 /* physfs_unicode.c */,
+ 617D78F416D932900091D4D6 /* physfs.c */,
+ 617D78F516D932900091D4D6 /* platform_macosx.c */,
+ 617D78F616D932900091D4D6 /* platform_posix.c */,
+ 617D78F716D932900091D4D6 /* platform_unix.c */,
+ 617D78F816D932900091D4D6 /* platform_windows.c */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 32C88DFF0371C24200C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ AA747D9E0F9514B9006C5449 /* Physfs_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC07A0554694100DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AA747D9F0F9514B9006C5449 /* Physfs_Prefix.pch in Headers */,
+ 617D790F16D932BC0091D4D6 /* physfs_casefolding.h in Headers */,
+ 617D791016D932BC0091D4D6 /* physfs_internal.h in Headers */,
+ 617D791116D932BC0091D4D6 /* physfs_miniz.h in Headers */,
+ 617D791216D932BC0091D4D6 /* physfs_platforms.h in Headers */,
+ 617D791316D932BC0091D4D6 /* physfs.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC07D0554694100DB518D /* Physfs */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Physfs" */;
+ buildPhases = (
+ D2AAC07A0554694100DB518D /* Headers */,
+ D2AAC07B0554694100DB518D /* Sources */,
+ D2AAC07C0554694100DB518D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Physfs;
+ productName = Physfs;
+ productReference = 617D78E716D932600091D4D6 /* libPhysfs.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physfs" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 0867D691FE84028FC02AAC07 /* Physfs */;
+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D2AAC07D0554694100DB518D /* Physfs */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC07B0554694100DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 617D78F916D932900091D4D6 /* archiver_dir.c in Sources */,
+ 617D78FA16D932900091D4D6 /* archiver_grp.c in Sources */,
+ 617D78FB16D932900091D4D6 /* archiver_hog.c in Sources */,
+ 617D78FC16D932900091D4D6 /* archiver_iso9660.c in Sources */,
+ 617D78FD16D932900091D4D6 /* archiver_lzma.c in Sources */,
+ 617D78FE16D932900091D4D6 /* archiver_mvl.c in Sources */,
+ 617D78FF16D932900091D4D6 /* archiver_qpak.c in Sources */,
+ 617D790016D932900091D4D6 /* archiver_unpacked.c in Sources */,
+ 617D790116D932900091D4D6 /* archiver_wad.c in Sources */,
+ 617D790216D932900091D4D6 /* archiver_zip.c in Sources */,
+ 617D790316D932900091D4D6 /* physfs_byteorder.c in Sources */,
+ 617D790416D932900091D4D6 /* physfs_unicode.c in Sources */,
+ 617D790516D932900091D4D6 /* physfs.c in Sources */,
+ 617D790616D932900091D4D6 /* platform_macosx.c in Sources */,
+ 617D790716D932900091D4D6 /* platform_posix.c in Sources */,
+ 617D790816D932900091D4D6 /* platform_unix.c in Sources */,
+ 617D790916D932900091D4D6 /* platform_windows.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB921F08733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = NO;
+ DSTROOT = /tmp/Physfs.dst;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Physfs_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Physfs;
+ };
+ name = Debug;
+ };
+ 1DEB922008733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ DSTROOT = /tmp/Physfs.dst;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Physfs_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Physfs;
+ };
+ name = Release;
+ };
+ 1DEB922308733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../liblua\"",
+ "\"$(SRCROOT)/../../../../Library/SDL/include\"",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 1DEB922408733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_PREPROCESSOR_DEFINITIONS = "";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../liblua\"",
+ "\"$(SRCROOT)/../../../../Library/SDL/include\"",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Physfs" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB921F08733DC00010E9CD /* Debug */,
+ 1DEB922008733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physfs" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB922308733DC00010E9CD /* Debug */,
+ 1DEB922408733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch b/misc/libphysfs/Xcode/Physfs_Prefix.pch
similarity index 100%
copy from misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch
copy to misc/libphysfs/Xcode/Physfs_Prefix.pch
diff --git a/misc/libphysfs/archiver_dir.c b/misc/libphysfs/archiver_dir.c
new file mode 100644
index 0000000..4fe74b3
--- /dev/null
+++ b/misc/libphysfs/archiver_dir.c
@@ -0,0 +1,201 @@
+/*
+ * Standard directory I/O support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+/* There's no PHYSFS_Io interface here. Use __PHYSFS_createNativeIo(). */
+
+
+
+static char *cvtToDependent(const char *prepend, const char *path, char *buf)
+{
+ BAIL_IF_MACRO(buf == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ sprintf(buf, "%s%s", prepend ? prepend : "", path);
+
+ if (__PHYSFS_platformDirSeparator != '/')
+ {
+ char *p;
+ for (p = strchr(buf, '/'); p != NULL; p = strchr(p + 1, '/'))
+ *p = __PHYSFS_platformDirSeparator;
+ } /* if */
+
+ return buf;
+} /* cvtToDependent */
+
+
+#define CVT_TO_DEPENDENT(buf, pre, dir) { \
+ const size_t len = ((pre) ? strlen((char *) pre) : 0) + strlen(dir) + 1; \
+ buf = cvtToDependent((char*)pre,dir,(char*)__PHYSFS_smallAlloc(len)); \
+}
+
+
+
+static void *DIR_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_Stat st;
+ const char dirsep = __PHYSFS_platformDirSeparator;
+ char *retval = NULL;
+ const size_t namelen = strlen(name);
+ const size_t seplen = 1;
+ int exists = 0;
+
+ assert(io == NULL); /* shouldn't create an Io for these. */
+ BAIL_IF_MACRO(!__PHYSFS_platformStat(name, &exists, &st), ERRPASS, NULL);
+ if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ retval = allocator.Malloc(namelen + seplen + 1);
+ BAIL_IF_MACRO(retval == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ strcpy(retval, name);
+
+ /* make sure there's a dir separator at the end of the string */
+ if (retval[namelen - 1] != dirsep)
+ {
+ retval[namelen] = dirsep;
+ retval[namelen + 1] = '\0';
+ } /* if */
+
+ return retval;
+} /* DIR_openArchive */
+
+
+static void DIR_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata)
+{
+ char *d;
+
+ CVT_TO_DEPENDENT(d, opaque, dname);
+ if (d != NULL)
+ {
+ __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
+ origdir, callbackdata);
+ __PHYSFS_smallFree(d);
+ } /* if */
+} /* DIR_enumerateFiles */
+
+
+static PHYSFS_Io *doOpen(PHYSFS_Dir *opaque, const char *name,
+ const int mode, int *fileExists)
+{
+ char *f;
+ PHYSFS_Io *io = NULL;
+ int existtmp = 0;
+
+ CVT_TO_DEPENDENT(f, opaque, name);
+ BAIL_IF_MACRO(!f, ERRPASS, NULL);
+
+ if (fileExists == NULL)
+ fileExists = &existtmp;
+
+ io = __PHYSFS_createNativeIo(f, mode);
+ if (io == NULL)
+ {
+ const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
+ PHYSFS_Stat statbuf;
+ __PHYSFS_platformStat(f, fileExists, &statbuf);
+ __PHYSFS_setError(err);
+ } /* if */
+ else
+ {
+ *fileExists = 1;
+ } /* else */
+
+ __PHYSFS_smallFree(f);
+
+ return io;
+} /* doOpen */
+
+
+static PHYSFS_Io *DIR_openRead(PHYSFS_Dir *opaque, const char *fnm, int *exist)
+{
+ return doOpen(opaque, fnm, 'r', exist);
+} /* DIR_openRead */
+
+
+static PHYSFS_Io *DIR_openWrite(PHYSFS_Dir *opaque, const char *filename)
+{
+ return doOpen(opaque, filename, 'w', NULL);
+} /* DIR_openWrite */
+
+
+static PHYSFS_Io *DIR_openAppend(PHYSFS_Dir *opaque, const char *filename)
+{
+ return doOpen(opaque, filename, 'a', NULL);
+} /* DIR_openAppend */
+
+
+static int DIR_remove(PHYSFS_Dir *opaque, const char *name)
+{
+ int retval;
+ char *f;
+
+ CVT_TO_DEPENDENT(f, opaque, name);
+ BAIL_IF_MACRO(!f, ERRPASS, 0);
+ retval = __PHYSFS_platformDelete(f);
+ __PHYSFS_smallFree(f);
+ return retval;
+} /* DIR_remove */
+
+
+static int DIR_mkdir(PHYSFS_Dir *opaque, const char *name)
+{
+ int retval;
+ char *f;
+
+ CVT_TO_DEPENDENT(f, opaque, name);
+ BAIL_IF_MACRO(!f, ERRPASS, 0);
+ retval = __PHYSFS_platformMkDir(f);
+ __PHYSFS_smallFree(f);
+ return retval;
+} /* DIR_mkdir */
+
+
+static void DIR_closeArchive(PHYSFS_Dir *opaque)
+{
+ allocator.Free(opaque);
+} /* DIR_closeArchive */
+
+
+static int DIR_stat(PHYSFS_Dir *opaque, const char *name,
+ int *exists, PHYSFS_Stat *stat)
+{
+ int retval = 0;
+ char *d;
+
+ CVT_TO_DEPENDENT(d, opaque, name);
+ BAIL_IF_MACRO(!d, ERRPASS, 0);
+ retval = __PHYSFS_platformStat(d, exists, stat);
+ __PHYSFS_smallFree(d);
+ return retval;
+} /* DIR_stat */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
+{
+ {
+ "",
+ "Non-archive, direct filesystem I/O",
+ "Ryan C. Gordon <icculus at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ DIR_openArchive, /* openArchive() method */
+ DIR_enumerateFiles, /* enumerateFiles() method */
+ DIR_openRead, /* openRead() method */
+ DIR_openWrite, /* openWrite() method */
+ DIR_openAppend, /* openAppend() method */
+ DIR_remove, /* remove() method */
+ DIR_mkdir, /* mkdir() method */
+ DIR_closeArchive, /* closeArchive() method */
+ DIR_stat /* stat() method */
+};
+
+/* end of dir.c ... */
+
diff --git a/misc/libphysfs/archiver_grp.c b/misc/libphysfs/archiver_grp.c
new file mode 100644
index 0000000..63199d5
--- /dev/null
+++ b/misc/libphysfs/archiver_grp.c
@@ -0,0 +1,110 @@
+/*
+ * GRP support routines for PhysicsFS.
+ *
+ * This driver handles BUILD engine archives ("groupfiles"). This format
+ * (but not this driver) was put together by Ken Silverman.
+ *
+ * The format is simple enough. In Ken's words:
+ *
+ * What's the .GRP file format?
+ *
+ * The ".grp" file format is just a collection of a lot of files stored
+ * into 1 big one. I tried to make the format as simple as possible: The
+ * first 12 bytes contains my name, "KenSilverman". The next 4 bytes is
+ * the number of files that were compacted into the group file. Then for
+ * each file, there is a 16 byte structure, where the first 12 bytes are
+ * the filename, and the last 4 bytes are the file's size. The rest of
+ * the group file is just the raw data packed one after the other in the
+ * same order as the list of files.
+ *
+ * (That info is from http://www.advsys.net/ken/build.htm ...)
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_GRP
+
+static UNPKentry *grpLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
+{
+ PHYSFS_uint32 location = 16; /* sizeof sig. */
+ UNPKentry *entries = NULL;
+ UNPKentry *entry = NULL;
+ char *ptr = NULL;
+
+ entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
+ BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ location += (16 * fileCount);
+
+ for (entry = entries; fileCount > 0; fileCount--, entry++)
+ {
+ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->name, 12), ERRPASS, failed);
+ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->size, 4), ERRPASS, failed);
+ entry->name[12] = '\0'; /* name isn't null-terminated in file. */
+ if ((ptr = strchr(entry->name, ' ')) != NULL)
+ *ptr = '\0'; /* trim extra spaces. */
+
+ entry->size = PHYSFS_swapULE32(entry->size);
+ entry->startPos = location;
+ location += entry->size;
+ } /* for */
+
+ return entries;
+
+failed:
+ allocator.Free(entries);
+ return NULL;
+} /* grpLoadEntries */
+
+
+static void *GRP_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_uint8 buf[12];
+ PHYSFS_uint32 count = 0;
+ UNPKentry *entries = NULL;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, sizeof (buf)), ERRPASS, NULL);
+ if (memcmp(buf, "KenSilverman", sizeof (buf)) != 0)
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof(count)), ERRPASS, NULL);
+ count = PHYSFS_swapULE32(count);
+
+ entries = grpLoadEntries(io, count);
+ BAIL_IF_MACRO(!entries, ERRPASS, NULL);
+ return UNPK_openArchive(io, entries, count);
+} /* GRP_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
+{
+ {
+ "GRP",
+ "Build engine Groupfile format",
+ "Ryan C. Gordon <icculus at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ GRP_openArchive, /* openArchive() method */
+ UNPK_enumerateFiles, /* enumerateFiles() method */
+ UNPK_openRead, /* openRead() method */
+ UNPK_openWrite, /* openWrite() method */
+ UNPK_openAppend, /* openAppend() method */
+ UNPK_remove, /* remove() method */
+ UNPK_mkdir, /* mkdir() method */
+ UNPK_closeArchive, /* closeArchive() method */
+ UNPK_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_GRP */
+
+/* end of grp.c ... */
+
diff --git a/misc/libphysfs/archiver_hog.c b/misc/libphysfs/archiver_hog.c
new file mode 100644
index 0000000..aca9fd5
--- /dev/null
+++ b/misc/libphysfs/archiver_hog.c
@@ -0,0 +1,116 @@
+/*
+ * HOG support routines for PhysicsFS.
+ *
+ * This driver handles Descent I/II HOG archives.
+ *
+ * The format is very simple:
+ *
+ * The file always starts with the 3-byte signature "DHF" (Descent
+ * HOG file). After that the files of a HOG are just attached after
+ * another, divided by a 17 bytes header, which specifies the name
+ * and length (in bytes) of the forthcoming file! So you just read
+ * the header with its information of how big the following file is,
+ * and then skip exact that number of bytes to get to the next file
+ * in that HOG.
+ *
+ * char sig[3] = {'D', 'H', 'F'}; // "DHF"=Descent HOG File
+ *
+ * struct {
+ * char file_name[13]; // Filename, padded to 13 bytes with 0s
+ * int file_size; // filesize in bytes
+ * char data[file_size]; // The file data
+ * } FILE_STRUCT; // Repeated until the end of the file.
+ *
+ * (That info is from http://www.descent2.com/ddn/specs/hog/)
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Bradley Bell.
+ * Based on grp.c by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_HOG
+
+static UNPKentry *hogLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 *_entCount)
+{
+ const PHYSFS_uint64 iolen = io->length(io);
+ PHYSFS_uint32 entCount = 0;
+ void *ptr = NULL;
+ UNPKentry *entries = NULL;
+ UNPKentry *entry = NULL;
+ PHYSFS_uint32 size = 0;
+ PHYSFS_uint32 pos = 3;
+
+ while (pos < iolen)
+ {
+ entCount++;
+ ptr = allocator.Realloc(ptr, sizeof (UNPKentry) * entCount);
+ GOTO_IF_MACRO(ptr == NULL, PHYSFS_ERR_OUT_OF_MEMORY, failed);
+ entries = (UNPKentry *) ptr;
+ entry = &entries[entCount-1];
+
+ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->name, 13), ERRPASS, failed);
+ pos += 13;
+ GOTO_IF_MACRO(!__PHYSFS_readAll(io, &size, 4), ERRPASS, failed);
+ pos += 4;
+
+ entry->size = PHYSFS_swapULE32(size);
+ entry->startPos = pos;
+ pos += size;
+
+ /* skip over entry */
+ GOTO_IF_MACRO(!io->seek(io, pos), ERRPASS, failed);
+ } /* while */
+
+ *_entCount = entCount;
+ return entries;
+
+failed:
+ allocator.Free(entries);
+ return NULL;
+} /* hogLoadEntries */
+
+
+static void *HOG_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_uint8 buf[3];
+ PHYSFS_uint32 count = 0;
+ UNPKentry *entries = NULL;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, 3), ERRPASS, NULL);
+ BAIL_IF_MACRO(memcmp(buf, "DHF", 3) != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ entries = hogLoadEntries(io, &count);
+ BAIL_IF_MACRO(!entries, ERRPASS, NULL);
+ return UNPK_openArchive(io, entries, count);
+} /* HOG_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
+{
+ {
+ "HOG",
+ "Descent I/II HOG file format",
+ "Bradley Bell <btb at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ HOG_openArchive, /* openArchive() method */
+ UNPK_enumerateFiles, /* enumerateFiles() method */
+ UNPK_openRead, /* openRead() method */
+ UNPK_openWrite, /* openWrite() method */
+ UNPK_openAppend, /* openAppend() method */
+ UNPK_remove, /* remove() method */
+ UNPK_mkdir, /* mkdir() method */
+ UNPK_closeArchive, /* closeArchive() method */
+ UNPK_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_HOG */
+
+/* end of hog.c ... */
+
diff --git a/misc/libphysfs/archiver_iso9660.c b/misc/libphysfs/archiver_iso9660.c
new file mode 100644
index 0000000..9c832d1
--- /dev/null
+++ b/misc/libphysfs/archiver_iso9660.c
@@ -0,0 +1,969 @@
+/*
+ * ISO9660 support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Christoph Nelles.
+ */
+
+/* !!! FIXME: this file needs Ryanification. */
+
+/*
+ * Handles CD-ROM disk images (and raw CD-ROM devices).
+ *
+ * Not supported:
+ * - RockRidge
+ * - Non 2048 Sectors
+ * - UDF
+ *
+ * Deviations from the standard
+ * - Ignores mandatory sort order
+ * - Allows various invalid file names
+ *
+ * Problems
+ * - Ambiguities in the standard
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_ISO9660
+
+#include <time.h>
+
+/* cache files smaller than this completely in memory */
+#define ISO9660_FULLCACHEMAXSIZE 2048
+
+/* !!! FIXME: this is going to cause trouble. */
+#pragma pack(push) /* push current alignment to stack */
+#pragma pack(1) /* set alignment to 1 byte boundary */
+
+/* This is the format as defined by the standard
+typedef struct
+{
+ PHYSFS_uint32 lsb;
+ PHYSFS_uint32 msb;
+} ISOBB32bit; // 32byte Both Byte type, means the value first in LSB then in MSB
+
+typedef struct
+{
+ PHYSFS_uint16 lsb;
+ PHYSFS_uint16 msb;
+} ISOBB16bit; // 16byte Both Byte type, means the value first in LSB then in MSB
+*/
+
+/* define better ones to simplify coding (less if's) */
+#if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN
+#define ISOBB32bit(name) PHYSFS_uint32 name; PHYSFS_uint32 __dummy_##name;
+#define ISOBB16bit(name) PHYSFS_uint16 name; PHYSFS_uint16 __dummy_##name;
+#else
+#define ISOBB32bit(name) PHYSFS_uint32 __dummy_##name; PHYSFS_uint32 name;
+#define ISOBB16bit(name) PHYSFS_uint16 __dummy_##name; PHYSFS_uint16 name;
+#endif
+
+typedef struct
+{
+ char year[4];
+ char month[2];
+ char day[2];
+ char hour[2];
+ char minute[2];
+ char second[2];
+ char centisec[2];
+ PHYSFS_sint8 offset; /* in 15min from GMT */
+} ISO9660VolumeTimestamp;
+
+typedef struct
+{
+ PHYSFS_uint8 year;
+ PHYSFS_uint8 month;
+ PHYSFS_uint8 day;
+ PHYSFS_uint8 hour;
+ PHYSFS_uint8 minute;
+ PHYSFS_uint8 second;
+ PHYSFS_sint8 offset;
+} ISO9660FileTimestamp;
+
+typedef struct
+{
+ unsigned existence:1;
+ unsigned directory:1;
+ unsigned associated_file:1;
+ unsigned record:1;
+ unsigned protection:1;
+ unsigned reserved:2;
+ unsigned multiextent:1;
+} ISO9660FileFlags;
+
+typedef struct
+{
+ PHYSFS_uint8 length;
+ PHYSFS_uint8 attribute_length;
+ ISOBB32bit(extent_location)
+ ISOBB32bit(data_length)
+ ISO9660FileTimestamp timestamp;
+ ISO9660FileFlags file_flags;
+ PHYSFS_uint8 file_unit_size;
+ PHYSFS_uint8 gap_size;
+ ISOBB16bit(vol_seq_no)
+ PHYSFS_uint8 len_fi;
+ char unused;
+} ISO9660RootDirectoryRecord;
+
+/* this structure is combined for all Volume descriptor types */
+typedef struct
+{
+ PHYSFS_uint8 type;
+ char identifier[5];
+ PHYSFS_uint8 version;
+ PHYSFS_uint8 flags;
+ char system_identifier[32];
+ char volume_identifier[32];
+ char unused2[8];
+ ISOBB32bit(space_size)
+ PHYSFS_uint8 escape_sequences[32];
+ ISOBB16bit(vol_set_size)
+ ISOBB16bit(vol_seq_no)
+ ISOBB16bit(block_size)
+ ISOBB32bit(path_table_size)
+/* PHYSFS_uint32 path_table_start_lsb; // why didn't they use both byte type?
+ PHYSFS_uint32 opt_path_table_start_lsb;
+ PHYSFS_uint32 path_table_start_msb;
+ PHYSFS_uint32 opt_path_table_start_msb;*/
+#if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN
+ PHYSFS_uint32 path_table_start;
+ PHYSFS_uint32 opt_path_table_start;
+ PHYSFS_uint32 unused6;
+ PHYSFS_uint32 unused7;
+#else
+ PHYSFS_uint32 unused6;
+ PHYSFS_uint32 unused7;
+ PHYSFS_uint32 path_table_start;
+ PHYSFS_uint32 opt_path_table_start;
+#endif
+ ISO9660RootDirectoryRecord rootdirectory;
+ char set_identifier[128];
+ char publisher_identifier[128];
+ char preparer_identifer[128];
+ char application_identifier[128];
+ char copyright_file_identifier[37];
+ char abstract_file_identifier[37];
+ char bibliographic_file_identifier[37];
+ ISO9660VolumeTimestamp creation_timestamp;
+ ISO9660VolumeTimestamp modification_timestamp;
+ ISO9660VolumeTimestamp expiration_timestamp;
+ ISO9660VolumeTimestamp effective_timestamp;
+ PHYSFS_uint8 file_structure_version;
+ char unused4;
+ char application_use[512];
+ char unused5[653];
+} ISO9660VolumeDescriptor;
+
+typedef struct
+{
+ PHYSFS_uint8 recordlen;
+ PHYSFS_uint8 extattributelen;
+ ISOBB32bit(extentpos)
+ ISOBB32bit(datalen)
+ ISO9660FileTimestamp recordtime;
+ ISO9660FileFlags flags;
+ PHYSFS_uint8 file_unit_size;
+ PHYSFS_uint8 interleave_gap;
+ ISOBB16bit(volseqno)
+ PHYSFS_uint8 filenamelen;
+ char filename[222]; /* This is not exact, but makes reading easier */
+} ISO9660FileDescriptor;
+
+typedef struct
+{
+ ISOBB16bit(owner)
+ ISOBB16bit(group)
+ PHYSFS_uint16 flags; /* not implemented*/
+ ISO9660VolumeTimestamp create_time; /* yes, not file timestamp */
+ ISO9660VolumeTimestamp mod_time;
+ ISO9660VolumeTimestamp expire_time;
+ ISO9660VolumeTimestamp effective_time;
+ PHYSFS_uint8 record_format;
+ PHYSFS_uint8 record_attributes;
+ ISOBB16bit(record_len)
+ char system_identifier[32];
+ char system_use[64];
+ PHYSFS_uint8 version;
+ ISOBB16bit(escape_len)
+ char reserved[64];
+ /** further fields not implemented */
+} ISO9660ExtAttributeRec;
+
+#pragma pack(pop) /* restore original alignment from stack */
+
+typedef struct
+{
+ PHYSFS_Io *io;
+ PHYSFS_uint32 rootdirstart;
+ PHYSFS_uint32 rootdirsize;
+ PHYSFS_uint64 currpos;
+ int isjoliet;
+ char *path;
+ void *mutex;
+} ISO9660Handle;
+
+
+typedef struct __ISO9660FileHandle
+{
+ PHYSFS_sint64 filesize;
+ PHYSFS_uint64 currpos;
+ PHYSFS_uint64 startblock;
+ ISO9660Handle *isohandle;
+ PHYSFS_uint32 (*read) (struct __ISO9660FileHandle *filehandle, void *buffer,
+ PHYSFS_uint64 len);
+ int (*seek)(struct __ISO9660FileHandle *filehandle, PHYSFS_sint64 offset);
+ void (*close)(struct __ISO9660FileHandle *filehandle);
+ /* !!! FIXME: anonymouse union is going to cause problems. */
+ union
+ {
+ /* !!! FIXME: just use a memory PHYSFS_Io here, unify all this code. */
+ char *cacheddata; /* data of file when cached */
+ PHYSFS_Io *io; /* handle to separate opened file */
+ };
+} ISO9660FileHandle;
+
+/*******************************************************************************
+ * Time conversion functions
+ ******************************************************************************/
+
+static PHYSFS_sint64 iso_mktime(ISO9660FileTimestamp *timestamp)
+{
+ struct tm tm;
+ tm.tm_year = timestamp->year;
+ tm.tm_mon = timestamp->month - 1;
+ tm.tm_mday = timestamp->day;
+ tm.tm_hour = timestamp->hour;
+ tm.tm_min = timestamp->minute;
+ tm.tm_sec = timestamp->second;
+ /* Ignore GMT offset for now... */
+ return mktime(&tm);
+} /* iso_mktime */
+
+static int iso_atoi2(char *text)
+{
+ return ((text[0] - 40) * 10) + (text[1] - 40);
+} /* iso_atoi2 */
+
+static int iso_atoi4(char *text)
+{
+ return ((text[0] - 40) * 1000) + ((text[1] - 40) * 100) +
+ ((text[2] - 40) * 10) + (text[3] - 40);
+} /* iso_atoi4 */
+
+static PHYSFS_sint64 iso_volume_mktime(ISO9660VolumeTimestamp *timestamp)
+{
+ struct tm tm;
+ tm.tm_year = iso_atoi4(timestamp->year);
+ tm.tm_mon = iso_atoi2(timestamp->month) - 1;
+ tm.tm_mday = iso_atoi2(timestamp->day);
+ tm.tm_hour = iso_atoi2(timestamp->hour);
+ tm.tm_min = iso_atoi2(timestamp->minute);
+ tm.tm_sec = iso_atoi2(timestamp->second);
+ /* this allows values outside the range of a unix timestamp... sanitize them */
+ PHYSFS_sint64 value = mktime(&tm);
+ return value == -1 ? 0 : value;
+} /* iso_volume_mktime */
+
+/*******************************************************************************
+ * Filename extraction
+ ******************************************************************************/
+
+static int iso_extractfilenameISO(ISO9660FileDescriptor *descriptor,
+ char *filename, int *version)
+{
+ *filename = '\0';
+ if (descriptor->flags.directory)
+ {
+ strncpy(filename, descriptor->filename, descriptor->filenamelen);
+ filename[descriptor->filenamelen] = '\0';
+ *version = 0;
+ } /* if */
+ else
+ {
+ /* find last SEPARATOR2 */
+ int pos = 0;
+ int lastfound = -1;
+ for(;pos < descriptor->filenamelen; pos++)
+ if (descriptor->filename[pos] == ';')
+ lastfound = pos;
+ BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NO_SUCH_PATH /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1);
+ BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NO_SUCH_PATH /* !!! PHYSFS_ERR_BAD_FILENAME */, -1);
+ strncpy(filename, descriptor->filename, lastfound);
+ if (filename[lastfound - 1] == '.')
+ filename[lastfound - 1] = '\0'; /* consume trailing ., as done in all implementations */
+ else
+ filename[lastfound] = '\0';
+ *version = atoi(descriptor->filename + lastfound);
+ } /* else */
+
+ return 0;
+} /* iso_extractfilenameISO */
+
+
+static int iso_extractfilenameUCS2(ISO9660FileDescriptor *descriptor,
+ char *filename, int *version)
+{
+ PHYSFS_uint16 tmp[128];
+ PHYSFS_uint16 *src;
+ int len;
+
+ *filename = '\0';
+ *version = 1; /* Joliet does not have versions.. at least not on my images */
+
+ src = (PHYSFS_uint16*) descriptor->filename;
+ len = descriptor->filenamelen / 2;
+ tmp[len] = 0;
+
+ while(len--)
+ tmp[len] = PHYSFS_swapUBE16(src[len]);
+
+ PHYSFS_utf8FromUcs2(tmp, filename, 255);
+
+ return 0;
+} /* iso_extractfilenameUCS2 */
+
+
+static int iso_extractfilename(ISO9660Handle *handle,
+ ISO9660FileDescriptor *descriptor, char *filename,int *version)
+{
+ if (handle->isjoliet)
+ return iso_extractfilenameUCS2(descriptor, filename, version);
+ else
+ return iso_extractfilenameISO(descriptor, filename, version);
+} /* iso_extractfilename */
+
+/*******************************************************************************
+ * Basic image read functions
+ ******************************************************************************/
+
+static int iso_readimage(ISO9660Handle *handle, PHYSFS_uint64 where,
+ void *buffer, PHYSFS_uint64 len)
+{
+ BAIL_IF_MACRO(!__PHYSFS_platformGrabMutex(handle->mutex), ERRPASS, -1);
+ int rc = -1;
+ if (where != handle->currpos)
+ GOTO_IF_MACRO(!handle->io->seek(handle->io,where), ERRPASS, unlockme);
+ rc = handle->io->read(handle->io, buffer, len);
+ if (rc == -1)
+ {
+ handle->currpos = (PHYSFS_uint64) -1;
+ goto unlockme;
+ } /* if */
+ handle->currpos += rc;
+
+ unlockme:
+ __PHYSFS_platformReleaseMutex(handle->mutex);
+ return rc;
+} /* iso_readimage */
+
+
+static PHYSFS_sint64 iso_readfiledescriptor(ISO9660Handle *handle,
+ PHYSFS_uint64 where,
+ ISO9660FileDescriptor *descriptor)
+{
+ PHYSFS_sint64 rc = iso_readimage(handle, where, descriptor,
+ sizeof (descriptor->recordlen));
+ BAIL_IF_MACRO(rc == -1, ERRPASS, -1);
+ BAIL_IF_MACRO(rc != 1, PHYSFS_ERR_CORRUPT, -1);
+
+ if (descriptor->recordlen == 0)
+ return 0; /* fill bytes at the end of a sector */
+
+ rc = iso_readimage(handle, where + 1, &descriptor->extattributelen,
+ descriptor->recordlen - sizeof(descriptor->recordlen));
+ BAIL_IF_MACRO(rc == -1, ERRPASS, -1);
+ BAIL_IF_MACRO(rc != 1, PHYSFS_ERR_CORRUPT, -1);
+
+ return 0;
+} /* iso_readfiledescriptor */
+
+static void iso_extractsubpath(char *path, char **subpath)
+{
+ *subpath = strchr(path,'/');
+ if (*subpath != 0)
+ {
+ **subpath = 0;
+ *subpath +=1;
+ } /* if */
+} /* iso_extractsubpath */
+
+/*
+ * Don't use path tables, they are not necessarily faster, but more complicated
+ * to implement as they store only directories and not files, so searching for
+ * a file needs to branch to the directory extent sooner or later.
+ */
+static int iso_find_dir_entry(ISO9660Handle *handle,const char *path,
+ ISO9660FileDescriptor *descriptor, int *exists)
+{
+ char *subpath = 0;
+ PHYSFS_uint64 readpos, end_of_dir;
+ char filename[255];
+ char pathcopy[256];
+ char *mypath;
+ int version = 0;
+
+ strcpy(pathcopy, path);
+ mypath = pathcopy;
+ *exists = 0;
+
+ readpos = handle->rootdirstart;
+ end_of_dir = handle->rootdirstart + handle->rootdirsize;
+ iso_extractsubpath(mypath, &subpath);
+ while (1)
+ {
+ BAIL_IF_MACRO(iso_readfiledescriptor(handle, readpos, descriptor), ERRPASS, -1);
+
+ /* recordlen = 0 -> no more entries or fill entry */
+ if (!descriptor->recordlen)
+ {
+ /* if we are in the last sector of the directory & it's 0 -> end */
+ if ((end_of_dir - 2048) <= (readpos -1))
+ break; /* finished */
+
+ /* else skip to the next sector & continue; */
+ readpos = (((readpos - 1) / 2048) + 1) * 2048;
+ continue;
+ } /* if */
+
+ readpos += descriptor->recordlen;
+ if (descriptor->filenamelen == 1 && (descriptor->filename[0] == 0
+ || descriptor->filename[0] == 1))
+ continue; /* special ones, ignore */
+
+ BAIL_IF_MACRO(
+ iso_extractfilename(handle, descriptor, filename, &version),
+ ERRPASS, -1);
+
+ if (strcmp(filename, mypath) == 0)
+ {
+ if ( (subpath == 0) || (subpath[0] == 0) )
+ {
+ *exists = 1;
+ return 0; /* no subpaths left and we found the entry */
+ } /* if */
+
+ if (descriptor->flags.directory)
+ {
+ /* shorten the path to the subpath */
+ mypath = subpath;
+ iso_extractsubpath(mypath, &subpath);
+ /* gosub to the new directory extent */
+ readpos = descriptor->extentpos * 2048;
+ end_of_dir = readpos + descriptor->datalen;
+ } /* if */
+ else
+ {
+ /* we're at a file but have a remaining subpath -> no match */
+ return 0;
+ } /* else */
+ } /* if */
+ } /* while */
+
+ return 0;
+} /* iso_find_dir_entry */
+
+
+static int iso_read_ext_attributes(ISO9660Handle *handle, int block,
+ ISO9660ExtAttributeRec *attributes)
+{
+ return iso_readimage(handle, block * 2048, attributes,
+ sizeof(ISO9660ExtAttributeRec));
+} /* iso_read_ext_attributes */
+
+
+static int ISO9660_flush(PHYSFS_Io *io) { return 1; /* no write support. */ }
+
+static PHYSFS_Io *ISO9660_duplicate(PHYSFS_Io *_io)
+{
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL); /* !!! FIXME: write me. */
+} /* ISO9660_duplicate */
+
+
+static void ISO9660_destroy(PHYSFS_Io *io)
+{
+ ISO9660FileHandle *fhandle = (ISO9660FileHandle*) io->opaque;
+ fhandle->close(fhandle);
+ allocator.Free(io);
+} /* ISO9660_destroy */
+
+
+static PHYSFS_sint64 ISO9660_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
+{
+ ISO9660FileHandle *fhandle = (ISO9660FileHandle*) io->opaque;
+ return fhandle->read(fhandle, buf, len);
+} /* ISO9660_read */
+
+
+static PHYSFS_sint64 ISO9660_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 l)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, -1);
+} /* ISO9660_write */
+
+
+static PHYSFS_sint64 ISO9660_tell(PHYSFS_Io *io)
+{
+ return ((ISO9660FileHandle*) io->opaque)->currpos;
+} /* ISO9660_tell */
+
+
+static int ISO9660_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ ISO9660FileHandle *fhandle = (ISO9660FileHandle*) io->opaque;
+ return fhandle->seek(fhandle, offset);
+} /* ISO9660_seek */
+
+
+static PHYSFS_sint64 ISO9660_length(PHYSFS_Io *io)
+{
+ return ((ISO9660FileHandle*) io->opaque)->filesize;
+} /* ISO9660_length */
+
+
+static const PHYSFS_Io ISO9660_Io =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ ISO9660_read,
+ ISO9660_write,
+ ISO9660_seek,
+ ISO9660_tell,
+ ISO9660_length,
+ ISO9660_duplicate,
+ ISO9660_flush,
+ ISO9660_destroy
+};
+
+
+/*******************************************************************************
+ * Archive management functions
+ ******************************************************************************/
+
+static void *ISO9660_openArchive(PHYSFS_Io *io, const char *filename, int forWriting)
+{
+ char magicnumber[6];
+ ISO9660Handle *handle;
+ int founddescriptor = 0;
+ int foundjoliet = 0;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+
+ /* Skip system area to magic number in Volume descriptor */
+ BAIL_IF_MACRO(!io->seek(io, 32769), ERRPASS, NULL);
+ BAIL_IF_MACRO(!io->read(io, magicnumber, 5) != 5, ERRPASS, NULL);
+ if (memcmp(magicnumber, "CD001", 6) != 0)
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ handle = allocator.Malloc(sizeof(ISO9660Handle));
+ GOTO_IF_MACRO(!handle, PHYSFS_ERR_OUT_OF_MEMORY, errorcleanup);
+ handle->path = 0;
+ handle->mutex= 0;
+ handle->io = NULL;
+
+ handle->path = allocator.Malloc(strlen(filename) + 1);
+ GOTO_IF_MACRO(!handle->path, PHYSFS_ERR_OUT_OF_MEMORY, errorcleanup);
+ strcpy(handle->path, filename);
+
+ handle->mutex = __PHYSFS_platformCreateMutex();
+ GOTO_IF_MACRO(!handle->mutex, ERRPASS, errorcleanup);
+
+ handle->io = io;
+
+ /* seek Primary Volume Descriptor */
+ GOTO_IF_MACRO(!io->seek(io, 32768), PHYSFS_ERR_IO, errorcleanup);
+
+ while (1)
+ {
+ ISO9660VolumeDescriptor descriptor;
+ GOTO_IF_MACRO(io->read(io, &descriptor, sizeof(ISO9660VolumeDescriptor)) != sizeof(ISO9660VolumeDescriptor), PHYSFS_ERR_IO, errorcleanup);
+ GOTO_IF_MACRO(strncmp(descriptor.identifier, "CD001", 5) != 0, PHYSFS_ERR_UNSUPPORTED, errorcleanup);
+
+ if (descriptor.type == 255)
+ {
+ /* type 255 terminates the volume descriptor list */
+ if (founddescriptor)
+ return handle; /* ok, we've found one volume descriptor */
+ else
+ GOTO_MACRO(PHYSFS_ERR_CORRUPT, errorcleanup);
+ } /* if */
+ if (descriptor.type == 1 && !founddescriptor)
+ {
+ handle->currpos = io->tell(io);
+ handle->rootdirstart =
+ descriptor.rootdirectory.extent_location * 2048;
+ handle->rootdirsize =
+ descriptor.rootdirectory.data_length;
+ handle->isjoliet = 0;
+ founddescriptor = 1; /* continue search for joliet */
+ } /* if */
+ if (descriptor.type == 2 && !foundjoliet)
+ {
+ /* check if is joliet */
+ PHYSFS_uint8 *s = descriptor.escape_sequences;
+ int joliet = !(descriptor.flags & 1)
+ && (s[0] == 0x25)
+ && (s[1] == 0x2F)
+ && ((s[2] == 0x40) || (s[2] == 0x43) || (s[2] == 0x45));
+ if (!joliet)
+ continue;
+
+ handle->currpos = io->tell(io);
+ handle->rootdirstart =
+ descriptor.rootdirectory.extent_location * 2048;
+ handle->rootdirsize =
+ descriptor.rootdirectory.data_length;
+ handle->isjoliet = 1;
+ founddescriptor = 1;
+ foundjoliet = 1;
+ } /* if */
+ } /* while */
+
+ GOTO_MACRO(PHYSFS_ERR_CORRUPT, errorcleanup); /* not found. */
+
+errorcleanup:
+ if (handle)
+ {
+ if (handle->path)
+ allocator.Free(handle->path);
+ if (handle->mutex)
+ __PHYSFS_platformDestroyMutex(handle->mutex);
+ allocator.Free(handle);
+ } /* if */
+ return NULL;
+} /* ISO9660_openArchive */
+
+
+static void ISO9660_closeArchive(PHYSFS_Dir *opaque)
+{
+ ISO9660Handle *handle = (ISO9660Handle*) opaque;
+ handle->io->destroy(handle->io);
+ __PHYSFS_platformDestroyMutex(handle->mutex);
+ allocator.Free(handle->path);
+ allocator.Free(handle);
+} /* ISO9660_closeArchive */
+
+
+/*******************************************************************************
+ * Read functions
+ ******************************************************************************/
+
+
+static PHYSFS_uint32 iso_file_read_mem(ISO9660FileHandle *filehandle,
+ void *buffer, PHYSFS_uint64 len)
+{
+ /* check remaining bytes & max obj which can be fetched */
+ const PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
+ if (bytesleft < len)
+ len = bytesleft;
+
+ if (len == 0)
+ return 0;
+
+ memcpy(buffer, filehandle->cacheddata + filehandle->currpos, (size_t) len);
+
+ filehandle->currpos += len;
+ return (PHYSFS_uint32) len;
+} /* iso_file_read_mem */
+
+
+static int iso_file_seek_mem(ISO9660FileHandle *fhandle, PHYSFS_sint64 offset)
+{
+ BAIL_IF_MACRO(offset < 0, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ BAIL_IF_MACRO(offset >= fhandle->filesize, PHYSFS_ERR_PAST_EOF, 0);
+
+ fhandle->currpos = offset;
+ return 0;
+} /* iso_file_seek_mem */
+
+
+static void iso_file_close_mem(ISO9660FileHandle *fhandle)
+{
+ allocator.Free(fhandle->cacheddata);
+ allocator.Free(fhandle);
+} /* iso_file_close_mem */
+
+
+static PHYSFS_uint32 iso_file_read_foreign(ISO9660FileHandle *filehandle,
+ void *buffer, PHYSFS_uint64 len)
+{
+ /* check remaining bytes & max obj which can be fetched */
+ const PHYSFS_sint64 bytesleft = filehandle->filesize - filehandle->currpos;
+ if (bytesleft < len)
+ len = bytesleft;
+
+ const PHYSFS_sint64 rc = filehandle->io->read(filehandle->io, buffer, len);
+ BAIL_IF_MACRO(rc == -1, ERRPASS, -1);
+
+ filehandle->currpos += rc; /* i trust my internal book keeping */
+ BAIL_IF_MACRO(rc < len, PHYSFS_ERR_CORRUPT, -1);
+ return rc;
+} /* iso_file_read_foreign */
+
+
+static int iso_file_seek_foreign(ISO9660FileHandle *fhandle,
+ PHYSFS_sint64 offset)
+{
+ BAIL_IF_MACRO(offset < 0, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ BAIL_IF_MACRO(offset >= fhandle->filesize, PHYSFS_ERR_PAST_EOF, 0);
+
+ PHYSFS_sint64 pos = fhandle->startblock * 2048 + offset;
+ BAIL_IF_MACRO(!fhandle->io->seek(fhandle->io, pos), ERRPASS, -1);
+
+ fhandle->currpos = offset;
+ return 0;
+} /* iso_file_seek_foreign */
+
+
+static void iso_file_close_foreign(ISO9660FileHandle *fhandle)
+{
+ fhandle->io->destroy(fhandle->io);
+ allocator.Free(fhandle);
+} /* iso_file_close_foreign */
+
+
+static int iso_file_open_mem(ISO9660Handle *handle, ISO9660FileHandle *fhandle)
+{
+ fhandle->cacheddata = allocator.Malloc(fhandle->filesize);
+ BAIL_IF_MACRO(!fhandle->cacheddata, PHYSFS_ERR_OUT_OF_MEMORY, -1);
+ int rc = iso_readimage(handle, fhandle->startblock * 2048,
+ fhandle->cacheddata, fhandle->filesize);
+ GOTO_IF_MACRO(rc < 0, ERRPASS, freemem);
+ GOTO_IF_MACRO(rc == 0, PHYSFS_ERR_CORRUPT, freemem);
+
+ fhandle->read = iso_file_read_mem;
+ fhandle->seek = iso_file_seek_mem;
+ fhandle->close = iso_file_close_mem;
+ return 0;
+
+freemem:
+ allocator.Free(fhandle->cacheddata);
+ return -1;
+} /* iso_file_open_mem */
+
+
+static int iso_file_open_foreign(ISO9660Handle *handle,
+ ISO9660FileHandle *fhandle)
+{
+ int rc;
+ fhandle->io = __PHYSFS_createNativeIo(handle->path, 'r');
+ BAIL_IF_MACRO(!fhandle->io, ERRPASS, -1);
+ rc = fhandle->io->seek(fhandle->io, fhandle->startblock * 2048);
+ GOTO_IF_MACRO(!rc, ERRPASS, closefile);
+
+ fhandle->read = iso_file_read_foreign;
+ fhandle->seek = iso_file_seek_foreign;
+ fhandle->close = iso_file_close_foreign;
+ return 0;
+
+closefile:
+ fhandle->io->destroy(fhandle->io);
+ return -1;
+} /* iso_file_open_foreign */
+
+
+static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename,
+ int *exists)
+{
+ PHYSFS_Io *retval = NULL;
+ ISO9660Handle *handle = (ISO9660Handle*) opaque;
+ ISO9660FileHandle *fhandle;
+ ISO9660FileDescriptor descriptor;
+ int rc;
+
+ fhandle = allocator.Malloc(sizeof(ISO9660FileHandle));
+ BAIL_IF_MACRO(fhandle == 0, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ fhandle->cacheddata = 0;
+
+ retval = allocator.Malloc(sizeof(PHYSFS_Io));
+ GOTO_IF_MACRO(retval == 0, PHYSFS_ERR_OUT_OF_MEMORY, errorhandling);
+
+ /* find file descriptor */
+ rc = iso_find_dir_entry(handle, filename, &descriptor, exists);
+ GOTO_IF_MACRO(rc, ERRPASS, errorhandling);
+ GOTO_IF_MACRO(!*exists, PHYSFS_ERR_NO_SUCH_PATH, errorhandling);
+
+ fhandle->startblock = descriptor.extentpos + descriptor.extattributelen;
+ fhandle->filesize = descriptor.datalen;
+ fhandle->currpos = 0;
+ fhandle->isohandle = handle;
+ fhandle->cacheddata = NULL;
+ fhandle->io = NULL;
+
+ if (descriptor.datalen <= ISO9660_FULLCACHEMAXSIZE)
+ rc = iso_file_open_mem(handle, fhandle);
+ else
+ rc = iso_file_open_foreign(handle, fhandle);
+ GOTO_IF_MACRO(rc, ERRPASS, errorhandling);
+
+ memcpy(retval, &ISO9660_Io, sizeof (PHYSFS_Io));
+ retval->opaque = fhandle;
+ return retval;
+
+errorhandling:
+ if (retval) allocator.Free(retval);
+ if (fhandle) allocator.Free(fhandle);
+ return NULL;
+} /* ISO9660_openRead */
+
+
+
+/*******************************************************************************
+ * Information gathering functions
+ ******************************************************************************/
+
+static void ISO9660_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks,
+ PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata)
+{
+ ISO9660Handle *handle = (ISO9660Handle*) opaque;
+ ISO9660FileDescriptor descriptor;
+ PHYSFS_uint64 readpos;
+ PHYSFS_uint64 end_of_dir;
+ char filename[130]; /* ISO allows 31, Joliet 128 -> 128 + 2 eol bytes */
+ int version = 0;
+
+ if (*dname == '\0')
+ {
+ readpos = handle->rootdirstart;
+ end_of_dir = readpos + handle->rootdirsize;
+ } /* if */
+ else
+ {
+ printf("pfad %s\n",dname);
+ int exists = 0;
+ BAIL_IF_MACRO(iso_find_dir_entry(handle,dname, &descriptor, &exists), ERRPASS,);
+ BAIL_IF_MACRO(!exists, ERRPASS, );
+ BAIL_IF_MACRO(!descriptor.flags.directory, ERRPASS,);
+
+ readpos = descriptor.extentpos * 2048;
+ end_of_dir = readpos + descriptor.datalen;
+ } /* else */
+
+ while (1)
+ {
+ BAIL_IF_MACRO(iso_readfiledescriptor(handle, readpos, &descriptor), ERRPASS, );
+
+ /* recordlen = 0 -> no more entries or fill entry */
+ if (!descriptor.recordlen)
+ {
+ /* if we are in the last sector of the directory & it's 0 -> end */
+ if ((end_of_dir - 2048) <= (readpos -1))
+ break; /* finished */
+
+ /* else skip to the next sector & continue; */
+ readpos = (((readpos - 1) / 2048) + 1) * 2048;
+ continue;
+ } /* if */
+
+ readpos += descriptor.recordlen;
+ if (descriptor.filenamelen == 1 && (descriptor.filename[0] == 0
+ || descriptor.filename[0] == 1))
+ continue; /* special ones, ignore */
+
+ strncpy(filename,descriptor.filename,descriptor.filenamelen);
+ iso_extractfilename(handle, &descriptor, filename, &version);
+ cb(callbackdata, origdir,filename);
+ } /* while */
+} /* ISO9660_enumerateFiles */
+
+
+static int ISO9660_stat(PHYSFS_Dir *opaque, const char *name, int *exists,
+ PHYSFS_Stat *stat)
+{
+ ISO9660Handle *handle = (ISO9660Handle*) opaque;
+ ISO9660FileDescriptor descriptor;
+ ISO9660ExtAttributeRec extattr;
+ BAIL_IF_MACRO(iso_find_dir_entry(handle, name, &descriptor, exists), ERRPASS, -1);
+ if (!*exists)
+ return 0;
+
+ stat->readonly = 1;
+
+ /* try to get extended info */
+ if (descriptor.extattributelen)
+ {
+ BAIL_IF_MACRO(iso_read_ext_attributes(handle,
+ descriptor.extentpos, &extattr), ERRPASS, -1);
+ stat->createtime = iso_volume_mktime(&extattr.create_time);
+ stat->modtime = iso_volume_mktime(&extattr.mod_time);
+ stat->accesstime = iso_volume_mktime(&extattr.mod_time);
+ } /* if */
+ else
+ {
+ stat->createtime = iso_mktime(&descriptor.recordtime);
+ stat->modtime = iso_mktime(&descriptor.recordtime);
+ stat->accesstime = iso_mktime(&descriptor.recordtime);
+ } /* else */
+
+ if (descriptor.flags.directory)
+ {
+ stat->filesize = 0;
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ } /* if */
+ else
+ {
+ stat->filesize = descriptor.datalen;
+ stat->filetype = PHYSFS_FILETYPE_REGULAR;
+ } /* else */
+
+ return 1;
+} /* ISO9660_stat */
+
+
+/*******************************************************************************
+ * Not supported functions
+ ******************************************************************************/
+
+static PHYSFS_Io *ISO9660_openWrite(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* ISO9660_openWrite */
+
+
+static PHYSFS_Io *ISO9660_openAppend(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* ISO9660_openAppend */
+
+
+static int ISO9660_remove(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* ISO9660_remove */
+
+
+static int ISO9660_mkdir(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* ISO9660_mkdir */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 =
+{
+ {
+ "ISO",
+ "ISO9660 image file",
+ "Christoph Nelles <evilazrael at evilazrael.de>",
+ "http://www.evilazrael.de/",
+ },
+ ISO9660_openArchive, /* openArchive() method */
+ ISO9660_enumerateFiles, /* enumerateFiles() method */
+ ISO9660_openRead, /* openRead() method */
+ ISO9660_openWrite, /* openWrite() method */
+ ISO9660_openAppend, /* openAppend() method */
+ ISO9660_remove, /* remove() method */
+ ISO9660_mkdir, /* mkdir() method */
+ ISO9660_closeArchive, /* closeArchive() method */
+ ISO9660_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_ISO9660 */
+
+/* end of archiver_iso9660.c ... */
+
diff --git a/misc/libphysfs/archiver_lzma.c b/misc/libphysfs/archiver_lzma.c
new file mode 100644
index 0000000..52fa220
--- /dev/null
+++ b/misc/libphysfs/archiver_lzma.c
@@ -0,0 +1,701 @@
+/*
+ * LZMA support routines for PhysicsFS.
+ *
+ * Please see the file lzma.txt in the lzma/ directory.
+ *
+ * This file was written by Dennis Schridde, with some peeking at "7zMain.c"
+ * by Igor Pavlov.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_7Z
+
+#include "lzma/C/7zCrc.h"
+#include "lzma/C/Archive/7z/7zIn.h"
+#include "lzma/C/Archive/7z/7zExtract.h"
+
+
+/* 7z internal from 7zIn.c */
+extern int TestSignatureCandidate(Byte *testBytes);
+
+
+#ifdef _LZMA_IN_CB
+# define BUFFER_SIZE (1 << 12)
+#endif /* _LZMA_IN_CB */
+
+
+/*
+ * Carries filestream metadata through 7z
+ */
+typedef struct _FileInputStream
+{
+ ISzAlloc allocImp; /* Allocation implementation, used by 7z */
+ ISzAlloc allocTempImp; /* Temporary allocation implementation, used by 7z */
+ ISzInStream inStream; /* Input stream with read callbacks, used by 7z */
+ PHYSFS_Io *io; /* Filehandle, used by read implementation */
+#ifdef _LZMA_IN_CB
+ Byte buffer[BUFFER_SIZE]; /* Buffer, used by read implementation */
+#endif /* _LZMA_IN_CB */
+} FileInputStream;
+
+/*
+ * In the 7z format archives are splited into blocks, those are called folders
+ * Set by LZMA_read()
+*/
+typedef struct _LZMAfolder
+{
+ PHYSFS_uint32 index; /* Index of folder in archive */
+ PHYSFS_uint32 references; /* Number of files using this block */
+ PHYSFS_uint8 *cache; /* Cached folder */
+ size_t size; /* Size of folder */
+} LZMAfolder;
+
+/*
+ * Set by LZMA_openArchive(), except folder which gets it's values
+ * in LZMA_read()
+ */
+typedef struct _LZMAarchive
+{
+ struct _LZMAfile *files; /* Array of files, size == archive->db.Database.NumFiles */
+ LZMAfolder *folders; /* Array of folders, size == archive->db.Database.NumFolders */
+ CArchiveDatabaseEx db; /* For 7z: Database */
+ FileInputStream stream; /* For 7z: Input file incl. read and seek callbacks */
+} LZMAarchive;
+
+/* Set by LZMA_openArchive(), except offset which is set by LZMA_read() */
+typedef struct _LZMAfile
+{
+ PHYSFS_uint32 index; /* Index of file in archive */
+ LZMAarchive *archive; /* Link to corresponding archive */
+ LZMAfolder *folder; /* Link to corresponding folder */
+ CFileItem *item; /* For 7z: File info, eg. name, size */
+ size_t offset; /* Offset in folder */
+ size_t position; /* Current "virtual" position in file */
+} LZMAfile;
+
+
+/* Memory management implementations to be passed to 7z */
+
+static void *SzAllocPhysicsFS(size_t size)
+{
+ return ((size == 0) ? NULL : allocator.Malloc(size));
+} /* SzAllocPhysicsFS */
+
+
+static void SzFreePhysicsFS(void *address)
+{
+ if (address != NULL)
+ allocator.Free(address);
+} /* SzFreePhysicsFS */
+
+
+/* Filesystem implementations to be passed to 7z */
+
+#ifdef _LZMA_IN_CB
+
+/*
+ * Read implementation, to be passed to 7z
+ * WARNING: If the ISzInStream in 'object' is not contained in a valid FileInputStream this _will_ break horribly!
+ */
+SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize,
+ size_t *processedSize)
+{
+ FileInputStream *s = (FileInputStream *)(object - offsetof(FileInputStream, inStream)); /* HACK! */
+ PHYSFS_sint64 processedSizeLoc = 0;
+
+ if (maxReqSize > BUFFER_SIZE)
+ maxReqSize = BUFFER_SIZE;
+ processedSizeLoc = s->io->read(s->io, s->buffer, maxReqSize);
+ *buffer = s->buffer;
+ if (processedSize != NULL)
+ *processedSize = (size_t) processedSizeLoc;
+
+ return SZ_OK;
+} /* SzFileReadImp */
+
+#else
+
+/*
+ * Read implementation, to be passed to 7z
+ * WARNING: If the ISzInStream in 'object' is not contained in a valid FileInputStream this _will_ break horribly!
+ */
+SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
+ size_t *processedSize)
+{
+ FileInputStream *s = (FileInputStream *)((unsigned long)object - offsetof(FileInputStream, inStream)); /* HACK! */
+ const size_t processedSizeLoc = s->io->read(s->io, buffer, size);
+ if (processedSize != NULL)
+ *processedSize = processedSizeLoc;
+ return SZ_OK;
+} /* SzFileReadImp */
+
+#endif
+
+/*
+ * Seek implementation, to be passed to 7z
+ * WARNING: If the ISzInStream in 'object' is not contained in a valid FileInputStream this _will_ break horribly!
+ */
+SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
+{
+ FileInputStream *s = (FileInputStream *)((unsigned long)object - offsetof(FileInputStream, inStream)); /* HACK! */
+ if (s->io->seek(s->io, (PHYSFS_uint64) pos))
+ return SZ_OK;
+ return SZE_FAIL;
+} /* SzFileSeekImp */
+
+
+/*
+ * Translate Microsoft FILETIME (used by 7zip) into UNIX timestamp
+ */
+static PHYSFS_sint64 lzma_filetime_to_unix_timestamp(CArchiveFileTime *ft)
+{
+ /* MS counts in nanoseconds ... */
+ const PHYSFS_uint64 FILETIME_NANOTICKS_PER_SECOND = __PHYSFS_UI64(10000000);
+ /* MS likes to count seconds since 01.01.1601 ... */
+ const PHYSFS_uint64 FILETIME_UNIX_DIFF = __PHYSFS_UI64(11644473600);
+
+ PHYSFS_uint64 filetime = ft->Low | ((PHYSFS_uint64)ft->High << 32);
+ return filetime/FILETIME_NANOTICKS_PER_SECOND - FILETIME_UNIX_DIFF;
+} /* lzma_filetime_to_unix_timestamp */
+
+
+/*
+ * Compare a file with a given name, C89 stdlib variant
+ * Used for sorting
+ */
+static int lzma_file_cmp_stdlib(const void *key, const void *object)
+{
+ const char *name = (const char *) key;
+ LZMAfile *file = (LZMAfile *) object;
+ return strcmp(name, file->item->Name);
+} /* lzma_file_cmp_posix */
+
+
+/*
+ * Compare two files with each other based on the name
+ * Used for sorting
+ */
+static int lzma_file_cmp(void *_a, size_t one, size_t two)
+{
+ LZMAfile *files = (LZMAfile *) _a;
+ return strcmp(files[one].item->Name, files[two].item->Name);
+} /* lzma_file_cmp */
+
+
+/*
+ * Swap two entries in the file array
+ */
+static void lzma_file_swap(void *_a, size_t one, size_t two)
+{
+ LZMAfile tmp;
+ LZMAfile *first = &(((LZMAfile *) _a)[one]);
+ LZMAfile *second = &(((LZMAfile *) _a)[two]);
+ memcpy(&tmp, first, sizeof (LZMAfile));
+ memcpy(first, second, sizeof (LZMAfile));
+ memcpy(second, &tmp, sizeof (LZMAfile));
+} /* lzma_file_swap */
+
+
+/*
+ * Find entry 'name' in 'archive'
+ */
+static LZMAfile * lzma_find_file(const LZMAarchive *archive, const char *name)
+{
+ LZMAfile *file = bsearch(name, archive->files, archive->db.Database.NumFiles, sizeof(*archive->files), lzma_file_cmp_stdlib); /* FIXME: Should become __PHYSFS_search!!! */
+
+ BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
+
+ return file;
+} /* lzma_find_file */
+
+
+/*
+ * Load metadata for the file at given index
+ */
+static int lzma_file_init(LZMAarchive *archive, PHYSFS_uint32 fileIndex)
+{
+ LZMAfile *file = &archive->files[fileIndex];
+ PHYSFS_uint32 folderIndex = archive->db.FileIndexToFolderIndexMap[fileIndex];
+
+ file->index = fileIndex; /* Store index into 7z array, since we sort our own. */
+ file->archive = archive;
+ file->folder = (folderIndex != (PHYSFS_uint32)-1 ? &archive->folders[folderIndex] : NULL); /* Directories don't have a folder (they contain no own data...) */
+ file->item = &archive->db.Database.Files[fileIndex]; /* Holds crucial data and is often referenced -> Store link */
+ file->position = 0;
+ file->offset = 0; /* Offset will be set by LZMA_read() */
+
+ return 1;
+} /* lzma_load_file */
+
+
+/*
+ * Load metadata for all files
+ */
+static int lzma_files_init(LZMAarchive *archive)
+{
+ PHYSFS_uint32 fileIndex = 0, numFiles = archive->db.Database.NumFiles;
+
+ for (fileIndex = 0; fileIndex < numFiles; fileIndex++ )
+ {
+ if (!lzma_file_init(archive, fileIndex))
+ {
+ return 0; /* FALSE on failure */
+ }
+ } /* for */
+
+ __PHYSFS_sort(archive->files, (size_t) numFiles, lzma_file_cmp, lzma_file_swap);
+
+ return 1;
+} /* lzma_load_files */
+
+
+/*
+ * Initialise specified archive
+ */
+static void lzma_archive_init(LZMAarchive *archive)
+{
+ memset(archive, 0, sizeof(*archive));
+
+ /* Prepare callbacks for 7z */
+ archive->stream.inStream.Read = SzFileReadImp;
+ archive->stream.inStream.Seek = SzFileSeekImp;
+
+ archive->stream.allocImp.Alloc = SzAllocPhysicsFS;
+ archive->stream.allocImp.Free = SzFreePhysicsFS;
+
+ archive->stream.allocTempImp.Alloc = SzAllocPhysicsFS;
+ archive->stream.allocTempImp.Free = SzFreePhysicsFS;
+}
+
+
+/*
+ * Deinitialise archive
+ */
+static void lzma_archive_exit(LZMAarchive *archive)
+{
+ /* Free arrays */
+ allocator.Free(archive->folders);
+ allocator.Free(archive->files);
+ allocator.Free(archive);
+}
+
+/*
+ * Wrap all 7z calls in this, so the physfs error state is set appropriately.
+ */
+static int lzma_err(SZ_RESULT rc)
+{
+ switch (rc)
+ {
+ case SZ_OK: /* Same as LZMA_RESULT_OK */
+ break;
+ case SZE_DATA_ERROR: /* Same as LZMA_RESULT_DATA_ERROR */
+ __PHYSFS_setError(PHYSFS_ERR_CORRUPT); /*!!!FIXME: was "PHYSFS_ERR_DATA_ERROR" */
+ break;
+ case SZE_OUTOFMEMORY:
+ __PHYSFS_setError(PHYSFS_ERR_OUT_OF_MEMORY);
+ break;
+ case SZE_CRC_ERROR:
+ __PHYSFS_setError(PHYSFS_ERR_CORRUPT);
+ break;
+ case SZE_NOTIMPL:
+ __PHYSFS_setError(PHYSFS_ERR_UNSUPPORTED);
+ break;
+ case SZE_FAIL:
+ __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR); /* !!! FIXME: right? */
+ break;
+ case SZE_ARCHIVE_ERROR:
+ __PHYSFS_setError(PHYSFS_ERR_CORRUPT); /* !!! FIXME: right? */
+ break;
+ default:
+ __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR);
+ } /* switch */
+
+ return rc;
+} /* lzma_err */
+
+
+static PHYSFS_sint64 LZMA_read(PHYSFS_Io *io, void *outBuf, PHYSFS_uint64 len)
+{
+ LZMAfile *file = (LZMAfile *) io->opaque;
+
+ size_t wantedSize = (size_t) len;
+ const size_t remainingSize = file->item->Size - file->position;
+ size_t fileSize = 0;
+
+ BAIL_IF_MACRO(wantedSize == 0, ERRPASS, 0); /* quick rejection. */
+ BAIL_IF_MACRO(remainingSize == 0, PHYSFS_ERR_PAST_EOF, 0);
+
+ if (wantedSize > remainingSize)
+ wantedSize = remainingSize;
+
+ /* Only decompress the folder if it is not already cached */
+ if (file->folder->cache == NULL)
+ {
+ const int rc = lzma_err(SzExtract(
+ &file->archive->stream.inStream, /* compressed data */
+ &file->archive->db, /* 7z's database, containing everything */
+ file->index, /* Index into database arrays */
+ /* Index of cached folder, will be changed by SzExtract */
+ &file->folder->index,
+ /* Cache for decompressed folder, allocated/freed by SzExtract */
+ &file->folder->cache,
+ /* Size of cache, will be changed by SzExtract */
+ &file->folder->size,
+ /* Offset of this file inside the cache, set by SzExtract */
+ &file->offset,
+ &fileSize, /* Size of this file */
+ &file->archive->stream.allocImp,
+ &file->archive->stream.allocTempImp));
+
+ if (rc != SZ_OK)
+ return -1;
+ } /* if */
+
+ /* Copy wanted bytes over from cache to outBuf */
+ memcpy(outBuf, (file->folder->cache + file->offset + file->position),
+ wantedSize);
+ file->position += wantedSize; /* Increase virtual position */
+
+ return wantedSize;
+} /* LZMA_read */
+
+
+static PHYSFS_sint64 LZMA_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, -1);
+} /* LZMA_write */
+
+
+static PHYSFS_sint64 LZMA_tell(PHYSFS_Io *io)
+{
+ LZMAfile *file = (LZMAfile *) io->opaque;
+ return file->position;
+} /* LZMA_tell */
+
+
+static int LZMA_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ LZMAfile *file = (LZMAfile *) io->opaque;
+
+ BAIL_IF_MACRO(offset > file->item->Size, PHYSFS_ERR_PAST_EOF, 0);
+
+ file->position = offset; /* We only use a virtual position... */
+
+ return 1;
+} /* LZMA_seek */
+
+
+static PHYSFS_sint64 LZMA_length(PHYSFS_Io *io)
+{
+ const LZMAfile *file = (LZMAfile *) io->opaque;
+ return (file->item->Size);
+} /* LZMA_length */
+
+
+static PHYSFS_Io *LZMA_duplicate(PHYSFS_Io *_io)
+{
+ /* !!! FIXME: this archiver needs to be reworked to allow multiple
+ * !!! FIXME: opens before we worry about duplication. */
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+} /* LZMA_duplicate */
+
+
+static int LZMA_flush(PHYSFS_Io *io) { return 1; /* no write support. */ }
+
+
+static void LZMA_destroy(PHYSFS_Io *io)
+{
+ LZMAfile *file = (LZMAfile *) io->opaque;
+
+ if (file->folder != NULL)
+ {
+ /* Only decrease refcount if someone actually requested this file... Prevents from overflows and close-on-open... */
+ if (file->folder->references > 0)
+ file->folder->references--;
+ if (file->folder->references == 0)
+ {
+ /* Free the cache which might have been allocated by LZMA_read() */
+ allocator.Free(file->folder->cache);
+ file->folder->cache = NULL;
+ }
+ /* !!! FIXME: we don't free (file) or (file->folder)?! */
+ } /* if */
+} /* LZMA_destroy */
+
+
+static const PHYSFS_Io LZMA_Io =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ LZMA_read,
+ LZMA_write,
+ LZMA_seek,
+ LZMA_tell,
+ LZMA_length,
+ LZMA_duplicate,
+ LZMA_flush,
+ LZMA_destroy
+};
+
+
+static void *LZMA_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_uint8 sig[k7zSignatureSize];
+ size_t len = 0;
+ LZMAarchive *archive = NULL;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+
+ if (io->read(io, sig, k7zSignatureSize) != k7zSignatureSize)
+ return 0;
+ BAIL_IF_MACRO(!TestSignatureCandidate(sig), PHYSFS_ERR_UNSUPPORTED, NULL);
+ BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL);
+
+ archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
+ BAIL_IF_MACRO(archive == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ lzma_archive_init(archive);
+ archive->stream.io = io;
+
+ CrcGenerateTable();
+ SzArDbExInit(&archive->db);
+ if (lzma_err(SzArchiveOpen(&archive->stream.inStream,
+ &archive->db,
+ &archive->stream.allocImp,
+ &archive->stream.allocTempImp)) != SZ_OK)
+ {
+ SzArDbExFree(&archive->db, SzFreePhysicsFS);
+ lzma_archive_exit(archive);
+ return NULL; /* Error is set by lzma_err! */
+ } /* if */
+
+ len = archive->db.Database.NumFiles * sizeof (LZMAfile);
+ archive->files = (LZMAfile *) allocator.Malloc(len);
+ if (archive->files == NULL)
+ {
+ SzArDbExFree(&archive->db, SzFreePhysicsFS);
+ lzma_archive_exit(archive);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ }
+
+ /*
+ * Init with 0 so we know when a folder is already cached
+ * Values will be set by LZMA_openRead()
+ */
+ memset(archive->files, 0, len);
+
+ len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
+ archive->folders = (LZMAfolder *) allocator.Malloc(len);
+ if (archive->folders == NULL)
+ {
+ SzArDbExFree(&archive->db, SzFreePhysicsFS);
+ lzma_archive_exit(archive);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ }
+
+ /*
+ * Init with 0 so we know when a folder is already cached
+ * Values will be set by LZMA_read()
+ */
+ memset(archive->folders, 0, len);
+
+ if(!lzma_files_init(archive))
+ {
+ SzArDbExFree(&archive->db, SzFreePhysicsFS);
+ lzma_archive_exit(archive);
+ BAIL_MACRO(PHYSFS_ERR_OTHER_ERROR, NULL);
+ }
+
+ return archive;
+} /* LZMA_openArchive */
+
+
+/*
+ * Moved to seperate function so we can use alloca then immediately throw
+ * away the allocated stack space...
+ */
+static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
+ const char *odir, const char *str, size_t flen)
+{
+ char *newstr = __PHYSFS_smallAlloc(flen + 1);
+ if (newstr == NULL)
+ return;
+
+ memcpy(newstr, str, flen);
+ newstr[flen] = '\0';
+ cb(callbackdata, odir, newstr);
+ __PHYSFS_smallFree(newstr);
+} /* doEnumCallback */
+
+
+static void LZMA_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata)
+{
+ size_t dlen = strlen(dname),
+ dlen_inc = dlen + ((dlen > 0) ? 1 : 0);
+ LZMAarchive *archive = (LZMAarchive *) opaque;
+ LZMAfile *file = NULL,
+ *lastFile = &archive->files[archive->db.Database.NumFiles];
+ if (dlen)
+ {
+ file = lzma_find_file(archive, dname);
+ if (file != NULL) /* if 'file' is NULL it should stay so, otherwise errors will not be handled */
+ file += 1;
+ }
+ else
+ {
+ file = archive->files;
+ }
+
+ BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, );
+
+ while (file < lastFile)
+ {
+ const char * fname = file->item->Name;
+ const char * dirNameEnd = fname + dlen_inc;
+
+ if (strncmp(dname, fname, dlen) != 0) /* Stop after mismatch, archive->files is sorted */
+ break;
+
+ if (strchr(dirNameEnd, '/')) /* Skip subdirs */
+ {
+ file++;
+ continue;
+ }
+
+ /* Do the actual callback... */
+ doEnumCallback(cb, callbackdata, origdir, dirNameEnd, strlen(dirNameEnd));
+
+ file++;
+ }
+} /* LZMA_enumerateFiles */
+
+
+static PHYSFS_Io *LZMA_openRead(PHYSFS_Dir *opaque, const char *name,
+ int *fileExists)
+{
+ LZMAarchive *archive = (LZMAarchive *) opaque;
+ LZMAfile *file = lzma_find_file(archive, name);
+ PHYSFS_Io *io = NULL;
+
+ *fileExists = (file != NULL);
+ BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
+ BAIL_IF_MACRO(file->folder == NULL, PHYSFS_ERR_NOT_A_FILE, NULL);
+
+ file->position = 0;
+ file->folder->references++; /* Increase refcount for automatic cleanup... */
+
+ io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ BAIL_IF_MACRO(io == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ memcpy(io, &LZMA_Io, sizeof (*io));
+ io->opaque = file;
+
+ return io;
+} /* LZMA_openRead */
+
+
+static PHYSFS_Io *LZMA_openWrite(PHYSFS_Dir *opaque, const char *filename)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* LZMA_openWrite */
+
+
+static PHYSFS_Io *LZMA_openAppend(PHYSFS_Dir *opaque, const char *filename)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* LZMA_openAppend */
+
+
+static void LZMA_closeArchive(PHYSFS_Dir *opaque)
+{
+ LZMAarchive *archive = (LZMAarchive *) opaque;
+
+#if 0 /* !!! FIXME: you shouldn't have to do this. */
+ PHYSFS_uint32 fileIndex = 0, numFiles = archive->db.Database.NumFiles;
+ for (fileIndex = 0; fileIndex < numFiles; fileIndex++)
+ {
+ LZMA_fileClose(&archive->files[fileIndex]);
+ } /* for */
+#endif
+
+ SzArDbExFree(&archive->db, SzFreePhysicsFS);
+ archive->stream.io->destroy(archive->stream.io);
+ lzma_archive_exit(archive);
+} /* LZMA_closeArchive */
+
+
+static int LZMA_remove(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* LZMA_remove */
+
+
+static int LZMA_mkdir(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* LZMA_mkdir */
+
+static int LZMA_stat(PHYSFS_Dir *opaque, const char *filename,
+ int *exists, PHYSFS_Stat *stat)
+{
+ const LZMAarchive *archive = (const LZMAarchive *) opaque;
+ const LZMAfile *file = lzma_find_file(archive, filename);
+
+ *exists = (file != 0);
+ if (!file)
+ return 0;
+
+ if(file->item->IsDirectory)
+ {
+ stat->filesize = 0;
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ } /* if */
+ else
+ {
+ stat->filesize = (PHYSFS_sint64) file->item->Size;
+ stat->filetype = PHYSFS_FILETYPE_REGULAR;
+ } /* else */
+
+ /* !!! FIXME: the 0's should be -1's? */
+ if (file->item->IsLastWriteTimeDefined)
+ stat->modtime = lzma_filetime_to_unix_timestamp(&file->item->LastWriteTime);
+ else
+ stat->modtime = 0;
+
+ /* real create and accesstype are currently not in the lzma SDK */
+ stat->createtime = stat->modtime;
+ stat->accesstime = 0;
+
+ stat->readonly = 1; /* 7zips are always read only */
+
+ return 1;
+} /* LZMA_stat */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_LZMA =
+{
+ {
+ "7Z",
+ "LZMA (7zip) format",
+ "Dennis Schridde <devurandom at gmx.net>",
+ "http://icculus.org/physfs/",
+ },
+ LZMA_openArchive, /* openArchive() method */
+ LZMA_enumerateFiles, /* enumerateFiles() method */
+ LZMA_openRead, /* openRead() method */
+ LZMA_openWrite, /* openWrite() method */
+ LZMA_openAppend, /* openAppend() method */
+ LZMA_remove, /* remove() method */
+ LZMA_mkdir, /* mkdir() method */
+ LZMA_closeArchive, /* closeArchive() method */
+ LZMA_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_7Z */
+
+/* end of lzma.c ... */
+
diff --git a/misc/libphysfs/archiver_mvl.c b/misc/libphysfs/archiver_mvl.c
new file mode 100644
index 0000000..f33dbe1
--- /dev/null
+++ b/misc/libphysfs/archiver_mvl.c
@@ -0,0 +1,103 @@
+/*
+ * MVL support routines for PhysicsFS.
+ *
+ * This driver handles Descent II Movielib archives.
+ *
+ * The file format of MVL is quite easy...
+ *
+ * //MVL File format - Written by Heiko Herrmann
+ * char sig[4] = {'D','M', 'V', 'L'}; // "DMVL"=Descent MoVie Library
+ *
+ * int num_files; // the number of files in this MVL
+ *
+ * struct {
+ * char file_name[13]; // Filename, padded to 13 bytes with 0s
+ * int file_size; // filesize in bytes
+ * }DIR_STRUCT[num_files];
+ *
+ * struct {
+ * char data[file_size]; // The file data
+ * }FILE_STRUCT[num_files];
+ *
+ * (That info is from http://www.descent2.com/ddn/specs/mvl/)
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Bradley Bell.
+ * Based on grp.c by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_MVL
+
+static UNPKentry *mvlLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
+{
+ PHYSFS_uint32 location = 8; /* sizeof sig. */
+ UNPKentry *entries = NULL;
+ UNPKentry *entry = NULL;
+
+ entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
+ BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ location += (17 * fileCount);
+
+ for (entry = entries; fileCount > 0; fileCount--, entry++)
+ {
+ if (!__PHYSFS_readAll(io, &entry->name, 13)) goto failed;
+ if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
+ entry->size = PHYSFS_swapULE32(entry->size);
+ entry->startPos = location;
+ location += entry->size;
+ } /* for */
+
+ return entries;
+
+failed:
+ allocator.Free(entries);
+ return NULL;
+} /* mvlLoadEntries */
+
+
+static void *MVL_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_uint8 buf[4];
+ PHYSFS_uint32 count = 0;
+ UNPKentry *entries = NULL;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, 4), ERRPASS, NULL);
+ BAIL_IF_MACRO(memcmp(buf, "DMVL", 4) != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof(count)), ERRPASS, NULL);
+
+ count = PHYSFS_swapULE32(count);
+ entries = mvlLoadEntries(io, count);
+ return (!entries) ? NULL : UNPK_openArchive(io, entries, count);
+} /* MVL_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
+{
+ {
+ "MVL",
+ "Descent II Movielib format",
+ "Bradley Bell <btb at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ MVL_openArchive, /* openArchive() method */
+ UNPK_enumerateFiles, /* enumerateFiles() method */
+ UNPK_openRead, /* openRead() method */
+ UNPK_openWrite, /* openWrite() method */
+ UNPK_openAppend, /* openAppend() method */
+ UNPK_remove, /* remove() method */
+ UNPK_mkdir, /* mkdir() method */
+ UNPK_closeArchive, /* closeArchive() method */
+ UNPK_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_MVL */
+
+/* end of mvl.c ... */
+
diff --git a/misc/libphysfs/archiver_qpak.c b/misc/libphysfs/archiver_qpak.c
new file mode 100644
index 0000000..67927e5
--- /dev/null
+++ b/misc/libphysfs/archiver_qpak.c
@@ -0,0 +1,119 @@
+/*
+ * QPAK support routines for PhysicsFS.
+ *
+ * This archiver handles the archive format utilized by Quake 1 and 2.
+ * Quake3-based games use the PkZip/Info-Zip format (which our zip.c
+ * archiver handles).
+ *
+ * ========================================================================
+ *
+ * This format info (in more detail) comes from:
+ * http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/pak.txt
+ *
+ * Quake PAK Format
+ *
+ * Header
+ * (4 bytes) signature = 'PACK'
+ * (4 bytes) directory offset
+ * (4 bytes) directory length
+ *
+ * Directory
+ * (56 bytes) file name
+ * (4 bytes) file position
+ * (4 bytes) file length
+ *
+ * ========================================================================
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_QPAK
+
+#define QPAK_SIG 0x4B434150 /* "PACK" in ASCII. */
+
+static UNPKentry *qpakLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
+{
+ UNPKentry *entries = NULL;
+ UNPKentry *entry = NULL;
+
+ entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
+ BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ for (entry = entries; fileCount > 0; fileCount--, entry++)
+ {
+ if (!__PHYSFS_readAll(io, &entry->name, 56)) goto failed;
+ if (!__PHYSFS_readAll(io, &entry->startPos, 4)) goto failed;
+ if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
+ entry->size = PHYSFS_swapULE32(entry->size);
+ entry->startPos = PHYSFS_swapULE32(entry->startPos);
+ } /* for */
+
+ return entries;
+
+failed:
+ allocator.Free(entries);
+ return NULL;
+} /* qpakLoadEntries */
+
+
+static void *QPAK_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ UNPKentry *entries = NULL;
+ PHYSFS_uint32 val = 0;
+ PHYSFS_uint32 pos = 0;
+ PHYSFS_uint32 count = 0;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
+ if (PHYSFS_swapULE32(val) != QPAK_SIG)
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
+ pos = PHYSFS_swapULE32(val); /* directory table offset. */
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
+ count = PHYSFS_swapULE32(val);
+
+ /* corrupted archive? */
+ BAIL_IF_MACRO((count % 64) != 0, PHYSFS_ERR_CORRUPT, NULL);
+ count /= 64;
+
+ BAIL_IF_MACRO(!io->seek(io, pos), ERRPASS, NULL);
+
+ entries = qpakLoadEntries(io, count);
+ BAIL_IF_MACRO(!entries, ERRPASS, NULL);
+ return UNPK_openArchive(io, entries, count);
+} /* QPAK_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
+{
+ {
+ "PAK",
+ "Quake I/II format",
+ "Ryan C. Gordon <icculus at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ QPAK_openArchive, /* openArchive() method */
+ UNPK_enumerateFiles, /* enumerateFiles() method */
+ UNPK_openRead, /* openRead() method */
+ UNPK_openWrite, /* openWrite() method */
+ UNPK_openAppend, /* openAppend() method */
+ UNPK_remove, /* remove() method */
+ UNPK_mkdir, /* mkdir() method */
+ UNPK_closeArchive, /* closeArchive() method */
+ UNPK_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_QPAK */
+
+/* end of qpak.c ... */
+
diff --git a/misc/libphysfs/archiver_unpacked.c b/misc/libphysfs/archiver_unpacked.c
new file mode 100644
index 0000000..1a7c104
--- /dev/null
+++ b/misc/libphysfs/archiver_unpacked.c
@@ -0,0 +1,470 @@
+/*
+ * High-level PhysicsFS archiver for simple unpacked file formats.
+ *
+ * This is a framework that basic archivers build on top of. It's for simple
+ * formats that can just hand back a list of files and the offsets of their
+ * uncompressed data. There are an alarming number of formats like this.
+ *
+ * RULES: Archive entries must be uncompressed, must not have separate subdir
+ * entries (but can have subdirs), must be case insensitive LOW ASCII
+ * filenames <= 56 bytes. No symlinks, etc. We can relax some of these rules
+ * as necessary.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+typedef struct
+{
+ PHYSFS_Io *io;
+ PHYSFS_uint32 entryCount;
+ UNPKentry *entries;
+} UNPKinfo;
+
+
+typedef struct
+{
+ PHYSFS_Io *io;
+ UNPKentry *entry;
+ PHYSFS_uint32 curPos;
+} UNPKfileinfo;
+
+
+void UNPK_closeArchive(PHYSFS_Dir *opaque)
+{
+ UNPKinfo *info = ((UNPKinfo *) opaque);
+ info->io->destroy(info->io);
+ allocator.Free(info->entries);
+ allocator.Free(info);
+} /* UNPK_closeArchive */
+
+
+static PHYSFS_sint64 UNPK_read(PHYSFS_Io *io, void *buffer, PHYSFS_uint64 len)
+{
+ UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
+ const UNPKentry *entry = finfo->entry;
+ const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
+ PHYSFS_sint64 rc;
+
+ if (bytesLeft < len)
+ len = bytesLeft;
+
+ rc = finfo->io->read(finfo->io, buffer, len);
+ if (rc > 0)
+ finfo->curPos += (PHYSFS_uint32) rc;
+
+ return rc;
+} /* UNPK_read */
+
+
+static PHYSFS_sint64 UNPK_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, -1);
+} /* UNPK_write */
+
+
+static PHYSFS_sint64 UNPK_tell(PHYSFS_Io *io)
+{
+ return ((UNPKfileinfo *) io->opaque)->curPos;
+} /* UNPK_tell */
+
+
+static int UNPK_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
+ const UNPKentry *entry = finfo->entry;
+ int rc;
+
+ BAIL_IF_MACRO(offset >= entry->size, PHYSFS_ERR_PAST_EOF, 0);
+ rc = finfo->io->seek(finfo->io, entry->startPos + offset);
+ if (rc)
+ finfo->curPos = (PHYSFS_uint32) offset;
+
+ return rc;
+} /* UNPK_seek */
+
+
+static PHYSFS_sint64 UNPK_length(PHYSFS_Io *io)
+{
+ const UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
+ return ((PHYSFS_sint64) finfo->entry->size);
+} /* UNPK_length */
+
+
+static PHYSFS_Io *UNPK_duplicate(PHYSFS_Io *_io)
+{
+ UNPKfileinfo *origfinfo = (UNPKfileinfo *) _io->opaque;
+ PHYSFS_Io *io = NULL;
+ PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ UNPKfileinfo *finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
+ GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
+ GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
+
+ io = origfinfo->io->duplicate(origfinfo->io);
+ if (!io) goto UNPK_duplicate_failed;
+ finfo->io = io;
+ finfo->entry = origfinfo->entry;
+ finfo->curPos = 0;
+ memcpy(retval, _io, sizeof (PHYSFS_Io));
+ retval->opaque = finfo;
+ return retval;
+
+UNPK_duplicate_failed:
+ if (finfo != NULL) allocator.Free(finfo);
+ if (retval != NULL) allocator.Free(retval);
+ if (io != NULL) io->destroy(io);
+ return NULL;
+} /* UNPK_duplicate */
+
+static int UNPK_flush(PHYSFS_Io *io) { return 1; /* no write support. */ }
+
+static void UNPK_destroy(PHYSFS_Io *io)
+{
+ UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
+ finfo->io->destroy(finfo->io);
+ allocator.Free(finfo);
+ allocator.Free(io);
+} /* UNPK_destroy */
+
+
+static const PHYSFS_Io UNPK_Io =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ UNPK_read,
+ UNPK_write,
+ UNPK_seek,
+ UNPK_tell,
+ UNPK_length,
+ UNPK_duplicate,
+ UNPK_flush,
+ UNPK_destroy
+};
+
+
+static int entryCmp(void *_a, size_t one, size_t two)
+{
+ if (one != two)
+ {
+ const UNPKentry *a = (const UNPKentry *) _a;
+ return __PHYSFS_stricmpASCII(a[one].name, a[two].name);
+ } /* if */
+
+ return 0;
+} /* entryCmp */
+
+
+static void entrySwap(void *_a, size_t one, size_t two)
+{
+ if (one != two)
+ {
+ UNPKentry tmp;
+ UNPKentry *first = &(((UNPKentry *) _a)[one]);
+ UNPKentry *second = &(((UNPKentry *) _a)[two]);
+ memcpy(&tmp, first, sizeof (UNPKentry));
+ memcpy(first, second, sizeof (UNPKentry));
+ memcpy(second, &tmp, sizeof (UNPKentry));
+ } /* if */
+} /* entrySwap */
+
+
+static PHYSFS_sint32 findStartOfDir(UNPKinfo *info, const char *path,
+ int stop_on_first_find)
+{
+ PHYSFS_sint32 lo = 0;
+ PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
+ PHYSFS_sint32 middle;
+ PHYSFS_uint32 dlen = (PHYSFS_uint32) strlen(path);
+ PHYSFS_sint32 retval = -1;
+ const char *name;
+ int rc;
+
+ if (*path == '\0') /* root dir? */
+ return 0;
+
+ if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen--;
+
+ while (lo <= hi)
+ {
+ middle = lo + ((hi - lo) / 2);
+ name = info->entries[middle].name;
+ rc = __PHYSFS_strnicmpASCII(path, name, dlen);
+ if (rc == 0)
+ {
+ char ch = name[dlen];
+ if (ch < '/') /* make sure this isn't just a substr match. */
+ rc = -1;
+ else if (ch > '/')
+ rc = 1;
+ else
+ {
+ if (stop_on_first_find) /* Just checking dir's existance? */
+ return middle;
+
+ if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
+ return (middle + 1);
+
+ /* there might be more entries earlier in the list. */
+ retval = middle;
+ hi = middle - 1;
+ } /* else */
+ } /* if */
+
+ if (rc > 0)
+ lo = middle + 1;
+ else
+ hi = middle - 1;
+ } /* while */
+
+ return retval;
+} /* findStartOfDir */
+
+
+/*
+ * Moved to seperate function so we can use alloca then immediately throw
+ * away the allocated stack space...
+ */
+static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
+ const char *odir, const char *str, PHYSFS_sint32 ln)
+{
+ char *newstr = __PHYSFS_smallAlloc(ln + 1);
+ if (newstr == NULL)
+ return;
+
+ memcpy(newstr, str, ln);
+ newstr[ln] = '\0';
+ cb(callbackdata, odir, newstr);
+ __PHYSFS_smallFree(newstr);
+} /* doEnumCallback */
+
+
+void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata)
+{
+ UNPKinfo *info = ((UNPKinfo *) opaque);
+ PHYSFS_sint32 dlen, dlen_inc, max, i;
+
+ i = findStartOfDir(info, dname, 0);
+ if (i == -1) /* no such directory. */
+ return;
+
+ dlen = (PHYSFS_sint32) strlen(dname);
+ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen--;
+
+ dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
+ max = (PHYSFS_sint32) info->entryCount;
+ while (i < max)
+ {
+ char *add;
+ char *ptr;
+ PHYSFS_sint32 ln;
+ char *e = info->entries[i].name;
+ if ((dlen) &&
+ ((__PHYSFS_strnicmpASCII(e, dname, dlen)) || (e[dlen] != '/')))
+ {
+ break; /* past end of this dir; we're done. */
+ } /* if */
+
+ add = e + dlen_inc;
+ ptr = strchr(add, '/');
+ ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
+ doEnumCallback(cb, callbackdata, origdir, add, ln);
+ ln += dlen_inc; /* point past entry to children... */
+
+ /* increment counter and skip children of subdirs... */
+ while ((++i < max) && (ptr != NULL))
+ {
+ char *e_new = info->entries[i].name;
+ if ((__PHYSFS_strnicmpASCII(e, e_new, ln) != 0) ||
+ (e_new[ln] != '/'))
+ {
+ break;
+ } /* if */
+ } /* while */
+ } /* while */
+} /* UNPK_enumerateFiles */
+
+
+/*
+ * This will find the UNPKentry associated with a path in platform-independent
+ * notation. Directories don't have UNPKentries associated with them, but
+ * (*isDir) will be set to non-zero if a dir was hit.
+ */
+static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir)
+{
+ UNPKentry *a = info->entries;
+ PHYSFS_sint32 pathlen = (PHYSFS_sint32) strlen(path);
+ PHYSFS_sint32 lo = 0;
+ PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
+ PHYSFS_sint32 middle;
+ const char *thispath = NULL;
+ int rc;
+
+ while (lo <= hi)
+ {
+ middle = lo + ((hi - lo) / 2);
+ thispath = a[middle].name;
+ rc = __PHYSFS_strnicmpASCII(path, thispath, pathlen);
+
+ if (rc > 0)
+ lo = middle + 1;
+
+ else if (rc < 0)
+ hi = middle - 1;
+
+ else /* substring match...might be dir or entry or nothing. */
+ {
+ if (isDir != NULL)
+ {
+ *isDir = (thispath[pathlen] == '/');
+ if (*isDir)
+ return NULL;
+ } /* if */
+
+ if (thispath[pathlen] == '\0') /* found entry? */
+ return &a[middle];
+ /* adjust search params, try again. */
+ else if (thispath[pathlen] > '/')
+ hi = middle - 1;
+ else
+ lo = middle + 1;
+ } /* if */
+ } /* while */
+
+ if (isDir != NULL)
+ *isDir = 0;
+
+ BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
+} /* findEntry */
+
+
+PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists)
+{
+ PHYSFS_Io *retval = NULL;
+ UNPKinfo *info = (UNPKinfo *) opaque;
+ UNPKfileinfo *finfo = NULL;
+ int isdir = 0;
+ UNPKentry *entry = findEntry(info, fnm, &isdir);
+
+ *fileExists = (entry != NULL);
+ GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed);
+ GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed);
+
+ retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
+
+ finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
+ GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
+
+ finfo->io = info->io->duplicate(info->io);
+ GOTO_IF_MACRO(!finfo->io, ERRPASS, UNPK_openRead_failed);
+
+ if (!finfo->io->seek(finfo->io, entry->startPos))
+ goto UNPK_openRead_failed;
+
+ finfo->curPos = 0;
+ finfo->entry = entry;
+
+ memcpy(retval, &UNPK_Io, sizeof (*retval));
+ retval->opaque = finfo;
+ return retval;
+
+UNPK_openRead_failed:
+ if (finfo != NULL)
+ {
+ if (finfo->io != NULL)
+ finfo->io->destroy(finfo->io);
+ allocator.Free(finfo);
+ } /* if */
+
+ if (retval != NULL)
+ allocator.Free(retval);
+
+ return NULL;
+} /* UNPK_openRead */
+
+
+PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* UNPK_openWrite */
+
+
+PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* UNPK_openAppend */
+
+
+int UNPK_remove(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* UNPK_remove */
+
+
+int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* UNPK_mkdir */
+
+
+int UNPK_stat(PHYSFS_Dir *opaque, const char *filename,
+ int *exists, PHYSFS_Stat *stat)
+{
+ int isDir = 0;
+ const UNPKinfo *info = (const UNPKinfo *) opaque;
+ const UNPKentry *entry = findEntry(info, filename, &isDir);
+
+ if (isDir)
+ {
+ *exists = 1;
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ stat->filesize = 0;
+ } /* if */
+ else if (entry != NULL)
+ {
+ *exists = 1;
+ stat->filetype = PHYSFS_FILETYPE_REGULAR;
+ stat->filesize = entry->size;
+ } /* else if */
+ else
+ {
+ *exists = 0;
+ return 0;
+ } /* else */
+
+ stat->modtime = -1;
+ stat->createtime = -1;
+ stat->accesstime = -1;
+ stat->readonly = 1;
+
+ return 1;
+} /* UNPK_stat */
+
+
+PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e,
+ const PHYSFS_uint32 num)
+{
+ UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
+ if (info == NULL)
+ {
+ allocator.Free(e);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ __PHYSFS_sort(e, (size_t) num, entryCmp, entrySwap);
+ info->io = io;
+ info->entryCount = num;
+ info->entries = e;
+
+ return info;
+} /* UNPK_openArchive */
+
+/* end of archiver_unpacked.c ... */
+
diff --git a/misc/libphysfs/archiver_wad.c b/misc/libphysfs/archiver_wad.c
new file mode 100644
index 0000000..7d3db54
--- /dev/null
+++ b/misc/libphysfs/archiver_wad.c
@@ -0,0 +1,127 @@
+/*
+ * WAD support routines for PhysicsFS.
+ *
+ * This driver handles DOOM engine archives ("wads").
+ * This format (but not this driver) was designed by id Software for use
+ * with the DOOM engine.
+ * The specs of the format are from the unofficial doom specs v1.666
+ * found here: http://www.gamers.org/dhs/helpdocs/dmsp1666.html
+ * The format of the archive: (from the specs)
+ *
+ * A WAD file has three parts:
+ * (1) a twelve-byte header
+ * (2) one or more "lumps"
+ * (3) a directory or "info table" that contains the names, offsets, and
+ * sizes of all the lumps in the WAD
+ *
+ * The header consists of three four-byte parts:
+ * (a) an ASCII string which must be either "IWAD" or "PWAD"
+ * (b) a 4-byte (long) integer which is the number of lumps in the wad
+ * (c) a long integer which is the file offset to the start of
+ * the directory
+ *
+ * The directory has one 16-byte entry for every lump. Each entry consists
+ * of three parts:
+ *
+ * (a) a long integer, the file offset to the start of the lump
+ * (b) a long integer, the size of the lump in bytes
+ * (c) an 8-byte ASCII string, the name of the lump, padded with zeros.
+ * For example, the "DEMO1" entry in hexadecimal would be
+ * (44 45 4D 4F 31 00 00 00)
+ *
+ * Note that there is no way to tell if an opened WAD archive is a
+ * IWAD or PWAD with this archiver.
+ * I couldn't think of a way to provide that information, without being too
+ * hacky.
+ * I don't think it's really that important though.
+ *
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Travis Wells, based on the GRP archiver by
+ * Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_WAD
+
+static UNPKentry *wadLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
+{
+ PHYSFS_uint32 directoryOffset;
+ UNPKentry *entries = NULL;
+ UNPKentry *entry = NULL;
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &directoryOffset, 4), ERRPASS, 0);
+ directoryOffset = PHYSFS_swapULE32(directoryOffset);
+
+ BAIL_IF_MACRO(!io->seek(io, directoryOffset), ERRPASS, 0);
+
+ entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
+ BAIL_IF_MACRO(!entries, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ for (entry = entries; fileCount > 0; fileCount--, entry++)
+ {
+ if (!__PHYSFS_readAll(io, &entry->startPos, 4)) goto failed;
+ if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
+ if (!__PHYSFS_readAll(io, &entry->name, 8)) goto failed;
+
+ entry->name[8] = '\0'; /* name might not be null-terminated in file. */
+ entry->size = PHYSFS_swapULE32(entry->size);
+ entry->startPos = PHYSFS_swapULE32(entry->startPos);
+ } /* for */
+
+ return entries;
+
+failed:
+ allocator.Free(entries);
+ return NULL;
+} /* wadLoadEntries */
+
+
+static void *WAD_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ PHYSFS_uint8 buf[4];
+ UNPKentry *entries = NULL;
+ PHYSFS_uint32 count = 0;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, sizeof (buf)), ERRPASS, NULL);
+ if ((memcmp(buf, "IWAD", 4) != 0) && (memcmp(buf, "PWAD", 4) != 0))
+ BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof (count)), ERRPASS, NULL);
+ count = PHYSFS_swapULE32(count);
+
+ entries = wadLoadEntries(io, count);
+ BAIL_IF_MACRO(!entries, ERRPASS, NULL);
+ return UNPK_openArchive(io, entries, count);
+} /* WAD_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
+{
+ {
+ "WAD",
+ "DOOM engine format",
+ "Travis Wells <traviswells at mchsi.com>",
+ "http://www.3dmm2.com/doom/",
+ },
+ WAD_openArchive, /* openArchive() method */
+ UNPK_enumerateFiles, /* enumerateFiles() method */
+ UNPK_openRead, /* openRead() method */
+ UNPK_openWrite, /* openWrite() method */
+ UNPK_openAppend, /* openAppend() method */
+ UNPK_remove, /* remove() method */
+ UNPK_mkdir, /* mkdir() method */
+ UNPK_closeArchive, /* closeArchive() method */
+ UNPK_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_WAD */
+
+/* end of wad.c ... */
+
diff --git a/misc/libphysfs/archiver_zip.c b/misc/libphysfs/archiver_zip.c
new file mode 100644
index 0000000..b1663c6
--- /dev/null
+++ b/misc/libphysfs/archiver_zip.c
@@ -0,0 +1,1717 @@
+/*
+ * ZIP support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon, with some peeking at "unzip.c"
+ * by Gilles Vollant.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_ZIP
+
+#include <errno.h>
+#include <time.h>
+
+#define USE_MINIZ 1
+#if USE_MINIZ
+#include "physfs_miniz.h"
+#else
+#include <zlib.h>
+#endif
+
+/*
+ * A buffer of ZIP_READBUFSIZE is allocated for each compressed file opened,
+ * and is freed when you close the file; compressed data is read into
+ * this buffer, and then is decompressed into the buffer passed to
+ * PHYSFS_read().
+ *
+ * Uncompressed entries in a zipfile do not allocate this buffer; they just
+ * read data directly into the buffer passed to PHYSFS_read().
+ *
+ * Depending on your speed and memory requirements, you should tweak this
+ * value.
+ */
+#define ZIP_READBUFSIZE (16 * 1024)
+
+
+/*
+ * Entries are "unresolved" until they are first opened. At that time,
+ * local file headers parsed/validated, data offsets will be updated to look
+ * at the actual file data instead of the header, and symlinks will be
+ * followed and optimized. This means that we don't seek and read around the
+ * archive until forced to do so, and after the first time, we had to do
+ * less reading and parsing, which is very CD-ROM friendly.
+ */
+typedef enum
+{
+ ZIP_UNRESOLVED_FILE,
+ ZIP_UNRESOLVED_SYMLINK,
+ ZIP_RESOLVING,
+ ZIP_RESOLVED,
+ ZIP_BROKEN_FILE,
+ ZIP_BROKEN_SYMLINK
+} ZipResolveType;
+
+
+/*
+ * One ZIPentry is kept for each file in an open ZIP archive.
+ */
+typedef struct _ZIPentry
+{
+ char *name; /* Name of file in archive */
+ struct _ZIPentry *symlink; /* NULL or file we symlink to */
+ ZipResolveType resolved; /* Have we resolved file/symlink? */
+ PHYSFS_uint64 offset; /* offset of data in archive */
+ PHYSFS_uint16 version; /* version made by */
+ PHYSFS_uint16 version_needed; /* version needed to extract */
+ PHYSFS_uint16 compression_method; /* compression method */
+ PHYSFS_uint32 crc; /* crc-32 */
+ PHYSFS_uint64 compressed_size; /* compressed size */
+ PHYSFS_uint64 uncompressed_size; /* uncompressed size */
+ PHYSFS_sint64 last_mod_time; /* last file mod time */
+} ZIPentry;
+
+/*
+ * One ZIPinfo is kept for each open ZIP archive.
+ */
+typedef struct
+{
+ PHYSFS_Io *io;
+ int zip64; /* non-zero if this is a Zip64 archive. */
+ PHYSFS_uint64 entryCount; /* Number of files in ZIP. */
+ ZIPentry *entries; /* info on all files in ZIP. */
+} ZIPinfo;
+
+/*
+ * One ZIPfileinfo is kept for each open file in a ZIP archive.
+ */
+typedef struct
+{
+ ZIPentry *entry; /* Info on file. */
+ PHYSFS_Io *io; /* physical file handle. */
+ PHYSFS_uint32 compressed_position; /* offset in compressed data. */
+ PHYSFS_uint32 uncompressed_position; /* tell() position. */
+ PHYSFS_uint8 *buffer; /* decompression buffer. */
+ z_stream stream; /* zlib stream state. */
+} ZIPfileinfo;
+
+
+/* Magic numbers... */
+#define ZIP_LOCAL_FILE_SIG 0x04034b50
+#define ZIP_CENTRAL_DIR_SIG 0x02014b50
+#define ZIP_END_OF_CENTRAL_DIR_SIG 0x06054b50
+#define ZIP64_END_OF_CENTRAL_DIR_SIG 0x06064b50
+#define ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG 0x07064b50
+#define ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG 0x0001
+
+/* compression methods... */
+#define COMPMETH_NONE 0
+/* ...and others... */
+
+
+#define UNIX_FILETYPE_MASK 0170000
+#define UNIX_FILETYPE_SYMLINK 0120000
+
+
+/*
+ * Bridge physfs allocation functions to zlib's format...
+ */
+static voidpf zlibPhysfsAlloc(voidpf opaque, uInt items, uInt size)
+{
+ return ((PHYSFS_Allocator *) opaque)->Malloc(items * size);
+} /* zlibPhysfsAlloc */
+
+/*
+ * Bridge physfs allocation functions to zlib's format...
+ */
+static void zlibPhysfsFree(voidpf opaque, voidpf address)
+{
+ ((PHYSFS_Allocator *) opaque)->Free(address);
+} /* zlibPhysfsFree */
+
+
+/*
+ * Construct a new z_stream to a sane state.
+ */
+static void initializeZStream(z_stream *pstr)
+{
+ memset(pstr, '\0', sizeof (z_stream));
+ pstr->zalloc = zlibPhysfsAlloc;
+ pstr->zfree = zlibPhysfsFree;
+ pstr->opaque = &allocator;
+} /* initializeZStream */
+
+
+static PHYSFS_ErrorCode zlib_error_code(int rc)
+{
+ switch (rc)
+ {
+ case Z_OK: return PHYSFS_ERR_OK; /* not an error. */
+ case Z_STREAM_END: return PHYSFS_ERR_OK; /* not an error. */
+ case Z_ERRNO: return PHYSFS_ERR_IO;
+ case Z_MEM_ERROR: return PHYSFS_ERR_OUT_OF_MEMORY;
+ default: return PHYSFS_ERR_CORRUPT;
+ } /* switch */
+} /* zlib_error_string */
+
+
+/*
+ * Wrap all zlib calls in this, so the physfs error state is set appropriately.
+ */
+static int zlib_err(const int rc)
+{
+ __PHYSFS_setError(zlib_error_code(rc));
+ return rc;
+} /* zlib_err */
+
+
+/*
+ * Read an unsigned 64-bit int and swap to native byte order.
+ */
+static int readui64(PHYSFS_Io *io, PHYSFS_uint64 *val)
+{
+ PHYSFS_uint64 v;
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &v, sizeof (v)), ERRPASS, 0);
+ *val = PHYSFS_swapULE64(v);
+ return 1;
+} /* readui64 */
+
+/*
+ * Read an unsigned 32-bit int and swap to native byte order.
+ */
+static int readui32(PHYSFS_Io *io, PHYSFS_uint32 *val)
+{
+ PHYSFS_uint32 v;
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &v, sizeof (v)), ERRPASS, 0);
+ *val = PHYSFS_swapULE32(v);
+ return 1;
+} /* readui32 */
+
+
+/*
+ * Read an unsigned 16-bit int and swap to native byte order.
+ */
+static int readui16(PHYSFS_Io *io, PHYSFS_uint16 *val)
+{
+ PHYSFS_uint16 v;
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, &v, sizeof (v)), ERRPASS, 0);
+ *val = PHYSFS_swapULE16(v);
+ return 1;
+} /* readui16 */
+
+
+static PHYSFS_sint64 ZIP_read(PHYSFS_Io *_io, void *buf, PHYSFS_uint64 len)
+{
+ ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
+ PHYSFS_Io *io = finfo->io;
+ ZIPentry *entry = finfo->entry;
+ PHYSFS_sint64 retval = 0;
+ PHYSFS_sint64 maxread = (PHYSFS_sint64) len;
+ PHYSFS_sint64 avail = entry->uncompressed_size -
+ finfo->uncompressed_position;
+
+ if (avail < maxread)
+ maxread = avail;
+
+ BAIL_IF_MACRO(maxread == 0, ERRPASS, 0); /* quick rejection. */
+
+ if (entry->compression_method == COMPMETH_NONE)
+ retval = io->read(io, buf, maxread);
+ else
+ {
+ finfo->stream.next_out = buf;
+ finfo->stream.avail_out = (uInt) maxread;
+
+ while (retval < maxread)
+ {
+ PHYSFS_uint32 before = finfo->stream.total_out;
+ int rc;
+
+ if (finfo->stream.avail_in == 0)
+ {
+ PHYSFS_sint64 br;
+
+ br = entry->compressed_size - finfo->compressed_position;
+ if (br > 0)
+ {
+ if (br > ZIP_READBUFSIZE)
+ br = ZIP_READBUFSIZE;
+
+ br = io->read(io, finfo->buffer, (PHYSFS_uint64) br);
+ if (br <= 0)
+ break;
+
+ finfo->compressed_position += (PHYSFS_uint32) br;
+ finfo->stream.next_in = finfo->buffer;
+ finfo->stream.avail_in = (PHYSFS_uint32) br;
+ } /* if */
+ } /* if */
+
+ rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
+ retval += (finfo->stream.total_out - before);
+
+ if (rc != Z_OK)
+ break;
+ } /* while */
+ } /* else */
+
+ if (retval > 0)
+ finfo->uncompressed_position += (PHYSFS_uint32) retval;
+
+ return retval;
+} /* ZIP_read */
+
+
+static PHYSFS_sint64 ZIP_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, -1);
+} /* ZIP_write */
+
+
+static PHYSFS_sint64 ZIP_tell(PHYSFS_Io *io)
+{
+ return ((ZIPfileinfo *) io->opaque)->uncompressed_position;
+} /* ZIP_tell */
+
+
+static int ZIP_seek(PHYSFS_Io *_io, PHYSFS_uint64 offset)
+{
+ ZIPfileinfo *finfo = (ZIPfileinfo *) _io->opaque;
+ ZIPentry *entry = finfo->entry;
+ PHYSFS_Io *io = finfo->io;
+
+ BAIL_IF_MACRO(offset > entry->uncompressed_size, PHYSFS_ERR_PAST_EOF, 0);
+
+ if (entry->compression_method == COMPMETH_NONE)
+ {
+ const PHYSFS_sint64 newpos = offset + entry->offset;
+ BAIL_IF_MACRO(!io->seek(io, newpos), ERRPASS, 0);
+ finfo->uncompressed_position = (PHYSFS_uint32) offset;
+ } /* if */
+
+ else
+ {
+ /*
+ * If seeking backwards, we need to redecode the file
+ * from the start and throw away the compressed bits until we hit
+ * the offset we need. If seeking forward, we still need to
+ * decode, but we don't rewind first.
+ */
+ if (offset < finfo->uncompressed_position)
+ {
+ /* we do a copy so state is sane if inflateInit2() fails. */
+ z_stream str;
+ initializeZStream(&str);
+ if (zlib_err(inflateInit2(&str, -MAX_WBITS)) != Z_OK)
+ return 0;
+
+ if (!io->seek(io, entry->offset))
+ return 0;
+
+ inflateEnd(&finfo->stream);
+ memcpy(&finfo->stream, &str, sizeof (z_stream));
+ finfo->uncompressed_position = finfo->compressed_position = 0;
+ } /* if */
+
+ while (finfo->uncompressed_position != offset)
+ {
+ PHYSFS_uint8 buf[512];
+ PHYSFS_uint32 maxread;
+
+ maxread = (PHYSFS_uint32) (offset - finfo->uncompressed_position);
+ if (maxread > sizeof (buf))
+ maxread = sizeof (buf);
+
+ if (ZIP_read(_io, buf, maxread) != maxread)
+ return 0;
+ } /* while */
+ } /* else */
+
+ return 1;
+} /* ZIP_seek */
+
+
+static PHYSFS_sint64 ZIP_length(PHYSFS_Io *io)
+{
+ const ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
+ return (PHYSFS_sint64) finfo->entry->uncompressed_size;
+} /* ZIP_length */
+
+
+static PHYSFS_Io *zip_get_io(PHYSFS_Io *io, ZIPinfo *inf, ZIPentry *entry);
+
+static PHYSFS_Io *ZIP_duplicate(PHYSFS_Io *io)
+{
+ ZIPfileinfo *origfinfo = (ZIPfileinfo *) io->opaque;
+ PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ ZIPfileinfo *finfo = (ZIPfileinfo *) allocator.Malloc(sizeof (ZIPfileinfo));
+ GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, failed);
+ GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, failed);
+ memset(finfo, '\0', sizeof (*finfo));
+
+ finfo->entry = origfinfo->entry;
+ finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
+ GOTO_IF_MACRO(!finfo->io, ERRPASS, failed);
+
+ if (finfo->entry->compression_method != COMPMETH_NONE)
+ {
+ finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
+ GOTO_IF_MACRO(!finfo->buffer, PHYSFS_ERR_OUT_OF_MEMORY, failed);
+ if (zlib_err(inflateInit2(&finfo->stream, -MAX_WBITS)) != Z_OK)
+ goto failed;
+ } /* if */
+
+ memcpy(retval, io, sizeof (PHYSFS_Io));
+ retval->opaque = finfo;
+ return retval;
+
+failed:
+ if (finfo != NULL)
+ {
+ if (finfo->io != NULL)
+ finfo->io->destroy(finfo->io);
+
+ if (finfo->buffer != NULL)
+ {
+ allocator.Free(finfo->buffer);
+ inflateEnd(&finfo->stream);
+ } /* if */
+
+ allocator.Free(finfo);
+ } /* if */
+
+ if (retval != NULL)
+ allocator.Free(retval);
+
+ return NULL;
+} /* ZIP_duplicate */
+
+static int ZIP_flush(PHYSFS_Io *io) { return 1; /* no write support. */ }
+
+static void ZIP_destroy(PHYSFS_Io *io)
+{
+ ZIPfileinfo *finfo = (ZIPfileinfo *) io->opaque;
+ finfo->io->destroy(finfo->io);
+
+ if (finfo->entry->compression_method != COMPMETH_NONE)
+ inflateEnd(&finfo->stream);
+
+ if (finfo->buffer != NULL)
+ allocator.Free(finfo->buffer);
+
+ allocator.Free(finfo);
+ allocator.Free(io);
+} /* ZIP_destroy */
+
+
+static const PHYSFS_Io ZIP_Io =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ ZIP_read,
+ ZIP_write,
+ ZIP_seek,
+ ZIP_tell,
+ ZIP_length,
+ ZIP_duplicate,
+ ZIP_flush,
+ ZIP_destroy
+};
+
+
+
+static PHYSFS_sint64 zip_find_end_of_central_dir(PHYSFS_Io *io, PHYSFS_sint64 *len)
+{
+ PHYSFS_uint8 buf[256];
+ PHYSFS_uint8 extra[4] = { 0, 0, 0, 0 };
+ PHYSFS_sint32 i = 0;
+ PHYSFS_sint64 filelen;
+ PHYSFS_sint64 filepos;
+ PHYSFS_sint32 maxread;
+ PHYSFS_sint32 totalread = 0;
+ int found = 0;
+
+ filelen = io->length(io);
+ BAIL_IF_MACRO(filelen == -1, ERRPASS, 0);
+
+ /*
+ * Jump to the end of the file and start reading backwards.
+ * The last thing in the file is the zipfile comment, which is variable
+ * length, and the field that specifies its size is before it in the
+ * file (argh!)...this means that we need to scan backwards until we
+ * hit the end-of-central-dir signature. We can then sanity check that
+ * the comment was as big as it should be to make sure we're in the
+ * right place. The comment length field is 16 bits, so we can stop
+ * searching for that signature after a little more than 64k at most,
+ * and call it a corrupted zipfile.
+ */
+
+ if (sizeof (buf) < filelen)
+ {
+ filepos = filelen - sizeof (buf);
+ maxread = sizeof (buf);
+ } /* if */
+ else
+ {
+ filepos = 0;
+ maxread = (PHYSFS_uint32) filelen;
+ } /* else */
+
+ while ((totalread < filelen) && (totalread < 65557))
+ {
+ BAIL_IF_MACRO(!io->seek(io, filepos), ERRPASS, -1);
+
+ /* make sure we catch a signature between buffers. */
+ if (totalread != 0)
+ {
+ if (!__PHYSFS_readAll(io, buf, maxread - 4))
+ return -1;
+ memcpy(&buf[maxread - 4], &extra, sizeof (extra));
+ totalread += maxread - 4;
+ } /* if */
+ else
+ {
+ if (!__PHYSFS_readAll(io, buf, maxread))
+ return -1;
+ totalread += maxread;
+ } /* else */
+
+ memcpy(&extra, buf, sizeof (extra));
+
+ for (i = maxread - 4; i > 0; i--)
+ {
+ if ((buf[i + 0] == 0x50) &&
+ (buf[i + 1] == 0x4B) &&
+ (buf[i + 2] == 0x05) &&
+ (buf[i + 3] == 0x06) )
+ {
+ found = 1; /* that's the signature! */
+ break;
+ } /* if */
+ } /* for */
+
+ if (found)
+ break;
+
+ filepos -= (maxread - 4);
+ if (filepos < 0)
+ filepos = 0;
+ } /* while */
+
+ BAIL_IF_MACRO(!found, PHYSFS_ERR_UNSUPPORTED, -1);
+
+ if (len != NULL)
+ *len = filelen;
+
+ return (filepos + i);
+} /* zip_find_end_of_central_dir */
+
+
+static int isZip(PHYSFS_Io *io)
+{
+ PHYSFS_uint32 sig = 0;
+ int retval = 0;
+
+ /*
+ * The first thing in a zip file might be the signature of the
+ * first local file record, so it makes for a quick determination.
+ */
+ if (readui32(io, &sig))
+ {
+ retval = (sig == ZIP_LOCAL_FILE_SIG);
+ if (!retval)
+ {
+ /*
+ * No sig...might be a ZIP with data at the start
+ * (a self-extracting executable, etc), so we'll have to do
+ * it the hard way...
+ */
+ retval = (zip_find_end_of_central_dir(io, NULL) != -1);
+ } /* if */
+ } /* if */
+
+ return retval;
+} /* isZip */
+
+
+static void zip_free_entries(ZIPentry *entries, PHYSFS_uint64 max)
+{
+ PHYSFS_uint64 i;
+ for (i = 0; i < max; i++)
+ {
+ ZIPentry *entry = &entries[i];
+ if (entry->name != NULL)
+ allocator.Free(entry->name);
+ } /* for */
+
+ allocator.Free(entries);
+} /* zip_free_entries */
+
+
+/*
+ * This will find the ZIPentry associated with a path in platform-independent
+ * notation. Directories don't have ZIPentries associated with them, but
+ * (*isDir) will be set to non-zero if a dir was hit.
+ */
+static ZIPentry *zip_find_entry(const ZIPinfo *info, const char *path,
+ int *isDir)
+{
+ ZIPentry *a = info->entries;
+ PHYSFS_sint32 pathlen = (PHYSFS_sint32) strlen(path);
+ PHYSFS_sint64 lo = 0;
+ PHYSFS_sint64 hi = (PHYSFS_sint64) (info->entryCount - 1);
+ PHYSFS_sint64 middle;
+ const char *thispath = NULL;
+ int rc;
+
+ while (lo <= hi)
+ {
+ middle = lo + ((hi - lo) / 2);
+ thispath = a[middle].name;
+ rc = strncmp(path, thispath, pathlen);
+
+ if (rc > 0)
+ lo = middle + 1;
+
+ else if (rc < 0)
+ hi = middle - 1;
+
+ else /* substring match...might be dir or entry or nothing. */
+ {
+ if (isDir != NULL)
+ {
+ *isDir = (thispath[pathlen] == '/');
+ if (*isDir)
+ return NULL;
+ } /* if */
+
+ if (thispath[pathlen] == '\0') /* found entry? */
+ return &a[middle];
+ /* adjust search params, try again. */
+ else if (thispath[pathlen] > '/')
+ hi = middle - 1;
+ else
+ lo = middle + 1;
+ } /* if */
+ } /* while */
+
+ if (isDir != NULL)
+ *isDir = 0;
+
+ BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
+} /* zip_find_entry */
+
+
+/* Convert paths from old, buggy DOS zippers... */
+static void zip_convert_dos_path(ZIPentry *entry, char *path)
+{
+ PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((entry->version >> 8) & 0xFF);
+ if (hosttype == 0) /* FS_FAT_ */
+ {
+ while (*path)
+ {
+ if (*path == '\\')
+ *path = '/';
+ path++;
+ } /* while */
+ } /* if */
+} /* zip_convert_dos_path */
+
+
+static void zip_expand_symlink_path(char *path)
+{
+ char *ptr = path;
+ char *prevptr = path;
+
+ while (1)
+ {
+ ptr = strchr(ptr, '/');
+ if (ptr == NULL)
+ break;
+
+ if (*(ptr + 1) == '.')
+ {
+ if (*(ptr + 2) == '/')
+ {
+ /* current dir in middle of string: ditch it. */
+ memmove(ptr, ptr + 2, strlen(ptr + 2) + 1);
+ } /* else if */
+
+ else if (*(ptr + 2) == '\0')
+ {
+ /* current dir at end of string: ditch it. */
+ *ptr = '\0';
+ } /* else if */
+
+ else if (*(ptr + 2) == '.')
+ {
+ if (*(ptr + 3) == '/')
+ {
+ /* parent dir in middle: move back one, if possible. */
+ memmove(prevptr, ptr + 4, strlen(ptr + 4) + 1);
+ ptr = prevptr;
+ while (prevptr != path)
+ {
+ prevptr--;
+ if (*prevptr == '/')
+ {
+ prevptr++;
+ break;
+ } /* if */
+ } /* while */
+ } /* if */
+
+ if (*(ptr + 3) == '\0')
+ {
+ /* parent dir at end: move back one, if possible. */
+ *prevptr = '\0';
+ } /* if */
+ } /* if */
+ } /* if */
+ else
+ {
+ prevptr = ptr;
+ ptr++;
+ } /* else */
+ } /* while */
+} /* zip_expand_symlink_path */
+
+/* (forward reference: zip_follow_symlink and zip_resolve call each other.) */
+static int zip_resolve(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry);
+
+/*
+ * Look for the entry named by (path). If it exists, resolve it, and return
+ * a pointer to that entry. If it's another symlink, keep resolving until you
+ * hit a real file and then return a pointer to the final non-symlink entry.
+ * If there's a problem, return NULL.
+ */
+static ZIPentry *zip_follow_symlink(PHYSFS_Io *io, ZIPinfo *info, char *path)
+{
+ ZIPentry *entry;
+
+ zip_expand_symlink_path(path);
+ entry = zip_find_entry(info, path, NULL);
+ if (entry != NULL)
+ {
+ if (!zip_resolve(io, info, entry)) /* recursive! */
+ entry = NULL;
+ else
+ {
+ if (entry->symlink != NULL)
+ entry = entry->symlink;
+ } /* else */
+ } /* if */
+
+ return entry;
+} /* zip_follow_symlink */
+
+
+static int zip_resolve_symlink(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry)
+{
+ const PHYSFS_uint64 size = entry->uncompressed_size;
+ char *path = NULL;
+ int rc = 0;
+
+ /*
+ * We've already parsed the local file header of the symlink at this
+ * point. Now we need to read the actual link from the file data and
+ * follow it.
+ */
+
+ BAIL_IF_MACRO(!io->seek(io, entry->offset), ERRPASS, 0);
+
+ path = (char *) __PHYSFS_smallAlloc(size + 1);
+ BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+
+ if (entry->compression_method == COMPMETH_NONE)
+ rc = __PHYSFS_readAll(io, path, size);
+
+ else /* symlink target path is compressed... */
+ {
+ z_stream stream;
+ const PHYSFS_uint64 complen = entry->compressed_size;
+ PHYSFS_uint8 *compressed = (PHYSFS_uint8*) __PHYSFS_smallAlloc(complen);
+ if (compressed != NULL)
+ {
+ if (__PHYSFS_readAll(io, compressed, complen))
+ {
+ initializeZStream(&stream);
+ stream.next_in = compressed;
+ stream.avail_in = complen;
+ stream.next_out = (unsigned char *) path;
+ stream.avail_out = size;
+ if (zlib_err(inflateInit2(&stream, -MAX_WBITS)) == Z_OK)
+ {
+ rc = zlib_err(inflate(&stream, Z_FINISH));
+ inflateEnd(&stream);
+
+ /* both are acceptable outcomes... */
+ rc = ((rc == Z_OK) || (rc == Z_STREAM_END));
+ } /* if */
+ } /* if */
+ __PHYSFS_smallFree(compressed);
+ } /* if */
+ } /* else */
+
+ if (rc)
+ {
+ path[entry->uncompressed_size] = '\0'; /* null-terminate it. */
+ zip_convert_dos_path(entry, path);
+ entry->symlink = zip_follow_symlink(io, info, path);
+ } /* else */
+
+ __PHYSFS_smallFree(path);
+
+ return (entry->symlink != NULL);
+} /* zip_resolve_symlink */
+
+
+/*
+ * Parse the local file header of an entry, and update entry->offset.
+ */
+static int zip_parse_local(PHYSFS_Io *io, ZIPentry *entry)
+{
+ PHYSFS_uint32 ui32;
+ PHYSFS_uint16 ui16;
+ PHYSFS_uint16 fnamelen;
+ PHYSFS_uint16 extralen;
+
+ /*
+ * crc and (un)compressed_size are always zero if this is a "JAR"
+ * archive created with Sun's Java tools, apparently. We only
+ * consider this archive corrupted if those entries don't match and
+ * aren't zero. That seems to work well.
+ * We also ignore a mismatch if the value is 0xFFFFFFFF here, since it's
+ * possible that's a Zip64 thing.
+ */
+
+ BAIL_IF_MACRO(!io->seek(io, entry->offset), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+ BAIL_IF_MACRO(ui16 != entry->version_needed, PHYSFS_ERR_CORRUPT, 0);
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0); /* general bits. */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+ BAIL_IF_MACRO(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0); /* date/time */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 && (ui32 != entry->crc), PHYSFS_ERR_CORRUPT, 0);
+
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 && (ui32 != 0xFFFFFFFF) &&
+ (ui32 != entry->compressed_size), PHYSFS_ERR_CORRUPT, 0);
+
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 && (ui32 != 0xFFFFFFFF) &&
+ (ui32 != entry->uncompressed_size), PHYSFS_ERR_CORRUPT, 0);
+
+ BAIL_IF_MACRO(!readui16(io, &fnamelen), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &extralen), ERRPASS, 0);
+
+ entry->offset += fnamelen + extralen + 30;
+ return 1;
+} /* zip_parse_local */
+
+
+static int zip_resolve(PHYSFS_Io *io, ZIPinfo *info, ZIPentry *entry)
+{
+ int retval = 1;
+ ZipResolveType resolve_type = entry->resolved;
+
+ /* Don't bother if we've failed to resolve this entry before. */
+ BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_FILE, PHYSFS_ERR_CORRUPT, 0);
+ BAIL_IF_MACRO(resolve_type == ZIP_BROKEN_SYMLINK, PHYSFS_ERR_CORRUPT, 0);
+
+ /* uhoh...infinite symlink loop! */
+ BAIL_IF_MACRO(resolve_type == ZIP_RESOLVING, PHYSFS_ERR_SYMLINK_LOOP, 0);
+
+ /*
+ * We fix up the offset to point to the actual data on the
+ * first open, since we don't want to seek across the whole file on
+ * archive open (can be SLOW on large, CD-stored files), but we
+ * need to check the local file header...not just for corruption,
+ * but since it stores offset info the central directory does not.
+ */
+ if (resolve_type != ZIP_RESOLVED)
+ {
+ entry->resolved = ZIP_RESOLVING;
+
+ retval = zip_parse_local(io, entry);
+ if (retval)
+ {
+ /*
+ * If it's a symlink, find the original file. This will cause
+ * resolution of other entries (other symlinks and, eventually,
+ * the real file) if all goes well.
+ */
+ if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
+ retval = zip_resolve_symlink(io, info, entry);
+ } /* if */
+
+ if (resolve_type == ZIP_UNRESOLVED_SYMLINK)
+ entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_SYMLINK);
+ else if (resolve_type == ZIP_UNRESOLVED_FILE)
+ entry->resolved = ((retval) ? ZIP_RESOLVED : ZIP_BROKEN_FILE);
+ } /* if */
+
+ return retval;
+} /* zip_resolve */
+
+
+static int zip_version_does_symlinks(PHYSFS_uint32 version)
+{
+ int retval = 0;
+ PHYSFS_uint8 hosttype = (PHYSFS_uint8) ((version >> 8) & 0xFF);
+
+ switch (hosttype)
+ {
+ /*
+ * These are the platforms that can NOT build an archive with
+ * symlinks, according to the Info-ZIP project.
+ */
+ case 0: /* FS_FAT_ */
+ case 1: /* AMIGA_ */
+ case 2: /* VMS_ */
+ case 4: /* VM_CSM_ */
+ case 6: /* FS_HPFS_ */
+ case 11: /* FS_NTFS_ */
+ case 14: /* FS_VFAT_ */
+ case 13: /* ACORN_ */
+ case 15: /* MVS_ */
+ case 18: /* THEOS_ */
+ break; /* do nothing. */
+
+ default: /* assume the rest to be unix-like. */
+ retval = 1;
+ break;
+ } /* switch */
+
+ return retval;
+} /* zip_version_does_symlinks */
+
+
+static int zip_entry_is_symlink(const ZIPentry *entry)
+{
+ return ((entry->resolved == ZIP_UNRESOLVED_SYMLINK) ||
+ (entry->resolved == ZIP_BROKEN_SYMLINK) ||
+ (entry->symlink));
+} /* zip_entry_is_symlink */
+
+
+static int zip_has_symlink_attr(ZIPentry *entry, PHYSFS_uint32 extern_attr)
+{
+ PHYSFS_uint16 xattr = ((extern_attr >> 16) & 0xFFFF);
+ return ( (zip_version_does_symlinks(entry->version)) &&
+ (entry->uncompressed_size > 0) &&
+ ((xattr & UNIX_FILETYPE_MASK) == UNIX_FILETYPE_SYMLINK) );
+} /* zip_has_symlink_attr */
+
+
+static PHYSFS_sint64 zip_dos_time_to_physfs_time(PHYSFS_uint32 dostime)
+{
+ PHYSFS_uint32 dosdate;
+ struct tm unixtime;
+ memset(&unixtime, '\0', sizeof (unixtime));
+
+ dosdate = (PHYSFS_uint32) ((dostime >> 16) & 0xFFFF);
+ dostime &= 0xFFFF;
+
+ /* dissect date */
+ unixtime.tm_year = ((dosdate >> 9) & 0x7F) + 80;
+ unixtime.tm_mon = ((dosdate >> 5) & 0x0F) - 1;
+ unixtime.tm_mday = ((dosdate ) & 0x1F);
+
+ /* dissect time */
+ unixtime.tm_hour = ((dostime >> 11) & 0x1F);
+ unixtime.tm_min = ((dostime >> 5) & 0x3F);
+ unixtime.tm_sec = ((dostime << 1) & 0x3E);
+
+ /* let mktime calculate daylight savings time. */
+ unixtime.tm_isdst = -1;
+
+ return ((PHYSFS_sint64) mktime(&unixtime));
+} /* zip_dos_time_to_physfs_time */
+
+
+static int zip_load_entry(PHYSFS_Io *io, const int zip64, ZIPentry *entry,
+ PHYSFS_uint64 ofs_fixup)
+{
+ PHYSFS_uint16 fnamelen, extralen, commentlen;
+ PHYSFS_uint32 external_attr;
+ PHYSFS_uint32 starting_disk;
+ PHYSFS_uint64 offset;
+ PHYSFS_uint16 ui16;
+ PHYSFS_uint32 ui32;
+ PHYSFS_sint64 si64;
+
+ /* sanity check with central directory signature... */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != ZIP_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, 0);
+
+ /* Get the pertinent parts of the record... */
+ BAIL_IF_MACRO(!readui16(io, &entry->version), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &entry->version_needed), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0); /* general bits */
+ BAIL_IF_MACRO(!readui16(io, &entry->compression_method), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ entry->last_mod_time = zip_dos_time_to_physfs_time(ui32);
+ BAIL_IF_MACRO(!readui32(io, &entry->crc), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ entry->compressed_size = (PHYSFS_uint64) ui32;
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ entry->uncompressed_size = (PHYSFS_uint64) ui32;
+ BAIL_IF_MACRO(!readui16(io, &fnamelen), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &extralen), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &commentlen), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+ starting_disk = (PHYSFS_uint32) ui16;
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0); /* internal file attribs */
+ BAIL_IF_MACRO(!readui32(io, &external_attr), ERRPASS, 0);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ offset = (PHYSFS_uint64) ui32;
+
+ entry->symlink = NULL; /* will be resolved later, if necessary. */
+ entry->resolved = (zip_has_symlink_attr(entry, external_attr)) ?
+ ZIP_UNRESOLVED_SYMLINK : ZIP_UNRESOLVED_FILE;
+
+ entry->name = (char *) allocator.Malloc(fnamelen + 1);
+ BAIL_IF_MACRO(entry->name == NULL, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ if (!__PHYSFS_readAll(io, entry->name, fnamelen))
+ goto zip_load_entry_puked;
+
+ entry->name[fnamelen] = '\0'; /* null-terminate the filename. */
+ zip_convert_dos_path(entry, entry->name);
+
+ si64 = io->tell(io);
+ if (si64 == -1)
+ goto zip_load_entry_puked;
+
+ /*
+ * The actual sizes didn't fit in 32-bits; look for the Zip64
+ * extended information extra field...
+ */
+ if ( (zip64) &&
+ ((offset == 0xFFFFFFFF) ||
+ (starting_disk == 0xFFFFFFFF) ||
+ (entry->compressed_size == 0xFFFFFFFF) ||
+ (entry->uncompressed_size == 0xFFFFFFFF)) )
+ {
+ int found = 0;
+ PHYSFS_uint16 sig, len;
+ while (extralen > 4)
+ {
+ if (!readui16(io, &sig))
+ goto zip_load_entry_puked;
+ else if (!readui16(io, &len))
+ goto zip_load_entry_puked;
+
+ si64 += 4 + len;
+ extralen -= 4 + len;
+ if (sig != ZIP64_EXTENDED_INFO_EXTRA_FIELD_SIG)
+ {
+ if (!io->seek(io, si64))
+ goto zip_load_entry_puked;
+ continue;
+ } /* if */
+
+ found = 1;
+ break;
+ } /* while */
+
+ GOTO_IF_MACRO(!found, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+
+ if (entry->uncompressed_size == 0xFFFFFFFF)
+ {
+ GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+ if (!readui64(io, &entry->uncompressed_size))
+ goto zip_load_entry_puked;
+ len -= 8;
+ } /* if */
+
+ if (entry->compressed_size == 0xFFFFFFFF)
+ {
+ GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+ if (!readui64(io, &entry->compressed_size))
+ goto zip_load_entry_puked;
+ len -= 8;
+ } /* if */
+
+ if (offset == 0xFFFFFFFF)
+ {
+ GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+ if (!readui64(io, &offset))
+ goto zip_load_entry_puked;
+ len -= 8;
+ } /* if */
+
+ if (starting_disk == 0xFFFFFFFF)
+ {
+ GOTO_IF_MACRO(len < 8, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+ if (!readui32(io, &starting_disk))
+ goto zip_load_entry_puked;
+ len -= 4;
+ } /* if */
+
+ GOTO_IF_MACRO(len != 0, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+ } /* if */
+
+ GOTO_IF_MACRO(starting_disk != 0, PHYSFS_ERR_CORRUPT, zip_load_entry_puked);
+
+ entry->offset = offset + ofs_fixup;
+
+ /* seek to the start of the next entry in the central directory... */
+ if (!io->seek(io, si64 + extralen + commentlen))
+ goto zip_load_entry_puked;
+
+ return 1; /* success. */
+
+zip_load_entry_puked:
+ allocator.Free(entry->name);
+ return 0; /* failure. */
+} /* zip_load_entry */
+
+
+static int zip_entry_cmp(void *_a, size_t one, size_t two)
+{
+ if (one != two)
+ {
+ const ZIPentry *a = (const ZIPentry *) _a;
+ return strcmp(a[one].name, a[two].name);
+ } /* if */
+
+ return 0;
+} /* zip_entry_cmp */
+
+
+static void zip_entry_swap(void *_a, size_t one, size_t two)
+{
+ if (one != two)
+ {
+ ZIPentry tmp;
+ ZIPentry *first = &(((ZIPentry *) _a)[one]);
+ ZIPentry *second = &(((ZIPentry *) _a)[two]);
+ memcpy(&tmp, first, sizeof (ZIPentry));
+ memcpy(first, second, sizeof (ZIPentry));
+ memcpy(second, &tmp, sizeof (ZIPentry));
+ } /* if */
+} /* zip_entry_swap */
+
+
+static int zip_load_entries(PHYSFS_Io *io, ZIPinfo *info,
+ const PHYSFS_uint64 data_ofs,
+ const PHYSFS_uint64 central_ofs)
+{
+ const PHYSFS_uint64 max = info->entryCount;
+ const int zip64 = info->zip64;
+ PHYSFS_uint64 i;
+
+ BAIL_IF_MACRO(!io->seek(io, central_ofs), ERRPASS, 0);
+
+ info->entries = (ZIPentry *) allocator.Malloc(sizeof (ZIPentry) * max);
+ BAIL_IF_MACRO(!info->entries, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+
+ for (i = 0; i < max; i++)
+ {
+ if (!zip_load_entry(io, zip64, &info->entries[i], data_ofs))
+ {
+ zip_free_entries(info->entries, i);
+ return 0;
+ } /* if */
+ } /* for */
+
+ __PHYSFS_sort(info->entries, (size_t) max, zip_entry_cmp, zip_entry_swap);
+ return 1;
+} /* zip_load_entries */
+
+
+static PHYSFS_sint64 zip64_find_end_of_central_dir(PHYSFS_Io *io,
+ PHYSFS_sint64 _pos,
+ PHYSFS_uint64 offset)
+{
+ /*
+ * Naturally, the offset is useless to us; it is the offset from the
+ * start of file, which is meaningless if we've appended this .zip to
+ * a self-extracting .exe. We need to find this on our own. It should
+ * be directly before the locator record, but the record in question,
+ * like the original end-of-central-directory record, ends with a
+ * variable-length field. Unlike the original, which has to store the
+ * size of that variable-length field in a 16-bit int and thus has to be
+ * within 64k, the new one gets 64-bits.
+ *
+ * Fortunately, the only currently-specified record for that variable
+ * length block is some weird proprietary thing that deals with EBCDIC
+ * and tape backups or something. So we don't seek far.
+ */
+
+ PHYSFS_uint32 ui32;
+ const PHYSFS_uint64 pos = (PHYSFS_uint64) _pos;
+
+ assert(_pos > 0);
+
+ /* Try offset specified in the Zip64 end of central directory locator. */
+ /* This works if the entire PHYSFS_Io is the zip file. */
+ BAIL_IF_MACRO(!io->seek(io, offset), ERRPASS, -1);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, -1);
+ if (ui32 == ZIP64_END_OF_CENTRAL_DIR_SIG)
+ return offset;
+
+ /* Try 56 bytes before the Zip64 end of central directory locator. */
+ /* This works if the record isn't variable length and is version 1. */
+ if (pos > 56)
+ {
+ BAIL_IF_MACRO(!io->seek(io, pos-56), ERRPASS, -1);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, -1);
+ if (ui32 == ZIP64_END_OF_CENTRAL_DIR_SIG)
+ return pos-56;
+ } /* if */
+
+ /* Try 84 bytes before the Zip64 end of central directory locator. */
+ /* This works if the record isn't variable length and is version 2. */
+ if (pos > 84)
+ {
+ BAIL_IF_MACRO(!io->seek(io, pos-84), ERRPASS, -1);
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, -1);
+ if (ui32 == ZIP64_END_OF_CENTRAL_DIR_SIG)
+ return pos-84;
+ } /* if */
+
+ /* Ok, brute force: we know it's between (offset) and (pos) somewhere. */
+ /* Just try moving back at most 256k. Oh well. */
+ if ((offset < pos) && (pos > 4))
+ {
+ /* we assume you can eat this stack if you handle Zip64 files. */
+ PHYSFS_uint8 buf[256 * 1024];
+ PHYSFS_uint64 len = pos - offset;
+ PHYSFS_sint32 i;
+
+ if (len > sizeof (buf))
+ len = sizeof (buf);
+
+ BAIL_IF_MACRO(!io->seek(io, pos - len), ERRPASS, -1);
+ BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, len), ERRPASS, -1);
+ for (i = (PHYSFS_sint32) (len - 4); i >= 0; i--)
+ {
+ if (buf[i] != 0x50)
+ continue;
+ if ( (buf[i+1] == 0x4b) &&
+ (buf[i+2] == 0x06) &&
+ (buf[i+3] == 0x06) )
+ return pos - (len - i);
+ } /* for */
+ } /* if */
+
+ BAIL_MACRO(PHYSFS_ERR_CORRUPT, -1); /* didn't find it. */
+} /* zip64_find_end_of_central_dir */
+
+
+static int zip64_parse_end_of_central_dir(PHYSFS_Io *io, ZIPinfo *info,
+ PHYSFS_uint64 *data_start,
+ PHYSFS_uint64 *dir_ofs,
+ PHYSFS_sint64 pos)
+{
+ PHYSFS_uint64 ui64;
+ PHYSFS_uint32 ui32;
+ PHYSFS_uint16 ui16;
+
+ /* We should be positioned right past the locator signature. */
+
+ if ((pos < 0) || (!io->seek(io, pos)))
+ return 0;
+
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ if (ui32 != ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG)
+ return -1; /* it's not a Zip64 archive. Not an error, though! */
+
+ info->zip64 = 1;
+
+ /* number of the disk with the start of the central directory. */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != 0, PHYSFS_ERR_CORRUPT, 0);
+
+ /* offset of Zip64 end of central directory record. */
+ BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
+
+ /* total number of disks */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != 1, PHYSFS_ERR_CORRUPT, 0);
+
+ pos = zip64_find_end_of_central_dir(io, pos, ui64);
+ if (pos < 0)
+ return 0; /* oh well. */
+
+ /*
+ * For self-extracting archives, etc, there's crapola in the file
+ * before the zipfile records; we calculate how much data there is
+ * prepended by determining how far the zip64-end-of-central-directory
+ * offset is from where it is supposed to be...the difference in bytes
+ * is how much arbitrary data is at the start of the physical file.
+ */
+ assert(((PHYSFS_uint64) pos) >= ui64);
+ *data_start = ((PHYSFS_uint64) pos) - ui64;
+
+ BAIL_IF_MACRO(!io->seek(io, pos), ERRPASS, 0);
+
+ /* check signature again, just in case. */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != ZIP64_END_OF_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, 0);
+
+ /* size of Zip64 end of central directory record. */
+ BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
+
+ /* version made by. */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+
+ /* version needed to extract. */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+
+ /* number of this disk. */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != 0, PHYSFS_ERR_CORRUPT, 0);
+
+ /* number of disk with start of central directory record. */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != 0, PHYSFS_ERR_CORRUPT, 0);
+
+ /* total number of entries in the central dir on this disk */
+ BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
+
+ /* total number of entries in the central dir */
+ BAIL_IF_MACRO(!readui64(io, &info->entryCount), ERRPASS, 0);
+ BAIL_IF_MACRO(ui64 != info->entryCount, PHYSFS_ERR_CORRUPT, 0);
+
+ /* size of the central directory */
+ BAIL_IF_MACRO(!readui64(io, &ui64), ERRPASS, 0);
+
+ /* offset of central directory */
+ BAIL_IF_MACRO(!readui64(io, dir_ofs), ERRPASS, 0);
+
+ /* Since we know the difference, fix up the central dir offset... */
+ *dir_ofs += *data_start;
+
+ /*
+ * There are more fields here, for encryption and feature-specific things,
+ * but we don't care about any of them at the moment.
+ */
+
+ return 1; /* made it. */
+} /* zip64_parse_end_of_central_dir */
+
+
+static int zip_parse_end_of_central_dir(PHYSFS_Io *io, ZIPinfo *info,
+ PHYSFS_uint64 *data_start,
+ PHYSFS_uint64 *dir_ofs)
+{
+ PHYSFS_uint16 entryCount16;
+ PHYSFS_uint32 offset32;
+ PHYSFS_uint32 ui32;
+ PHYSFS_uint16 ui16;
+ PHYSFS_sint64 len;
+ PHYSFS_sint64 pos;
+ int rc;
+
+ /* find the end-of-central-dir record, and seek to it. */
+ pos = zip_find_end_of_central_dir(io, &len);
+ BAIL_IF_MACRO(pos == -1, ERRPASS, 0);
+ BAIL_IF_MACRO(!io->seek(io, pos), ERRPASS, 0);
+
+ /* check signature again, just in case. */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+ BAIL_IF_MACRO(ui32 != ZIP_END_OF_CENTRAL_DIR_SIG, PHYSFS_ERR_CORRUPT, 0);
+
+ /* Seek back to see if "Zip64 end of central directory locator" exists. */
+ /* this record is 20 bytes before end-of-central-dir */
+ rc = zip64_parse_end_of_central_dir(io, info, data_start, dir_ofs, pos-20);
+ BAIL_IF_MACRO(rc == 0, ERRPASS, 0);
+ if (rc == 1)
+ return 1; /* we're done here. */
+
+ assert(rc == -1); /* no error, just not a Zip64 archive. */
+
+ /* Not Zip64? Seek back to where we were and keep processing. */
+ BAIL_IF_MACRO(!io->seek(io, pos + 4), ERRPASS, 0);
+
+ /* number of this disk */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+ BAIL_IF_MACRO(ui16 != 0, PHYSFS_ERR_CORRUPT, 0);
+
+ /* number of the disk with the start of the central directory */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+ BAIL_IF_MACRO(ui16 != 0, PHYSFS_ERR_CORRUPT, 0);
+
+ /* total number of entries in the central dir on this disk */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+
+ /* total number of entries in the central dir */
+ BAIL_IF_MACRO(!readui16(io, &entryCount16), ERRPASS, 0);
+ BAIL_IF_MACRO(ui16 != entryCount16, PHYSFS_ERR_CORRUPT, 0);
+
+ info->entryCount = entryCount16;
+
+ /* size of the central directory */
+ BAIL_IF_MACRO(!readui32(io, &ui32), ERRPASS, 0);
+
+ /* offset of central directory */
+ BAIL_IF_MACRO(!readui32(io, &offset32), ERRPASS, 0);
+ *dir_ofs = (PHYSFS_uint64) offset32;
+ BAIL_IF_MACRO(pos < (*dir_ofs + ui32), PHYSFS_ERR_CORRUPT, 0);
+
+ /*
+ * For self-extracting archives, etc, there's crapola in the file
+ * before the zipfile records; we calculate how much data there is
+ * prepended by determining how far the central directory offset is
+ * from where it is supposed to be (start of end-of-central-dir minus
+ * sizeof central dir)...the difference in bytes is how much arbitrary
+ * data is at the start of the physical file.
+ */
+ *data_start = (PHYSFS_uint64) (pos - (*dir_ofs + ui32));
+
+ /* Now that we know the difference, fix up the central dir offset... */
+ *dir_ofs += *data_start;
+
+ /* zipfile comment length */
+ BAIL_IF_MACRO(!readui16(io, &ui16), ERRPASS, 0);
+
+ /*
+ * Make sure that the comment length matches to the end of file...
+ * If it doesn't, we're either in the wrong part of the file, or the
+ * file is corrupted, but we give up either way.
+ */
+ BAIL_IF_MACRO((pos + 22 + ui16) != len, PHYSFS_ERR_CORRUPT, 0);
+
+ return 1; /* made it. */
+} /* zip_parse_end_of_central_dir */
+
+
+static void *ZIP_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
+{
+ ZIPinfo *info = NULL;
+ PHYSFS_uint64 data_start;
+ PHYSFS_uint64 cent_dir_ofs;
+
+ assert(io != NULL); /* shouldn't ever happen. */
+
+ BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+ BAIL_IF_MACRO(!isZip(io), ERRPASS, NULL);
+
+ info = (ZIPinfo *) allocator.Malloc(sizeof (ZIPinfo));
+ BAIL_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ memset(info, '\0', sizeof (ZIPinfo));
+ info->io = io;
+
+ if (!zip_parse_end_of_central_dir(io, info, &data_start, ¢_dir_ofs))
+ goto ZIP_openarchive_failed;
+
+ if (!zip_load_entries(io, info, data_start, cent_dir_ofs))
+ goto ZIP_openarchive_failed;
+
+ return info;
+
+ZIP_openarchive_failed:
+ if (info != NULL)
+ allocator.Free(info);
+
+ return NULL;
+} /* ZIP_openArchive */
+
+
+static PHYSFS_sint64 zip_find_start_of_dir(ZIPinfo *info, const char *path,
+ int stop_on_first_find)
+{
+ PHYSFS_sint64 lo = 0;
+ PHYSFS_sint64 hi = (PHYSFS_sint64) (info->entryCount - 1);
+ PHYSFS_sint64 middle;
+ PHYSFS_uint32 dlen = (PHYSFS_uint32) strlen(path);
+ PHYSFS_sint64 retval = -1;
+ const char *name;
+ int rc;
+
+ if (*path == '\0') /* root dir? */
+ return 0;
+
+ if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen--;
+
+ while (lo <= hi)
+ {
+ middle = lo + ((hi - lo) / 2);
+ name = info->entries[middle].name;
+ rc = strncmp(path, name, dlen);
+ if (rc == 0)
+ {
+ char ch = name[dlen];
+ if ('/' < ch) /* make sure this isn't just a substr match. */
+ rc = -1;
+ else if ('/' > ch)
+ rc = 1;
+ else
+ {
+ if (stop_on_first_find) /* Just checking dir's existance? */
+ return middle;
+
+ if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
+ return (middle + 1);
+
+ /* there might be more entries earlier in the list. */
+ retval = middle;
+ hi = middle - 1;
+ } /* else */
+ } /* if */
+
+ if (rc > 0)
+ lo = middle + 1;
+ else
+ hi = middle - 1;
+ } /* while */
+
+ return retval;
+} /* zip_find_start_of_dir */
+
+
+/*
+ * Moved to seperate function so we can use alloca then immediately throw
+ * away the allocated stack space...
+ */
+static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
+ const char *odir, const char *str, PHYSFS_sint32 ln)
+{
+ char *newstr = __PHYSFS_smallAlloc(ln + 1);
+ if (newstr == NULL)
+ return;
+
+ memcpy(newstr, str, ln);
+ newstr[ln] = '\0';
+ cb(callbackdata, odir, newstr);
+ __PHYSFS_smallFree(newstr);
+} /* doEnumCallback */
+
+
+static void ZIP_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata)
+{
+ ZIPinfo *info = ((ZIPinfo *) opaque);
+ PHYSFS_sint32 dlen, dlen_inc;
+ PHYSFS_sint64 i, max;
+
+ i = zip_find_start_of_dir(info, dname, 0);
+ if (i == -1) /* no such directory. */
+ return;
+
+ dlen = (PHYSFS_sint32) strlen(dname);
+ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen--;
+
+ dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
+ max = (PHYSFS_sint64) info->entryCount;
+ while (i < max)
+ {
+ char *e = info->entries[i].name;
+ if ((dlen) && ((strncmp(e, dname, dlen) != 0) || (e[dlen] != '/')))
+ break; /* past end of this dir; we're done. */
+
+ if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
+ i++;
+ else
+ {
+ char *add = e + dlen_inc;
+ char *ptr = strchr(add, '/');
+ PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
+ doEnumCallback(cb, callbackdata, origdir, add, ln);
+ ln += dlen_inc; /* point past entry to children... */
+
+ /* increment counter and skip children of subdirs... */
+ while ((++i < max) && (ptr != NULL))
+ {
+ char *e_new = info->entries[i].name;
+ if ((strncmp(e, e_new, ln) != 0) || (e_new[ln] != '/'))
+ break;
+ } /* while */
+ } /* else */
+ } /* while */
+} /* ZIP_enumerateFiles */
+
+
+static PHYSFS_Io *zip_get_io(PHYSFS_Io *io, ZIPinfo *inf, ZIPentry *entry)
+{
+ int success;
+ PHYSFS_Io *retval = io->duplicate(io);
+ BAIL_IF_MACRO(!retval, ERRPASS, NULL);
+
+ /* !!! FIXME: if you open a dir here, it should bail ERR_NOT_A_FILE */
+
+ /* (inf) can be NULL if we already resolved. */
+ success = (inf == NULL) || zip_resolve(retval, inf, entry);
+ if (success)
+ {
+ PHYSFS_sint64 offset;
+ offset = ((entry->symlink) ? entry->symlink->offset : entry->offset);
+ success = retval->seek(retval, offset);
+ } /* if */
+
+ if (!success)
+ {
+ retval->destroy(retval);
+ retval = NULL;
+ } /* if */
+
+ return retval;
+} /* zip_get_io */
+
+
+static PHYSFS_Io *ZIP_openRead(PHYSFS_Dir *opaque, const char *fnm,
+ int *fileExists)
+{
+ PHYSFS_Io *retval = NULL;
+ ZIPinfo *info = (ZIPinfo *) opaque;
+ ZIPentry *entry = zip_find_entry(info, fnm, NULL);
+ ZIPfileinfo *finfo = NULL;
+
+ *fileExists = (entry != NULL);
+ BAIL_IF_MACRO(!entry, ERRPASS, NULL);
+
+ retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, ZIP_openRead_failed);
+
+ finfo = (ZIPfileinfo *) allocator.Malloc(sizeof (ZIPfileinfo));
+ GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, ZIP_openRead_failed);
+ memset(finfo, '\0', sizeof (ZIPfileinfo));
+
+ finfo->io = zip_get_io(info->io, info, entry);
+ GOTO_IF_MACRO(!finfo->io, ERRPASS, ZIP_openRead_failed);
+ finfo->entry = ((entry->symlink != NULL) ? entry->symlink : entry);
+ initializeZStream(&finfo->stream);
+
+ if (finfo->entry->compression_method != COMPMETH_NONE)
+ {
+ finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
+ if (!finfo->buffer)
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, ZIP_openRead_failed);
+ else if (zlib_err(inflateInit2(&finfo->stream, -MAX_WBITS)) != Z_OK)
+ goto ZIP_openRead_failed;
+ } /* if */
+
+ memcpy(retval, &ZIP_Io, sizeof (PHYSFS_Io));
+ retval->opaque = finfo;
+
+ return retval;
+
+ZIP_openRead_failed:
+ if (finfo != NULL)
+ {
+ if (finfo->io != NULL)
+ finfo->io->destroy(finfo->io);
+
+ if (finfo->buffer != NULL)
+ {
+ allocator.Free(finfo->buffer);
+ inflateEnd(&finfo->stream);
+ } /* if */
+
+ allocator.Free(finfo);
+ } /* if */
+
+ if (retval != NULL)
+ allocator.Free(retval);
+
+ return NULL;
+} /* ZIP_openRead */
+
+
+static PHYSFS_Io *ZIP_openWrite(PHYSFS_Dir *opaque, const char *filename)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* ZIP_openWrite */
+
+
+static PHYSFS_Io *ZIP_openAppend(PHYSFS_Dir *opaque, const char *filename)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
+} /* ZIP_openAppend */
+
+
+static void ZIP_closeArchive(PHYSFS_Dir *opaque)
+{
+ ZIPinfo *zi = (ZIPinfo *) (opaque);
+ zi->io->destroy(zi->io);
+ zip_free_entries(zi->entries, zi->entryCount);
+ allocator.Free(zi);
+} /* ZIP_closeArchive */
+
+
+static int ZIP_remove(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* ZIP_remove */
+
+
+static int ZIP_mkdir(PHYSFS_Dir *opaque, const char *name)
+{
+ BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
+} /* ZIP_mkdir */
+
+
+static int ZIP_stat(PHYSFS_Dir *opaque, const char *filename, int *exists,
+ PHYSFS_Stat *stat)
+{
+ int isDir = 0;
+ const ZIPinfo *info = (const ZIPinfo *) opaque;
+ const ZIPentry *entry = zip_find_entry(info, filename, &isDir);
+
+ /* !!! FIXME: does this need to resolve entries here? */
+
+ *exists = isDir || (entry != 0);
+ if (!*exists)
+ return 0;
+
+ if (isDir)
+ {
+ stat->filesize = 0;
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ } /* if */
+
+ else if (zip_entry_is_symlink(entry))
+ {
+ stat->filesize = 0;
+ stat->filetype = PHYSFS_FILETYPE_SYMLINK;
+ } /* else if */
+
+ else
+ {
+ stat->filesize = (PHYSFS_sint64) entry->uncompressed_size;
+ stat->filetype = PHYSFS_FILETYPE_REGULAR;
+ } /* else */
+
+ stat->modtime = ((entry) ? entry->last_mod_time : 0);
+ stat->createtime = stat->modtime;
+ stat->accesstime = 0;
+ stat->readonly = 1; /* .zip files are always read only */
+
+ return 1;
+} /* ZIP_stat */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_ZIP =
+{
+ {
+ "ZIP",
+ "PkZip/WinZip/Info-Zip compatible",
+ "Ryan C. Gordon <icculus at icculus.org>",
+ "http://icculus.org/physfs/",
+ },
+ ZIP_openArchive, /* openArchive() method */
+ ZIP_enumerateFiles, /* enumerateFiles() method */
+ ZIP_openRead, /* openRead() method */
+ ZIP_openWrite, /* openWrite() method */
+ ZIP_openAppend, /* openAppend() method */
+ ZIP_remove, /* remove() method */
+ ZIP_mkdir, /* mkdir() method */
+ ZIP_closeArchive, /* closeArchive() method */
+ ZIP_stat /* stat() method */
+};
+
+#endif /* defined PHYSFS_SUPPORTS_ZIP */
+
+/* end of zip.c ... */
+
diff --git a/misc/libphysfs/physfs.c b/misc/libphysfs/physfs.c
new file mode 100644
index 0000000..f57837e
--- /dev/null
+++ b/misc/libphysfs/physfs.c
@@ -0,0 +1,2744 @@
+/**
+ * PhysicsFS; a portable, flexible file i/o abstraction.
+ *
+ * Documentation is in physfs.h. It's verbose, honest. :)
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+/* !!! FIXME: ERR_PAST_EOF shouldn't trigger for reads. Just return zero. */
+/* !!! FIXME: use snprintf(), not sprintf(). */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+
+typedef struct __PHYSFS_DIRHANDLE__
+{
+ void *opaque; /* Instance data unique to the archiver. */
+ char *dirName; /* Path to archive in platform-dependent notation. */
+ char *mountPoint; /* Mountpoint in virtual file tree. */
+ const PHYSFS_Archiver *funcs; /* Ptr to archiver info for this handle. */
+ struct __PHYSFS_DIRHANDLE__ *next; /* linked list stuff. */
+} DirHandle;
+
+
+typedef struct __PHYSFS_FILEHANDLE__
+{
+ PHYSFS_Io *io; /* Instance data unique to the archiver for this file. */
+ PHYSFS_uint8 forReading; /* Non-zero if reading, zero if write/append */
+ const DirHandle *dirHandle; /* Archiver instance that created this */
+ PHYSFS_uint8 *buffer; /* Buffer, if set (NULL otherwise). Don't touch! */
+ PHYSFS_uint32 bufsize; /* Bufsize, if set (0 otherwise). Don't touch! */
+ PHYSFS_uint32 buffill; /* Buffer fill size. Don't touch! */
+ PHYSFS_uint32 bufpos; /* Buffer position. Don't touch! */
+ struct __PHYSFS_FILEHANDLE__ *next; /* linked list stuff. */
+} FileHandle;
+
+
+typedef struct __PHYSFS_ERRSTATETYPE__
+{
+ void *tid;
+ PHYSFS_ErrorCode code;
+ struct __PHYSFS_ERRSTATETYPE__ *next;
+} ErrState;
+
+
+/* The various i/o drivers...some of these may not be compiled in. */
+extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
+
+static const PHYSFS_Archiver *staticArchivers[] =
+{
+#if PHYSFS_SUPPORTS_ZIP
+ &__PHYSFS_Archiver_ZIP,
+#endif
+#if PHYSFS_SUPPORTS_7Z
+ &__PHYSFS_Archiver_LZMA,
+#endif
+#if PHYSFS_SUPPORTS_GRP
+ &__PHYSFS_Archiver_GRP,
+#endif
+#if PHYSFS_SUPPORTS_QPAK
+ &__PHYSFS_Archiver_QPAK,
+#endif
+#if PHYSFS_SUPPORTS_HOG
+ &__PHYSFS_Archiver_HOG,
+#endif
+#if PHYSFS_SUPPORTS_MVL
+ &__PHYSFS_Archiver_MVL,
+#endif
+#if PHYSFS_SUPPORTS_WAD
+ &__PHYSFS_Archiver_WAD,
+#endif
+#if PHYSFS_SUPPORTS_ISO9660
+ &__PHYSFS_Archiver_ISO9660,
+#endif
+ NULL
+};
+
+
+
+/* General PhysicsFS state ... */
+static int initialized = 0;
+static ErrState *errorStates = NULL;
+static DirHandle *searchPath = NULL;
+static DirHandle *writeDir = NULL;
+static FileHandle *openWriteList = NULL;
+static FileHandle *openReadList = NULL;
+static char *baseDir = NULL;
+static char *userDir = NULL;
+static char *prefDir = NULL;
+static int allowSymLinks = 0;
+static const PHYSFS_Archiver **archivers = NULL;
+static const PHYSFS_ArchiveInfo **archiveInfo = NULL;
+
+/* mutexes ... */
+static void *errorLock = NULL; /* protects error message list. */
+static void *stateLock = NULL; /* protects other PhysFS static state. */
+
+/* allocator ... */
+static int externalAllocator = 0;
+PHYSFS_Allocator allocator;
+
+
+/* PHYSFS_Io implementation for i/o to physical filesystem... */
+
+/* !!! FIXME: maybe refcount the paths in a string pool? */
+typedef struct __PHYSFS_NativeIoInfo
+{
+ void *handle;
+ const char *path;
+ int mode; /* 'r', 'w', or 'a' */
+} NativeIoInfo;
+
+static PHYSFS_sint64 nativeIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_platformRead(info->handle, buf, len);
+} /* nativeIo_read */
+
+static PHYSFS_sint64 nativeIo_write(PHYSFS_Io *io, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_platformWrite(info->handle, buffer, len);
+} /* nativeIo_write */
+
+static int nativeIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_platformSeek(info->handle, offset);
+} /* nativeIo_seek */
+
+static PHYSFS_sint64 nativeIo_tell(PHYSFS_Io *io)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_platformTell(info->handle);
+} /* nativeIo_tell */
+
+static PHYSFS_sint64 nativeIo_length(PHYSFS_Io *io)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_platformFileLength(info->handle);
+} /* nativeIo_length */
+
+static PHYSFS_Io *nativeIo_duplicate(PHYSFS_Io *io)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ return __PHYSFS_createNativeIo(info->path, info->mode);
+} /* nativeIo_duplicate */
+
+static int nativeIo_flush(PHYSFS_Io *io)
+{
+ return __PHYSFS_platformFlush(io->opaque);
+} /* nativeIo_flush */
+
+static void nativeIo_destroy(PHYSFS_Io *io)
+{
+ NativeIoInfo *info = (NativeIoInfo *) io->opaque;
+ __PHYSFS_platformClose(info->handle);
+ allocator.Free((void *) info->path);
+ allocator.Free(info);
+ allocator.Free(io);
+} /* nativeIo_destroy */
+
+static const PHYSFS_Io __PHYSFS_nativeIoInterface =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ nativeIo_read,
+ nativeIo_write,
+ nativeIo_seek,
+ nativeIo_tell,
+ nativeIo_length,
+ nativeIo_duplicate,
+ nativeIo_flush,
+ nativeIo_destroy
+};
+
+PHYSFS_Io *__PHYSFS_createNativeIo(const char *path, const int mode)
+{
+ PHYSFS_Io *io = NULL;
+ NativeIoInfo *info = NULL;
+ void *handle = NULL;
+ char *pathdup = NULL;
+
+ assert((mode == 'r') || (mode == 'w') || (mode == 'a'));
+
+ io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ GOTO_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
+ info = (NativeIoInfo *) allocator.Malloc(sizeof (NativeIoInfo));
+ GOTO_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
+ pathdup = (char *) allocator.Malloc(strlen(path) + 1);
+ GOTO_IF_MACRO(!pathdup, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
+
+ if (mode == 'r')
+ handle = __PHYSFS_platformOpenRead(path);
+ else if (mode == 'w')
+ handle = __PHYSFS_platformOpenWrite(path);
+ else if (mode == 'a')
+ handle = __PHYSFS_platformOpenAppend(path);
+
+ GOTO_IF_MACRO(!handle, ERRPASS, createNativeIo_failed);
+
+ strcpy(pathdup, path);
+ info->handle = handle;
+ info->path = pathdup;
+ info->mode = mode;
+ memcpy(io, &__PHYSFS_nativeIoInterface, sizeof (*io));
+ io->opaque = info;
+ return io;
+
+createNativeIo_failed:
+ if (handle != NULL) __PHYSFS_platformClose(handle);
+ if (pathdup != NULL) allocator.Free(pathdup);
+ if (info != NULL) allocator.Free(info);
+ if (io != NULL) allocator.Free(io);
+ return NULL;
+} /* __PHYSFS_createNativeIo */
+
+
+/* PHYSFS_Io implementation for i/o to a memory buffer... */
+
+typedef struct __PHYSFS_MemoryIoInfo
+{
+ const PHYSFS_uint8 *buf;
+ PHYSFS_uint64 len;
+ PHYSFS_uint64 pos;
+ PHYSFS_Io *parent;
+ volatile PHYSFS_uint32 refcount;
+ void (*destruct)(void *);
+} MemoryIoInfo;
+
+static PHYSFS_sint64 memoryIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
+{
+ MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ const PHYSFS_uint64 avail = info->len - info->pos;
+ assert(avail <= info->len);
+
+ if (avail == 0)
+ return 0; /* we're at EOF; nothing to do. */
+
+ if (len > avail)
+ len = avail;
+
+ memcpy(buf, info->buf + info->pos, (size_t) len);
+ info->pos += len;
+ return len;
+} /* memoryIo_read */
+
+static PHYSFS_sint64 memoryIo_write(PHYSFS_Io *io, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ BAIL_MACRO(PHYSFS_ERR_OPEN_FOR_READING, -1);
+} /* memoryIo_write */
+
+static int memoryIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ BAIL_IF_MACRO(offset > info->len, PHYSFS_ERR_PAST_EOF, 0);
+ info->pos = offset;
+ return 1;
+} /* memoryIo_seek */
+
+static PHYSFS_sint64 memoryIo_tell(PHYSFS_Io *io)
+{
+ const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ return (PHYSFS_sint64) info->pos;
+} /* memoryIo_tell */
+
+static PHYSFS_sint64 memoryIo_length(PHYSFS_Io *io)
+{
+ const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ return (PHYSFS_sint64) info->len;
+} /* memoryIo_length */
+
+static PHYSFS_Io *memoryIo_duplicate(PHYSFS_Io *io)
+{
+ MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ MemoryIoInfo *newinfo = NULL;
+ PHYSFS_Io *parent = info->parent;
+ PHYSFS_Io *retval = NULL;
+
+ /* avoid deep copies. */
+ assert((!parent) || (!((MemoryIoInfo *) parent->opaque)->parent) );
+
+ /* share the buffer between duplicates. */
+ if (parent != NULL) /* dup the parent, increment its refcount. */
+ return parent->duplicate(parent);
+
+ /* we're the parent. */
+
+ retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ newinfo = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
+ if (!newinfo)
+ {
+ allocator.Free(retval);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ /* !!! FIXME: want lockless atomic increment. */
+ __PHYSFS_platformGrabMutex(stateLock);
+ info->refcount++;
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ memset(newinfo, '\0', sizeof (*info));
+ newinfo->buf = info->buf;
+ newinfo->len = info->len;
+ newinfo->pos = 0;
+ newinfo->parent = io;
+ newinfo->refcount = 0;
+ newinfo->destruct = NULL;
+
+ memcpy(retval, io, sizeof (*retval));
+ retval->opaque = newinfo;
+ return retval;
+} /* memoryIo_duplicate */
+
+static int memoryIo_flush(PHYSFS_Io *io) { return 1; /* it's read-only. */ }
+
+static void memoryIo_destroy(PHYSFS_Io *io)
+{
+ MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ PHYSFS_Io *parent = info->parent;
+ int should_die = 0;
+
+ if (parent != NULL)
+ {
+ assert(info->buf == ((MemoryIoInfo *) info->parent->opaque)->buf);
+ assert(info->len == ((MemoryIoInfo *) info->parent->opaque)->len);
+ assert(info->refcount == 0);
+ assert(info->destruct == NULL);
+ allocator.Free(info);
+ allocator.Free(io);
+ parent->destroy(parent); /* decrements refcount. */
+ return;
+ } /* if */
+
+ /* we _are_ the parent. */
+ assert(info->refcount > 0); /* even in a race, we hold a reference. */
+
+ /* !!! FIXME: want lockless atomic decrement. */
+ __PHYSFS_platformGrabMutex(stateLock);
+ info->refcount--;
+ should_die = (info->refcount == 0);
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ if (should_die)
+ {
+ void (*destruct)(void *) = info->destruct;
+ void *buf = (void *) info->buf;
+ io->opaque = NULL; /* kill this here in case of race. */
+ allocator.Free(info);
+ allocator.Free(io);
+ if (destruct != NULL)
+ destruct(buf);
+ } /* if */
+} /* memoryIo_destroy */
+
+
+static const PHYSFS_Io __PHYSFS_memoryIoInterface =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ memoryIo_read,
+ memoryIo_write,
+ memoryIo_seek,
+ memoryIo_tell,
+ memoryIo_length,
+ memoryIo_duplicate,
+ memoryIo_flush,
+ memoryIo_destroy
+};
+
+PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
+ void (*destruct)(void *))
+{
+ PHYSFS_Io *io = NULL;
+ MemoryIoInfo *info = NULL;
+
+ io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ GOTO_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
+ info = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
+ GOTO_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
+
+ memset(info, '\0', sizeof (*info));
+ info->buf = (const PHYSFS_uint8 *) buf;
+ info->len = len;
+ info->pos = 0;
+ info->parent = NULL;
+ info->refcount = 1;
+ info->destruct = destruct;
+
+ memcpy(io, &__PHYSFS_memoryIoInterface, sizeof (*io));
+ io->opaque = info;
+ return io;
+
+createMemoryIo_failed:
+ if (info != NULL) allocator.Free(info);
+ if (io != NULL) allocator.Free(io);
+ return NULL;
+} /* __PHYSFS_createMemoryIo */
+
+
+/* PHYSFS_Io implementation for i/o to a PHYSFS_File... */
+
+static PHYSFS_sint64 handleIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
+{
+ return PHYSFS_readBytes((PHYSFS_File *) io->opaque, buf, len);
+} /* handleIo_read */
+
+static PHYSFS_sint64 handleIo_write(PHYSFS_Io *io, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ return PHYSFS_writeBytes((PHYSFS_File *) io->opaque, buffer, len);
+} /* handleIo_write */
+
+static int handleIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
+{
+ return PHYSFS_seek((PHYSFS_File *) io->opaque, offset);
+} /* handleIo_seek */
+
+static PHYSFS_sint64 handleIo_tell(PHYSFS_Io *io)
+{
+ return PHYSFS_tell((PHYSFS_File *) io->opaque);
+} /* handleIo_tell */
+
+static PHYSFS_sint64 handleIo_length(PHYSFS_Io *io)
+{
+ return PHYSFS_fileLength((PHYSFS_File *) io->opaque);
+} /* handleIo_length */
+
+static PHYSFS_Io *handleIo_duplicate(PHYSFS_Io *io)
+{
+ /*
+ * There's no duplicate at the PHYSFS_File level, so we break the
+ * abstraction. We're allowed to: we're physfs.c!
+ */
+ FileHandle *origfh = (FileHandle *) io->opaque;
+ FileHandle *newfh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
+ PHYSFS_Io *retval = NULL;
+
+ GOTO_IF_MACRO(!newfh, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
+ memset(newfh, '\0', sizeof (*newfh));
+
+ retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
+
+#if 0 /* we don't buffer the duplicate, at least not at the moment. */
+ if (origfh->buffer != NULL)
+ {
+ newfh->buffer = (PHYSFS_uint8 *) allocator.Malloc(origfh->bufsize);
+ if (!newfh->buffer)
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
+ newfh->bufsize = origfh->bufsize;
+ } /* if */
+#endif
+
+ newfh->io = origfh->io->duplicate(origfh->io);
+ GOTO_IF_MACRO(!newfh->io, ERRPASS, handleIo_dupe_failed);
+
+ newfh->forReading = origfh->forReading;
+ newfh->dirHandle = origfh->dirHandle;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ if (newfh->forReading)
+ {
+ newfh->next = openReadList;
+ openReadList = newfh;
+ } /* if */
+ else
+ {
+ newfh->next = openWriteList;
+ openWriteList = newfh;
+ } /* else */
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ memcpy(retval, io, sizeof (PHYSFS_Io));
+ retval->opaque = newfh;
+ return retval;
+
+handleIo_dupe_failed:
+ if (newfh)
+ {
+ if (newfh->io != NULL) newfh->io->destroy(newfh->io);
+ if (newfh->buffer != NULL) allocator.Free(newfh->buffer);
+ allocator.Free(newfh);
+ } /* if */
+
+ return NULL;
+} /* handleIo_duplicate */
+
+static int handleIo_flush(PHYSFS_Io *io)
+{
+ return PHYSFS_flush((PHYSFS_File *) io->opaque);
+} /* handleIo_flush */
+
+static void handleIo_destroy(PHYSFS_Io *io)
+{
+ if (io->opaque != NULL)
+ PHYSFS_close((PHYSFS_File *) io->opaque);
+ allocator.Free(io);
+} /* handleIo_destroy */
+
+static const PHYSFS_Io __PHYSFS_handleIoInterface =
+{
+ CURRENT_PHYSFS_IO_API_VERSION, NULL,
+ handleIo_read,
+ handleIo_write,
+ handleIo_seek,
+ handleIo_tell,
+ handleIo_length,
+ handleIo_duplicate,
+ handleIo_flush,
+ handleIo_destroy
+};
+
+static PHYSFS_Io *__PHYSFS_createHandleIo(PHYSFS_File *f)
+{
+ PHYSFS_Io *io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
+ BAIL_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ memcpy(io, &__PHYSFS_handleIoInterface, sizeof (*io));
+ io->opaque = f;
+ return io;
+} /* __PHYSFS_createHandleIo */
+
+
+/* functions ... */
+
+typedef struct
+{
+ char **list;
+ PHYSFS_uint32 size;
+ PHYSFS_ErrorCode errcode;
+} EnumStringListCallbackData;
+
+static void enumStringListCallback(void *data, const char *str)
+{
+ void *ptr;
+ char *newstr;
+ EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
+
+ if (pecd->errcode)
+ return;
+
+ ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
+ newstr = (char *) allocator.Malloc(strlen(str) + 1);
+ if (ptr != NULL)
+ pecd->list = (char **) ptr;
+
+ if ((ptr == NULL) || (newstr == NULL))
+ {
+ pecd->errcode = PHYSFS_ERR_OUT_OF_MEMORY;
+ pecd->list[pecd->size] = NULL;
+ PHYSFS_freeList(pecd->list);
+ return;
+ } /* if */
+
+ strcpy(newstr, str);
+ pecd->list[pecd->size] = newstr;
+ pecd->size++;
+} /* enumStringListCallback */
+
+
+static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
+{
+ EnumStringListCallbackData ecd;
+ memset(&ecd, '\0', sizeof (ecd));
+ ecd.list = (char **) allocator.Malloc(sizeof (char *));
+ BAIL_IF_MACRO(!ecd.list, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ func(enumStringListCallback, &ecd);
+
+ if (ecd.errcode)
+ {
+ __PHYSFS_setError(ecd.errcode);
+ return NULL;
+ } /* if */
+
+ ecd.list[ecd.size] = NULL;
+ return ecd.list;
+} /* doEnumStringList */
+
+
+static void __PHYSFS_bubble_sort(void *a, size_t lo, size_t hi,
+ int (*cmpfn)(void *, size_t, size_t),
+ void (*swapfn)(void *, size_t, size_t))
+{
+ size_t i;
+ int sorted;
+
+ do
+ {
+ sorted = 1;
+ for (i = lo; i < hi; i++)
+ {
+ if (cmpfn(a, i, i + 1) > 0)
+ {
+ swapfn(a, i, i + 1);
+ sorted = 0;
+ } /* if */
+ } /* for */
+ } while (!sorted);
+} /* __PHYSFS_bubble_sort */
+
+
+static void __PHYSFS_quick_sort(void *a, size_t lo, size_t hi,
+ int (*cmpfn)(void *, size_t, size_t),
+ void (*swapfn)(void *, size_t, size_t))
+{
+ size_t i;
+ size_t j;
+ size_t v;
+
+ if ((hi - lo) <= PHYSFS_QUICKSORT_THRESHOLD)
+ __PHYSFS_bubble_sort(a, lo, hi, cmpfn, swapfn);
+ else
+ {
+ i = (hi + lo) / 2;
+
+ if (cmpfn(a, lo, i) > 0) swapfn(a, lo, i);
+ if (cmpfn(a, lo, hi) > 0) swapfn(a, lo, hi);
+ if (cmpfn(a, i, hi) > 0) swapfn(a, i, hi);
+
+ j = hi - 1;
+ swapfn(a, i, j);
+ i = lo;
+ v = j;
+ while (1)
+ {
+ while(cmpfn(a, ++i, v) < 0) { /* do nothing */ }
+ while(cmpfn(a, --j, v) > 0) { /* do nothing */ }
+ if (j < i)
+ break;
+ swapfn(a, i, j);
+ } /* while */
+ if (i != (hi-1))
+ swapfn(a, i, hi-1);
+ __PHYSFS_quick_sort(a, lo, j, cmpfn, swapfn);
+ __PHYSFS_quick_sort(a, i+1, hi, cmpfn, swapfn);
+ } /* else */
+} /* __PHYSFS_quick_sort */
+
+
+void __PHYSFS_sort(void *entries, size_t max,
+ int (*cmpfn)(void *, size_t, size_t),
+ void (*swapfn)(void *, size_t, size_t))
+{
+ /*
+ * Quicksort w/ Bubblesort fallback algorithm inspired by code from here:
+ * http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
+ */
+ if (max > 0)
+ __PHYSFS_quick_sort(entries, 0, max - 1, cmpfn, swapfn);
+} /* __PHYSFS_sort */
+
+
+static ErrState *findErrorForCurrentThread(void)
+{
+ ErrState *i;
+ void *tid;
+
+ if (errorLock != NULL)
+ __PHYSFS_platformGrabMutex(errorLock);
+
+ if (errorStates != NULL)
+ {
+ tid = __PHYSFS_platformGetThreadID();
+
+ for (i = errorStates; i != NULL; i = i->next)
+ {
+ if (i->tid == tid)
+ {
+ if (errorLock != NULL)
+ __PHYSFS_platformReleaseMutex(errorLock);
+ return i;
+ } /* if */
+ } /* for */
+ } /* if */
+
+ if (errorLock != NULL)
+ __PHYSFS_platformReleaseMutex(errorLock);
+
+ return NULL; /* no error available. */
+} /* findErrorForCurrentThread */
+
+
+void __PHYSFS_setError(const PHYSFS_ErrorCode errcode)
+{
+ ErrState *err;
+
+ if (!errcode)
+ return;
+
+ err = findErrorForCurrentThread();
+ if (err == NULL)
+ {
+ err = (ErrState *) allocator.Malloc(sizeof (ErrState));
+ if (err == NULL)
+ return; /* uhh...? */
+
+ memset(err, '\0', sizeof (ErrState));
+ err->tid = __PHYSFS_platformGetThreadID();
+
+ if (errorLock != NULL)
+ __PHYSFS_platformGrabMutex(errorLock);
+
+ err->next = errorStates;
+ errorStates = err;
+
+ if (errorLock != NULL)
+ __PHYSFS_platformReleaseMutex(errorLock);
+ } /* if */
+
+ err->code = errcode;
+} /* __PHYSFS_setError */
+
+
+PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
+{
+ ErrState *err = findErrorForCurrentThread();
+ const PHYSFS_ErrorCode retval = (err) ? err->code : PHYSFS_ERR_OK;
+ if (err)
+ err->code = PHYSFS_ERR_OK;
+ return retval;
+} /* PHYSFS_getLastErrorCode */
+
+
+PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
+{
+ switch (code)
+ {
+ case PHYSFS_ERR_OK: return "no error";
+ case PHYSFS_ERR_OTHER_ERROR: return "unknown error";
+ case PHYSFS_ERR_OUT_OF_MEMORY: return "out of memory";
+ case PHYSFS_ERR_NOT_INITIALIZED: return "not initialized";
+ case PHYSFS_ERR_IS_INITIALIZED: return "already initialized";
+ case PHYSFS_ERR_ARGV0_IS_NULL: return "argv[0] is NULL";
+ case PHYSFS_ERR_UNSUPPORTED: return "unsupported";
+ case PHYSFS_ERR_PAST_EOF: return "past end of file";
+ case PHYSFS_ERR_FILES_STILL_OPEN: return "files still open";
+ case PHYSFS_ERR_INVALID_ARGUMENT: return "invalid argument";
+ case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
+ case PHYSFS_ERR_NO_SUCH_PATH: return "no such path";
+ case PHYSFS_ERR_SYMLINK_FORBIDDEN: return "symlinks are forbidden";
+ case PHYSFS_ERR_NO_WRITE_DIR: return "write directory is not set";
+ case PHYSFS_ERR_OPEN_FOR_READING: return "file open for reading";
+ case PHYSFS_ERR_OPEN_FOR_WRITING: return "file open for writing";
+ case PHYSFS_ERR_NOT_A_FILE: return "not a file";
+ case PHYSFS_ERR_READ_ONLY: return "read-only filesystem";
+ case PHYSFS_ERR_CORRUPT: return "corrupted";
+ case PHYSFS_ERR_SYMLINK_LOOP: return "infinite symbolic link loop";
+ case PHYSFS_ERR_IO: return "i/o error";
+ case PHYSFS_ERR_PERMISSION: return "permission denied";
+ case PHYSFS_ERR_NO_SPACE: return "no space available for writing";
+ case PHYSFS_ERR_BAD_FILENAME: return "filename is illegal or insecure";
+ case PHYSFS_ERR_BUSY: return "tried to modify a file the OS needs";
+ case PHYSFS_ERR_DIR_NOT_EMPTY: return "directory isn't empty";
+ case PHYSFS_ERR_OS_ERROR: return "OS reported an error";
+ } /* switch */
+
+ return NULL; /* don't know this error code. */
+} /* PHYSFS_getErrorByCode */
+
+
+void PHYSFS_setErrorCode(PHYSFS_ErrorCode code)
+{
+ __PHYSFS_setError(code);
+} /* PHYSFS_setErrorCode */
+
+
+const char *PHYSFS_getLastError(void)
+{
+ const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
+ return (err) ? PHYSFS_getErrorByCode(err) : NULL;
+} /* PHYSFS_getLastError */
+
+
+/* MAKE SURE that errorLock is held before calling this! */
+static void freeErrorStates(void)
+{
+ ErrState *i;
+ ErrState *next;
+
+ for (i = errorStates; i != NULL; i = next)
+ {
+ next = i->next;
+ allocator.Free(i);
+ } /* for */
+
+ errorStates = NULL;
+} /* freeErrorStates */
+
+
+void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
+{
+ if (ver != NULL)
+ {
+ ver->major = PHYSFS_VER_MAJOR;
+ ver->minor = PHYSFS_VER_MINOR;
+ ver->patch = PHYSFS_VER_PATCH;
+ } /* if */
+} /* PHYSFS_getLinkedVersion */
+
+
+static const char *find_filename_extension(const char *fname)
+{
+ const char *retval = NULL;
+ if (fname != NULL)
+ {
+ const char *p = strchr(fname, '.');
+ retval = p;
+
+ while (p != NULL)
+ {
+ p = strchr(p + 1, '.');
+ if (p != NULL)
+ retval = p;
+ } /* while */
+
+ if (retval != NULL)
+ retval++; /* skip '.' */
+ } /* if */
+
+ return retval;
+} /* find_filename_extension */
+
+
+static DirHandle *tryOpenDir(PHYSFS_Io *io, const PHYSFS_Archiver *funcs,
+ const char *d, int forWriting)
+{
+ DirHandle *retval = NULL;
+ void *opaque = NULL;
+
+ if (io != NULL)
+ BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL);
+
+ opaque = funcs->openArchive(io, d, forWriting);
+ if (opaque != NULL)
+ {
+ retval = (DirHandle *) allocator.Malloc(sizeof (DirHandle));
+ if (retval == NULL)
+ funcs->closeArchive(opaque);
+ else
+ {
+ memset(retval, '\0', sizeof (DirHandle));
+ retval->mountPoint = NULL;
+ retval->funcs = funcs;
+ retval->opaque = opaque;
+ } /* else */
+ } /* if */
+
+ return retval;
+} /* tryOpenDir */
+
+
+static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
+{
+ DirHandle *retval = NULL;
+ const PHYSFS_Archiver **i;
+ const char *ext;
+
+ assert((io != NULL) || (d != NULL));
+
+ if (io == NULL)
+ {
+ /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
+ retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting);
+ if (retval != NULL)
+ return retval;
+
+ io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
+ BAIL_IF_MACRO(!io, ERRPASS, 0);
+ } /* if */
+
+ ext = find_filename_extension(d);
+ if (ext != NULL)
+ {
+ /* Look for archivers with matching file extensions first... */
+ for (i = archivers; (*i != NULL) && (retval == NULL); i++)
+ {
+ if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) == 0)
+ retval = tryOpenDir(io, *i, d, forWriting);
+ } /* for */
+
+ /* failing an exact file extension match, try all the others... */
+ for (i = archivers; (*i != NULL) && (retval == NULL); i++)
+ {
+ if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) != 0)
+ retval = tryOpenDir(io, *i, d, forWriting);
+ } /* for */
+ } /* if */
+
+ else /* no extension? Try them all. */
+ {
+ for (i = archivers; (*i != NULL) && (retval == NULL); i++)
+ retval = tryOpenDir(io, *i, d, forWriting);
+ } /* else */
+
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_UNSUPPORTED, NULL);
+ return retval;
+} /* openDirectory */
+
+
+/*
+ * Make a platform-independent path string sane. Doesn't actually check the
+ * file hierarchy, it just cleans up the string.
+ * (dst) must be a buffer at least as big as (src), as this is where the
+ * cleaned up string is deposited.
+ * If there are illegal bits in the path (".." entries, etc) then we
+ * return zero and (dst) is undefined. Non-zero if the path was sanitized.
+ */
+static int sanitizePlatformIndependentPath(const char *src, char *dst)
+{
+ char *prev;
+ char ch;
+
+ while (*src == '/') /* skip initial '/' chars... */
+ src++;
+
+ prev = dst;
+ do
+ {
+ ch = *(src++);
+
+ if ((ch == ':') || (ch == '\\')) /* illegal chars in a physfs path. */
+ BAIL_MACRO(PHYSFS_ERR_BAD_FILENAME, 0);
+
+ if (ch == '/') /* path separator. */
+ {
+ *dst = '\0'; /* "." and ".." are illegal pathnames. */
+ if ((strcmp(prev, ".") == 0) || (strcmp(prev, "..") == 0))
+ BAIL_MACRO(PHYSFS_ERR_BAD_FILENAME, 0);
+
+ while (*src == '/') /* chop out doubles... */
+ src++;
+
+ if (*src == '\0') /* ends with a pathsep? */
+ break; /* we're done, don't add final pathsep to dst. */
+
+ prev = dst + 1;
+ } /* if */
+
+ *(dst++) = ch;
+ } while (ch != '\0');
+
+ return 1;
+} /* sanitizePlatformIndependentPath */
+
+
+/*
+ * Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an
+ * output from sanitizePlatformIndependentPath(), so that it is in a known
+ * state.
+ *
+ * This only finds legitimate segments of a mountpoint. If the mountpoint is
+ * "/a/b/c" and (fname) is "/a/b/c", "/", or "/a/b/c/d", then the results are
+ * all zero. "/a/b" will succeed, though.
+ */
+static int partOfMountPoint(DirHandle *h, char *fname)
+{
+ /* !!! FIXME: This code feels gross. */
+ int rc;
+ size_t len, mntpntlen;
+
+ if (h->mountPoint == NULL)
+ return 0;
+ else if (*fname == '\0')
+ return 1;
+
+ len = strlen(fname);
+ mntpntlen = strlen(h->mountPoint);
+ if (len > mntpntlen) /* can't be a subset of mountpoint. */
+ return 0;
+
+ /* if true, must be not a match or a complete match, but not a subset. */
+ if ((len + 1) == mntpntlen)
+ return 0;
+
+ rc = strncmp(fname, h->mountPoint, len); /* !!! FIXME: case insensitive? */
+ if (rc != 0)
+ return 0; /* not a match. */
+
+ /* make sure /a/b matches /a/b/ and not /a/bc ... */
+ return h->mountPoint[len] == '/';
+} /* partOfMountPoint */
+
+
+static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
+ const char *mountPoint, int forWriting)
+{
+ DirHandle *dirHandle = NULL;
+ char *tmpmntpnt = NULL;
+
+ if (mountPoint != NULL)
+ {
+ const size_t len = strlen(mountPoint) + 1;
+ tmpmntpnt = (char *) __PHYSFS_smallAlloc(len);
+ GOTO_IF_MACRO(!tmpmntpnt, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
+ if (!sanitizePlatformIndependentPath(mountPoint, tmpmntpnt))
+ goto badDirHandle;
+ mountPoint = tmpmntpnt; /* sanitized version. */
+ } /* if */
+
+ dirHandle = openDirectory(io, newDir, forWriting);
+ GOTO_IF_MACRO(!dirHandle, ERRPASS, badDirHandle);
+
+ if (newDir == NULL)
+ dirHandle->dirName = NULL;
+ else
+ {
+ dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
+ if (!dirHandle->dirName)
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
+ strcpy(dirHandle->dirName, newDir);
+ } /* else */
+
+ if ((mountPoint != NULL) && (*mountPoint != '\0'))
+ {
+ dirHandle->mountPoint = (char *)allocator.Malloc(strlen(mountPoint)+2);
+ if (!dirHandle->mountPoint)
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
+ strcpy(dirHandle->mountPoint, mountPoint);
+ strcat(dirHandle->mountPoint, "/");
+ } /* if */
+
+ __PHYSFS_smallFree(tmpmntpnt);
+ return dirHandle;
+
+badDirHandle:
+ if (dirHandle != NULL)
+ {
+ dirHandle->funcs->closeArchive(dirHandle->opaque);
+ allocator.Free(dirHandle->dirName);
+ allocator.Free(dirHandle->mountPoint);
+ allocator.Free(dirHandle);
+ } /* if */
+
+ __PHYSFS_smallFree(tmpmntpnt);
+ return NULL;
+} /* createDirHandle */
+
+
+/* MAKE SURE you've got the stateLock held before calling this! */
+static int freeDirHandle(DirHandle *dh, FileHandle *openList)
+{
+ FileHandle *i;
+
+ if (dh == NULL)
+ return 1;
+
+ for (i = openList; i != NULL; i = i->next)
+ BAIL_IF_MACRO(i->dirHandle == dh, PHYSFS_ERR_FILES_STILL_OPEN, 0);
+
+ dh->funcs->closeArchive(dh->opaque);
+ allocator.Free(dh->dirName);
+ allocator.Free(dh->mountPoint);
+ allocator.Free(dh);
+ return 1;
+} /* freeDirHandle */
+
+
+static char *calculateBaseDir(const char *argv0)
+{
+ const char dirsep = __PHYSFS_platformDirSeparator;
+ char *retval = NULL;
+ char *ptr = NULL;
+
+ /* Give the platform layer first shot at this. */
+ retval = __PHYSFS_platformCalcBaseDir(argv0);
+ if (retval != NULL)
+ return retval;
+
+ /* We need argv0 to go on. */
+ BAIL_IF_MACRO(argv0 == NULL, PHYSFS_ERR_ARGV0_IS_NULL, NULL);
+
+ ptr = strrchr(argv0, dirsep);
+ if (ptr != NULL)
+ {
+ const size_t size = ((size_t) (ptr - argv0)) + 1;
+ retval = (char *) allocator.Malloc(size + 1);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ memcpy(retval, argv0, size);
+ retval[size] = '\0';
+ return retval;
+ } /* if */
+
+ /* argv0 wasn't helpful. */
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+} /* calculateBaseDir */
+
+
+static int initializeMutexes(void)
+{
+ errorLock = __PHYSFS_platformCreateMutex();
+ if (errorLock == NULL)
+ goto initializeMutexes_failed;
+
+ stateLock = __PHYSFS_platformCreateMutex();
+ if (stateLock == NULL)
+ goto initializeMutexes_failed;
+
+ return 1; /* success. */
+
+initializeMutexes_failed:
+ if (errorLock != NULL)
+ __PHYSFS_platformDestroyMutex(errorLock);
+
+ if (stateLock != NULL)
+ __PHYSFS_platformDestroyMutex(stateLock);
+
+ errorLock = stateLock = NULL;
+ return 0; /* failed. */
+} /* initializeMutexes */
+
+
+static void setDefaultAllocator(void);
+
+static int initStaticArchivers(void)
+{
+ const size_t numStaticArchivers = __PHYSFS_ARRAYLEN(staticArchivers);
+ const size_t len = numStaticArchivers * sizeof (void *);
+ size_t i;
+
+ assert(numStaticArchivers > 0); /* seriously, none at all?! */
+ assert(staticArchivers[numStaticArchivers - 1] == NULL);
+
+ archiveInfo = (const PHYSFS_ArchiveInfo **) allocator.Malloc(len);
+ BAIL_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ archivers = (const PHYSFS_Archiver **) allocator.Malloc(len);
+ BAIL_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+
+ for (i = 0; i < numStaticArchivers - 1; i++)
+ archiveInfo[i] = &staticArchivers[i]->info;
+ archiveInfo[numStaticArchivers - 1] = NULL;
+
+ memcpy(archivers, staticArchivers, len);
+
+ return 1;
+} /* initStaticArchivers */
+
+
+static int doDeinit(void);
+
+int PHYSFS_init(const char *argv0)
+{
+ BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0);
+
+ if (!externalAllocator)
+ setDefaultAllocator();
+
+ if ((allocator.Init != NULL) && (!allocator.Init())) return 0;
+
+ if (!__PHYSFS_platformInit())
+ {
+ if (allocator.Deinit != NULL) allocator.Deinit();
+ return 0;
+ } /* if */
+
+ /* everything below here can be cleaned up safely by doDeinit(). */
+
+ if (!initializeMutexes()) goto initFailed;
+
+ baseDir = calculateBaseDir(argv0);
+ if (!baseDir) goto initFailed;
+
+ userDir = __PHYSFS_platformCalcUserDir();
+ if (!userDir) goto initFailed;
+
+ /* Platform layer is required to append a dirsep. */
+ assert(baseDir[strlen(baseDir) - 1] == __PHYSFS_platformDirSeparator);
+ assert(userDir[strlen(userDir) - 1] == __PHYSFS_platformDirSeparator);
+
+ if (!initStaticArchivers()) goto initFailed;
+
+ initialized = 1;
+
+ /* This makes sure that the error subsystem is initialized. */
+ __PHYSFS_setError(PHYSFS_getLastErrorCode());
+
+ return 1;
+
+initFailed:
+ doDeinit();
+ return 0;
+} /* PHYSFS_init */
+
+
+/* MAKE SURE you hold stateLock before calling this! */
+static int closeFileHandleList(FileHandle **list)
+{
+ FileHandle *i;
+ FileHandle *next = NULL;
+
+ for (i = *list; i != NULL; i = next)
+ {
+ PHYSFS_Io *io = i->io;
+ next = i->next;
+
+ if (!io->flush(io))
+ {
+ *list = i;
+ return 0;
+ } /* if */
+
+ io->destroy(io);
+ allocator.Free(i);
+ } /* for */
+
+ *list = NULL;
+ return 1;
+} /* closeFileHandleList */
+
+
+/* MAKE SURE you hold the stateLock before calling this! */
+static void freeSearchPath(void)
+{
+ DirHandle *i;
+ DirHandle *next = NULL;
+
+ closeFileHandleList(&openReadList);
+
+ if (searchPath != NULL)
+ {
+ for (i = searchPath; i != NULL; i = next)
+ {
+ next = i->next;
+ freeDirHandle(i, openReadList);
+ } /* for */
+ searchPath = NULL;
+ } /* if */
+} /* freeSearchPath */
+
+
+static int doDeinit(void)
+{
+ BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), ERRPASS, 0);
+
+ closeFileHandleList(&openWriteList);
+ BAIL_IF_MACRO(!PHYSFS_setWriteDir(NULL), PHYSFS_ERR_FILES_STILL_OPEN, 0);
+
+ freeSearchPath();
+ freeErrorStates();
+
+ if (baseDir != NULL)
+ {
+ allocator.Free(baseDir);
+ baseDir = NULL;
+ } /* if */
+
+ if (userDir != NULL)
+ {
+ allocator.Free(userDir);
+ userDir = NULL;
+ } /* if */
+
+ if (prefDir != NULL)
+ {
+ allocator.Free(prefDir);
+ prefDir = NULL;
+ } /* if */
+
+ if (archiveInfo != NULL)
+ {
+ allocator.Free(archiveInfo);
+ archiveInfo = NULL;
+ } /* if */
+
+ if (archivers != NULL)
+ {
+ allocator.Free(archivers);
+ archivers = NULL;
+ } /* if */
+
+ allowSymLinks = 0;
+ initialized = 0;
+
+ if (errorLock) __PHYSFS_platformDestroyMutex(errorLock);
+ if (stateLock) __PHYSFS_platformDestroyMutex(stateLock);
+
+ if (allocator.Deinit != NULL)
+ allocator.Deinit();
+
+ errorLock = stateLock = NULL;
+ return 1;
+} /* doDeinit */
+
+
+int PHYSFS_deinit(void)
+{
+ BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
+ return doDeinit();
+} /* PHYSFS_deinit */
+
+
+int PHYSFS_isInit(void)
+{
+ return initialized;
+} /* PHYSFS_isInit */
+
+
+const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
+{
+ BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL);
+ return archiveInfo;
+} /* PHYSFS_supportedArchiveTypes */
+
+
+void PHYSFS_freeList(void *list)
+{
+ void **i;
+ if (list != NULL)
+ {
+ for (i = (void **) list; *i != NULL; i++)
+ allocator.Free(*i);
+
+ allocator.Free(list);
+ } /* if */
+} /* PHYSFS_freeList */
+
+
+const char *PHYSFS_getDirSeparator(void)
+{
+ static char retval[2] = { __PHYSFS_platformDirSeparator, '\0' };
+ return retval;
+} /* PHYSFS_getDirSeparator */
+
+
+char **PHYSFS_getCdRomDirs(void)
+{
+ return doEnumStringList(__PHYSFS_platformDetectAvailableCDs);
+} /* PHYSFS_getCdRomDirs */
+
+
+void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
+{
+ __PHYSFS_platformDetectAvailableCDs(callback, data);
+} /* PHYSFS_getCdRomDirsCallback */
+
+
+const char *PHYSFS_getPrefDir(const char *org, const char *app)
+{
+ const char dirsep = __PHYSFS_platformDirSeparator;
+ PHYSFS_Stat statbuf;
+ char *ptr = NULL;
+ char *endstr = NULL;
+ int exists = 0;
+
+ BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
+ BAIL_IF_MACRO(!org, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+ BAIL_IF_MACRO(*org == '\0', PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+ BAIL_IF_MACRO(!app, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+ BAIL_IF_MACRO(*app == '\0', PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+
+ allocator.Free(prefDir);
+ prefDir = __PHYSFS_platformCalcPrefDir(org, app);
+ BAIL_IF_MACRO(!prefDir, ERRPASS, NULL);
+
+ assert(strlen(prefDir) > 0);
+ endstr = prefDir + (strlen(prefDir) - 1);
+ assert(*endstr == dirsep);
+ *endstr = '\0'; /* mask out the final dirsep for now. */
+
+ if (!__PHYSFS_platformStat(prefDir, &exists, &statbuf))
+ {
+ for (ptr = strchr(prefDir, dirsep); ptr; ptr = strchr(ptr+1, dirsep))
+ {
+ *ptr = '\0';
+ __PHYSFS_platformMkDir(prefDir);
+ *ptr = dirsep;
+ } /* for */
+
+ if (!__PHYSFS_platformMkDir(prefDir))
+ {
+ allocator.Free(prefDir);
+ prefDir = NULL;
+ } /* if */
+ } /* if */
+
+ *endstr = dirsep; /* readd the final dirsep. */
+
+ return prefDir;
+} /* PHYSFS_getPrefDir */
+
+
+const char *PHYSFS_getBaseDir(void)
+{
+ return baseDir; /* this is calculated in PHYSFS_init()... */
+} /* PHYSFS_getBaseDir */
+
+
+const char *__PHYSFS_getUserDir(void) /* not deprecated internal version. */
+{
+ return userDir; /* this is calculated in PHYSFS_init()... */
+} /* __PHYSFS_getUserDir */
+
+
+const char *PHYSFS_getUserDir(void)
+{
+ return __PHYSFS_getUserDir();
+} /* PHYSFS_getUserDir */
+
+
+const char *PHYSFS_getWriteDir(void)
+{
+ const char *retval = NULL;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ if (writeDir != NULL)
+ retval = writeDir->dirName;
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ return retval;
+} /* PHYSFS_getWriteDir */
+
+
+int PHYSFS_setWriteDir(const char *newDir)
+{
+ int retval = 1;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ if (writeDir != NULL)
+ {
+ BAIL_IF_MACRO_MUTEX(!freeDirHandle(writeDir, openWriteList), ERRPASS,
+ stateLock, 0);
+ writeDir = NULL;
+ } /* if */
+
+ if (newDir != NULL)
+ {
+ /* !!! FIXME: PHYSFS_Io shouldn't be NULL */
+ writeDir = createDirHandle(NULL, newDir, NULL, 1);
+ retval = (writeDir != NULL);
+ } /* if */
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ return retval;
+} /* PHYSFS_setWriteDir */
+
+
+static int doMount(PHYSFS_Io *io, const char *fname,
+ const char *mountPoint, int appendToPath)
+{
+ DirHandle *dh;
+ DirHandle *prev = NULL;
+ DirHandle *i;
+
+ if (mountPoint == NULL)
+ mountPoint = "/";
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ if (fname != NULL)
+ {
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ /* already in search path? */
+ if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
+ BAIL_MACRO_MUTEX(ERRPASS, stateLock, 1);
+ prev = i;
+ } /* for */
+ } /* if */
+
+ dh = createDirHandle(io, fname, mountPoint, 0);
+ BAIL_IF_MACRO_MUTEX(!dh, ERRPASS, stateLock, 0);
+
+ if (appendToPath)
+ {
+ if (prev == NULL)
+ searchPath = dh;
+ else
+ prev->next = dh;
+ } /* if */
+ else
+ {
+ dh->next = searchPath;
+ searchPath = dh;
+ } /* else */
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+ return 1;
+} /* doMount */
+
+
+int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
+ const char *mountPoint, int appendToPath)
+{
+ BAIL_IF_MACRO(!io, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ BAIL_IF_MACRO(io->version != 0, PHYSFS_ERR_UNSUPPORTED, 0);
+ return doMount(io, fname, mountPoint, appendToPath);
+} /* PHYSFS_mountIo */
+
+
+int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *),
+ const char *fname, const char *mountPoint,
+ int appendToPath)
+{
+ int retval = 0;
+ PHYSFS_Io *io = NULL;
+
+ BAIL_IF_MACRO(!buf, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+
+ io = __PHYSFS_createMemoryIo(buf, len, del);
+ BAIL_IF_MACRO(!io, ERRPASS, 0);
+ retval = doMount(io, fname, mountPoint, appendToPath);
+ if (!retval)
+ {
+ /* docs say not to call (del) in case of failure, so cheat. */
+ MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
+ info->destruct = NULL;
+ io->destroy(io);
+ } /* if */
+
+ return retval;
+} /* PHYSFS_mountMemory */
+
+
+int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
+ const char *mountPoint, int appendToPath)
+{
+ int retval = 0;
+ PHYSFS_Io *io = NULL;
+
+ BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+
+ io = __PHYSFS_createHandleIo(file);
+ BAIL_IF_MACRO(!io, ERRPASS, 0);
+ retval = doMount(io, fname, mountPoint, appendToPath);
+ if (!retval)
+ {
+ /* docs say not to destruct in case of failure, so cheat. */
+ io->opaque = NULL;
+ io->destroy(io);
+ } /* if */
+
+ return retval;
+} /* PHYSFS_mountHandle */
+
+
+int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
+{
+ BAIL_IF_MACRO(!newDir, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ return doMount(NULL, newDir, mountPoint, appendToPath);
+} /* PHYSFS_mount */
+
+
+int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
+{
+ return doMount(NULL, newDir, NULL, appendToPath);
+} /* PHYSFS_addToSearchPath */
+
+
+int PHYSFS_removeFromSearchPath(const char *oldDir)
+{
+ return PHYSFS_unmount(oldDir);
+} /* PHYSFS_removeFromSearchPath */
+
+
+int PHYSFS_unmount(const char *oldDir)
+{
+ DirHandle *i;
+ DirHandle *prev = NULL;
+ DirHandle *next = NULL;
+
+ BAIL_IF_MACRO(oldDir == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ if (strcmp(i->dirName, oldDir) == 0)
+ {
+ next = i->next;
+ BAIL_IF_MACRO_MUTEX(!freeDirHandle(i, openReadList), ERRPASS,
+ stateLock, 0);
+
+ if (prev == NULL)
+ searchPath = next;
+ else
+ prev->next = next;
+
+ BAIL_MACRO_MUTEX(ERRPASS, stateLock, 1);
+ } /* if */
+ prev = i;
+ } /* for */
+
+ BAIL_MACRO_MUTEX(PHYSFS_ERR_NOT_MOUNTED, stateLock, 0);
+} /* PHYSFS_unmount */
+
+
+char **PHYSFS_getSearchPath(void)
+{
+ return doEnumStringList(PHYSFS_getSearchPathCallback);
+} /* PHYSFS_getSearchPath */
+
+
+const char *PHYSFS_getMountPoint(const char *dir)
+{
+ DirHandle *i;
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ if (strcmp(i->dirName, dir) == 0)
+ {
+ const char *retval = ((i->mountPoint) ? i->mountPoint : "/");
+ __PHYSFS_platformReleaseMutex(stateLock);
+ return retval;
+ } /* if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+
+ BAIL_MACRO(PHYSFS_ERR_NOT_MOUNTED, NULL);
+} /* PHYSFS_getMountPoint */
+
+
+void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
+{
+ DirHandle *i;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ for (i = searchPath; i != NULL; i = i->next)
+ callback(data, i->dirName);
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+} /* PHYSFS_getSearchPathCallback */
+
+
+/* Split out to avoid stack allocation in a loop. */
+static void setSaneCfgAddPath(const char *i, const size_t l, const char *dirsep,
+ int archivesFirst)
+{
+ const char *d = PHYSFS_getRealDir(i);
+ const size_t allocsize = strlen(d) + strlen(dirsep) + l + 1;
+ char *str = (char *) __PHYSFS_smallAlloc(allocsize);
+ if (str != NULL)
+ {
+ sprintf(str, "%s%s%s", d, dirsep, i);
+ PHYSFS_mount(str, NULL, archivesFirst == 0);
+ __PHYSFS_smallFree(str);
+ } /* if */
+} /* setSaneCfgAddPath */
+
+
+int PHYSFS_setSaneConfig(const char *organization, const char *appName,
+ const char *archiveExt, int includeCdRoms,
+ int archivesFirst)
+{
+ const char *dirsep = PHYSFS_getDirSeparator();
+ const char *basedir;
+ const char *prefdir;
+
+ BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
+
+ prefdir = PHYSFS_getPrefDir(organization, appName);
+ BAIL_IF_MACRO(!prefdir, ERRPASS, 0);
+
+ basedir = PHYSFS_getBaseDir();
+ BAIL_IF_MACRO(!basedir, ERRPASS, 0);
+
+ BAIL_IF_MACRO(!PHYSFS_setWriteDir(prefdir), PHYSFS_ERR_NO_WRITE_DIR, 0);
+
+ /* Put write dir first in search path... */
+ PHYSFS_mount(prefdir, NULL, 0);
+
+ /* Put base path on search path... */
+ PHYSFS_mount(basedir, NULL, 1);
+
+ /* handle CD-ROMs... */
+ if (includeCdRoms)
+ {
+ char **cds = PHYSFS_getCdRomDirs();
+ char **i;
+ for (i = cds; *i != NULL; i++)
+ PHYSFS_mount(*i, NULL, 1);
+ PHYSFS_freeList(cds);
+ } /* if */
+
+ /* Root out archives, and add them to search path... */
+ if (archiveExt != NULL)
+ {
+ char **rc = PHYSFS_enumerateFiles("/");
+ char **i;
+ size_t extlen = strlen(archiveExt);
+ char *ext;
+
+ for (i = rc; *i != NULL; i++)
+ {
+ size_t l = strlen(*i);
+ if ((l > extlen) && ((*i)[l - extlen - 1] == '.'))
+ {
+ ext = (*i) + (l - extlen);
+ if (__PHYSFS_stricmpASCII(ext, archiveExt) == 0)
+ setSaneCfgAddPath(*i, l, dirsep, archivesFirst);
+ } /* if */
+ } /* for */
+
+ PHYSFS_freeList(rc);
+ } /* if */
+
+ return 1;
+} /* PHYSFS_setSaneConfig */
+
+
+void PHYSFS_permitSymbolicLinks(int allow)
+{
+ allowSymLinks = allow;
+} /* PHYSFS_permitSymbolicLinks */
+
+
+int PHYSFS_symbolicLinksPermitted(void)
+{
+ return allowSymLinks;
+} /* PHYSFS_symbolicLinksPermitted */
+
+
+/*
+ * Verify that (fname) (in platform-independent notation), in relation
+ * to (h) is secure. That means that each element of fname is checked
+ * for symlinks (if they aren't permitted). This also allows for quick
+ * rejection of files that exist outside an archive's mountpoint.
+ *
+ * With some exceptions (like PHYSFS_mkdir(), which builds multiple subdirs
+ * at a time), you should always pass zero for "allowMissing" for efficiency.
+ *
+ * (fname) must point to an output from sanitizePlatformIndependentPath(),
+ * since it will make sure that path names are in the right format for
+ * passing certain checks. It will also do checks for "insecure" pathnames
+ * like ".." which should be done once instead of once per archive. This also
+ * gives us license to treat (fname) as scratch space in this function.
+ *
+ * Returns non-zero if string is safe, zero if there's a security issue.
+ * PHYSFS_getLastError() will specify what was wrong. (*fname) will be
+ * updated to point past any mount point elements so it is prepared to
+ * be used with the archiver directly.
+ */
+static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
+{
+ char *fname = *_fname;
+ int retval = 1;
+ char *start;
+ char *end;
+
+ if (*fname == '\0') /* quick rejection. */
+ return 1;
+
+ /* !!! FIXME: This codeblock sucks. */
+ if (h->mountPoint != NULL) /* NULL mountpoint means "/". */
+ {
+ size_t mntpntlen = strlen(h->mountPoint);
+ size_t len = strlen(fname);
+ assert(mntpntlen > 1); /* root mount points should be NULL. */
+ /* not under the mountpoint, so skip this archive. */
+ BAIL_IF_MACRO(len < mntpntlen-1, PHYSFS_ERR_NO_SUCH_PATH, 0);
+ /* !!! FIXME: Case insensitive? */
+ retval = strncmp(h->mountPoint, fname, mntpntlen-1);
+ BAIL_IF_MACRO(retval != 0, PHYSFS_ERR_NO_SUCH_PATH, 0);
+ if (len > mntpntlen-1) /* corner case... */
+ BAIL_IF_MACRO(fname[mntpntlen-1]!='/', PHYSFS_ERR_NO_SUCH_PATH, 0);
+ fname += mntpntlen-1; /* move to start of actual archive path. */
+ if (*fname == '/')
+ fname++;
+ *_fname = fname; /* skip mountpoint for later use. */
+ retval = 1; /* may be reset, below. */
+ } /* if */
+
+ start = fname;
+ if (!allowSymLinks)
+ {
+ while (1)
+ {
+ PHYSFS_Stat statbuf;
+ int rc = 0;
+ end = strchr(start, '/');
+
+ if (end != NULL) *end = '\0';
+ rc = h->funcs->stat(h->opaque, fname, &retval, &statbuf);
+ if (rc)
+ rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
+ if (end != NULL) *end = '/';
+
+ /* insecure path (has a disallowed symlink in it)? */
+ BAIL_IF_MACRO(rc, PHYSFS_ERR_SYMLINK_FORBIDDEN, 0);
+
+ /* break out early if path element is missing. */
+ if (!retval)
+ {
+ /*
+ * We need to clear it if it's the last element of the path,
+ * since this might be a non-existant file we're opening
+ * for writing...
+ */
+ if ((end == NULL) || (allowMissing))
+ retval = 1;
+ break;
+ } /* if */
+
+ if (end == NULL)
+ break;
+
+ start = end + 1;
+ } /* while */
+ } /* if */
+
+ return retval;
+} /* verifyPath */
+
+
+static int doMkdir(const char *_dname, char *dname)
+{
+ DirHandle *h;
+ char *start;
+ char *end;
+ int retval = 0;
+ int exists = 1; /* force existance check on first path element. */
+
+ BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_dname, dname), ERRPASS, 0);
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ BAIL_IF_MACRO_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
+ h = writeDir;
+ BAIL_IF_MACRO_MUTEX(!verifyPath(h, &dname, 1), ERRPASS, stateLock, 0);
+
+ start = dname;
+ while (1)
+ {
+ end = strchr(start, '/');
+ if (end != NULL)
+ *end = '\0';
+
+ /* only check for existance if all parent dirs existed, too... */
+ if (exists)
+ {
+ PHYSFS_Stat statbuf;
+ const int rc = h->funcs->stat(h->opaque, dname, &exists, &statbuf);
+ retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
+ } /* if */
+
+ if (!exists)
+ retval = h->funcs->mkdir(h->opaque, dname);
+
+ if (!retval)
+ break;
+
+ if (end == NULL)
+ break;
+
+ *end = '/';
+ start = end + 1;
+ } /* while */
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+ return retval;
+} /* doMkdir */
+
+
+int PHYSFS_mkdir(const char *_dname)
+{
+ int retval = 0;
+ char *dname;
+ size_t len;
+
+ BAIL_IF_MACRO(!_dname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ len = strlen(_dname) + 1;
+ dname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!dname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ retval = doMkdir(_dname, dname);
+ __PHYSFS_smallFree(dname);
+ return retval;
+} /* PHYSFS_mkdir */
+
+
+static int doDelete(const char *_fname, char *fname)
+{
+ int retval;
+ DirHandle *h;
+ BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_fname, fname), ERRPASS, 0);
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ BAIL_IF_MACRO_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
+ h = writeDir;
+ BAIL_IF_MACRO_MUTEX(!verifyPath(h, &fname, 0), ERRPASS, stateLock, 0);
+ retval = h->funcs->remove(h->opaque, fname);
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+ return retval;
+} /* doDelete */
+
+
+int PHYSFS_delete(const char *_fname)
+{
+ int retval;
+ char *fname;
+ size_t len;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ retval = doDelete(_fname, fname);
+ __PHYSFS_smallFree(fname);
+ return retval;
+} /* PHYSFS_delete */
+
+
+const char *PHYSFS_getRealDir(const char *_fname)
+{
+ const char *retval = NULL;
+ char *fname = NULL;
+ size_t len;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
+ len = strlen(_fname) + 1;
+ fname = __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ DirHandle *i;
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ char *arcfname = fname;
+ if (partOfMountPoint(i, arcfname))
+ {
+ retval = i->dirName;
+ break;
+ } /* if */
+ else if (verifyPath(i, &arcfname, 0))
+ {
+ PHYSFS_Stat statbuf;
+ int exists = 0;
+ if (i->funcs->stat(i->opaque, arcfname, &exists, &statbuf))
+ {
+ if (exists)
+ retval = i->dirName;
+ break;
+ } /* if */
+ } /* if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+ return retval;
+} /* PHYSFS_getRealDir */
+
+
+static int locateInStringList(const char *str,
+ char **list,
+ PHYSFS_uint32 *pos)
+{
+ PHYSFS_uint32 len = *pos;
+ PHYSFS_uint32 half_len;
+ PHYSFS_uint32 lo = 0;
+ PHYSFS_uint32 middle;
+ int cmp;
+
+ while (len > 0)
+ {
+ half_len = len >> 1;
+ middle = lo + half_len;
+ cmp = strcmp(list[middle], str);
+
+ if (cmp == 0) /* it's in the list already. */
+ return 1;
+ else if (cmp > 0)
+ len = half_len;
+ else
+ {
+ lo = middle + 1;
+ len -= half_len + 1;
+ } /* else */
+ } /* while */
+
+ *pos = lo;
+ return 0;
+} /* locateInStringList */
+
+
+static void enumFilesCallback(void *data, const char *origdir, const char *str)
+{
+ PHYSFS_uint32 pos;
+ void *ptr;
+ char *newstr;
+ EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
+
+ /*
+ * See if file is in the list already, and if not, insert it in there
+ * alphabetically...
+ */
+ pos = pecd->size;
+ if (locateInStringList(str, pecd->list, &pos))
+ return; /* already in the list. */
+
+ ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
+ newstr = (char *) allocator.Malloc(strlen(str) + 1);
+ if (ptr != NULL)
+ pecd->list = (char **) ptr;
+
+ if ((ptr == NULL) || (newstr == NULL))
+ return; /* better luck next time. */
+
+ strcpy(newstr, str);
+
+ if (pos != pecd->size)
+ {
+ memmove(&pecd->list[pos+1], &pecd->list[pos],
+ sizeof (char *) * ((pecd->size) - pos));
+ } /* if */
+
+ pecd->list[pos] = newstr;
+ pecd->size++;
+} /* enumFilesCallback */
+
+
+char **PHYSFS_enumerateFiles(const char *path)
+{
+ EnumStringListCallbackData ecd;
+ memset(&ecd, '\0', sizeof (ecd));
+ ecd.list = (char **) allocator.Malloc(sizeof (char *));
+ BAIL_IF_MACRO(!ecd.list, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ PHYSFS_enumerateFilesCallback(path, enumFilesCallback, &ecd);
+ ecd.list[ecd.size] = NULL;
+ return ecd.list;
+} /* PHYSFS_enumerateFiles */
+
+
+/*
+ * Broke out to seperate function so we can use stack allocation gratuitously.
+ */
+static void enumerateFromMountPoint(DirHandle *i, const char *arcfname,
+ PHYSFS_EnumFilesCallback callback,
+ const char *_fname, void *data)
+{
+ const size_t len = strlen(arcfname);
+ char *ptr = NULL;
+ char *end = NULL;
+ const size_t slen = strlen(i->mountPoint) + 1;
+ char *mountPoint = (char *) __PHYSFS_smallAlloc(slen);
+
+ if (mountPoint == NULL)
+ return; /* oh well. */
+
+ strcpy(mountPoint, i->mountPoint);
+ ptr = mountPoint + ((len) ? len + 1 : 0);
+ end = strchr(ptr, '/');
+ assert(end); /* should always find a terminating '/'. */
+ *end = '\0';
+ callback(data, _fname, ptr);
+ __PHYSFS_smallFree(mountPoint);
+} /* enumerateFromMountPoint */
+
+
+/* !!! FIXME: this should report error conditions. */
+void PHYSFS_enumerateFilesCallback(const char *_fname,
+ PHYSFS_EnumFilesCallback callback,
+ void *data)
+{
+ size_t len;
+ char *fname;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, ) /*0*/;
+ BAIL_IF_MACRO(!callback, PHYSFS_ERR_INVALID_ARGUMENT, ) /*0*/;
+
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, ) /*0*/;
+
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ DirHandle *i;
+ int noSyms;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+ noSyms = !allowSymLinks;
+ for (i = searchPath; i != NULL; i = i->next)
+ {
+ char *arcfname = fname;
+ if (partOfMountPoint(i, arcfname))
+ enumerateFromMountPoint(i, arcfname, callback, _fname, data);
+
+ else if (verifyPath(i, &arcfname, 0))
+ {
+ i->funcs->enumerateFiles(i->opaque, arcfname, noSyms,
+ callback, _fname, data);
+ } /* else if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+} /* PHYSFS_enumerateFilesCallback */
+
+
+int PHYSFS_exists(const char *fname)
+{
+ return (PHYSFS_getRealDir(fname) != NULL);
+} /* PHYSFS_exists */
+
+
+PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
+{
+ PHYSFS_Stat statbuf;
+ BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, -1);
+ return statbuf.modtime;
+} /* PHYSFS_getLastModTime */
+
+
+int PHYSFS_isDirectory(const char *fname)
+{
+ PHYSFS_Stat statbuf;
+ BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, 0);
+ return (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
+} /* PHYSFS_isDirectory */
+
+
+int PHYSFS_isSymbolicLink(const char *fname)
+{
+ PHYSFS_Stat statbuf;
+ BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, 0);
+ return (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
+} /* PHYSFS_isSymbolicLink */
+
+
+static PHYSFS_File *doOpenWrite(const char *_fname, int appending)
+{
+ FileHandle *fh = NULL;
+ size_t len;
+ char *fname;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ PHYSFS_Io *io = NULL;
+ DirHandle *h = NULL;
+ const PHYSFS_Archiver *f;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ GOTO_IF_MACRO(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, doOpenWriteEnd);
+
+ h = writeDir;
+ GOTO_IF_MACRO(!verifyPath(h, &fname, 0), ERRPASS, doOpenWriteEnd);
+
+ f = h->funcs;
+ if (appending)
+ io = f->openAppend(h->opaque, fname);
+ else
+ io = f->openWrite(h->opaque, fname);
+
+ GOTO_IF_MACRO(!io, ERRPASS, doOpenWriteEnd);
+
+ fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
+ if (fh == NULL)
+ {
+ io->destroy(io);
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, doOpenWriteEnd);
+ } /* if */
+ else
+ {
+ memset(fh, '\0', sizeof (FileHandle));
+ fh->io = io;
+ fh->dirHandle = h;
+ fh->next = openWriteList;
+ openWriteList = fh;
+ } /* else */
+
+ doOpenWriteEnd:
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+ return ((PHYSFS_File *) fh);
+} /* doOpenWrite */
+
+
+PHYSFS_File *PHYSFS_openWrite(const char *filename)
+{
+ return doOpenWrite(filename, 0);
+} /* PHYSFS_openWrite */
+
+
+PHYSFS_File *PHYSFS_openAppend(const char *filename)
+{
+ return doOpenWrite(filename, 1);
+} /* PHYSFS_openAppend */
+
+
+PHYSFS_File *PHYSFS_openRead(const char *_fname)
+{
+ FileHandle *fh = NULL;
+ char *fname;
+ size_t len;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ int fileExists = 0;
+ DirHandle *i = NULL;
+ PHYSFS_Io *io = NULL;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ GOTO_IF_MACRO(!searchPath, PHYSFS_ERR_NO_SUCH_PATH, openReadEnd);
+
+ for (i = searchPath; (i != NULL) && (!fileExists); i = i->next)
+ {
+ char *arcfname = fname;
+ if (verifyPath(i, &arcfname, 0))
+ {
+ io = i->funcs->openRead(i->opaque, arcfname, &fileExists);
+ if (io)
+ break;
+ } /* if */
+ } /* for */
+
+ GOTO_IF_MACRO(!io, ERRPASS, openReadEnd);
+
+ fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
+ if (fh == NULL)
+ {
+ io->destroy(io);
+ GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, openReadEnd);
+ } /* if */
+
+ memset(fh, '\0', sizeof (FileHandle));
+ fh->io = io;
+ fh->forReading = 1;
+ fh->dirHandle = i;
+ fh->next = openReadList;
+ openReadList = fh;
+
+ openReadEnd:
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+ return ((PHYSFS_File *) fh);
+} /* PHYSFS_openRead */
+
+
+static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
+{
+ FileHandle *prev = NULL;
+ FileHandle *i;
+ int rc = 1;
+
+ for (i = *list; i != NULL; i = i->next)
+ {
+ if (i == handle) /* handle is in this list? */
+ {
+ PHYSFS_Io *io = handle->io;
+ PHYSFS_uint8 *tmp = handle->buffer;
+ rc = PHYSFS_flush((PHYSFS_File *) handle);
+ if (!rc)
+ return -1;
+ io->destroy(io);
+
+ if (tmp != NULL) /* free any associated buffer. */
+ allocator.Free(tmp);
+
+ if (prev == NULL)
+ *list = handle->next;
+ else
+ prev->next = handle->next;
+
+ allocator.Free(handle);
+ return 1;
+ } /* if */
+ prev = i;
+ } /* for */
+
+ return 0;
+} /* closeHandleInOpenList */
+
+
+int PHYSFS_close(PHYSFS_File *_handle)
+{
+ FileHandle *handle = (FileHandle *) _handle;
+ int rc;
+
+ __PHYSFS_platformGrabMutex(stateLock);
+
+ /* -1 == close failure. 0 == not found. 1 == success. */
+ rc = closeHandleInOpenList(&openReadList, handle);
+ BAIL_IF_MACRO_MUTEX(rc == -1, ERRPASS, stateLock, 0);
+ if (!rc)
+ {
+ rc = closeHandleInOpenList(&openWriteList, handle);
+ BAIL_IF_MACRO_MUTEX(rc == -1, ERRPASS, stateLock, 0);
+ } /* if */
+
+ __PHYSFS_platformReleaseMutex(stateLock);
+ BAIL_IF_MACRO(!rc, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ return 1;
+} /* PHYSFS_close */
+
+
+static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *buffer,
+ PHYSFS_uint64 len)
+{
+ PHYSFS_Io *io = NULL;
+ PHYSFS_sint64 retval = 0;
+ PHYSFS_uint32 buffered = 0;
+ PHYSFS_sint64 rc = 0;
+
+ if (len == 0)
+ return 0;
+
+ buffered = fh->buffill - fh->bufpos;
+ if (buffered >= len) /* totally in the buffer, just copy and return! */
+ {
+ memcpy(buffer, fh->buffer + fh->bufpos, (size_t) len);
+ fh->bufpos += (PHYSFS_uint32) len;
+ return (PHYSFS_sint64) len;
+ } /* else if */
+
+ if (buffered > 0) /* partially in the buffer... */
+ {
+ memcpy(buffer, fh->buffer + fh->bufpos, (size_t) buffered);
+ buffer = ((PHYSFS_uint8 *) buffer) + buffered;
+ len -= buffered;
+ retval = buffered;
+ fh->buffill = fh->bufpos = 0;
+ } /* if */
+
+ /* if you got here, the buffer is drained and we still need bytes. */
+ assert(len > 0);
+
+ io = fh->io;
+ if (len >= fh->bufsize) /* need more than the buffer takes. */
+ {
+ /* leave buffer empty, go right to output instead. */
+ rc = io->read(io, buffer, len);
+ if (rc < 0)
+ return ((retval == 0) ? rc : retval);
+ return retval + rc;
+ } /* if */
+
+ /* need less than buffer can take. Fill buffer. */
+ rc = io->read(io, fh->buffer, fh->bufsize);
+ if (rc < 0)
+ return ((retval == 0) ? rc : retval);
+
+ assert(fh->bufpos == 0);
+ fh->buffill = (PHYSFS_uint32) rc;
+ rc = doBufferedRead(fh, buffer, len); /* go from the start, again. */
+ if (rc < 0)
+ return ((retval == 0) ? rc : retval);
+
+ return retval + rc;
+} /* doBufferedRead */
+
+
+PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+{
+ const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
+ const PHYSFS_sint64 retval = PHYSFS_readBytes(handle, buffer, len);
+ return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) size)) );
+} /* PHYSFS_read */
+
+
+PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer,
+ PHYSFS_uint64 len)
+{
+ FileHandle *fh = (FileHandle *) handle;
+
+#ifdef PHYSFS_NO_64BIT_SUPPORT
+ const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
+#else
+ const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
+#endif
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ BAIL_IF_MACRO(len > maxlen, PHYSFS_ERR_INVALID_ARGUMENT, -1);
+ BAIL_IF_MACRO(!fh->forReading, PHYSFS_ERR_OPEN_FOR_WRITING, -1);
+ BAIL_IF_MACRO(len == 0, ERRPASS, 0);
+ if (fh->buffer)
+ return doBufferedRead(fh, buffer, len);
+
+ return fh->io->read(fh->io, buffer, len);
+} /* PHYSFS_readBytes */
+
+
+static PHYSFS_sint64 doBufferedWrite(PHYSFS_File *handle, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ FileHandle *fh = (FileHandle *) handle;
+
+ /* whole thing fits in the buffer? */
+ if ( (((PHYSFS_uint64) fh->buffill) + len) < fh->bufsize )
+ {
+ memcpy(fh->buffer + fh->buffill, buffer, (size_t) len);
+ fh->buffill += (PHYSFS_uint32) len;
+ return (PHYSFS_sint64) len;
+ } /* if */
+
+ /* would overflow buffer. Flush and then write the new objects, too. */
+ BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, -1);
+ return fh->io->write(fh->io, buffer, len);
+} /* doBufferedWrite */
+
+
+PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+{
+ const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
+ const PHYSFS_sint64 retval = PHYSFS_writeBytes(handle, buffer, len);
+ return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) size)) );
+} /* PHYSFS_write */
+
+
+PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ FileHandle *fh = (FileHandle *) handle;
+
+#ifdef PHYSFS_NO_64BIT_SUPPORT
+ const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
+#else
+ const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
+#endif
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ BAIL_IF_MACRO(len > maxlen, PHYSFS_ERR_INVALID_ARGUMENT, -1);
+ BAIL_IF_MACRO(fh->forReading, PHYSFS_ERR_OPEN_FOR_READING, -1);
+ BAIL_IF_MACRO(len == 0, ERRPASS, 0);
+ if (fh->buffer)
+ return doBufferedWrite(handle, buffer, len);
+
+ return fh->io->write(fh->io, buffer, len);
+} /* PHYSFS_write */
+
+
+int PHYSFS_eof(PHYSFS_File *handle)
+{
+ FileHandle *fh = (FileHandle *) handle;
+
+ if (!fh->forReading) /* never EOF on files opened for write/append. */
+ return 0;
+
+ /* can't be eof if buffer isn't empty */
+ if (fh->bufpos == fh->buffill)
+ {
+ /* check the Io. */
+ PHYSFS_Io *io = fh->io;
+ const PHYSFS_sint64 pos = io->tell(io);
+ const PHYSFS_sint64 len = io->length(io);
+ if ((pos < 0) || (len < 0))
+ return 0; /* beats me. */
+ return (pos >= len);
+ } /* if */
+
+ return 0;
+} /* PHYSFS_eof */
+
+
+PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle)
+{
+ FileHandle *fh = (FileHandle *) handle;
+ const PHYSFS_sint64 pos = fh->io->tell(fh->io);
+ const PHYSFS_sint64 retval = fh->forReading ?
+ (pos - fh->buffill) + fh->bufpos :
+ (pos + fh->buffill);
+ return retval;
+} /* PHYSFS_tell */
+
+
+int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos)
+{
+ FileHandle *fh = (FileHandle *) handle;
+ BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, 0);
+
+ if (fh->buffer && fh->forReading)
+ {
+ /* avoid throwing away our precious buffer if seeking within it. */
+ PHYSFS_sint64 offset = pos - PHYSFS_tell(handle);
+ if ( /* seeking within the already-buffered range? */
+ ((offset >= 0) && (offset <= fh->buffill - fh->bufpos)) /* fwd */
+ || ((offset < 0) && (-offset <= fh->bufpos)) /* backward */ )
+ {
+ fh->bufpos += (PHYSFS_uint32) offset;
+ return 1; /* successful seek */
+ } /* if */
+ } /* if */
+
+ /* we have to fall back to a 'raw' seek. */
+ fh->buffill = fh->bufpos = 0;
+ return fh->io->seek(fh->io, pos);
+} /* PHYSFS_seek */
+
+
+PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle)
+{
+ PHYSFS_Io *io = ((FileHandle *) handle)->io;
+ return io->length(io);
+} /* PHYSFS_filelength */
+
+
+int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 _bufsize)
+{
+ FileHandle *fh = (FileHandle *) handle;
+ PHYSFS_uint32 bufsize;
+
+ /* !!! FIXME: actually, why use 32 bits here? */
+ /*BAIL_IF_MACRO(_bufsize > 0xFFFFFFFF, "buffer must fit in 32-bits", 0);*/
+ BAIL_IF_MACRO(_bufsize > 0xFFFFFFFF, PHYSFS_ERR_INVALID_ARGUMENT, 0);
+ bufsize = (PHYSFS_uint32) _bufsize;
+
+ BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, 0);
+
+ /*
+ * For reads, we need to move the file pointer to where it would be
+ * if we weren't buffering, so that the next read will get the
+ * right chunk of stuff from the file. PHYSFS_flush() handles writes.
+ */
+ if ((fh->forReading) && (fh->buffill != fh->bufpos))
+ {
+ PHYSFS_uint64 pos;
+ const PHYSFS_sint64 curpos = fh->io->tell(fh->io);
+ BAIL_IF_MACRO(curpos == -1, ERRPASS, 0);
+ pos = ((curpos - fh->buffill) + fh->bufpos);
+ BAIL_IF_MACRO(!fh->io->seek(fh->io, pos), ERRPASS, 0);
+ } /* if */
+
+ if (bufsize == 0) /* delete existing buffer. */
+ {
+ if (fh->buffer)
+ {
+ allocator.Free(fh->buffer);
+ fh->buffer = NULL;
+ } /* if */
+ } /* if */
+
+ else
+ {
+ PHYSFS_uint8 *newbuf;
+ newbuf = (PHYSFS_uint8 *) allocator.Realloc(fh->buffer, bufsize);
+ BAIL_IF_MACRO(!newbuf, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ fh->buffer = newbuf;
+ } /* else */
+
+ fh->bufsize = bufsize;
+ fh->buffill = fh->bufpos = 0;
+ return 1;
+} /* PHYSFS_setBuffer */
+
+
+int PHYSFS_flush(PHYSFS_File *handle)
+{
+ FileHandle *fh = (FileHandle *) handle;
+ PHYSFS_Io *io;
+ PHYSFS_sint64 rc;
+
+ if ((fh->forReading) || (fh->bufpos == fh->buffill))
+ return 1; /* open for read or buffer empty are successful no-ops. */
+
+ /* dump buffer to disk. */
+ io = fh->io;
+ rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
+ BAIL_IF_MACRO(rc <= 0, ERRPASS, 0);
+ fh->bufpos = fh->buffill = 0;
+ return io->flush(io);
+} /* PHYSFS_flush */
+
+
+int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
+{
+ int retval = 0;
+ char *fname;
+ size_t len;
+
+ BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, -1);
+ BAIL_IF_MACRO(!stat, PHYSFS_ERR_INVALID_ARGUMENT, -1);
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, -1);
+
+ /* set some sane defaults... */
+ stat->filesize = -1;
+ stat->modtime = -1;
+ stat->createtime = -1;
+ stat->accesstime = -1;
+ stat->filetype = PHYSFS_FILETYPE_OTHER;
+ stat->readonly = 1; /* !!! FIXME */
+
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ if (*fname == '\0')
+ {
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ stat->readonly = !writeDir; /* Writeable if we have a writeDir */
+ retval = 1;
+ } /* if */
+ else
+ {
+ DirHandle *i;
+ int exists = 0;
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
+ {
+ char *arcfname = fname;
+ exists = partOfMountPoint(i, arcfname);
+ if (exists)
+ {
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ stat->readonly = 1; /* !!! FIXME */
+ retval = 1;
+ } /* if */
+ else if (verifyPath(i, &arcfname, 0))
+ {
+ /* !!! FIXME: this test is wrong and should be elsewhere. */
+ stat->readonly = !(writeDir &&
+ (strcmp(writeDir->dirName, i->dirName) == 0));
+ retval = i->funcs->stat(i->opaque, arcfname, &exists, stat);
+ } /* else if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* else */
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+ return retval;
+} /* PHYSFS_stat */
+
+
+int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const PHYSFS_uint64 len)
+{
+ return (io->read(io, buf, len) == len);
+} /* __PHYSFS_readAll */
+
+
+void *__PHYSFS_initSmallAlloc(void *ptr, PHYSFS_uint64 len)
+{
+ void *useHeap = ((ptr == NULL) ? ((void *) 1) : ((void *) 0));
+ if (useHeap) /* too large for stack allocation or alloca() failed. */
+ ptr = allocator.Malloc(len+sizeof (void *));
+
+ if (ptr != NULL)
+ {
+ void **retval = (void **) ptr;
+ /*printf("%s alloc'd (%d) bytes at (%p).\n",
+ useHeap ? "heap" : "stack", (int) len, ptr);*/
+ *retval = useHeap;
+ return retval + 1;
+ } /* if */
+
+ return NULL; /* allocation failed. */
+} /* __PHYSFS_initSmallAlloc */
+
+
+void __PHYSFS_smallFree(void *ptr)
+{
+ if (ptr != NULL)
+ {
+ void **block = ((void **) ptr) - 1;
+ const int useHeap = (*block != 0);
+ if (useHeap)
+ allocator.Free(block);
+ /*printf("%s free'd (%p).\n", useHeap ? "heap" : "stack", block);*/
+ } /* if */
+} /* __PHYSFS_smallFree */
+
+
+int PHYSFS_setAllocator(const PHYSFS_Allocator *a)
+{
+ BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0);
+ externalAllocator = (a != NULL);
+ if (externalAllocator)
+ memcpy(&allocator, a, sizeof (PHYSFS_Allocator));
+
+ return 1;
+} /* PHYSFS_setAllocator */
+
+
+const PHYSFS_Allocator *PHYSFS_getAllocator(void)
+{
+ BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL);
+ return &allocator;
+} /* PHYSFS_getAllocator */
+
+
+static void *mallocAllocatorMalloc(PHYSFS_uint64 s)
+{
+ if (!__PHYSFS_ui64FitsAddressSpace(s))
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ #undef malloc
+ return malloc((size_t) s);
+} /* mallocAllocatorMalloc */
+
+
+static void *mallocAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
+{
+ if (!__PHYSFS_ui64FitsAddressSpace(s))
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ #undef realloc
+ return realloc(ptr, (size_t) s);
+} /* mallocAllocatorRealloc */
+
+
+static void mallocAllocatorFree(void *ptr)
+{
+ #undef free
+ free(ptr);
+} /* mallocAllocatorFree */
+
+
+static void setDefaultAllocator(void)
+{
+ assert(!externalAllocator);
+ if (!__PHYSFS_platformSetDefaultAllocator(&allocator))
+ {
+ allocator.Init = NULL;
+ allocator.Deinit = NULL;
+ allocator.Malloc = mallocAllocatorMalloc;
+ allocator.Realloc = mallocAllocatorRealloc;
+ allocator.Free = mallocAllocatorFree;
+ } /* if */
+} /* setDefaultAllocator */
+
+/* end of physfs.c ... */
+
diff --git a/misc/libphysfs/physfs.h b/misc/libphysfs/physfs.h
new file mode 100644
index 0000000..830ee55
--- /dev/null
+++ b/misc/libphysfs/physfs.h
@@ -0,0 +1,3324 @@
+/**
+ * \file physfs.h
+ *
+ * Main header file for PhysicsFS.
+ */
+
+/**
+ * \mainpage PhysicsFS
+ *
+ * The latest version of PhysicsFS can be found at:
+ * http://icculus.org/physfs/
+ *
+ * PhysicsFS; a portable, flexible file i/o abstraction.
+ *
+ * This API gives you access to a system file system in ways superior to the
+ * stdio or system i/o calls. The brief benefits:
+ *
+ * - It's portable.
+ * - It's safe. No file access is permitted outside the specified dirs.
+ * - It's flexible. Archives (.ZIP files) can be used transparently as
+ * directory structures.
+ *
+ * This system is largely inspired by Quake 3's PK3 files and the related
+ * fs_* cvars. If you've ever tinkered with these, then this API will be
+ * familiar to you.
+ *
+ * With PhysicsFS, you have a single writing directory and multiple
+ * directories (the "search path") for reading. You can think of this as a
+ * filesystem within a filesystem. If (on Windows) you were to set the
+ * writing directory to "C:\MyGame\MyWritingDirectory", then no PHYSFS calls
+ * could touch anything above this directory, including the "C:\MyGame" and
+ * "C:\" directories. This prevents an application's internal scripting
+ * language from piddling over c:\\config.sys, for example. If you'd rather
+ * give PHYSFS full access to the system's REAL file system, set the writing
+ * dir to "C:\", but that's generally A Bad Thing for several reasons.
+ *
+ * Drive letters are hidden in PhysicsFS once you set up your initial paths.
+ * The search path creates a single, hierarchical directory structure.
+ * Not only does this lend itself well to general abstraction with archives,
+ * it also gives better support to operating systems like MacOS and Unix.
+ * Generally speaking, you shouldn't ever hardcode a drive letter; not only
+ * does this hurt portability to non-Microsoft OSes, but it limits your win32
+ * users to a single drive, too. Use the PhysicsFS abstraction functions and
+ * allow user-defined configuration options, too. When opening a file, you
+ * specify it like it was on a Unix filesystem: if you want to write to
+ * "C:\MyGame\MyConfigFiles\game.cfg", then you might set the write dir to
+ * "C:\MyGame" and then open "MyConfigFiles/game.cfg". This gives an
+ * abstraction across all platforms. Specifying a file in this way is termed
+ * "platform-independent notation" in this documentation. Specifying a
+ * a filename in a form such as "C:\mydir\myfile" or
+ * "MacOS hard drive:My Directory:My File" is termed "platform-dependent
+ * notation". The only time you use platform-dependent notation is when
+ * setting up your write directory and search path; after that, all file
+ * access into those directories are done with platform-independent notation.
+ *
+ * All files opened for writing are opened in relation to the write directory,
+ * which is the root of the writable filesystem. When opening a file for
+ * reading, PhysicsFS goes through the search path. This is NOT the
+ * same thing as the PATH environment variable. An application using
+ * PhysicsFS specifies directories to be searched which may be actual
+ * directories, or archive files that contain files and subdirectories of
+ * their own. See the end of these docs for currently supported archive
+ * formats.
+ *
+ * Once the search path is defined, you may open files for reading. If you've
+ * got the following search path defined (to use a win32 example again):
+ *
+ * - C:\\mygame
+ * - C:\\mygame\\myuserfiles
+ * - D:\\mygamescdromdatafiles
+ * - C:\\mygame\\installeddatafiles.zip
+ *
+ * Then a call to PHYSFS_openRead("textfiles/myfile.txt") (note the directory
+ * separator, lack of drive letter, and lack of dir separator at the start of
+ * the string; this is platform-independent notation) will check for
+ * C:\\mygame\\textfiles\\myfile.txt, then
+ * C:\\mygame\\myuserfiles\\textfiles\\myfile.txt, then
+ * D:\\mygamescdromdatafiles\\textfiles\\myfile.txt, then, finally, for
+ * textfiles\\myfile.txt inside of C:\\mygame\\installeddatafiles.zip.
+ * Remember that most archive types and platform filesystems store their
+ * filenames in a case-sensitive manner, so you should be careful to specify
+ * it correctly.
+ *
+ * Files opened through PhysicsFS may NOT contain "." or ".." or ":" as dir
+ * elements. Not only are these meaningless on MacOS Classic and/or Unix,
+ * they are a security hole. Also, symbolic links (which can be found in
+ * some archive types and directly in the filesystem on Unix platforms) are
+ * NOT followed until you call PHYSFS_permitSymbolicLinks(). That's left to
+ * your own discretion, as following a symlink can allow for access outside
+ * the write dir and search paths. For portability, there is no mechanism for
+ * creating new symlinks in PhysicsFS.
+ *
+ * The write dir is not included in the search path unless you specifically
+ * add it. While you CAN change the write dir as many times as you like,
+ * you should probably set it once and stick to it. Remember that your
+ * program will not have permission to write in every directory on Unix and
+ * NT systems.
+ *
+ * All files are opened in binary mode; there is no endline conversion for
+ * textfiles. Other than that, PhysicsFS has some convenience functions for
+ * platform-independence. There is a function to tell you the current
+ * platform's dir separator ("\\" on windows, "/" on Unix, ":" on MacOS),
+ * which is needed only to set up your search/write paths. There is a
+ * function to tell you what CD-ROM drives contain accessible discs, and a
+ * function to recommend a good search path, etc.
+ *
+ * A recommended order for the search path is the write dir, then the base dir,
+ * then the cdrom dir, then any archives discovered. Quake 3 does something
+ * like this, but moves the archives to the start of the search path. Build
+ * Engine games, like Duke Nukem 3D and Blood, place the archives last, and
+ * use the base dir for both searching and writing. There is a helper
+ * function (PHYSFS_setSaneConfig()) that puts together a basic configuration
+ * for you, based on a few parameters. Also see the comments on
+ * PHYSFS_getBaseDir(), and PHYSFS_getPrefDir() for info on what those
+ * are and how they can help you determine an optimal search path.
+ *
+ * PhysicsFS 2.0 adds the concept of "mounting" archives to arbitrary points
+ * in the search path. If a zipfile contains "maps/level.map" and you mount
+ * that archive at "mods/mymod", then you would have to open
+ * "mods/mymod/maps/level.map" to access the file, even though "mods/mymod"
+ * isn't actually specified in the .zip file. Unlike the Unix mentality of
+ * mounting a filesystem, "mods/mymod" doesn't actually have to exist when
+ * mounting the zipfile. It's a "virtual" directory. The mounting mechanism
+ * allows the developer to seperate archives in the tree and avoid trampling
+ * over files when added new archives, such as including mod support in a
+ * game...keeping external content on a tight leash in this manner can be of
+ * utmost importance to some applications.
+ *
+ * PhysicsFS is mostly thread safe. The error messages returned by
+ * PHYSFS_getLastError() are unique by thread, and library-state-setting
+ * functions are mutex'd. For efficiency, individual file accesses are
+ * not locked, so you can not safely read/write/seek/close/etc the same
+ * file from two threads at the same time. Other race conditions are bugs
+ * that should be reported/patched.
+ *
+ * While you CAN use stdio/syscall file access in a program that has PHYSFS_*
+ * calls, doing so is not recommended, and you can not use system
+ * filehandles with PhysicsFS and vice versa.
+ *
+ * Note that archives need not be named as such: if you have a ZIP file and
+ * rename it with a .PKG extension, the file will still be recognized as a
+ * ZIP archive by PhysicsFS; the file's contents are used to determine its
+ * type where possible.
+ *
+ * Currently supported archive types:
+ * - .ZIP (pkZip/WinZip/Info-ZIP compatible)
+ * - .7Z (7zip archives)
+ * - .ISO (ISO9660 files, CD-ROM images)
+ * - .GRP (Build Engine groupfile archives)
+ * - .PAK (Quake I/II archive format)
+ * - .HOG (Descent I/II HOG file archives)
+ * - .MVL (Descent II movielib archives)
+ * - .WAD (DOOM engine archives)
+ *
+ *
+ * String policy for PhysicsFS 2.0 and later:
+ *
+ * PhysicsFS 1.0 could only deal with null-terminated ASCII strings. All high
+ * ASCII chars resulted in undefined behaviour, and there was no Unicode
+ * support at all. PhysicsFS 2.0 supports Unicode without breaking binary
+ * compatibility with the 1.0 API by using UTF-8 encoding of all strings
+ * passed in and out of the library.
+ *
+ * All strings passed through PhysicsFS are in null-terminated UTF-8 format.
+ * This means that if all you care about is English (ASCII characters <= 127)
+ * then you just use regular C strings. If you care about Unicode (and you
+ * should!) then you need to figure out what your platform wants, needs, and
+ * offers. If you are on Windows before Win2000 and build with Unicode
+ * support, your TCHAR strings are two bytes per character (this is called
+ * "UCS-2 encoding"). Any modern Windows uses UTF-16, which is two bytes
+ * per character for most characters, but some characters are four. You
+ * should convert them to UTF-8 before handing them to PhysicsFS with
+ * PHYSFS_utf8FromUtf16(), which handles both UTF-16 and UCS-2. If you're
+ * using Unix or Mac OS X, your wchar_t strings are four bytes per character
+ * ("UCS-4 encoding"). Use PHYSFS_utf8FromUcs4(). Mac OS X can give you UTF-8
+ * directly from a CFString or NSString, and many Unixes generally give you C
+ * strings in UTF-8 format everywhere. If you have a single-byte high ASCII
+ * charset, like so-many European "codepages" you may be out of luck. We'll
+ * convert from "Latin1" to UTF-8 only, and never back to Latin1. If you're
+ * above ASCII 127, all bets are off: move to Unicode or use your platform's
+ * facilities. Passing a C string with high-ASCII data that isn't UTF-8
+ * encoded will NOT do what you expect!
+ *
+ * Naturally, there's also PHYSFS_utf8ToUcs2(), PHYSFS_utf8ToUtf16(), and
+ * PHYSFS_utf8ToUcs4() to get data back into a format you like. Behind the
+ * scenes, PhysicsFS will use Unicode where possible: the UTF-8 strings on
+ * Windows will be converted and used with the multibyte Windows APIs, for
+ * example.
+ *
+ * PhysicsFS offers basic encoding conversion support, but not a whole string
+ * library. Get your stuff into whatever format you can work with.
+ *
+ * All platforms supported by PhysicsFS 2.1 and later fully support Unicode.
+ * We have dropped platforms that don't (OS/2, Mac OS 9, Windows 95, etc), as
+ * even an OS that's over a decade old should be expected to handle this well.
+ * If you absolutely must support one of these platforms, you should use an
+ * older release of PhysicsFS.
+ *
+ * Many game-specific archivers are seriously unprepared for Unicode (the
+ * Descent HOG/MVL and Build Engine GRP archivers, for example, only offer a
+ * DOS 8.3 filename, for example). Nothing can be done for these, but they
+ * tend to be legacy formats for existing content that was all ASCII (and
+ * thus, valid UTF-8) anyhow. Other formats, like .ZIP, don't explicitly
+ * offer Unicode support, but unofficially expect filenames to be UTF-8
+ * encoded, and thus Just Work. Most everything does the right thing without
+ * bothering you, but it's good to be aware of these nuances in case they
+ * don't.
+ *
+ *
+ * Other stuff:
+ *
+ * Please see the file LICENSE.txt in the source's root directory for
+ * licensing and redistribution rights.
+ *
+ * Please see the file CREDITS.txt in the source's "docs" directory for
+ * a more or less complete list of who's responsible for this.
+ *
+ * \author Ryan C. Gordon.
+ */
+
+#ifndef _INCLUDE_PHYSFS_H_
+#define _INCLUDE_PHYSFS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(PHYSFS_DECL)
+/* do nothing. */
+#elif (defined SWIG)
+#define PHYSFS_DECL extern
+#elif (defined _MSC_VER)
+#define PHYSFS_DECL __declspec(dllexport)
+#elif (defined __SUNPRO_C)
+#define PHYSFS_DECL __global
+#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
+#define PHYSFS_DECL __attribute__((visibility("default")))
+#else
+#define PHYSFS_DECL
+#endif
+
+#if defined(PHYSFS_DEPRECATED)
+/* do nothing. */
+#elif (defined SWIG) /* ignore deprecated, since bindings use everything. */
+#define PHYSFS_DEPRECATED
+#elif (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
+#define PHYSFS_DEPRECATED __attribute__((deprecated))
+#else
+#define PHYSFS_DEPRECATED
+#endif
+
+#if 0 /* !!! FIXME: look into this later. */
+#if defined(PHYSFS_CALL)
+/* do nothing. */
+#elif defined(__WIN32__) && !defined(__GNUC__)
+#define PHYSFS_CALL __cdecl
+#else
+#define PHYSFS_CALL
+#endif
+#endif
+
+/**
+ * \typedef PHYSFS_uint8
+ * \brief An unsigned, 8-bit integer type.
+ */
+typedef unsigned char PHYSFS_uint8;
+
+/**
+ * \typedef PHYSFS_sint8
+ * \brief A signed, 8-bit integer type.
+ */
+typedef signed char PHYSFS_sint8;
+
+/**
+ * \typedef PHYSFS_uint16
+ * \brief An unsigned, 16-bit integer type.
+ */
+typedef unsigned short PHYSFS_uint16;
+
+/**
+ * \typedef PHYSFS_sint16
+ * \brief A signed, 16-bit integer type.
+ */
+typedef signed short PHYSFS_sint16;
+
+/**
+ * \typedef PHYSFS_uint32
+ * \brief An unsigned, 32-bit integer type.
+ */
+typedef unsigned int PHYSFS_uint32;
+
+/**
+ * \typedef PHYSFS_sint32
+ * \brief A signed, 32-bit integer type.
+ */
+typedef signed int PHYSFS_sint32;
+
+/**
+ * \typedef PHYSFS_uint64
+ * \brief An unsigned, 64-bit integer type.
+ * \warning on platforms without any sort of 64-bit datatype, this is
+ * equivalent to PHYSFS_uint32!
+ */
+
+/**
+ * \typedef PHYSFS_sint64
+ * \brief A signed, 64-bit integer type.
+ * \warning on platforms without any sort of 64-bit datatype, this is
+ * equivalent to PHYSFS_sint32!
+ */
+
+
+#if (defined PHYSFS_NO_64BIT_SUPPORT) /* oh well. */
+typedef PHYSFS_uint32 PHYSFS_uint64;
+typedef PHYSFS_sint32 PHYSFS_sint64;
+#elif (defined _MSC_VER)
+typedef signed __int64 PHYSFS_sint64;
+typedef unsigned __int64 PHYSFS_uint64;
+#else
+typedef unsigned long long PHYSFS_uint64;
+typedef signed long long PHYSFS_sint64;
+#endif
+
+
+#ifndef SWIG
+#ifndef DOXYGEN_SHOULD_IGNORE_THIS
+/* Make sure the types really have the right sizes */
+#define PHYSFS_COMPILE_TIME_ASSERT(name, x) \
+ typedef int PHYSFS_dummy_ ## name[(x) * 2 - 1]
+
+PHYSFS_COMPILE_TIME_ASSERT(uint8, sizeof(PHYSFS_uint8) == 1);
+PHYSFS_COMPILE_TIME_ASSERT(sint8, sizeof(PHYSFS_sint8) == 1);
+PHYSFS_COMPILE_TIME_ASSERT(uint16, sizeof(PHYSFS_uint16) == 2);
+PHYSFS_COMPILE_TIME_ASSERT(sint16, sizeof(PHYSFS_sint16) == 2);
+PHYSFS_COMPILE_TIME_ASSERT(uint32, sizeof(PHYSFS_uint32) == 4);
+PHYSFS_COMPILE_TIME_ASSERT(sint32, sizeof(PHYSFS_sint32) == 4);
+
+#ifndef PHYSFS_NO_64BIT_SUPPORT
+PHYSFS_COMPILE_TIME_ASSERT(uint64, sizeof(PHYSFS_uint64) == 8);
+PHYSFS_COMPILE_TIME_ASSERT(sint64, sizeof(PHYSFS_sint64) == 8);
+#endif
+
+#undef PHYSFS_COMPILE_TIME_ASSERT
+
+#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
+#endif /* SWIG */
+
+
+/**
+ * \struct PHYSFS_File
+ * \brief A PhysicsFS file handle.
+ *
+ * You get a pointer to one of these when you open a file for reading,
+ * writing, or appending via PhysicsFS.
+ *
+ * As you can see from the lack of meaningful fields, you should treat this
+ * as opaque data. Don't try to manipulate the file handle, just pass the
+ * pointer you got, unmolested, to various PhysicsFS APIs.
+ *
+ * \sa PHYSFS_openRead
+ * \sa PHYSFS_openWrite
+ * \sa PHYSFS_openAppend
+ * \sa PHYSFS_close
+ * \sa PHYSFS_read
+ * \sa PHYSFS_write
+ * \sa PHYSFS_seek
+ * \sa PHYSFS_tell
+ * \sa PHYSFS_eof
+ * \sa PHYSFS_setBuffer
+ * \sa PHYSFS_flush
+ */
+typedef struct PHYSFS_File
+{
+ void *opaque; /**< That's all you get. Don't touch. */
+} PHYSFS_File;
+
+
+/**
+ * \def PHYSFS_file
+ * \brief 1.0 API compatibility define.
+ *
+ * PHYSFS_file is identical to PHYSFS_File. This #define is here for backwards
+ * compatibility with the 1.0 API, which had an inconsistent capitalization
+ * convention in this case. New code should use PHYSFS_File, as this #define
+ * may go away someday.
+ *
+ * \sa PHYSFS_File
+ */
+#define PHYSFS_file PHYSFS_File
+
+
+/**
+ * \struct PHYSFS_ArchiveInfo
+ * \brief Information on various PhysicsFS-supported archives.
+ *
+ * This structure gives you details on what sort of archives are supported
+ * by this implementation of PhysicsFS. Archives tend to be things like
+ * ZIP files and such.
+ *
+ * \warning Not all binaries are created equal! PhysicsFS can be built with
+ * or without support for various archives. You can check with
+ * PHYSFS_supportedArchiveTypes() to see if your archive type is
+ * supported.
+ *
+ * \sa PHYSFS_supportedArchiveTypes
+ */
+typedef struct PHYSFS_ArchiveInfo
+{
+ const char *extension; /**< Archive file extension: "ZIP", for example. */
+ const char *description; /**< Human-readable archive description. */
+ const char *author; /**< Person who did support for this archive. */
+ const char *url; /**< URL related to this archive */
+} PHYSFS_ArchiveInfo;
+
+
+/**
+ * \struct PHYSFS_Version
+ * \brief Information the version of PhysicsFS in use.
+ *
+ * Represents the library's version as three levels: major revision
+ * (increments with massive changes, additions, and enhancements),
+ * minor revision (increments with backwards-compatible changes to the
+ * major revision), and patchlevel (increments with fixes to the minor
+ * revision).
+ *
+ * \sa PHYSFS_VERSION
+ * \sa PHYSFS_getLinkedVersion
+ */
+typedef struct PHYSFS_Version
+{
+ PHYSFS_uint8 major; /**< major revision */
+ PHYSFS_uint8 minor; /**< minor revision */
+ PHYSFS_uint8 patch; /**< patchlevel */
+} PHYSFS_Version;
+
+
+#ifndef SWIG /* not available from scripting languages. */
+
+#ifndef DOXYGEN_SHOULD_IGNORE_THIS
+#define PHYSFS_VER_MAJOR 2
+#define PHYSFS_VER_MINOR 1
+#define PHYSFS_VER_PATCH 0
+#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
+
+
+/* PhysicsFS state stuff ... */
+
+/**
+ * \def PHYSFS_VERSION(x)
+ * \brief Macro to determine PhysicsFS version program was compiled against.
+ *
+ * This macro fills in a PHYSFS_Version structure with the version of the
+ * library you compiled against. This is determined by what header the
+ * compiler uses. Note that if you dynamically linked the library, you might
+ * have a slightly newer or older version at runtime. That version can be
+ * determined with PHYSFS_getLinkedVersion(), which, unlike PHYSFS_VERSION,
+ * is not a macro.
+ *
+ * \param x A pointer to a PHYSFS_Version struct to initialize.
+ *
+ * \sa PHYSFS_Version
+ * \sa PHYSFS_getLinkedVersion
+ */
+#define PHYSFS_VERSION(x) \
+{ \
+ (x)->major = PHYSFS_VER_MAJOR; \
+ (x)->minor = PHYSFS_VER_MINOR; \
+ (x)->patch = PHYSFS_VER_PATCH; \
+}
+
+#endif /* SWIG */
+
+
+/**
+ * \fn void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
+ * \brief Get the version of PhysicsFS that is linked against your program.
+ *
+ * If you are using a shared library (DLL) version of PhysFS, then it is
+ * possible that it will be different than the version you compiled against.
+ *
+ * This is a real function; the macro PHYSFS_VERSION tells you what version
+ * of PhysFS you compiled against:
+ *
+ * \code
+ * PHYSFS_Version compiled;
+ * PHYSFS_Version linked;
+ *
+ * PHYSFS_VERSION(&compiled);
+ * PHYSFS_getLinkedVersion(&linked);
+ * printf("We compiled against PhysFS version %d.%d.%d ...\n",
+ * compiled.major, compiled.minor, compiled.patch);
+ * printf("But we linked against PhysFS version %d.%d.%d.\n",
+ * linked.major, linked.minor, linked.patch);
+ * \endcode
+ *
+ * This function may be called safely at any time, even before PHYSFS_init().
+ *
+ * \sa PHYSFS_VERSION
+ */
+PHYSFS_DECL void PHYSFS_getLinkedVersion(PHYSFS_Version *ver);
+
+
+/**
+ * \fn int PHYSFS_init(const char *argv0)
+ * \brief Initialize the PhysicsFS library.
+ *
+ * This must be called before any other PhysicsFS function.
+ *
+ * This should be called prior to any attempts to change your process's
+ * current working directory.
+ *
+ * \param argv0 the argv[0] string passed to your program's mainline.
+ * This may be NULL on most platforms (such as ones without a
+ * standard main() function), but you should always try to pass
+ * something in here. Unix-like systems such as Linux _need_ to
+ * pass argv[0] from main() in here.
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_deinit
+ * \sa PHYSFS_isInit
+ */
+PHYSFS_DECL int PHYSFS_init(const char *argv0);
+
+
+/**
+ * \fn int PHYSFS_deinit(void)
+ * \brief Deinitialize the PhysicsFS library.
+ *
+ * This closes any files opened via PhysicsFS, blanks the search/write paths,
+ * frees memory, and invalidates all of your file handles.
+ *
+ * Note that this call can FAIL if there's a file open for writing that
+ * refuses to close (for example, the underlying operating system was
+ * buffering writes to network filesystem, and the fileserver has crashed,
+ * or a hard drive has failed, etc). It is usually best to close all write
+ * handles yourself before calling this function, so that you can gracefully
+ * handle a specific failure.
+ *
+ * Once successfully deinitialized, PHYSFS_init() can be called again to
+ * restart the subsystem. All default API states are restored at this
+ * point, with the exception of any custom allocator you might have
+ * specified, which survives between initializations.
+ *
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError(). If failure, state of PhysFS is
+ * undefined, and probably badly screwed up.
+ *
+ * \sa PHYSFS_init
+ * \sa PHYSFS_isInit
+ */
+PHYSFS_DECL int PHYSFS_deinit(void);
+
+
+/**
+ * \fn const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
+ * \brief Get a list of supported archive types.
+ *
+ * Get a list of archive types supported by this implementation of PhysicFS.
+ * These are the file formats usable for search path entries. This is for
+ * informational purposes only. Note that the extension listed is merely
+ * convention: if we list "ZIP", you can open a PkZip-compatible archive
+ * with an extension of "XYZ", if you like.
+ *
+ * The returned value is an array of pointers to PHYSFS_ArchiveInfo structures,
+ * with a NULL entry to signify the end of the list:
+ *
+ * \code
+ * PHYSFS_ArchiveInfo **i;
+ *
+ * for (i = PHYSFS_supportedArchiveTypes(); *i != NULL; i++)
+ * {
+ * printf("Supported archive: [%s], which is [%s].\n",
+ * (*i)->extension, (*i)->description);
+ * }
+ * \endcode
+ *
+ * The return values are pointers to internal memory, and should
+ * be considered READ ONLY, and never freed. The returned values are
+ * valid until the next call to PHYSFS_deinit().
+ *
+ * \return READ ONLY Null-terminated array of READ ONLY structures.
+ */
+PHYSFS_DECL const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void);
+
+
+/**
+ * \fn void PHYSFS_freeList(void *listVar)
+ * \brief Deallocate resources of lists returned by PhysicsFS.
+ *
+ * Certain PhysicsFS functions return lists of information that are
+ * dynamically allocated. Use this function to free those resources.
+ *
+ * It is safe to pass a NULL here, but doing so will cause a crash in versions
+ * before PhysicsFS 2.1.0.
+ *
+ * \param listVar List of information specified as freeable by this function.
+ * Passing NULL is safe; it is a valid no-op.
+ *
+ * \sa PHYSFS_getCdRomDirs
+ * \sa PHYSFS_enumerateFiles
+ * \sa PHYSFS_getSearchPath
+ */
+PHYSFS_DECL void PHYSFS_freeList(void *listVar);
+
+
+/**
+ * \fn const char *PHYSFS_getLastError(void)
+ * \brief Get human-readable error information.
+ *
+ * \warning As of PhysicsFS 2.1, this function has been nerfed.
+ * Before PhysicsFS 2.1, this function was the only way to get
+ * error details beyond a given function's basic return value.
+ * This was meant to be a human-readable string in one of several
+ * languages, and was not useful for application parsing. This was
+ * a problem, because the developer and not the user chose the
+ * language at compile time, and the PhysicsFS maintainers had
+ * to (poorly) maintain a significant amount of localization work.
+ * The app couldn't parse the strings, even if they counted on a
+ * specific language, since some were dynamically generated.
+ * In 2.1 and later, this always returns a static string in
+ * English; you may use it as a key string for your own
+ * localizations if you like, as we'll promise not to change
+ * existing error strings. Also, if your application wants to
+ * look at specific errors, we now offer a better option:
+ * use PHYSFS_getLastErrorCode() instead.
+ *
+ * Get the last PhysicsFS error message as a human-readable, null-terminated
+ * string. This will return NULL if there's been no error since the last call
+ * to this function. The pointer returned by this call points to an internal
+ * buffer. Each thread has a unique error state associated with it, but each
+ * time a new error message is set, it will overwrite the previous one
+ * associated with that thread. It is safe to call this function at anytime,
+ * even before PHYSFS_init().
+ *
+ * PHYSFS_getLastError() and PHYSFS_getLastErrorCode() both reset the same
+ * thread-specific error state. Calling one will wipe out the other's
+ * data. If you need both, call PHYSFS_getLastErrorCode(), then pass that
+ * value to PHYSFS_getErrorByCode().
+ *
+ * As of PhysicsFS 2.1, this function only presents text in the English
+ * language, but the strings are static, so you can use them as keys into
+ * your own localization dictionary. These strings are meant to be passed on
+ * directly to the user.
+ *
+ * Generally, applications should only concern themselves with whether a
+ * given function failed; however, if your code require more specifics, you
+ * should use PHYSFS_getLastErrorCode() instead of this function.
+ *
+ * \return READ ONLY string of last error message.
+ *
+ * \sa PHYSFS_getLastErrorCode
+ * \sa PHYSFS_getErrorByCode
+ */
+PHYSFS_DECL const char *PHYSFS_getLastError(void);
+
+
+/**
+ * \fn const char *PHYSFS_getDirSeparator(void)
+ * \brief Get platform-dependent dir separator string.
+ *
+ * This returns "\\" on win32, "/" on Unix, and ":" on MacOS. It may be more
+ * than one character, depending on the platform, and your code should take
+ * that into account. Note that this is only useful for setting up the
+ * search/write paths, since access into those dirs always use '/'
+ * (platform-independent notation) to separate directories. This is also
+ * handy for getting platform-independent access when using stdio calls.
+ *
+ * \return READ ONLY null-terminated string of platform's dir separator.
+ */
+PHYSFS_DECL const char *PHYSFS_getDirSeparator(void);
+
+
+/**
+ * \fn void PHYSFS_permitSymbolicLinks(int allow)
+ * \brief Enable or disable following of symbolic links.
+ *
+ * Some physical filesystems and archives contain files that are just pointers
+ * to other files. On the physical filesystem, opening such a link will
+ * (transparently) open the file that is pointed to.
+ *
+ * By default, PhysicsFS will check if a file is really a symlink during open
+ * calls and fail if it is. Otherwise, the link could take you outside the
+ * write and search paths, and compromise security.
+ *
+ * If you want to take that risk, call this function with a non-zero parameter.
+ * Note that this is more for sandboxing a program's scripting language, in
+ * case untrusted scripts try to compromise the system. Generally speaking,
+ * a user could very well have a legitimate reason to set up a symlink, so
+ * unless you feel there's a specific danger in allowing them, you should
+ * permit them.
+ *
+ * Symlinks are only explicitly checked when dealing with filenames
+ * in platform-independent notation. That is, when setting up your
+ * search and write paths, etc, symlinks are never checked for.
+ *
+ * Please note that PHYSFS_stat() will always check the path specified; if
+ * that path is a symlink, it will not be followed in any case. If symlinks
+ * aren't permitted through this function, PHYSFS_stat() ignores them, and
+ * would treat the query as if the path didn't exist at all.
+ *
+ * Symbolic link permission can be enabled or disabled at any time after
+ * you've called PHYSFS_init(), and is disabled by default.
+ *
+ * \param allow nonzero to permit symlinks, zero to deny linking.
+ *
+ * \sa PHYSFS_symbolicLinksPermitted
+ */
+PHYSFS_DECL void PHYSFS_permitSymbolicLinks(int allow);
+
+
+/* !!! FIXME: const this? */
+/**
+ * \fn char **PHYSFS_getCdRomDirs(void)
+ * \brief Get an array of paths to available CD-ROM drives.
+ *
+ * The dirs returned are platform-dependent ("D:\" on Win32, "/cdrom" or
+ * whatnot on Unix). Dirs are only returned if there is a disc ready and
+ * accessible in the drive. So if you've got two drives (D: and E:), and only
+ * E: has a disc in it, then that's all you get. If the user inserts a disc
+ * in D: and you call this function again, you get both drives. If, on a
+ * Unix box, the user unmounts a disc and remounts it elsewhere, the next
+ * call to this function will reflect that change.
+ *
+ * This function refers to "CD-ROM" media, but it really means "inserted disc
+ * media," such as DVD-ROM, HD-DVD, CDRW, and Blu-Ray discs. It looks for
+ * filesystems, and as such won't report an audio CD, unless there's a
+ * mounted filesystem track on it.
+ *
+ * The returned value is an array of strings, with a NULL entry to signify the
+ * end of the list:
+ *
+ * \code
+ * char **cds = PHYSFS_getCdRomDirs();
+ * char **i;
+ *
+ * for (i = cds; *i != NULL; i++)
+ * printf("cdrom dir [%s] is available.\n", *i);
+ *
+ * PHYSFS_freeList(cds);
+ * \endcode
+ *
+ * This call may block while drives spin up. Be forewarned.
+ *
+ * When you are done with the returned information, you may dispose of the
+ * resources by calling PHYSFS_freeList() with the returned pointer.
+ *
+ * \return Null-terminated array of null-terminated strings.
+ *
+ * \sa PHYSFS_getCdRomDirsCallback
+ */
+PHYSFS_DECL char **PHYSFS_getCdRomDirs(void);
+
+
+/**
+ * \fn const char *PHYSFS_getBaseDir(void)
+ * \brief Get the path where the application resides.
+ *
+ * Helper function.
+ *
+ * Get the "base dir". This is the directory where the application was run
+ * from, which is probably the installation directory, and may or may not
+ * be the process's current working directory.
+ *
+ * You should probably use the base dir in your search path.
+ *
+ * \return READ ONLY string of base dir in platform-dependent notation.
+ *
+ * \sa PHYSFS_getPrefDir
+ */
+PHYSFS_DECL const char *PHYSFS_getBaseDir(void);
+
+
+/**
+ * \fn const char *PHYSFS_getUserDir(void)
+ * \brief Get the path where user's home directory resides.
+ *
+ * \deprecated As of PhysicsFS 2.1, you probably want PHYSFS_getPrefDir().
+ *
+ * Helper function.
+ *
+ * Get the "user dir". This is meant to be a suggestion of where a specific
+ * user of the system can store files. On Unix, this is her home directory.
+ * On systems with no concept of multiple home directories (MacOS, win95),
+ * this will default to something like "C:\mybasedir\users\username"
+ * where "username" will either be the login name, or "default" if the
+ * platform doesn't support multiple users, either.
+ *
+ * \return READ ONLY string of user dir in platform-dependent notation.
+ *
+ * \sa PHYSFS_getBaseDir
+ * \sa PHYSFS_getPrefDir
+ */
+PHYSFS_DECL const char *PHYSFS_getUserDir(void) PHYSFS_DEPRECATED;
+
+
+/**
+ * \fn const char *PHYSFS_getWriteDir(void)
+ * \brief Get path where PhysicsFS will allow file writing.
+ *
+ * Get the current write dir. The default write dir is NULL.
+ *
+ * \return READ ONLY string of write dir in platform-dependent notation,
+ * OR NULL IF NO WRITE PATH IS CURRENTLY SET.
+ *
+ * \sa PHYSFS_setWriteDir
+ */
+PHYSFS_DECL const char *PHYSFS_getWriteDir(void);
+
+
+/**
+ * \fn int PHYSFS_setWriteDir(const char *newDir)
+ * \brief Tell PhysicsFS where it may write files.
+ *
+ * Set a new write dir. This will override the previous setting.
+ *
+ * This call will fail (and fail to change the write dir) if the current
+ * write dir still has files open in it.
+ *
+ * \param newDir The new directory to be the root of the write dir,
+ * specified in platform-dependent notation. Setting to NULL
+ * disables the write dir, so no files can be opened for
+ * writing via PhysicsFS.
+ * \return non-zero on success, zero on failure. All attempts to open a file
+ * for writing via PhysicsFS will fail until this call succeeds.
+ * Specifics of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_getWriteDir
+ */
+PHYSFS_DECL int PHYSFS_setWriteDir(const char *newDir);
+
+
+/**
+ * \fn int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
+ * \brief Add an archive or directory to the search path.
+ *
+ * \deprecated As of PhysicsFS 2.0, use PHYSFS_mount() instead. This
+ * function just wraps it anyhow.
+ *
+ * This function is equivalent to:
+ *
+ * \code
+ * PHYSFS_mount(newDir, NULL, appendToPath);
+ * \endcode
+ *
+ * You must use this and not PHYSFS_mount if binary compatibility with
+ * PhysicsFS 1.0 is important (which it may not be for many people).
+ *
+ * \sa PHYSFS_mount
+ * \sa PHYSFS_removeFromSearchPath
+ * \sa PHYSFS_getSearchPath
+ */
+PHYSFS_DECL int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
+ PHYSFS_DEPRECATED;
+
+/**
+ * \fn int PHYSFS_removeFromSearchPath(const char *oldDir)
+ * \brief Remove a directory or archive from the search path.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_unmount() instead. This
+ * function just wraps it anyhow. There's no functional difference
+ * except the vocabulary changed from "adding to the search path"
+ * to "mounting" when that functionality was extended, and thus
+ * the preferred way to accomplish this function's work is now
+ * called "unmounting."
+ *
+ * This function is equivalent to:
+ *
+ * \code
+ * PHYSFS_unmount(oldDir);
+ * \endcode
+ *
+ * You must use this and not PHYSFS_unmount if binary compatibility with
+ * PhysicsFS 1.0 is important (which it may not be for many people).
+ *
+ * \sa PHYSFS_addToSearchPath
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_unmount
+ */
+PHYSFS_DECL int PHYSFS_removeFromSearchPath(const char *oldDir)
+ PHYSFS_DEPRECATED;
+
+
+/**
+ * \fn char **PHYSFS_getSearchPath(void)
+ * \brief Get the current search path.
+ *
+ * The default search path is an empty list.
+ *
+ * The returned value is an array of strings, with a NULL entry to signify the
+ * end of the list:
+ *
+ * \code
+ * char **i;
+ *
+ * for (i = PHYSFS_getSearchPath(); *i != NULL; i++)
+ * printf("[%s] is in the search path.\n", *i);
+ * \endcode
+ *
+ * When you are done with the returned information, you may dispose of the
+ * resources by calling PHYSFS_freeList() with the returned pointer.
+ *
+ * \return Null-terminated array of null-terminated strings. NULL if there
+ * was a problem (read: OUT OF MEMORY).
+ *
+ * \sa PHYSFS_getSearchPathCallback
+ * \sa PHYSFS_addToSearchPath
+ * \sa PHYSFS_removeFromSearchPath
+ */
+PHYSFS_DECL char **PHYSFS_getSearchPath(void);
+
+
+/**
+ * \fn int PHYSFS_setSaneConfig(const char *organization, const char *appName, const char *archiveExt, int includeCdRoms, int archivesFirst)
+ * \brief Set up sane, default paths.
+ *
+ * Helper function.
+ *
+ * The write dir will be set to the pref dir returned by
+ * \code PHYSFS_getPrefDir(organization, appName) \endcode, which is
+ * created if it doesn't exist.
+ *
+ * The above is sufficient to make sure your program's configuration directory
+ * is separated from other clutter, and platform-independent.
+ *
+ * The search path will be:
+ *
+ * - The Write Dir (created if it doesn't exist)
+ * - The Base Dir (PHYSFS_getBaseDir())
+ * - All found CD-ROM dirs (optionally)
+ *
+ * These directories are then searched for files ending with the extension
+ * (archiveExt), which, if they are valid and supported archives, will also
+ * be added to the search path. If you specified "PKG" for (archiveExt), and
+ * there's a file named data.PKG in the base dir, it'll be checked. Archives
+ * can either be appended or prepended to the search path in alphabetical
+ * order, regardless of which directories they were found in. All archives
+ * are mounted in the root of the virtual file system ("/").
+ *
+ * All of this can be accomplished from the application, but this just does it
+ * all for you. Feel free to add more to the search path manually, too.
+ *
+ * \param organization Name of your company/group/etc to be used as a
+ * dirname, so keep it small, and no-frills.
+ *
+ * \param appName Program-specific name of your program, to separate it
+ * from other programs using PhysicsFS.
+ *
+ * \param archiveExt File extension used by your program to specify an
+ * archive. For example, Quake 3 uses "pk3", even though
+ * they are just zipfiles. Specify NULL to not dig out
+ * archives automatically. Do not specify the '.' char;
+ * If you want to look for ZIP files, specify "ZIP" and
+ * not ".ZIP" ... the archive search is case-insensitive.
+ *
+ * \param includeCdRoms Non-zero to include CD-ROMs in the search path, and
+ * (if (archiveExt) != NULL) search them for archives.
+ * This may cause a significant amount of blocking
+ * while discs are accessed, and if there are no discs
+ * in the drive (or even not mounted on Unix systems),
+ * then they may not be made available anyhow. You may
+ * want to specify zero and handle the disc setup
+ * yourself.
+ *
+ * \param archivesFirst Non-zero to prepend the archives to the search path.
+ * Zero to append them. Ignored if !(archiveExt).
+ *
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_setSaneConfig(const char *organization,
+ const char *appName,
+ const char *archiveExt,
+ int includeCdRoms,
+ int archivesFirst);
+
+
+/* Directory management stuff ... */
+
+/**
+ * \fn int PHYSFS_mkdir(const char *dirName)
+ * \brief Create a directory.
+ *
+ * This is specified in platform-independent notation in relation to the
+ * write dir. All missing parent directories are also created if they
+ * don't exist.
+ *
+ * So if you've got the write dir set to "C:\mygame\writedir" and call
+ * PHYSFS_mkdir("downloads/maps") then the directories
+ * "C:\mygame\writedir\downloads" and "C:\mygame\writedir\downloads\maps"
+ * will be created if possible. If the creation of "maps" fails after we
+ * have successfully created "downloads", then the function leaves the
+ * created directory behind and reports failure.
+ *
+ * \param dirName New dir to create.
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_delete
+ */
+PHYSFS_DECL int PHYSFS_mkdir(const char *dirName);
+
+
+/**
+ * \fn int PHYSFS_delete(const char *filename)
+ * \brief Delete a file or directory.
+ *
+ * (filename) is specified in platform-independent notation in relation to the
+ * write dir.
+ *
+ * A directory must be empty before this call can delete it.
+ *
+ * Deleting a symlink will remove the link, not what it points to, regardless
+ * of whether you "permitSymLinks" or not.
+ *
+ * So if you've got the write dir set to "C:\mygame\writedir" and call
+ * PHYSFS_delete("downloads/maps/level1.map") then the file
+ * "C:\mygame\writedir\downloads\maps\level1.map" is removed from the
+ * physical filesystem, if it exists and the operating system permits the
+ * deletion.
+ *
+ * Note that on Unix systems, deleting a file may be successful, but the
+ * actual file won't be removed until all processes that have an open
+ * filehandle to it (including your program) close their handles.
+ *
+ * Chances are, the bits that make up the file still exist, they are just
+ * made available to be written over at a later point. Don't consider this
+ * a security method or anything. :)
+ *
+ * \param filename Filename to delete.
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_delete(const char *filename);
+
+
+/**
+ * \fn const char *PHYSFS_getRealDir(const char *filename)
+ * \brief Figure out where in the search path a file resides.
+ *
+ * The file is specified in platform-independent notation. The returned
+ * filename will be the element of the search path where the file was found,
+ * which may be a directory, or an archive. Even if there are multiple
+ * matches in different parts of the search path, only the first one found
+ * is used, just like when opening a file.
+ *
+ * So, if you look for "maps/level1.map", and C:\\mygame is in your search
+ * path and C:\\mygame\\maps\\level1.map exists, then "C:\mygame" is returned.
+ *
+ * If a any part of a match is a symbolic link, and you've not explicitly
+ * permitted symlinks, then it will be ignored, and the search for a match
+ * will continue.
+ *
+ * If you specify a fake directory that only exists as a mount point, it'll
+ * be associated with the first archive mounted there, even though that
+ * directory isn't necessarily contained in a real archive.
+ *
+ * \warning This will return NULL if there is no real directory associated
+ * with (filename). Specifically, PHYSFS_mountIo(),
+ * PHYSFS_mountMemory(), and PHYSFS_mountHandle() will return NULL
+ * even if the filename is found in the search path. Plan accordingly.
+ *
+ * \param filename file to look for.
+ * \return READ ONLY string of element of search path containing the
+ * the file in question. NULL if not found.
+ */
+PHYSFS_DECL const char *PHYSFS_getRealDir(const char *filename);
+
+
+/**
+ * \fn char **PHYSFS_enumerateFiles(const char *dir)
+ * \brief Get a file listing of a search path's directory.
+ *
+ * Matching directories are interpolated. That is, if "C:\mydir" is in the
+ * search path and contains a directory "savegames" that contains "x.sav",
+ * "y.sav", and "z.sav", and there is also a "C:\userdir" in the search path
+ * that has a "savegames" subdirectory with "w.sav", then the following code:
+ *
+ * \code
+ * char **rc = PHYSFS_enumerateFiles("savegames");
+ * char **i;
+ *
+ * for (i = rc; *i != NULL; i++)
+ * printf(" * We've got [%s].\n", *i);
+ *
+ * PHYSFS_freeList(rc);
+ * \endcode
+ *
+ * \...will print:
+ *
+ * \verbatim
+ * We've got [x.sav].
+ * We've got [y.sav].
+ * We've got [z.sav].
+ * We've got [w.sav].\endverbatim
+ *
+ * Feel free to sort the list however you like. We only promise there will
+ * be no duplicates, but not what order the final list will come back in.
+ *
+ * Don't forget to call PHYSFS_freeList() with the return value from this
+ * function when you are done with it.
+ *
+ * \param dir directory in platform-independent notation to enumerate.
+ * \return Null-terminated array of null-terminated strings.
+ *
+ * \sa PHYSFS_enumerateFilesCallback
+ */
+PHYSFS_DECL char **PHYSFS_enumerateFiles(const char *dir);
+
+
+/**
+ * \fn int PHYSFS_exists(const char *fname)
+ * \brief Determine if a file exists in the search path.
+ *
+ * Reports true if there is an entry anywhere in the search path by the
+ * name of (fname).
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you
+ * might end up further down in the search path than expected.
+ *
+ * \param fname filename in platform-independent notation.
+ * \return non-zero if filename exists. zero otherwise.
+ */
+PHYSFS_DECL int PHYSFS_exists(const char *fname);
+
+
+/**
+ * \fn int PHYSFS_isDirectory(const char *fname)
+ * \brief Determine if a file in the search path is really a directory.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_stat() instead. This
+ * function just wraps it anyhow.
+ *
+ * Determine if the first occurence of (fname) in the search path is
+ * really a directory entry.
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, so you
+ * might end up further down in the search path than expected.
+ *
+ * \param fname filename in platform-independent notation.
+ * \return non-zero if filename exists and is a directory. zero otherwise.
+ *
+ * \sa PHYSFS_stat
+ * \sa PHYSFS_exists
+ */
+PHYSFS_DECL int PHYSFS_isDirectory(const char *fname) PHYSFS_DEPRECATED;
+
+
+/**
+ * \fn int PHYSFS_isSymbolicLink(const char *fname)
+ * \brief Determine if a file in the search path is really a symbolic link.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_stat() instead. This
+ * function just wraps it anyhow.
+ *
+ * Determine if the first occurence of (fname) in the search path is
+ * really a symbolic link.
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, and as such,
+ * this function will always return 0 in that case.
+ *
+ * \param fname filename in platform-independent notation.
+ * \return non-zero if filename exists and is a symlink. zero otherwise.
+ *
+ * \sa PHYSFS_stat
+ * \sa PHYSFS_exists
+ */
+PHYSFS_DECL int PHYSFS_isSymbolicLink(const char *fname) PHYSFS_DEPRECATED;
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename)
+ * \brief Get the last modification time of a file.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_stat() instead. This
+ * function just wraps it anyhow.
+ *
+ * The modtime is returned as a number of seconds since the Unix epoch
+ * (midnight, Jan 1, 1970). The exact derivation and accuracy of this time
+ * depends on the particular archiver. If there is no reasonable way to
+ * obtain this information for a particular archiver, or there was some sort
+ * of error, this function returns (-1).
+ *
+ * You must use this and not PHYSFS_stat() if binary compatibility with
+ * PhysicsFS 2.0 is important (which it may not be for many people).
+ *
+ * \param filename filename to check, in platform-independent notation.
+ * \return last modified time of the file. -1 if it can't be determined.
+ *
+ * \sa PHYSFS_stat
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_getLastModTime(const char *filename)
+ PHYSFS_DEPRECATED;
+
+
+/* i/o stuff... */
+
+/**
+ * \fn PHYSFS_File *PHYSFS_openWrite(const char *filename)
+ * \brief Open a file for writing.
+ *
+ * Open a file for writing, in platform-independent notation and in relation
+ * to the write dir as the root of the writable filesystem. The specified
+ * file is created if it doesn't exist. If it does exist, it is truncated to
+ * zero bytes, and the writing offset is set to the start.
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
+ * symlink with this function will fail in such a case.
+ *
+ * \param filename File to open.
+ * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_openRead
+ * \sa PHYSFS_openAppend
+ * \sa PHYSFS_write
+ * \sa PHYSFS_close
+ */
+PHYSFS_DECL PHYSFS_File *PHYSFS_openWrite(const char *filename);
+
+
+/**
+ * \fn PHYSFS_File *PHYSFS_openAppend(const char *filename)
+ * \brief Open a file for appending.
+ *
+ * Open a file for writing, in platform-independent notation and in relation
+ * to the write dir as the root of the writable filesystem. The specified
+ * file is created if it doesn't exist. If it does exist, the writing offset
+ * is set to the end of the file, so the first write will be the byte after
+ * the end.
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
+ * symlink with this function will fail in such a case.
+ *
+ * \param filename File to open.
+ * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_openRead
+ * \sa PHYSFS_openWrite
+ * \sa PHYSFS_write
+ * \sa PHYSFS_close
+ */
+PHYSFS_DECL PHYSFS_File *PHYSFS_openAppend(const char *filename);
+
+
+/**
+ * \fn PHYSFS_File *PHYSFS_openRead(const char *filename)
+ * \brief Open a file for reading.
+ *
+ * Open a file for reading, in platform-independent notation. The search path
+ * is checked one at a time until a matching file is found, in which case an
+ * abstract filehandle is associated with it, and reading may be done.
+ * The reading offset is set to the first byte of the file.
+ *
+ * Note that entries that are symlinks are ignored if
+ * PHYSFS_permitSymbolicLinks(1) hasn't been called, and opening a
+ * symlink with this function will fail in such a case.
+ *
+ * \param filename File to open.
+ * \return A valid PhysicsFS filehandle on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_openWrite
+ * \sa PHYSFS_openAppend
+ * \sa PHYSFS_read
+ * \sa PHYSFS_close
+ */
+PHYSFS_DECL PHYSFS_File *PHYSFS_openRead(const char *filename);
+
+
+/**
+ * \fn int PHYSFS_close(PHYSFS_File *handle)
+ * \brief Close a PhysicsFS filehandle.
+ *
+ * This call is capable of failing if the operating system was buffering
+ * writes to the physical media, and, now forced to write those changes to
+ * physical media, can not store the data for some reason. In such a case,
+ * the filehandle stays open. A well-written program should ALWAYS check the
+ * return value from the close call in addition to every writing call!
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_openRead
+ * \sa PHYSFS_openWrite
+ * \sa PHYSFS_openAppend
+ */
+PHYSFS_DECL int PHYSFS_close(PHYSFS_File *handle);
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ * \brief Read data from a PhysicsFS filehandle
+ *
+ * The file must be opened for reading.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_readBytes() instead. This
+ * function just wraps it anyhow. This function never clarified
+ * what would happen if you managed to read a partial object, so
+ * working at the byte level makes this cleaner for everyone,
+ * especially now that PHYSFS_Io interfaces can be supplied by the
+ * application.
+ *
+ * \param handle handle returned from PHYSFS_openRead().
+ * \param buffer buffer to store read data into.
+ * \param objSize size in bytes of objects being read from (handle).
+ * \param objCount number of (objSize) objects to read from (handle).
+ * \return number of objects read. PHYSFS_getLastError() can shed light on
+ * the reason this might be < (objCount), as can PHYSFS_eof().
+ * -1 if complete failure.
+ *
+ * \sa PHYSFS_readBytes
+ * \sa PHYSFS_eof
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle,
+ void *buffer,
+ PHYSFS_uint32 objSize,
+ PHYSFS_uint32 objCount)
+ PHYSFS_DEPRECATED;
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
+ * \brief Write data to a PhysicsFS filehandle
+ *
+ * The file must be opened for writing.
+ *
+ * \deprecated As of PhysicsFS 2.1, use PHYSFS_writeBytes() instead. This
+ * function just wraps it anyhow. This function never clarified
+ * what would happen if you managed to write a partial object, so
+ * working at the byte level makes this cleaner for everyone,
+ * especially now that PHYSFS_Io interfaces can be supplied by the
+ * application.
+ *
+ * \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend().
+ * \param buffer buffer of bytes to write to (handle).
+ * \param objSize size in bytes of objects being written to (handle).
+ * \param objCount number of (objSize) objects to write to (handle).
+ * \return number of objects written. PHYSFS_getLastError() can shed light on
+ * the reason this might be < (objCount). -1 if complete failure.
+ *
+ * \sa PHYSFS_writeBytes
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle,
+ const void *buffer,
+ PHYSFS_uint32 objSize,
+ PHYSFS_uint32 objCount)
+ PHYSFS_DEPRECATED;
+
+
+/* File position stuff... */
+
+/**
+ * \fn int PHYSFS_eof(PHYSFS_File *handle)
+ * \brief Check for end-of-file state on a PhysicsFS filehandle.
+ *
+ * Determine if the end of file has been reached in a PhysicsFS filehandle.
+ *
+ * \param handle handle returned from PHYSFS_openRead().
+ * \return nonzero if EOF, zero if not.
+ *
+ * \sa PHYSFS_read
+ * \sa PHYSFS_tell
+ */
+PHYSFS_DECL int PHYSFS_eof(PHYSFS_File *handle);
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle)
+ * \brief Determine current position within a PhysicsFS filehandle.
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \return offset in bytes from start of file. -1 if error occurred.
+ * Specifics of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_seek
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle);
+
+
+/**
+ * \fn int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos)
+ * \brief Seek to a new position within a PhysicsFS filehandle.
+ *
+ * The next read or write will occur at that place. Seeking past the
+ * beginning or end of the file is not allowed, and causes an error.
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \param pos number of bytes from start of file to seek to.
+ * \return nonzero on success, zero on error. Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_tell
+ */
+PHYSFS_DECL int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos);
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle)
+ * \brief Get total length of a file in bytes.
+ *
+ * Note that if another process/thread is writing to this file at the same
+ * time, then the information this function supplies could be incorrect
+ * before you get it. Use with caution, or better yet, don't use at all.
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \return size in bytes of the file. -1 if can't be determined.
+ *
+ * \sa PHYSFS_tell
+ * \sa PHYSFS_seek
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle);
+
+
+/* Buffering stuff... */
+
+/**
+ * \fn int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize)
+ * \brief Set up buffering for a PhysicsFS file handle.
+ *
+ * Define an i/o buffer for a file handle. A memory block of (bufsize) bytes
+ * will be allocated and associated with (handle).
+ *
+ * For files opened for reading, up to (bufsize) bytes are read from (handle)
+ * and stored in the internal buffer. Calls to PHYSFS_read() will pull
+ * from this buffer until it is empty, and then refill it for more reading.
+ * Note that compressed files, like ZIP archives, will decompress while
+ * buffering, so this can be handy for offsetting CPU-intensive operations.
+ * The buffer isn't filled until you do your next read.
+ *
+ * For files opened for writing, data will be buffered to memory until the
+ * buffer is full or the buffer is flushed. Closing a handle implicitly
+ * causes a flush...check your return values!
+ *
+ * Seeking, etc transparently accounts for buffering.
+ *
+ * You can resize an existing buffer by calling this function more than once
+ * on the same file. Setting the buffer size to zero will free an existing
+ * buffer.
+ *
+ * PhysicsFS file handles are unbuffered by default.
+ *
+ * Please check the return value of this function! Failures can include
+ * not being able to seek backwards in a read-only file when removing the
+ * buffer, not being able to allocate the buffer, and not being able to
+ * flush the buffer to disk, among other unexpected problems.
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \param bufsize size, in bytes, of buffer to allocate.
+ * \return nonzero if successful, zero on error.
+ *
+ * \sa PHYSFS_flush
+ * \sa PHYSFS_read
+ * \sa PHYSFS_write
+ * \sa PHYSFS_close
+ */
+PHYSFS_DECL int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 bufsize);
+
+
+/**
+ * \fn int PHYSFS_flush(PHYSFS_File *handle)
+ * \brief Flush a buffered PhysicsFS file handle.
+ *
+ * For buffered files opened for writing, this will put the current contents
+ * of the buffer to disk and flag the buffer as empty if possible.
+ *
+ * For buffered files opened for reading or unbuffered files, this is a safe
+ * no-op, and will report success.
+ *
+ * \param handle handle returned from PHYSFS_open*().
+ * \return nonzero if successful, zero on error.
+ *
+ * \sa PHYSFS_setBuffer
+ * \sa PHYSFS_close
+ */
+PHYSFS_DECL int PHYSFS_flush(PHYSFS_File *handle);
+
+
+/* Byteorder stuff... */
+
+#ifndef SWIG /* not available from scripting languages. */
+
+/**
+ * \fn PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val)
+ * \brief Swap littleendian signed 16 to platform's native byte order.
+ *
+ * Take a 16-bit signed value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 val);
+
+
+/**
+ * \fn PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val)
+ * \brief Swap littleendian unsigned 16 to platform's native byte order.
+ *
+ * Take a 16-bit unsigned value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 val);
+
+/**
+ * \fn PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val)
+ * \brief Swap littleendian signed 32 to platform's native byte order.
+ *
+ * Take a 32-bit signed value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 val);
+
+
+/**
+ * \fn PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val)
+ * \brief Swap littleendian unsigned 32 to platform's native byte order.
+ *
+ * Take a 32-bit unsigned value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 val);
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val)
+ * \brief Swap littleendian signed 64 to platform's native byte order.
+ *
+ * Take a 64-bit signed value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 val);
+
+
+/**
+ * \fn PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val)
+ * \brief Swap littleendian unsigned 64 to platform's native byte order.
+ *
+ * Take a 64-bit unsigned value in littleendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 val);
+
+
+/**
+ * \fn PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val)
+ * \brief Swap bigendian signed 16 to platform's native byte order.
+ *
+ * Take a 16-bit signed value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 val);
+
+
+/**
+ * \fn PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val)
+ * \brief Swap bigendian unsigned 16 to platform's native byte order.
+ *
+ * Take a 16-bit unsigned value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 val);
+
+/**
+ * \fn PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val)
+ * \brief Swap bigendian signed 32 to platform's native byte order.
+ *
+ * Take a 32-bit signed value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 val);
+
+
+/**
+ * \fn PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val)
+ * \brief Swap bigendian unsigned 32 to platform's native byte order.
+ *
+ * Take a 32-bit unsigned value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ */
+PHYSFS_DECL PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 val);
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val)
+ * \brief Swap bigendian signed 64 to platform's native byte order.
+ *
+ * Take a 64-bit signed value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 val);
+
+
+/**
+ * \fn PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val)
+ * \brief Swap bigendian unsigned 64 to platform's native byte order.
+ *
+ * Take a 64-bit unsigned value in bigendian format and convert it to
+ * the platform's native byte order.
+ *
+ * \param val value to convert
+ * \return converted value.
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 val);
+
+#endif /* SWIG */
+
+
+/**
+ * \fn int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val)
+ * \brief Read and convert a signed 16-bit littleendian value.
+ *
+ * Convenience function. Read a signed 16-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_readSLE16(PHYSFS_File *file, PHYSFS_sint16 *val);
+
+
+/**
+ * \fn int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val)
+ * \brief Read and convert an unsigned 16-bit littleendian value.
+ *
+ * Convenience function. Read an unsigned 16-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ */
+PHYSFS_DECL int PHYSFS_readULE16(PHYSFS_File *file, PHYSFS_uint16 *val);
+
+
+/**
+ * \fn int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val)
+ * \brief Read and convert a signed 16-bit bigendian value.
+ *
+ * Convenience function. Read a signed 16-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_readSBE16(PHYSFS_File *file, PHYSFS_sint16 *val);
+
+
+/**
+ * \fn int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val)
+ * \brief Read and convert an unsigned 16-bit bigendian value.
+ *
+ * Convenience function. Read an unsigned 16-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ */
+PHYSFS_DECL int PHYSFS_readUBE16(PHYSFS_File *file, PHYSFS_uint16 *val);
+
+
+/**
+ * \fn int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val)
+ * \brief Read and convert a signed 32-bit littleendian value.
+ *
+ * Convenience function. Read a signed 32-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_readSLE32(PHYSFS_File *file, PHYSFS_sint32 *val);
+
+
+/**
+ * \fn int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val)
+ * \brief Read and convert an unsigned 32-bit littleendian value.
+ *
+ * Convenience function. Read an unsigned 32-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ */
+PHYSFS_DECL int PHYSFS_readULE32(PHYSFS_File *file, PHYSFS_uint32 *val);
+
+
+/**
+ * \fn int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val)
+ * \brief Read and convert a signed 32-bit bigendian value.
+ *
+ * Convenience function. Read a signed 32-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_readSBE32(PHYSFS_File *file, PHYSFS_sint32 *val);
+
+
+/**
+ * \fn int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val)
+ * \brief Read and convert an unsigned 32-bit bigendian value.
+ *
+ * Convenience function. Read an unsigned 32-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ */
+PHYSFS_DECL int PHYSFS_readUBE32(PHYSFS_File *file, PHYSFS_uint32 *val);
+
+
+/**
+ * \fn int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val)
+ * \brief Read and convert a signed 64-bit littleendian value.
+ *
+ * Convenience function. Read a signed 64-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_readSLE64(PHYSFS_File *file, PHYSFS_sint64 *val);
+
+
+/**
+ * \fn int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val)
+ * \brief Read and convert an unsigned 64-bit littleendian value.
+ *
+ * Convenience function. Read an unsigned 64-bit littleendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_readULE64(PHYSFS_File *file, PHYSFS_uint64 *val);
+
+
+/**
+ * \fn int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val)
+ * \brief Read and convert a signed 64-bit bigendian value.
+ *
+ * Convenience function. Read a signed 64-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_sint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_readSBE64(PHYSFS_File *file, PHYSFS_sint64 *val);
+
+
+/**
+ * \fn int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val)
+ * \brief Read and convert an unsigned 64-bit bigendian value.
+ *
+ * Convenience function. Read an unsigned 64-bit bigendian value from a
+ * file and convert it to the platform's native byte order.
+ *
+ * \param file PhysicsFS file handle from which to read.
+ * \param val pointer to where value should be stored.
+ * \return zero on failure, non-zero on success. If successful, (*val) will
+ * store the result. On failure, you can find out what went wrong
+ * from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_readUBE64(PHYSFS_File *file, PHYSFS_uint64 *val);
+
+
+/**
+ * \fn int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val)
+ * \brief Convert and write a signed 16-bit littleendian value.
+ *
+ * Convenience function. Convert a signed 16-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeSLE16(PHYSFS_File *file, PHYSFS_sint16 val);
+
+
+/**
+ * \fn int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val)
+ * \brief Convert and write an unsigned 16-bit littleendian value.
+ *
+ * Convenience function. Convert an unsigned 16-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeULE16(PHYSFS_File *file, PHYSFS_uint16 val);
+
+
+/**
+ * \fn int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val)
+ * \brief Convert and write a signed 16-bit bigendian value.
+ *
+ * Convenience function. Convert a signed 16-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeSBE16(PHYSFS_File *file, PHYSFS_sint16 val);
+
+
+/**
+ * \fn int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val)
+ * \brief Convert and write an unsigned 16-bit bigendian value.
+ *
+ * Convenience function. Convert an unsigned 16-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeUBE16(PHYSFS_File *file, PHYSFS_uint16 val);
+
+
+/**
+ * \fn int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val)
+ * \brief Convert and write a signed 32-bit littleendian value.
+ *
+ * Convenience function. Convert a signed 32-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeSLE32(PHYSFS_File *file, PHYSFS_sint32 val);
+
+
+/**
+ * \fn int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val)
+ * \brief Convert and write an unsigned 32-bit littleendian value.
+ *
+ * Convenience function. Convert an unsigned 32-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeULE32(PHYSFS_File *file, PHYSFS_uint32 val);
+
+
+/**
+ * \fn int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val)
+ * \brief Convert and write a signed 32-bit bigendian value.
+ *
+ * Convenience function. Convert a signed 32-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeSBE32(PHYSFS_File *file, PHYSFS_sint32 val);
+
+
+/**
+ * \fn int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val)
+ * \brief Convert and write an unsigned 32-bit bigendian value.
+ *
+ * Convenience function. Convert an unsigned 32-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ */
+PHYSFS_DECL int PHYSFS_writeUBE32(PHYSFS_File *file, PHYSFS_uint32 val);
+
+
+/**
+ * \fn int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val)
+ * \brief Convert and write a signed 64-bit littleendian value.
+ *
+ * Convenience function. Convert a signed 64-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_writeSLE64(PHYSFS_File *file, PHYSFS_sint64 val);
+
+
+/**
+ * \fn int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val)
+ * \brief Convert and write an unsigned 64-bit littleendian value.
+ *
+ * Convenience function. Convert an unsigned 64-bit value from the platform's
+ * native byte order to littleendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_writeULE64(PHYSFS_File *file, PHYSFS_uint64 val);
+
+
+/**
+ * \fn int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val)
+ * \brief Convert and write a signed 64-bit bigending value.
+ *
+ * Convenience function. Convert a signed 64-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_writeSBE64(PHYSFS_File *file, PHYSFS_sint64 val);
+
+
+/**
+ * \fn int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val)
+ * \brief Convert and write an unsigned 64-bit bigendian value.
+ *
+ * Convenience function. Convert an unsigned 64-bit value from the platform's
+ * native byte order to bigendian and write it to a file.
+ *
+ * \param file PhysicsFS file handle to which to write.
+ * \param val Value to convert and write.
+ * \return zero on failure, non-zero on success. On failure, you can
+ * find out what went wrong from PHYSFS_getLastError().
+ *
+ * \warning Remember, PHYSFS_uint64 is only 32 bits on platforms without
+ * any sort of 64-bit support.
+ */
+PHYSFS_DECL int PHYSFS_writeUBE64(PHYSFS_File *file, PHYSFS_uint64 val);
+
+
+/* Everything above this line is part of the PhysicsFS 1.0 API. */
+
+/**
+ * \fn int PHYSFS_isInit(void)
+ * \brief Determine if the PhysicsFS library is initialized.
+ *
+ * Once PHYSFS_init() returns successfully, this will return non-zero.
+ * Before a successful PHYSFS_init() and after PHYSFS_deinit() returns
+ * successfully, this will return zero. This function is safe to call at
+ * any time.
+ *
+ * \return non-zero if library is initialized, zero if library is not.
+ *
+ * \sa PHYSFS_init
+ * \sa PHYSFS_deinit
+ */
+PHYSFS_DECL int PHYSFS_isInit(void);
+
+
+/**
+ * \fn int PHYSFS_symbolicLinksPermitted(void)
+ * \brief Determine if the symbolic links are permitted.
+ *
+ * This reports the setting from the last call to PHYSFS_permitSymbolicLinks().
+ * If PHYSFS_permitSymbolicLinks() hasn't been called since the library was
+ * last initialized, symbolic links are implicitly disabled.
+ *
+ * \return non-zero if symlinks are permitted, zero if not.
+ *
+ * \sa PHYSFS_permitSymbolicLinks
+ */
+PHYSFS_DECL int PHYSFS_symbolicLinksPermitted(void);
+
+
+#ifndef SWIG /* not available from scripting languages. */
+
+/**
+ * \struct PHYSFS_Allocator
+ * \brief PhysicsFS allocation function pointers.
+ *
+ * (This is for limited, hardcore use. If you don't immediately see a need
+ * for it, you can probably ignore this forever.)
+ *
+ * You create one of these structures for use with PHYSFS_setAllocator.
+ * Allocators are assumed to be reentrant by the caller; please mutex
+ * accordingly.
+ *
+ * Allocations are always discussed in 64-bits, for future expansion...we're
+ * on the cusp of a 64-bit transition, and we'll probably be allocating 6
+ * gigabytes like it's nothing sooner or later, and I don't want to change
+ * this again at that point. If you're on a 32-bit platform and have to
+ * downcast, it's okay to return NULL if the allocation is greater than
+ * 4 gigabytes, since you'd have to do so anyhow.
+ *
+ * \sa PHYSFS_setAllocator
+ */
+typedef struct PHYSFS_Allocator
+{
+ int (*Init)(void); /**< Initialize. Can be NULL. Zero on failure. */
+ void (*Deinit)(void); /**< Deinitialize your allocator. Can be NULL. */
+ void *(*Malloc)(PHYSFS_uint64); /**< Allocate like malloc(). */
+ void *(*Realloc)(void *, PHYSFS_uint64); /**< Reallocate like realloc(). */
+ void (*Free)(void *); /**< Free memory from Malloc or Realloc. */
+} PHYSFS_Allocator;
+
+
+/**
+ * \fn int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator)
+ * \brief Hook your own allocation routines into PhysicsFS.
+ *
+ * (This is for limited, hardcore use. If you don't immediately see a need
+ * for it, you can probably ignore this forever.)
+ *
+ * By default, PhysicsFS will use whatever is reasonable for a platform
+ * to manage dynamic memory (usually ANSI C malloc/realloc/free, but
+ * some platforms might use something else), but in some uncommon cases, the
+ * app might want more control over the library's memory management. This
+ * lets you redirect PhysicsFS to use your own allocation routines instead.
+ * You can only call this function before PHYSFS_init(); if the library is
+ * initialized, it'll reject your efforts to change the allocator mid-stream.
+ * You may call this function after PHYSFS_deinit() if you are willing to
+ * shut down the library and restart it with a new allocator; this is a safe
+ * and supported operation. The allocator remains intact between deinit/init
+ * calls. If you want to return to the platform's default allocator, pass a
+ * NULL in here.
+ *
+ * If you aren't immediately sure what to do with this function, you can
+ * safely ignore it altogether.
+ *
+ * \param allocator Structure containing your allocator's entry points.
+ * \return zero on failure, non-zero on success. This call only fails
+ * when used between PHYSFS_init() and PHYSFS_deinit() calls.
+ */
+PHYSFS_DECL int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator);
+
+#endif /* SWIG */
+
+
+/**
+ * \fn int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
+ * \brief Add an archive or directory to the search path.
+ *
+ * If this is a duplicate, the entry is not added again, even though the
+ * function succeeds. You may not add the same archive to two different
+ * mountpoints: duplicate checking is done against the archive and not the
+ * mountpoint.
+ *
+ * When you mount an archive, it is added to a virtual file system...all files
+ * in all of the archives are interpolated into a single hierachical file
+ * tree. Two archives mounted at the same place (or an archive with files
+ * overlapping another mountpoint) may have overlapping files: in such a case,
+ * the file earliest in the search path is selected, and the other files are
+ * inaccessible to the application. This allows archives to be used to
+ * override previous revisions; you can use the mounting mechanism to place
+ * archives at a specific point in the file tree and prevent overlap; this
+ * is useful for downloadable mods that might trample over application data
+ * or each other, for example.
+ *
+ * The mountpoint does not need to exist prior to mounting, which is different
+ * than those familiar with the Unix concept of "mounting" may not expect.
+ * As well, more than one archive can be mounted to the same mountpoint, or
+ * mountpoints and archive contents can overlap...the interpolation mechanism
+ * still functions as usual.
+ *
+ * \param newDir directory or archive to add to the path, in
+ * platform-dependent notation.
+ * \param mountPoint Location in the interpolated tree that this archive
+ * will be "mounted", in platform-independent notation.
+ * NULL or "" is equivalent to "/".
+ * \param appendToPath nonzero to append to search path, zero to prepend.
+ * \return nonzero if added to path, zero on failure (bogus archive, dir
+ * missing, etc). Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_removeFromSearchPath
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_getMountPoint
+ * \sa PHYSFS_mountIo
+ */
+PHYSFS_DECL int PHYSFS_mount(const char *newDir,
+ const char *mountPoint,
+ int appendToPath);
+
+/**
+ * \fn int PHYSFS_getMountPoint(const char *dir)
+ * \brief Determine a mounted archive's mountpoint.
+ *
+ * You give this function the name of an archive or dir you successfully
+ * added to the search path, and it reports the location in the interpolated
+ * tree where it is mounted. Files mounted with a NULL mountpoint or through
+ * PHYSFS_addToSearchPath() will report "/". The return value is READ ONLY
+ * and valid until the archive is removed from the search path.
+ *
+ * \param dir directory or archive previously added to the path, in
+ * platform-dependent notation. This must match the string
+ * used when adding, even if your string would also reference
+ * the same file with a different string of characters.
+ * \return READ-ONLY string of mount point if added to path, NULL on failure
+ * (bogus archive, etc) Specifics of the error can be gleaned from
+ * PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_removeFromSearchPath
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_getMountPoint
+ */
+PHYSFS_DECL const char *PHYSFS_getMountPoint(const char *dir);
+
+
+#ifndef SWIG /* not available from scripting languages. */
+
+/**
+ * \typedef PHYSFS_StringCallback
+ * \brief Function signature for callbacks that report strings.
+ *
+ * These are used to report a list of strings to an original caller, one
+ * string per callback. All strings are UTF-8 encoded. Functions should not
+ * try to modify or free the string's memory.
+ *
+ * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to
+ * functions that would return lists that need to be cleaned up with
+ * PHYSFS_freeList(). The callback means that the library doesn't need to
+ * allocate an entire list and all the strings up front.
+ *
+ * Be aware that promises data ordering in the list versions are not
+ * necessarily so in the callback versions. Check the documentation on
+ * specific APIs, but strings may not be sorted as you expect.
+ *
+ * \param data User-defined data pointer, passed through from the API
+ * that eventually called the callback.
+ * \param str The string data about which the callback is meant to inform.
+ *
+ * \sa PHYSFS_getCdRomDirsCallback
+ * \sa PHYSFS_getSearchPathCallback
+ */
+typedef void (*PHYSFS_StringCallback)(void *data, const char *str);
+
+
+/**
+ * \typedef PHYSFS_EnumFilesCallback
+ * \brief Function signature for callbacks that enumerate files.
+ *
+ * These are used to report a list of directory entries to an original caller,
+ * one file/dir/symlink per callback. All strings are UTF-8 encoded.
+ * Functions should not try to modify or free any string's memory.
+ *
+ * These callbacks are used, starting in PhysicsFS 1.1, as an alternative to
+ * functions that would return lists that need to be cleaned up with
+ * PHYSFS_freeList(). The callback means that the library doesn't need to
+ * allocate an entire list and all the strings up front.
+ *
+ * Be aware that promises data ordering in the list versions are not
+ * necessarily so in the callback versions. Check the documentation on
+ * specific APIs, but strings may not be sorted as you expect.
+ *
+ * \param data User-defined data pointer, passed through from the API
+ * that eventually called the callback.
+ * \param origdir A string containing the full path, in platform-independent
+ * notation, of the directory containing this file. In most
+ * cases, this is the directory on which you requested
+ * enumeration, passed in the callback for your convenience.
+ * \param fname The filename that is being enumerated. It may not be in
+ * alphabetical order compared to other callbacks that have
+ * fired, and it will not contain the full path. You can
+ * recreate the fullpath with $origdir/$fname ... The file
+ * can be a subdirectory, a file, a symlink, etc.
+ *
+ * \sa PHYSFS_enumerateFilesCallback
+ */
+typedef void (*PHYSFS_EnumFilesCallback)(void *data, const char *origdir,
+ const char *fname);
+
+
+/**
+ * \fn void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d)
+ * \brief Enumerate CD-ROM directories, using an application-defined callback.
+ *
+ * Internally, PHYSFS_getCdRomDirs() just calls this function and then builds
+ * a list before returning to the application, so functionality is identical
+ * except for how the information is represented to the application.
+ *
+ * Unlike PHYSFS_getCdRomDirs(), this function does not return an array.
+ * Rather, it calls a function specified by the application once per
+ * detected disc:
+ *
+ * \code
+ *
+ * static void foundDisc(void *data, const char *cddir)
+ * {
+ * printf("cdrom dir [%s] is available.\n", cddir);
+ * }
+ *
+ * // ...
+ * PHYSFS_getCdRomDirsCallback(foundDisc, NULL);
+ * \endcode
+ *
+ * This call may block while drives spin up. Be forewarned.
+ *
+ * \param c Callback function to notify about detected drives.
+ * \param d Application-defined data passed to callback. Can be NULL.
+ *
+ * \sa PHYSFS_StringCallback
+ * \sa PHYSFS_getCdRomDirs
+ */
+PHYSFS_DECL void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d);
+
+
+/**
+ * \fn void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d)
+ * \brief Enumerate the search path, using an application-defined callback.
+ *
+ * Internally, PHYSFS_getSearchPath() just calls this function and then builds
+ * a list before returning to the application, so functionality is identical
+ * except for how the information is represented to the application.
+ *
+ * Unlike PHYSFS_getSearchPath(), this function does not return an array.
+ * Rather, it calls a function specified by the application once per
+ * element of the search path:
+ *
+ * \code
+ *
+ * static void printSearchPath(void *data, const char *pathItem)
+ * {
+ * printf("[%s] is in the search path.\n", pathItem);
+ * }
+ *
+ * // ...
+ * PHYSFS_getSearchPathCallback(printSearchPath, NULL);
+ * \endcode
+ *
+ * Elements of the search path are reported in order search priority, so the
+ * first archive/dir that would be examined when looking for a file is the
+ * first element passed through the callback.
+ *
+ * \param c Callback function to notify about search path elements.
+ * \param d Application-defined data passed to callback. Can be NULL.
+ *
+ * \sa PHYSFS_StringCallback
+ * \sa PHYSFS_getSearchPath
+ */
+PHYSFS_DECL void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d);
+
+
+/**
+ * \fn void PHYSFS_enumerateFilesCallback(const char *dir, PHYSFS_EnumFilesCallback c, void *d)
+ * \brief Get a file listing of a search path's directory, using an application-defined callback.
+ *
+ * Internally, PHYSFS_enumerateFiles() just calls this function and then builds
+ * a list before returning to the application, so functionality is identical
+ * except for how the information is represented to the application.
+ *
+ * Unlike PHYSFS_enumerateFiles(), this function does not return an array.
+ * Rather, it calls a function specified by the application once per
+ * element of the search path:
+ *
+ * \code
+ *
+ * static void printDir(void *data, const char *origdir, const char *fname)
+ * {
+ * printf(" * We've got [%s] in [%s].\n", fname, origdir);
+ * }
+ *
+ * // ...
+ * PHYSFS_enumerateFilesCallback("/some/path", printDir, NULL);
+ * \endcode
+ *
+ * !!! FIXME: enumerateFiles() does not promise alphabetical sorting by
+ * !!! FIXME: case-sensitivity in the code, and doesn't promise sorting at
+ * !!! FIXME: all in the above docs.
+ *
+ * Items sent to the callback are not guaranteed to be in any order whatsoever.
+ * There is no sorting done at this level, and if you need that, you should
+ * probably use PHYSFS_enumerateFiles() instead, which guarantees
+ * alphabetical sorting. This form reports whatever is discovered in each
+ * archive before moving on to the next. Even within one archive, we can't
+ * guarantee what order it will discover data. <em>Any sorting you find in
+ * these callbacks is just pure luck. Do not rely on it.</em> As this walks
+ * the entire list of archives, you may receive duplicate filenames.
+ *
+ * \param dir Directory, in platform-independent notation, to enumerate.
+ * \param c Callback function to notify about search path elements.
+ * \param d Application-defined data passed to callback. Can be NULL.
+ *
+ * \sa PHYSFS_EnumFilesCallback
+ * \sa PHYSFS_enumerateFiles
+ */
+PHYSFS_DECL void PHYSFS_enumerateFilesCallback(const char *dir,
+ PHYSFS_EnumFilesCallback c,
+ void *d);
+
+/**
+ * \fn void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
+ * \brief Convert a UCS-4 string to a UTF-8 string.
+ *
+ * UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is the same size as the source buffer. UTF-8
+ * never uses more than 32-bits per character, so while it may shrink a UCS-4
+ * string, it will never expand it.
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UTF-8
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * \param src Null-terminated source string in UCS-4 format.
+ * \param dst Buffer to store converted UTF-8 string.
+ * \param len Size, in bytes, of destination buffer.
+ */
+PHYSFS_DECL void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
+ * \brief Convert a UTF-8 string to a UCS-4 string.
+ *
+ * UCS-4 strings are 32-bits per character: \c wchar_t on Unix.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is four times the size of the source buffer.
+ * UTF-8 uses from one to four bytes per character, but UCS-4 always uses
+ * four, so an entirely low-ASCII string will quadruple in size!
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UCS-4
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * \param src Null-terminated source string in UTF-8 format.
+ * \param dst Buffer to store converted UCS-4 string.
+ * \param len Size, in bytes, of destination buffer.
+ */
+PHYSFS_DECL void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+ * \brief Convert a UCS-2 string to a UTF-8 string.
+ *
+ * \warning you almost certainly should use PHYSFS_utf8FromUtf16(), which
+ * became available in PhysicsFS 2.1, unless you know what you're doing.
+ *
+ * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
+ * with Unicode support. Please note that modern versions of Windows use
+ * UTF-16, which is an extended form of UCS-2, and not UCS-2 itself. You
+ * almost certainly want PHYSFS_utf8FromUtf16() instead.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is double the size of the source buffer.
+ * UTF-8 never uses more than 32-bits per character, so while it may shrink
+ * a UCS-2 string, it may also expand it.
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UTF-8
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * \param src Null-terminated source string in UCS-2 format.
+ * \param dst Buffer to store converted UTF-8 string.
+ * \param len Size, in bytes, of destination buffer.
+ *
+ * \sa PHYSFS_utf8FromUtf16
+ */
+PHYSFS_DECL void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+ * \brief Convert a UTF-8 string to a UCS-2 string.
+ *
+ * \warning you almost certainly should use PHYSFS_utf8ToUtf16(), which
+ * became available in PhysicsFS 2.1, unless you know what you're doing.
+ *
+ * UCS-2 strings are 16-bits per character: \c TCHAR on Windows, when building
+ * with Unicode support. Please note that modern versions of Windows use
+ * UTF-16, which is an extended form of UCS-2, and not UCS-2 itself. You
+ * almost certainly want PHYSFS_utf8ToUtf16() instead, but you need to
+ * understand how that changes things, too.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is double the size of the source buffer.
+ * UTF-8 uses from one to four bytes per character, but UCS-2 always uses
+ * two, so an entirely low-ASCII string will double in size!
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UCS-2
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * \param src Null-terminated source string in UTF-8 format.
+ * \param dst Buffer to store converted UCS-2 string.
+ * \param len Size, in bytes, of destination buffer.
+ *
+ * \sa PHYSFS_utf8ToUtf16
+ */
+PHYSFS_DECL void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
+ * \brief Convert a UTF-8 string to a Latin1 string.
+ *
+ * Latin1 strings are 8-bits per character: a popular "high ASCII" encoding.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is double the size of the source buffer.
+ * UTF-8 expands latin1 codepoints over 127 from 1 to 2 bytes, so the string
+ * may grow in some cases.
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UTF-8
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * Please note that we do not supply a UTF-8 to Latin1 converter, since Latin1
+ * can't express most Unicode codepoints. It's a legacy encoding; you should
+ * be converting away from it at all times.
+ *
+ * \param src Null-terminated source string in Latin1 format.
+ * \param dst Buffer to store converted UTF-8 string.
+ * \param len Size, in bytes, of destination buffer.
+ */
+PHYSFS_DECL void PHYSFS_utf8FromLatin1(const char *src, char *dst,
+ PHYSFS_uint64 len);
+
+/* Everything above this line is part of the PhysicsFS 2.0 API. */
+
+/**
+ * \fn int PHYSFS_unmount(const char *oldDir)
+ * \brief Remove a directory or archive from the search path.
+ *
+ * This is functionally equivalent to PHYSFS_removeFromSearchPath(), but that
+ * function is deprecated to keep the vocabulary paired with PHYSFS_mount().
+ *
+ * This must be a (case-sensitive) match to a dir or archive already in the
+ * search path, specified in platform-dependent notation.
+ *
+ * This call will fail (and fail to remove from the path) if the element still
+ * has files open in it.
+ *
+ * \param oldDir dir/archive to remove.
+ * \return nonzero on success, zero on failure.
+ * Specifics of the error can be gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_mount
+ */
+PHYSFS_DECL int PHYSFS_unmount(const char *oldDir);
+
+/**
+ * \fn const PHYSFS_Allocator *PHYSFS_getAllocator(void)
+ * \brief Discover the current allocator.
+ *
+ * (This is for limited, hardcore use. If you don't immediately see a need
+ * for it, you can probably ignore this forever.)
+ *
+ * This function exposes the function pointers that make up the currently used
+ * allocator. This can be useful for apps that want to access PhysicsFS's
+ * internal, default allocation routines, as well as for external code that
+ * wants to share the same allocator, even if the application specified their
+ * own.
+ *
+ * This call is only valid between PHYSFS_init() and PHYSFS_deinit() calls;
+ * it will return NULL if the library isn't initialized. As we can't
+ * guarantee the state of the internal allocators unless the library is
+ * initialized, you shouldn't use any allocator returned here after a call
+ * to PHYSFS_deinit().
+ *
+ * Do not call the returned allocator's Init() or Deinit() methods under any
+ * circumstances.
+ *
+ * If you aren't immediately sure what to do with this function, you can
+ * safely ignore it altogether.
+ *
+ * \return Current allocator, as set by PHYSFS_setAllocator(), or PhysicsFS's
+ * internal, default allocator if no application defined allocator
+ * is currently set. Will return NULL if the library is not
+ * initialized.
+ *
+ * \sa PHYSFS_Allocator
+ * \sa PHYSFS_setAllocator
+ */
+PHYSFS_DECL const PHYSFS_Allocator *PHYSFS_getAllocator(void);
+
+#endif /* SWIG */
+
+/**
+ * \enum PHYSFS_FileType
+ * \brief Type of a File
+ *
+ * Possible types of a file.
+ *
+ * \sa PHYSFS_stat
+ */
+typedef enum PHYSFS_FileType
+{
+ PHYSFS_FILETYPE_REGULAR, /**< a normal file */
+ PHYSFS_FILETYPE_DIRECTORY, /**< a directory */
+ PHYSFS_FILETYPE_SYMLINK, /**< a symlink */
+ PHYSFS_FILETYPE_OTHER /**< something completely different like a device */
+} PHYSFS_FileType;
+
+/**
+ * \struct PHYSFS_Stat
+ * \brief Meta data for a file or directory
+ *
+ * Container for various meta data about a file in the virtual file system.
+ * PHYSFS_stat() uses this structure for returning the information. The time
+ * data will be either the number of seconds since the Unix epoch (midnight,
+ * Jan 1, 1970), or -1 if the information isn't available or applicable.
+ * The (filesize) field is measured in bytes.
+ * The (readonly) field tells you whether when you open a file for writing you
+ * are writing to the same file as if you were opening it, given you have
+ * enough filesystem rights to do that. !!! FIXME: this might change.
+ *
+ * \sa PHYSFS_stat
+ * \sa PHYSFS_FileType
+ */
+typedef struct PHYSFS_Stat
+{
+ PHYSFS_sint64 filesize; /**< size in bytes, -1 for non-files and unknown */
+ PHYSFS_sint64 modtime; /**< last modification time */
+ PHYSFS_sint64 createtime; /**< like modtime, but for file creation time */
+ PHYSFS_sint64 accesstime; /**< like modtime, but for file access time */
+ PHYSFS_FileType filetype; /**< File? Directory? Symlink? */
+ int readonly; /**< non-zero if read only, zero if writable. */
+} PHYSFS_Stat;
+
+/**
+ * \fn int PHYSFS_stat(const char *fname, PHYSFS_Stat *stat)
+ * \brief Get various information about a directory or a file.
+ *
+ * Obtain various information about a file or directory from the meta data.
+ *
+ * This function will never follow symbolic links. If you haven't enabled
+ * symlinks with PHYSFS_permitSymbolicLinks(), stat'ing a symlink will be
+ * treated like stat'ing a non-existant file. If symlinks are enabled,
+ * stat'ing a symlink will give you information on the link itself and not
+ * what it points to.
+ *
+ * \param fname filename to check, in platform-indepedent notation.
+ * \param stat pointer to structure to fill in with data about (fname).
+ * \return non-zero on success, zero on failure. On failure, (stat)'s
+ * contents are undefined.
+ *
+ * \sa PHYSFS_Stat
+ */
+PHYSFS_DECL int PHYSFS_stat(const char *fname, PHYSFS_Stat *stat);
+
+
+#ifndef SWIG /* not available from scripting languages. */
+
+/**
+ * \fn void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+ * \brief Convert a UTF-16 string to a UTF-8 string.
+ *
+ * UTF-16 strings are 16-bits per character (except some chars, which are
+ * 32-bits): \c TCHAR on Windows, when building with Unicode support. Modern
+ * Windows releases use UTF-16. Windows releases before 2000 used TCHAR, but
+ * only handled UCS-2. UTF-16 _is_ UCS-2, except for the characters that
+ * are 4 bytes, which aren't representable in UCS-2 at all anyhow. If you
+ * aren't sure, you should be using UTF-16 at this point on Windows.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is double the size of the source buffer.
+ * UTF-8 never uses more than 32-bits per character, so while it may shrink
+ * a UTF-16 string, it may also expand it.
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UTF-8
+ * sequence at the end. If the buffer length is 0, this function does nothing.
+ *
+ * \param src Null-terminated source string in UTF-16 format.
+ * \param dst Buffer to store converted UTF-8 string.
+ * \param len Size, in bytes, of destination buffer.
+ */
+PHYSFS_DECL void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+ * \brief Convert a UTF-8 string to a UTF-16 string.
+ *
+ * UTF-16 strings are 16-bits per character (except some chars, which are
+ * 32-bits): \c TCHAR on Windows, when building with Unicode support. Modern
+ * Windows releases use UTF-16. Windows releases before 2000 used TCHAR, but
+ * only handled UCS-2. UTF-16 _is_ UCS-2, except for the characters that
+ * are 4 bytes, which aren't representable in UCS-2 at all anyhow. If you
+ * aren't sure, you should be using UTF-16 at this point on Windows.
+ *
+ * To ensure that the destination buffer is large enough for the conversion,
+ * please allocate a buffer that is double the size of the source buffer.
+ * UTF-8 uses from one to four bytes per character, but UTF-16 always uses
+ * two to four, so an entirely low-ASCII string will double in size! The
+ * UTF-16 characters that would take four bytes also take four bytes in UTF-8,
+ * so you don't need to allocate 4x the space just in case: double will do.
+ *
+ * Strings that don't fit in the destination buffer will be truncated, but
+ * will always be null-terminated and never have an incomplete UTF-16
+ * surrogate pair at the end. If the buffer length is 0, this function does
+ * nothing.
+ *
+ * \param src Null-terminated source string in UTF-8 format.
+ * \param dst Buffer to store converted UTF-16 string.
+ * \param len Size, in bytes, of destination buffer.
+ *
+ * \sa PHYSFS_utf8ToUtf16
+ */
+PHYSFS_DECL void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst,
+ PHYSFS_uint64 len);
+
+#endif /* SWIG */
+
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer, PHYSFS_uint64 len)
+ * \brief Read bytes from a PhysicsFS filehandle
+ *
+ * The file must be opened for reading.
+ *
+ * \param handle handle returned from PHYSFS_openRead().
+ * \param buffer buffer of at least (len) bytes to store read data into.
+ * \param len number of bytes being read from (handle).
+ * \return number of bytes read. This may be less than (len); this does not
+ * signify an error, necessarily (a short read may mean EOF).
+ * PHYSFS_getLastError() can shed light on the reason this might
+ * be < (len), as can PHYSFS_eof(). -1 if complete failure.
+ *
+ * \sa PHYSFS_eof
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer,
+ PHYSFS_uint64 len);
+
+/**
+ * \fn PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle, const void *buffer, PHYSFS_uint64 len)
+ * \brief Write data to a PhysicsFS filehandle
+ *
+ * The file must be opened for writing.
+ *
+ * Please note that while (len) is an unsigned 64-bit integer, you are limited
+ * to 63 bits (9223372036854775807 bytes), so we can return a negative value
+ * on error. If length is greater than 0x7FFFFFFFFFFFFFFF, this function will
+ * immediately fail. For systems without a 64-bit datatype, you are limited
+ * to 31 bits (0x7FFFFFFF, or 2147483647 bytes). We trust most things won't
+ * need to do multiple gigabytes of i/o in one call anyhow, but why limit
+ * things?
+ *
+ * \param handle retval from PHYSFS_openWrite() or PHYSFS_openAppend().
+ * \param buffer buffer of (len) bytes to write to (handle).
+ * \param len number of bytes being written to (handle).
+ * \return number of bytes written. This may be less than (len); in the case
+ * of an error, the system may try to write as many bytes as possible,
+ * so an incomplete write might occur. PHYSFS_getLastError() can shed
+ * light on the reason this might be < (len). -1 if complete failure.
+ */
+PHYSFS_DECL PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle,
+ const void *buffer,
+ PHYSFS_uint64 len);
+
+
+#ifndef SWIG /* not available from scripting languages. */
+
+/**
+ * \struct PHYSFS_Io
+ * \brief An abstract i/o interface.
+ *
+ * \warning This is advanced, hardcore stuff. You don't need this unless you
+ * really know what you're doing. Most apps will not need this.
+ *
+ * Historically, PhysicsFS provided access to the physical filesystem and
+ * archives within that filesystem. However, sometimes you need more power
+ * than this. Perhaps you need to provide an archive that is entirely
+ * contained in RAM, or you need to bridge some other file i/o API to
+ * PhysicsFS, or you need to translate the bits (perhaps you have a
+ * a standard .zip file that's encrypted, and you need to decrypt on the fly
+ * for the unsuspecting zip archiver).
+ *
+ * A PHYSFS_Io is the interface that Archivers use to get archive data.
+ * Historically, this has mapped to file i/o to the physical filesystem, but
+ * as of PhysicsFS 2.1, applications can provide their own i/o implementations
+ * at runtime.
+ *
+ * This interface isn't necessarily a good universal fit for i/o. There are a
+ * few requirements of note:
+ *
+ * - They only do blocking i/o (at least, for now).
+ * - They need to be able to duplicate. If you have a file handle from
+ * fopen(), you need to be able to create a unique clone of it (so we
+ * have two handles to the same file that can both seek/read/etc without
+ * stepping on each other).
+ * - They need to know the size of their entire data set.
+ * - They need to be able to seek and rewind on demand.
+ *
+ * ...in short, you're probably not going to write an HTTP implementation.
+ *
+ * Thread safety: TO BE DECIDED. !!! FIXME
+ *
+ * \sa PHYSFS_mountIo
+ */
+typedef struct PHYSFS_Io
+{
+ /**
+ * \brief Binary compatibility information.
+ *
+ * This must be set to zero at this time. Future versions of this
+ * struct will increment this field, so we know what a given
+ * implementation supports. We'll presumably keep supporting older
+ * versions as we offer new features, though.
+ */
+ PHYSFS_uint32 version;
+
+ /**
+ * \brief Instance data for this struct.
+ *
+ * Each instance has a pointer associated with it that can be used to
+ * store anything it likes. This pointer is per-instance of the stream,
+ * so presumably it will change when calling duplicate(). This can be
+ * deallocated during the destroy() method.
+ */
+ void *opaque;
+
+ /**
+ * \brief Read more data.
+ *
+ * Read (len) bytes from the interface, at the current i/o position, and
+ * store them in (buffer). The current i/o position should move ahead
+ * by the number of bytes successfully read.
+ *
+ * You don't have to implement this; set it to NULL if not implemented.
+ * This will only be used if the file is opened for reading. If set to
+ * NULL, a default implementation that immediately reports failure will
+ * be used.
+ *
+ * \param io The i/o instance to read from.
+ * \param buf The buffer to store data into. It must be at least
+ * (len) bytes long and can't be NULL.
+ * \param len The number of bytes to read from the interface.
+ * \return number of bytes read from file, 0 on EOF, -1 if complete
+ * failure.
+ */
+ PHYSFS_sint64 (*read)(struct PHYSFS_Io *io, void *buf, PHYSFS_uint64 len);
+
+ /**
+ * \brief Write more data.
+ *
+ * Write (len) bytes from (buffer) to the interface at the current i/o
+ * position. The current i/o position should move ahead by the number of
+ * bytes successfully written.
+ *
+ * You don't have to implement this; set it to NULL if not implemented.
+ * This will only be used if the file is opened for writing. If set to
+ * NULL, a default implementation that immediately reports failure will
+ * be used.
+ *
+ * You are allowed to buffer; a write can succeed here and then later
+ * fail when flushing. Note that PHYSFS_setBuffer() may be operating a
+ * level above your i/o, so you should usually not implement your
+ * own buffering routines.
+ *
+ * \param io The i/o instance to write to.
+ * \param buffer The buffer to read data from. It must be at least
+ * (len) bytes long and can't be NULL.
+ * \param len The number of bytes to read from (buffer).
+ * \return number of bytes written to file, -1 if complete failure.
+ */
+ PHYSFS_sint64 (*write)(struct PHYSFS_Io *io, const void *buffer,
+ PHYSFS_uint64 len);
+
+ /**
+ * \brief Move i/o position to a given byte offset from start.
+ *
+ * This method moves the i/o position, so the next read/write will
+ * be of the byte at (offset) offset. Seeks past the end of file should
+ * be treated as an error condition.
+ *
+ * \param io The i/o instance to seek.
+ * \param offset The new byte offset for the i/o position.
+ * \return non-zero on success, zero on error.
+ */
+ int (*seek)(struct PHYSFS_Io *io, PHYSFS_uint64 offset);
+
+ /**
+ * \brief Report current i/o position.
+ *
+ * Return bytes offset, or -1 if you aren't able to determine. A failure
+ * will almost certainly be fatal to further use of this stream, so you
+ * may not leave this unimplemented.
+ *
+ * \param io The i/o instance to query.
+ * \return The current byte offset for the i/o position, -1 if unknown.
+ */
+ PHYSFS_sint64 (*tell)(struct PHYSFS_Io *io);
+
+ /**
+ * \brief Determine size of the i/o instance's dataset.
+ *
+ * Return number of bytes available in the file, or -1 if you
+ * aren't able to determine. A failure will almost certainly be fatal
+ * to further use of this stream, so you may not leave this unimplemented.
+ *
+ * \param io The i/o instance to query.
+ * \return Total size, in bytes, of the dataset.
+ */
+ PHYSFS_sint64 (*length)(struct PHYSFS_Io *io);
+
+ /**
+ * \brief Duplicate this i/o instance.
+ *
+ * // !!! FIXME: write me.
+ *
+ * \param io The i/o instance to duplicate.
+ * \return A new value for a stream's (opaque) field, or NULL on error.
+ */
+ struct PHYSFS_Io *(*duplicate)(struct PHYSFS_Io *io);
+
+ /**
+ * \brief Flush resources to media, or wherever.
+ *
+ * This is the chance to report failure for writes that had claimed
+ * success earlier, but still had a chance to actually fail. This method
+ * can be NULL if flushing isn't necessary.
+ *
+ * This function may be called before destroy(), as it can report failure
+ * and destroy() can not. It may be called at other times, too.
+ *
+ * \param io The i/o instance to flush.
+ * \return Zero on error, non-zero on success.
+ */
+ int (*flush)(struct PHYSFS_Io *io);
+
+ /**
+ * \brief Cleanup and deallocate i/o instance.
+ *
+ * Free associated resources, including (opaque) if applicable.
+ *
+ * This function must always succeed: as such, it returns void. The
+ * system may call your flush() method before this. You may report
+ * failure there if necessary. This method may still be called if
+ * flush() fails, in which case you'll have to abandon unflushed data
+ * and other failing conditions and clean up.
+ *
+ * Once this method is called for a given instance, the system will assume
+ * it is unsafe to touch that instance again and will discard any
+ * references to it.
+ *
+ * \param s The i/o instance to destroy.
+ */
+ void (*destroy)(struct PHYSFS_Io *io);
+} PHYSFS_Io;
+
+
+/**
+ * \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname, const char *mountPoint, int appendToPath)
+ * \brief Add an archive, built on a PHYSFS_Io, to the search path.
+ *
+ * \warning Unless you have some special, low-level need, you should be using
+ * PHYSFS_mount() instead of this.
+ *
+ * This function operates just like PHYSFS_mount(), but takes a PHYSFS_Io
+ * instead of a pathname. Behind the scenes, PHYSFS_mount() calls this
+ * function with a physical-filesystem-based PHYSFS_Io.
+ *
+ * (filename) is only used here to optimize archiver selection (if you name it
+ * XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
+ * need to refer to a real file at all, and can even be NULL. If the filename
+ * isn't helpful, the system will try every archiver until one works or none
+ * of them do.
+ *
+ * (io) must remain until the archive is unmounted. When the archive is
+ * unmounted, the system will call (io)->destroy(io), which will give you
+ * a chance to free your resources.
+ *
+ * If this function fails, (io)->destroy(io) is not called.
+ *
+ * \param io i/o instance for archive to add to the path.
+ * \param fname Filename that can represent this stream. Can be NULL.
+ * \param mountPoint Location in the interpolated tree that this archive
+ * will be "mounted", in platform-independent notation.
+ * NULL or "" is equivalent to "/".
+ * \param appendToPath nonzero to append to search path, zero to prepend.
+ * \return nonzero if added to path, zero on failure (bogus archive, stream
+ * i/o issue, etc). Specifics of the error can be
+ * gleaned from PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_unmount
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_getMountPoint
+ */
+PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
+ const char *mountPoint, int appendToPath);
+
+#endif /* SWIG */
+
+/**
+ * \fn int PHYSFS_mountMemory(const void *ptr, PHYSFS_uint64 len, void (*del)(void *), const char *fname, const char *mountPoint, int appendToPath)
+ * \brief Add an archive, contained in a memory buffer, to the search path.
+ *
+ * \warning Unless you have some special, low-level need, you should be using
+ * PHYSFS_mount() instead of this.
+ *
+ * This function operates just like PHYSFS_mount(), but takes a memory buffer
+ * instead of a pathname. This buffer contains all the data of the archive,
+ * and is used instead of a real file in the physical filesystem.
+ *
+ * (filename) is only used here to optimize archiver selection (if you name it
+ * XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
+ * need to refer to a real file at all, and can even be NULL. If the filename
+ * isn't helpful, the system will try every archiver until one works or none
+ * of them do.
+ *
+ * (ptr) must remain until the archive is unmounted. When the archive is
+ * unmounted, the system will call (del)(ptr), which will notify you that
+ * the system is done with the buffer, and give you a chance to free your
+ * resources. (del) can be NULL, in which case the system will make no
+ * attempt to free the buffer.
+ *
+ * If this function fails, (del) is not called.
+ *
+ * \param ptr Address of the memory buffer containing the archive data.
+ * \param len Size of memory buffer, in bytes.
+ * \param del A callback that triggers upon unmount. Can be NULL.
+ * \param fname Filename that can represent this stream. Can be NULL.
+ * \param mountPoint Location in the interpolated tree that this archive
+ * will be "mounted", in platform-independent notation.
+ * NULL or "" is equivalent to "/".
+ * \param appendToPath nonzero to append to search path, zero to prepend.
+ * \return nonzero if added to path, zero on failure (bogus archive, etc).
+ * Specifics of the error can be gleaned from
+ * PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_unmount
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_getMountPoint
+ */
+PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
+ void (*del)(void *), const char *fname,
+ const char *mountPoint, int appendToPath);
+
+
+/**
+ * \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname, const char *mountPoint, int appendToPath)
+ * \brief Add an archive, contained in a PHYSFS_File handle, to the search path.
+ *
+ * \warning Unless you have some special, low-level need, you should be using
+ * PHYSFS_mount() instead of this.
+ *
+ * \warning Archives-in-archives may be very slow! While a PHYSFS_File can
+ * seek even when the data is compressed, it may do so by rewinding
+ * to the start and decompressing everything before the seek point.
+ * Normal archive usage may do a lot of seeking behind the scenes.
+ * As such, you might find normal archive usage extremely painful
+ * if mounted this way. Plan accordingly: if you, say, have a
+ * self-extracting .zip file, and want to mount something in it,
+ * compress the contents of the inner archive and make sure the outer
+ * .zip file doesn't compress the inner archive too.
+ *
+ * This function operates just like PHYSFS_mount(), but takes a PHYSFS_File
+ * handle instead of a pathname. This handle contains all the data of the
+ * archive, and is used instead of a real file in the physical filesystem.
+ * The PHYSFS_File may be backed by a real file in the physical filesystem,
+ * but isn't necessarily. The most popular use for this is likely to mount
+ * archives stored inside other archives.
+ *
+ * (filename) is only used here to optimize archiver selection (if you name it
+ * XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
+ * need to refer to a real file at all, and can even be NULL. If the filename
+ * isn't helpful, the system will try every archiver until one works or none
+ * of them do.
+ *
+ * (file) must remain until the archive is unmounted. When the archive is
+ * unmounted, the system will call PHYSFS_close(file). If you need this
+ * handle to survive, you will have to wrap this in a PHYSFS_Io and use
+ * PHYSFS_mountIo() instead.
+ *
+ * If this function fails, PHYSFS_close(file) is not called.
+ *
+ * \param file The PHYSFS_File handle containing archive data.
+ * \param fname Filename that can represent this stream. Can be NULL.
+ * \param mountPoint Location in the interpolated tree that this archive
+ * will be "mounted", in platform-independent notation.
+ * NULL or "" is equivalent to "/".
+ * \param appendToPath nonzero to append to search path, zero to prepend.
+ * \return nonzero if added to path, zero on failure (bogus archive, etc).
+ * Specifics of the error can be gleaned from
+ * PHYSFS_getLastError().
+ *
+ * \sa PHYSFS_unmount
+ * \sa PHYSFS_getSearchPath
+ * \sa PHYSFS_getMountPoint
+ */
+PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
+ const char *mountPoint, int appendToPath);
+
+
+/**
+ * \enum PHYSFS_ErrorCode
+ * \brief Values that represent specific causes of failure.
+ *
+ * Most of the time, you should only concern yourself with whether a given
+ * operation failed or not, but there may be occasions where you plan to
+ * handle a specific failure case gracefully, so we provide specific error
+ * codes.
+ *
+ * Most of these errors are a little vague, and most aren't things you can
+ * fix...if there's a permission error, for example, all you can really do
+ * is pass that information on to the user and let them figure out how to
+ * handle it. In most these cases, your program should only care that it
+ * failed to accomplish its goals, and not care specifically why.
+ *
+ * \sa PHYSFS_getLastErrorCode
+ * \sa PHYSFS_getErrorByCode
+ */
+typedef enum PHYSFS_ErrorCode
+{
+ PHYSFS_ERR_OK, /**< Success; no error. */
+ PHYSFS_ERR_OTHER_ERROR, /**< Error not otherwise covered here. */
+ PHYSFS_ERR_OUT_OF_MEMORY, /**< Memory allocation failed. */
+ PHYSFS_ERR_NOT_INITIALIZED, /**< PhysicsFS is not initialized. */
+ PHYSFS_ERR_IS_INITIALIZED, /**< PhysicsFS is already initialized. */
+ PHYSFS_ERR_ARGV0_IS_NULL, /**< Needed argv[0], but it is NULL. */
+ PHYSFS_ERR_UNSUPPORTED, /**< Operation or feature unsupported. */
+ PHYSFS_ERR_PAST_EOF, /**< Attempted to access past end of file. */
+ PHYSFS_ERR_FILES_STILL_OPEN, /**< Files still open. */
+ PHYSFS_ERR_INVALID_ARGUMENT, /**< Bad parameter passed to an function. */
+ PHYSFS_ERR_NOT_MOUNTED, /**< Requested archive/dir not mounted. */
+ PHYSFS_ERR_NO_SUCH_PATH, /**< No such file, directory, or parent. */
+ PHYSFS_ERR_SYMLINK_FORBIDDEN,/**< Symlink seen when not permitted. */
+ PHYSFS_ERR_NO_WRITE_DIR, /**< No write dir has been specified. */
+ PHYSFS_ERR_OPEN_FOR_READING, /**< Wrote to a file opened for reading. */
+ PHYSFS_ERR_OPEN_FOR_WRITING, /**< Read from a file opened for writing. */
+ PHYSFS_ERR_NOT_A_FILE, /**< Needed a file, got a directory (etc). */
+ PHYSFS_ERR_READ_ONLY, /**< Wrote to a read-only filesystem. */
+ PHYSFS_ERR_CORRUPT, /**< Corrupted data encountered. */
+ PHYSFS_ERR_SYMLINK_LOOP, /**< Infinite symbolic link loop. */
+ PHYSFS_ERR_IO, /**< i/o error (hardware failure, etc). */
+ PHYSFS_ERR_PERMISSION, /**< Permission denied. */
+ PHYSFS_ERR_NO_SPACE, /**< No space (disk full, over quota, etc) */
+ PHYSFS_ERR_BAD_FILENAME, /**< Filename is bogus/insecure. */
+ PHYSFS_ERR_BUSY, /**< Tried to modify a file the OS needs. */
+ PHYSFS_ERR_DIR_NOT_EMPTY, /**< Tried to delete dir with files in it. */
+ PHYSFS_ERR_OS_ERROR /**< Unspecified OS-level error. */
+} PHYSFS_ErrorCode;
+
+
+/**
+ * \fn PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
+ * \brief Get machine-readable error information.
+ *
+ * Get the last PhysicsFS error message as an integer value. This will return
+ * PHYSFS_ERR_OK if there's been no error since the last call to this
+ * function. Each thread has a unique error state associated with it, but
+ * each time a new error message is set, it will overwrite the previous one
+ * associated with that thread. It is safe to call this function at anytime,
+ * even before PHYSFS_init().
+ *
+ * PHYSFS_getLastError() and PHYSFS_getLastErrorCode() both reset the same
+ * thread-specific error state. Calling one will wipe out the other's
+ * data. If you need both, call PHYSFS_getLastErrorCode(), then pass that
+ * value to PHYSFS_getErrorByCode().
+ *
+ * Generally, applications should only concern themselves with whether a
+ * given function failed; however, if you require more specifics, you can
+ * try this function to glean information, if there's some specific problem
+ * you're expecting and plan to handle. But with most things that involve
+ * file systems, the best course of action is usually to give up, report the
+ * problem to the user, and let them figure out what should be done about it.
+ * For that, you might prefer PHYSFS_getLastError() instead.
+ *
+ * \return Enumeration value that represents last reported error.
+ *
+ * \sa PHYSFS_getErrorByCode
+ */
+PHYSFS_DECL PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void);
+
+
+/**
+ * \fn const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
+ * \brief Get human-readable description string for a given error code.
+ *
+ * Get a static string, in UTF-8 format, that represents an English
+ * description of a given error code.
+ *
+ * This string is guaranteed to never change (although we may add new strings
+ * for new error codes in later versions of PhysicsFS), so you can use it
+ * for keying a localization dictionary.
+ *
+ * It is safe to call this function at anytime, even before PHYSFS_init().
+ *
+ * These strings are meant to be passed on directly to the user.
+ * Generally, applications should only concern themselves with whether a
+ * given function failed, but not care about the specifics much.
+ *
+ * Do not attempt to free the returned strings; they are read-only and you
+ * don't own their memory pages.
+ *
+ * \param code Error code to convert to a string.
+ * \return READ ONLY string of requested error message, NULL if this
+ * is not a valid PhysicsFS error code. Always check for NULL if
+ * you might be looking up an error code that didn't exist in an
+ * earlier version of PhysicsFS.
+ *
+ * \sa PHYSFS_getLastErrorCode
+ */
+PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code);
+
+/**
+ * \fn void PHYSFS_setErrorCode(PHYSFS_ErrorCode code)
+ * \brief Set the current thread's error code.
+ *
+ * This lets you set the value that will be returned by the next call to
+ * PHYSFS_getLastErrorCode(). This will replace any existing error code,
+ * whether set by your application or internally by PhysicsFS.
+ *
+ * Error codes are stored per-thread; what you set here will not be
+ * accessible to another thread.
+ *
+ * Any call into PhysicsFS may change the current error code, so any code you
+ * set here is somewhat fragile, and thus you shouldn't build any serious
+ * error reporting framework on this function. The primary goal of this
+ * function is to allow PHYSFS_Io implementations to set the error state,
+ * which generally will be passed back to your application when PhysicsFS
+ * makes a PHYSFS_Io call that fails internally.
+ *
+ * This function doesn't care if the error code is a value known to PhysicsFS
+ * or not (but PHYSFS_getErrorByCode() will return NULL for unknown values).
+ * The value will be reported unmolested by PHYSFS_getLastErrorCode().
+ *
+ * \param code Error code to become the current thread's new error state.
+ *
+ * \sa PHYSFS_getLastErrorCode
+ * \sa PHYSFS_getErrorByCode
+ */
+PHYSFS_DECL void PHYSFS_setErrorCode(PHYSFS_ErrorCode code);
+
+
+/**
+ * \fn const char *PHYSFS_getPrefDir(const char *org, const char *app)
+ * \brief Get the user-and-app-specific path where files can be written.
+ *
+ * Helper function.
+ *
+ * Get the "pref dir". This is meant to be where users can write personal
+ * files (preferences and save games, etc) that are specific to your
+ * application. This directory is unique per user, per application.
+ *
+ * This function will decide the appropriate location in the native filesystem,
+ * create the directory if necessary, and return a string in
+ * platform-dependent notation, suitable for passing to PHYSFS_setWriteDir().
+ *
+ * On Windows, this might look like:
+ * "C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name"
+ *
+ * On Linux, this might look like:
+ * "/home/bob/.local/share/My Program Name"
+ *
+ * On Mac OS X, this might look like:
+ * "/Users/bob/Library/Application Support/My Program Name"
+ *
+ * (etc.)
+ *
+ * You should probably use the pref dir for your write dir, and also put it
+ * near the beginning of your search path. Older versions of PhysicsFS
+ * offered only PHYSFS_getUserDir() and left you to figure out where the
+ * files should go under that tree. This finds the correct location
+ * for whatever platform, which not only changes between operating systems,
+ * but also versions of the same operating system.
+ *
+ * You specify the name of your organization (if it's not a real organization,
+ * your name or an Internet domain you own might do) and the name of your
+ * application. These should be proper names.
+ *
+ * Both the (org) and (app) strings may become part of a directory name, so
+ * please follow these rules:
+ *
+ * - Try to use the same org string (including case-sensitivity) for
+ * all your applications that use this function.
+ * - Always use a unique app string for each one, and make sure it never
+ * changes for an app once you've decided on it.
+ * - Unicode characters are legal, as long as it's UTF-8 encoded, but...
+ * - ...only use letters, numbers, and spaces. Avoid punctuation like
+ * "Game Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient.
+ *
+ * The pointer returned by this function remains valid until you call this
+ * function again, or call PHYSFS_deinit(). This is not necessarily a fast
+ * call, though, so you should call this once at startup and copy the string
+ * if you need it.
+ *
+ * You should assume the path returned by this function is the only safe
+ * place to write files (and that PHYSFS_getUserDir() and PHYSFS_getBaseDir(),
+ * while they might be writable, or even parents of the returned path, aren't
+ * where you should be writing things).
+ *
+ * \param org The name of your organization.
+ * \param app The name of your application.
+ * \return READ ONLY string of user dir in platform-dependent notation. NULL
+ * if there's a problem (creating directory failed, etc).
+ *
+ * \sa PHYSFS_getBaseDir
+ * \sa PHYSFS_getUserDir
+ */
+PHYSFS_DECL const char *PHYSFS_getPrefDir(const char *org, const char *app);
+
+
+/* Everything above this line is part of the PhysicsFS 2.1 API. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined _INCLUDE_PHYSFS_H_ */
+
+/* end of physfs.h ... */
+
diff --git a/misc/libphysfs/physfs_byteorder.c b/misc/libphysfs/physfs_byteorder.c
new file mode 100644
index 0000000..b3706ff
--- /dev/null
+++ b/misc/libphysfs/physfs_byteorder.c
@@ -0,0 +1,137 @@
+/**
+ * PhysicsFS; a portable, flexible file i/o abstraction.
+ *
+ * Documentation is in physfs.h. It's verbose, honest. :)
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#ifndef PHYSFS_Swap16
+static inline PHYSFS_uint16 PHYSFS_Swap16(PHYSFS_uint16 D)
+{
+ return ((D<<8)|(D>>8));
+}
+#endif
+#ifndef PHYSFS_Swap32
+static inline PHYSFS_uint32 PHYSFS_Swap32(PHYSFS_uint32 D)
+{
+ return ((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
+}
+#endif
+#ifndef PHYSFS_NO_64BIT_SUPPORT
+#ifndef PHYSFS_Swap64
+static inline PHYSFS_uint64 PHYSFS_Swap64(PHYSFS_uint64 val) {
+ PHYSFS_uint32 hi, lo;
+
+ /* Separate into high and low 32-bit values and swap them */
+ lo = (PHYSFS_uint32)(val&0xFFFFFFFF);
+ val >>= 32;
+ hi = (PHYSFS_uint32)(val&0xFFFFFFFF);
+ val = PHYSFS_Swap32(lo);
+ val <<= 32;
+ val |= PHYSFS_Swap32(hi);
+ return val;
+}
+#endif
+#else
+#ifndef PHYSFS_Swap64
+/* This is mainly to keep compilers from complaining in PHYSFS code.
+ If there is no real 64-bit datatype, then compilers will complain about
+ the fake 64-bit datatype that PHYSFS provides when it compiles user code.
+*/
+#define PHYSFS_Swap64(X) (X)
+#endif
+#endif /* PHYSFS_NO_64BIT_SUPPORT */
+
+
+/* Byteswap item from the specified endianness to the native endianness */
+#if PHYSFS_BYTEORDER == PHYSFS_LIL_ENDIAN
+PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return x; }
+PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return x; }
+PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return x; }
+PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return x; }
+PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return x; }
+PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return x; }
+
+PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); }
+PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); }
+PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); }
+PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); }
+PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); }
+PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); }
+#else
+PHYSFS_uint16 PHYSFS_swapULE16(PHYSFS_uint16 x) { return PHYSFS_Swap16(x); }
+PHYSFS_sint16 PHYSFS_swapSLE16(PHYSFS_sint16 x) { return PHYSFS_Swap16(x); }
+PHYSFS_uint32 PHYSFS_swapULE32(PHYSFS_uint32 x) { return PHYSFS_Swap32(x); }
+PHYSFS_sint32 PHYSFS_swapSLE32(PHYSFS_sint32 x) { return PHYSFS_Swap32(x); }
+PHYSFS_uint64 PHYSFS_swapULE64(PHYSFS_uint64 x) { return PHYSFS_Swap64(x); }
+PHYSFS_sint64 PHYSFS_swapSLE64(PHYSFS_sint64 x) { return PHYSFS_Swap64(x); }
+
+PHYSFS_uint16 PHYSFS_swapUBE16(PHYSFS_uint16 x) { return x; }
+PHYSFS_sint16 PHYSFS_swapSBE16(PHYSFS_sint16 x) { return x; }
+PHYSFS_uint32 PHYSFS_swapUBE32(PHYSFS_uint32 x) { return x; }
+PHYSFS_sint32 PHYSFS_swapSBE32(PHYSFS_sint32 x) { return x; }
+PHYSFS_uint64 PHYSFS_swapUBE64(PHYSFS_uint64 x) { return x; }
+PHYSFS_sint64 PHYSFS_swapSBE64(PHYSFS_sint64 x) { return x; }
+#endif
+
+static inline int readAll(PHYSFS_File *file, void *val, const size_t len)
+{
+ return (PHYSFS_readBytes(file, val, len) == len);
+} /* readAll */
+
+#define PHYSFS_BYTEORDER_READ(datatype, swaptype) \
+ int PHYSFS_read##swaptype(PHYSFS_File *file, PHYSFS_##datatype *val) { \
+ PHYSFS_##datatype in; \
+ BAIL_IF_MACRO(val == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0); \
+ BAIL_IF_MACRO(!readAll(file, &in, sizeof (in)), ERRPASS, 0); \
+ *val = PHYSFS_swap##swaptype(in); \
+ return 1; \
+ }
+
+PHYSFS_BYTEORDER_READ(sint16, SLE16)
+PHYSFS_BYTEORDER_READ(uint16, ULE16)
+PHYSFS_BYTEORDER_READ(sint16, SBE16)
+PHYSFS_BYTEORDER_READ(uint16, UBE16)
+PHYSFS_BYTEORDER_READ(sint32, SLE32)
+PHYSFS_BYTEORDER_READ(uint32, ULE32)
+PHYSFS_BYTEORDER_READ(sint32, SBE32)
+PHYSFS_BYTEORDER_READ(uint32, UBE32)
+PHYSFS_BYTEORDER_READ(sint64, SLE64)
+PHYSFS_BYTEORDER_READ(uint64, ULE64)
+PHYSFS_BYTEORDER_READ(sint64, SBE64)
+PHYSFS_BYTEORDER_READ(uint64, UBE64)
+
+
+static inline int writeAll(PHYSFS_File *f, const void *val, const size_t len)
+{
+ return (PHYSFS_writeBytes(f, val, len) == len);
+} /* writeAll */
+
+#define PHYSFS_BYTEORDER_WRITE(datatype, swaptype) \
+ int PHYSFS_write##swaptype(PHYSFS_File *file, PHYSFS_##datatype val) { \
+ const PHYSFS_##datatype out = PHYSFS_swap##swaptype(val); \
+ BAIL_IF_MACRO(!writeAll(file, &out, sizeof (out)), ERRPASS, 0); \
+ return 1; \
+ }
+
+PHYSFS_BYTEORDER_WRITE(sint16, SLE16)
+PHYSFS_BYTEORDER_WRITE(uint16, ULE16)
+PHYSFS_BYTEORDER_WRITE(sint16, SBE16)
+PHYSFS_BYTEORDER_WRITE(uint16, UBE16)
+PHYSFS_BYTEORDER_WRITE(sint32, SLE32)
+PHYSFS_BYTEORDER_WRITE(uint32, ULE32)
+PHYSFS_BYTEORDER_WRITE(sint32, SBE32)
+PHYSFS_BYTEORDER_WRITE(uint32, UBE32)
+PHYSFS_BYTEORDER_WRITE(sint64, SLE64)
+PHYSFS_BYTEORDER_WRITE(uint64, ULE64)
+PHYSFS_BYTEORDER_WRITE(sint64, SBE64)
+PHYSFS_BYTEORDER_WRITE(uint64, UBE64)
+
+/* end of physfs_byteorder.c ... */
+
diff --git a/misc/libphysfs/physfs_casefolding.h b/misc/libphysfs/physfs_casefolding.h
new file mode 100644
index 0000000..0e50f1e
--- /dev/null
+++ b/misc/libphysfs/physfs_casefolding.h
@@ -0,0 +1,2013 @@
+/*
+ * This file is part of PhysicsFS (http://icculus.org/physfs/)
+ *
+ * This data generated by physfs/extras/makecasefoldhashtable.pl ...
+ * Do not manually edit this file!
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ */
+
+#ifndef __PHYSICSFS_INTERNAL__
+#error Do not include this header from your applications.
+#endif
+
+static const CaseFoldMapping case_fold_000[] = {
+ { 0x0202, 0x0203, 0x0000, 0x0000 },
+ { 0x0404, 0x0454, 0x0000, 0x0000 },
+ { 0x1E1E, 0x1E1F, 0x0000, 0x0000 },
+ { 0x2C2C, 0x2C5C, 0x0000, 0x0000 },
+ { 0x10404, 0x1042C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_001[] = {
+ { 0x0100, 0x0101, 0x0000, 0x0000 },
+ { 0x0405, 0x0455, 0x0000, 0x0000 },
+ { 0x0504, 0x0505, 0x0000, 0x0000 },
+ { 0x2C2D, 0x2C5D, 0x0000, 0x0000 },
+ { 0x10405, 0x1042D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_002[] = {
+ { 0x0200, 0x0201, 0x0000, 0x0000 },
+ { 0x0406, 0x0456, 0x0000, 0x0000 },
+ { 0x1E1C, 0x1E1D, 0x0000, 0x0000 },
+ { 0x1F1D, 0x1F15, 0x0000, 0x0000 },
+ { 0x2C2E, 0x2C5E, 0x0000, 0x0000 },
+ { 0x10406, 0x1042E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_003[] = {
+ { 0x0102, 0x0103, 0x0000, 0x0000 },
+ { 0x0407, 0x0457, 0x0000, 0x0000 },
+ { 0x0506, 0x0507, 0x0000, 0x0000 },
+ { 0x1F1C, 0x1F14, 0x0000, 0x0000 },
+ { 0x10407, 0x1042F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_004[] = {
+ { 0x0206, 0x0207, 0x0000, 0x0000 },
+ { 0x0400, 0x0450, 0x0000, 0x0000 },
+ { 0x1E1A, 0x1E1B, 0x0000, 0x0000 },
+ { 0x1F1B, 0x1F13, 0x0000, 0x0000 },
+ { 0x2C28, 0x2C58, 0x0000, 0x0000 },
+ { 0x10400, 0x10428, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_005[] = {
+ { 0x0104, 0x0105, 0x0000, 0x0000 },
+ { 0x0401, 0x0451, 0x0000, 0x0000 },
+ { 0x0500, 0x0501, 0x0000, 0x0000 },
+ { 0x1F1A, 0x1F12, 0x0000, 0x0000 },
+ { 0x2C29, 0x2C59, 0x0000, 0x0000 },
+ { 0x10401, 0x10429, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_006[] = {
+ { 0x0204, 0x0205, 0x0000, 0x0000 },
+ { 0x0402, 0x0452, 0x0000, 0x0000 },
+ { 0x1E18, 0x1E19, 0x0000, 0x0000 },
+ { 0x1F19, 0x1F11, 0x0000, 0x0000 },
+ { 0x2C2A, 0x2C5A, 0x0000, 0x0000 },
+ { 0x10402, 0x1042A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_007[] = {
+ { 0x0106, 0x0107, 0x0000, 0x0000 },
+ { 0x0403, 0x0453, 0x0000, 0x0000 },
+ { 0x0502, 0x0503, 0x0000, 0x0000 },
+ { 0x1F18, 0x1F10, 0x0000, 0x0000 },
+ { 0x2126, 0x03C9, 0x0000, 0x0000 },
+ { 0x2C2B, 0x2C5B, 0x0000, 0x0000 },
+ { 0x10403, 0x1042B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_008[] = {
+ { 0x020A, 0x020B, 0x0000, 0x0000 },
+ { 0x040C, 0x045C, 0x0000, 0x0000 },
+ { 0x1E16, 0x1E17, 0x0000, 0x0000 },
+ { 0x2C24, 0x2C54, 0x0000, 0x0000 },
+ { 0x1040C, 0x10434, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_009[] = {
+ { 0x0108, 0x0109, 0x0000, 0x0000 },
+ { 0x040D, 0x045D, 0x0000, 0x0000 },
+ { 0x050C, 0x050D, 0x0000, 0x0000 },
+ { 0x2C25, 0x2C55, 0x0000, 0x0000 },
+ { 0x1040D, 0x10435, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_010[] = {
+ { 0x0208, 0x0209, 0x0000, 0x0000 },
+ { 0x040E, 0x045E, 0x0000, 0x0000 },
+ { 0x1E14, 0x1E15, 0x0000, 0x0000 },
+ { 0x212B, 0x00E5, 0x0000, 0x0000 },
+ { 0x2C26, 0x2C56, 0x0000, 0x0000 },
+ { 0x1040E, 0x10436, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_011[] = {
+ { 0x010A, 0x010B, 0x0000, 0x0000 },
+ { 0x040F, 0x045F, 0x0000, 0x0000 },
+ { 0x050E, 0x050F, 0x0000, 0x0000 },
+ { 0x212A, 0x006B, 0x0000, 0x0000 },
+ { 0x2C27, 0x2C57, 0x0000, 0x0000 },
+ { 0x1040F, 0x10437, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_012[] = {
+ { 0x020E, 0x020F, 0x0000, 0x0000 },
+ { 0x0408, 0x0458, 0x0000, 0x0000 },
+ { 0x1E12, 0x1E13, 0x0000, 0x0000 },
+ { 0x2C20, 0x2C50, 0x0000, 0x0000 },
+ { 0x10408, 0x10430, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_013[] = {
+ { 0x010C, 0x010D, 0x0000, 0x0000 },
+ { 0x0409, 0x0459, 0x0000, 0x0000 },
+ { 0x0508, 0x0509, 0x0000, 0x0000 },
+ { 0x2C21, 0x2C51, 0x0000, 0x0000 },
+ { 0x10409, 0x10431, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_014[] = {
+ { 0x020C, 0x020D, 0x0000, 0x0000 },
+ { 0x040A, 0x045A, 0x0000, 0x0000 },
+ { 0x1E10, 0x1E11, 0x0000, 0x0000 },
+ { 0x2C22, 0x2C52, 0x0000, 0x0000 },
+ { 0x1040A, 0x10432, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_015[] = {
+ { 0x010E, 0x010F, 0x0000, 0x0000 },
+ { 0x040B, 0x045B, 0x0000, 0x0000 },
+ { 0x050A, 0x050B, 0x0000, 0x0000 },
+ { 0x2C23, 0x2C53, 0x0000, 0x0000 },
+ { 0x1040B, 0x10433, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_016[] = {
+ { 0x0212, 0x0213, 0x0000, 0x0000 },
+ { 0x0414, 0x0434, 0x0000, 0x0000 },
+ { 0x1E0E, 0x1E0F, 0x0000, 0x0000 },
+ { 0x1F0F, 0x1F07, 0x0000, 0x0000 },
+ { 0x10414, 0x1043C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_017[] = {
+ { 0x0110, 0x0111, 0x0000, 0x0000 },
+ { 0x0415, 0x0435, 0x0000, 0x0000 },
+ { 0x1F0E, 0x1F06, 0x0000, 0x0000 },
+ { 0x10415, 0x1043D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_018[] = {
+ { 0x0210, 0x0211, 0x0000, 0x0000 },
+ { 0x0416, 0x0436, 0x0000, 0x0000 },
+ { 0x1E0C, 0x1E0D, 0x0000, 0x0000 },
+ { 0x1F0D, 0x1F05, 0x0000, 0x0000 },
+ { 0x10416, 0x1043E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_019[] = {
+ { 0x0112, 0x0113, 0x0000, 0x0000 },
+ { 0x0417, 0x0437, 0x0000, 0x0000 },
+ { 0x1F0C, 0x1F04, 0x0000, 0x0000 },
+ { 0x10417, 0x1043F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_020[] = {
+ { 0x0216, 0x0217, 0x0000, 0x0000 },
+ { 0x0410, 0x0430, 0x0000, 0x0000 },
+ { 0x1E0A, 0x1E0B, 0x0000, 0x0000 },
+ { 0x1F0B, 0x1F03, 0x0000, 0x0000 },
+ { 0x10410, 0x10438, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_021[] = {
+ { 0x0114, 0x0115, 0x0000, 0x0000 },
+ { 0x0411, 0x0431, 0x0000, 0x0000 },
+ { 0x1F0A, 0x1F02, 0x0000, 0x0000 },
+ { 0x10411, 0x10439, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_022[] = {
+ { 0x0214, 0x0215, 0x0000, 0x0000 },
+ { 0x0412, 0x0432, 0x0000, 0x0000 },
+ { 0x1E08, 0x1E09, 0x0000, 0x0000 },
+ { 0x1F09, 0x1F01, 0x0000, 0x0000 },
+ { 0x10412, 0x1043A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_023[] = {
+ { 0x0116, 0x0117, 0x0000, 0x0000 },
+ { 0x0413, 0x0433, 0x0000, 0x0000 },
+ { 0x1F08, 0x1F00, 0x0000, 0x0000 },
+ { 0x10413, 0x1043B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_024[] = {
+ { 0x021A, 0x021B, 0x0000, 0x0000 },
+ { 0x041C, 0x043C, 0x0000, 0x0000 },
+ { 0x1E06, 0x1E07, 0x0000, 0x0000 },
+ { 0x1041C, 0x10444, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_025[] = {
+ { 0x0118, 0x0119, 0x0000, 0x0000 },
+ { 0x041D, 0x043D, 0x0000, 0x0000 },
+ { 0x1041D, 0x10445, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_026[] = {
+ { 0x0218, 0x0219, 0x0000, 0x0000 },
+ { 0x041E, 0x043E, 0x0000, 0x0000 },
+ { 0x1E04, 0x1E05, 0x0000, 0x0000 },
+ { 0x1041E, 0x10446, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_027[] = {
+ { 0x011A, 0x011B, 0x0000, 0x0000 },
+ { 0x041F, 0x043F, 0x0000, 0x0000 },
+ { 0x1041F, 0x10447, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_028[] = {
+ { 0x021E, 0x021F, 0x0000, 0x0000 },
+ { 0x0418, 0x0438, 0x0000, 0x0000 },
+ { 0x1E02, 0x1E03, 0x0000, 0x0000 },
+ { 0x10418, 0x10440, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_029[] = {
+ { 0x011C, 0x011D, 0x0000, 0x0000 },
+ { 0x0419, 0x0439, 0x0000, 0x0000 },
+ { 0x10419, 0x10441, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_030[] = {
+ { 0x021C, 0x021D, 0x0000, 0x0000 },
+ { 0x041A, 0x043A, 0x0000, 0x0000 },
+ { 0x1E00, 0x1E01, 0x0000, 0x0000 },
+ { 0x1041A, 0x10442, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_031[] = {
+ { 0x011E, 0x011F, 0x0000, 0x0000 },
+ { 0x041B, 0x043B, 0x0000, 0x0000 },
+ { 0x1041B, 0x10443, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_032[] = {
+ { 0x0222, 0x0223, 0x0000, 0x0000 },
+ { 0x0424, 0x0444, 0x0000, 0x0000 },
+ { 0x1E3E, 0x1E3F, 0x0000, 0x0000 },
+ { 0x1F3F, 0x1F37, 0x0000, 0x0000 },
+ { 0x2C0C, 0x2C3C, 0x0000, 0x0000 },
+ { 0x10424, 0x1044C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_033[] = {
+ { 0x0120, 0x0121, 0x0000, 0x0000 },
+ { 0x0425, 0x0445, 0x0000, 0x0000 },
+ { 0x1F3E, 0x1F36, 0x0000, 0x0000 },
+ { 0x2C0D, 0x2C3D, 0x0000, 0x0000 },
+ { 0x10425, 0x1044D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_034[] = {
+ { 0x0220, 0x019E, 0x0000, 0x0000 },
+ { 0x0426, 0x0446, 0x0000, 0x0000 },
+ { 0x1E3C, 0x1E3D, 0x0000, 0x0000 },
+ { 0x1F3D, 0x1F35, 0x0000, 0x0000 },
+ { 0x2C0E, 0x2C3E, 0x0000, 0x0000 },
+ { 0x10426, 0x1044E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_035[] = {
+ { 0x0122, 0x0123, 0x0000, 0x0000 },
+ { 0x0427, 0x0447, 0x0000, 0x0000 },
+ { 0x1F3C, 0x1F34, 0x0000, 0x0000 },
+ { 0x2C0F, 0x2C3F, 0x0000, 0x0000 },
+ { 0x10427, 0x1044F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_036[] = {
+ { 0x0226, 0x0227, 0x0000, 0x0000 },
+ { 0x0420, 0x0440, 0x0000, 0x0000 },
+ { 0x1E3A, 0x1E3B, 0x0000, 0x0000 },
+ { 0x1F3B, 0x1F33, 0x0000, 0x0000 },
+ { 0x2C08, 0x2C38, 0x0000, 0x0000 },
+ { 0x10420, 0x10448, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_037[] = {
+ { 0x0124, 0x0125, 0x0000, 0x0000 },
+ { 0x0421, 0x0441, 0x0000, 0x0000 },
+ { 0x1F3A, 0x1F32, 0x0000, 0x0000 },
+ { 0x2C09, 0x2C39, 0x0000, 0x0000 },
+ { 0x10421, 0x10449, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_038[] = {
+ { 0x0224, 0x0225, 0x0000, 0x0000 },
+ { 0x0422, 0x0442, 0x0000, 0x0000 },
+ { 0x1E38, 0x1E39, 0x0000, 0x0000 },
+ { 0x1F39, 0x1F31, 0x0000, 0x0000 },
+ { 0x2C0A, 0x2C3A, 0x0000, 0x0000 },
+ { 0x10422, 0x1044A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_039[] = {
+ { 0x0126, 0x0127, 0x0000, 0x0000 },
+ { 0x0423, 0x0443, 0x0000, 0x0000 },
+ { 0x1F38, 0x1F30, 0x0000, 0x0000 },
+ { 0x2C0B, 0x2C3B, 0x0000, 0x0000 },
+ { 0x10423, 0x1044B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_040[] = {
+ { 0x022A, 0x022B, 0x0000, 0x0000 },
+ { 0x042C, 0x044C, 0x0000, 0x0000 },
+ { 0x1E36, 0x1E37, 0x0000, 0x0000 },
+ { 0x2C04, 0x2C34, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_041[] = {
+ { 0x0128, 0x0129, 0x0000, 0x0000 },
+ { 0x042D, 0x044D, 0x0000, 0x0000 },
+ { 0x2C05, 0x2C35, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_042[] = {
+ { 0x0228, 0x0229, 0x0000, 0x0000 },
+ { 0x042E, 0x044E, 0x0000, 0x0000 },
+ { 0x1E34, 0x1E35, 0x0000, 0x0000 },
+ { 0x2C06, 0x2C36, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_043[] = {
+ { 0x012A, 0x012B, 0x0000, 0x0000 },
+ { 0x042F, 0x044F, 0x0000, 0x0000 },
+ { 0x2C07, 0x2C37, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_044[] = {
+ { 0x022E, 0x022F, 0x0000, 0x0000 },
+ { 0x0428, 0x0448, 0x0000, 0x0000 },
+ { 0x1E32, 0x1E33, 0x0000, 0x0000 },
+ { 0x2C00, 0x2C30, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_045[] = {
+ { 0x012C, 0x012D, 0x0000, 0x0000 },
+ { 0x0429, 0x0449, 0x0000, 0x0000 },
+ { 0x2C01, 0x2C31, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_046[] = {
+ { 0x022C, 0x022D, 0x0000, 0x0000 },
+ { 0x042A, 0x044A, 0x0000, 0x0000 },
+ { 0x1E30, 0x1E31, 0x0000, 0x0000 },
+ { 0x2C02, 0x2C32, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_047[] = {
+ { 0x012E, 0x012F, 0x0000, 0x0000 },
+ { 0x042B, 0x044B, 0x0000, 0x0000 },
+ { 0x2C03, 0x2C33, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_048[] = {
+ { 0x0232, 0x0233, 0x0000, 0x0000 },
+ { 0x0535, 0x0565, 0x0000, 0x0000 },
+ { 0x1E2E, 0x1E2F, 0x0000, 0x0000 },
+ { 0x1F2F, 0x1F27, 0x0000, 0x0000 },
+ { 0x2C1C, 0x2C4C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_049[] = {
+ { 0x0130, 0x0069, 0x0307, 0x0000 },
+ { 0x0534, 0x0564, 0x0000, 0x0000 },
+ { 0x1F2E, 0x1F26, 0x0000, 0x0000 },
+ { 0x2C1D, 0x2C4D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_050[] = {
+ { 0x0230, 0x0231, 0x0000, 0x0000 },
+ { 0x0537, 0x0567, 0x0000, 0x0000 },
+ { 0x1E2C, 0x1E2D, 0x0000, 0x0000 },
+ { 0x1F2D, 0x1F25, 0x0000, 0x0000 },
+ { 0x2C1E, 0x2C4E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_051[] = {
+ { 0x0132, 0x0133, 0x0000, 0x0000 },
+ { 0x0536, 0x0566, 0x0000, 0x0000 },
+ { 0x1F2C, 0x1F24, 0x0000, 0x0000 },
+ { 0x2C1F, 0x2C4F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_052[] = {
+ { 0x0531, 0x0561, 0x0000, 0x0000 },
+ { 0x1E2A, 0x1E2B, 0x0000, 0x0000 },
+ { 0x1F2B, 0x1F23, 0x0000, 0x0000 },
+ { 0x2C18, 0x2C48, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_053[] = {
+ { 0x0134, 0x0135, 0x0000, 0x0000 },
+ { 0x1F2A, 0x1F22, 0x0000, 0x0000 },
+ { 0x2C19, 0x2C49, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_054[] = {
+ { 0x0533, 0x0563, 0x0000, 0x0000 },
+ { 0x1E28, 0x1E29, 0x0000, 0x0000 },
+ { 0x1F29, 0x1F21, 0x0000, 0x0000 },
+ { 0x2C1A, 0x2C4A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_055[] = {
+ { 0x0136, 0x0137, 0x0000, 0x0000 },
+ { 0x0532, 0x0562, 0x0000, 0x0000 },
+ { 0x1F28, 0x1F20, 0x0000, 0x0000 },
+ { 0x2C1B, 0x2C4B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_056[] = {
+ { 0x0139, 0x013A, 0x0000, 0x0000 },
+ { 0x053D, 0x056D, 0x0000, 0x0000 },
+ { 0x1E26, 0x1E27, 0x0000, 0x0000 },
+ { 0x2C14, 0x2C44, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_057[] = {
+ { 0x023B, 0x023C, 0x0000, 0x0000 },
+ { 0x053C, 0x056C, 0x0000, 0x0000 },
+ { 0x2C15, 0x2C45, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_058[] = {
+ { 0x013B, 0x013C, 0x0000, 0x0000 },
+ { 0x053F, 0x056F, 0x0000, 0x0000 },
+ { 0x1E24, 0x1E25, 0x0000, 0x0000 },
+ { 0x2C16, 0x2C46, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_059[] = {
+ { 0x053E, 0x056E, 0x0000, 0x0000 },
+ { 0x2C17, 0x2C47, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_060[] = {
+ { 0x013D, 0x013E, 0x0000, 0x0000 },
+ { 0x0539, 0x0569, 0x0000, 0x0000 },
+ { 0x1E22, 0x1E23, 0x0000, 0x0000 },
+ { 0x2C10, 0x2C40, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_061[] = {
+ { 0x0538, 0x0568, 0x0000, 0x0000 },
+ { 0x2C11, 0x2C41, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_062[] = {
+ { 0x013F, 0x0140, 0x0000, 0x0000 },
+ { 0x053B, 0x056B, 0x0000, 0x0000 },
+ { 0x1E20, 0x1E21, 0x0000, 0x0000 },
+ { 0x2C12, 0x2C42, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_063[] = {
+ { 0x023D, 0x019A, 0x0000, 0x0000 },
+ { 0x053A, 0x056A, 0x0000, 0x0000 },
+ { 0x2C13, 0x2C43, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_064[] = {
+ { 0x0141, 0x0142, 0x0000, 0x0000 },
+ { 0x0545, 0x0575, 0x0000, 0x0000 },
+ { 0x1E5E, 0x1E5F, 0x0000, 0x0000 },
+ { 0x1F5F, 0x1F57, 0x0000, 0x0000 },
+ { 0x2161, 0x2171, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_065[] = {
+ { 0x0041, 0x0061, 0x0000, 0x0000 },
+ { 0x0544, 0x0574, 0x0000, 0x0000 },
+ { 0x2160, 0x2170, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_066[] = {
+ { 0x0042, 0x0062, 0x0000, 0x0000 },
+ { 0x0143, 0x0144, 0x0000, 0x0000 },
+ { 0x0547, 0x0577, 0x0000, 0x0000 },
+ { 0x1E5C, 0x1E5D, 0x0000, 0x0000 },
+ { 0x1F5D, 0x1F55, 0x0000, 0x0000 },
+ { 0x2163, 0x2173, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_067[] = {
+ { 0x0043, 0x0063, 0x0000, 0x0000 },
+ { 0x0241, 0x0294, 0x0000, 0x0000 },
+ { 0x0546, 0x0576, 0x0000, 0x0000 },
+ { 0x2162, 0x2172, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_068[] = {
+ { 0x0044, 0x0064, 0x0000, 0x0000 },
+ { 0x0145, 0x0146, 0x0000, 0x0000 },
+ { 0x0541, 0x0571, 0x0000, 0x0000 },
+ { 0x1E5A, 0x1E5B, 0x0000, 0x0000 },
+ { 0x1F5B, 0x1F53, 0x0000, 0x0000 },
+ { 0x2165, 0x2175, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_069[] = {
+ { 0x0045, 0x0065, 0x0000, 0x0000 },
+ { 0x0540, 0x0570, 0x0000, 0x0000 },
+ { 0x2164, 0x2174, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_070[] = {
+ { 0x0046, 0x0066, 0x0000, 0x0000 },
+ { 0x0147, 0x0148, 0x0000, 0x0000 },
+ { 0x0345, 0x03B9, 0x0000, 0x0000 },
+ { 0x0543, 0x0573, 0x0000, 0x0000 },
+ { 0x1E58, 0x1E59, 0x0000, 0x0000 },
+ { 0x1F59, 0x1F51, 0x0000, 0x0000 },
+ { 0x2167, 0x2177, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_071[] = {
+ { 0x0047, 0x0067, 0x0000, 0x0000 },
+ { 0x0542, 0x0572, 0x0000, 0x0000 },
+ { 0x2166, 0x2176, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_072[] = {
+ { 0x0048, 0x0068, 0x0000, 0x0000 },
+ { 0x0149, 0x02BC, 0x006E, 0x0000 },
+ { 0x054D, 0x057D, 0x0000, 0x0000 },
+ { 0x1E56, 0x1E57, 0x0000, 0x0000 },
+ { 0x2169, 0x2179, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_073[] = {
+ { 0x0049, 0x0069, 0x0000, 0x0000 },
+ { 0x054C, 0x057C, 0x0000, 0x0000 },
+ { 0x1F56, 0x03C5, 0x0313, 0x0342 },
+ { 0x2168, 0x2178, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_074[] = {
+ { 0x004A, 0x006A, 0x0000, 0x0000 },
+ { 0x054F, 0x057F, 0x0000, 0x0000 },
+ { 0x1E54, 0x1E55, 0x0000, 0x0000 },
+ { 0x216B, 0x217B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_075[] = {
+ { 0x004B, 0x006B, 0x0000, 0x0000 },
+ { 0x014A, 0x014B, 0x0000, 0x0000 },
+ { 0x054E, 0x057E, 0x0000, 0x0000 },
+ { 0x1F54, 0x03C5, 0x0313, 0x0301 },
+ { 0x216A, 0x217A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_076[] = {
+ { 0x004C, 0x006C, 0x0000, 0x0000 },
+ { 0x0549, 0x0579, 0x0000, 0x0000 },
+ { 0x1E52, 0x1E53, 0x0000, 0x0000 },
+ { 0x216D, 0x217D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_077[] = {
+ { 0x004D, 0x006D, 0x0000, 0x0000 },
+ { 0x014C, 0x014D, 0x0000, 0x0000 },
+ { 0x0548, 0x0578, 0x0000, 0x0000 },
+ { 0x1F52, 0x03C5, 0x0313, 0x0300 },
+ { 0x216C, 0x217C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_078[] = {
+ { 0x004E, 0x006E, 0x0000, 0x0000 },
+ { 0x054B, 0x057B, 0x0000, 0x0000 },
+ { 0x1E50, 0x1E51, 0x0000, 0x0000 },
+ { 0x216F, 0x217F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_079[] = {
+ { 0x004F, 0x006F, 0x0000, 0x0000 },
+ { 0x014E, 0x014F, 0x0000, 0x0000 },
+ { 0x054A, 0x057A, 0x0000, 0x0000 },
+ { 0x1F50, 0x03C5, 0x0313, 0x0000 },
+ { 0x216E, 0x217E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_080[] = {
+ { 0x0050, 0x0070, 0x0000, 0x0000 },
+ { 0x0555, 0x0585, 0x0000, 0x0000 },
+ { 0x1E4E, 0x1E4F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_081[] = {
+ { 0x0051, 0x0071, 0x0000, 0x0000 },
+ { 0x0150, 0x0151, 0x0000, 0x0000 },
+ { 0x0554, 0x0584, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_082[] = {
+ { 0x0052, 0x0072, 0x0000, 0x0000 },
+ { 0x1E4C, 0x1E4D, 0x0000, 0x0000 },
+ { 0x1F4D, 0x1F45, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_083[] = {
+ { 0x0053, 0x0073, 0x0000, 0x0000 },
+ { 0x0152, 0x0153, 0x0000, 0x0000 },
+ { 0x0556, 0x0586, 0x0000, 0x0000 },
+ { 0x1F4C, 0x1F44, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_084[] = {
+ { 0x0054, 0x0074, 0x0000, 0x0000 },
+ { 0x0551, 0x0581, 0x0000, 0x0000 },
+ { 0x1E4A, 0x1E4B, 0x0000, 0x0000 },
+ { 0x1F4B, 0x1F43, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_085[] = {
+ { 0x0055, 0x0075, 0x0000, 0x0000 },
+ { 0x0154, 0x0155, 0x0000, 0x0000 },
+ { 0x0550, 0x0580, 0x0000, 0x0000 },
+ { 0x1F4A, 0x1F42, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_086[] = {
+ { 0x0056, 0x0076, 0x0000, 0x0000 },
+ { 0x0553, 0x0583, 0x0000, 0x0000 },
+ { 0x1E48, 0x1E49, 0x0000, 0x0000 },
+ { 0x1F49, 0x1F41, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_087[] = {
+ { 0x0057, 0x0077, 0x0000, 0x0000 },
+ { 0x0156, 0x0157, 0x0000, 0x0000 },
+ { 0x0552, 0x0582, 0x0000, 0x0000 },
+ { 0x1F48, 0x1F40, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_088[] = {
+ { 0x0058, 0x0078, 0x0000, 0x0000 },
+ { 0x1E46, 0x1E47, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_089[] = {
+ { 0x0059, 0x0079, 0x0000, 0x0000 },
+ { 0x0158, 0x0159, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_090[] = {
+ { 0x005A, 0x007A, 0x0000, 0x0000 },
+ { 0x1E44, 0x1E45, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_091[] = {
+ { 0x015A, 0x015B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_092[] = {
+ { 0x1E42, 0x1E43, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_093[] = {
+ { 0x015C, 0x015D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_094[] = {
+ { 0x1E40, 0x1E41, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_095[] = {
+ { 0x015E, 0x015F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_096[] = {
+ { 0x0464, 0x0465, 0x0000, 0x0000 },
+ { 0x1E7E, 0x1E7F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_097[] = {
+ { 0x0160, 0x0161, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_098[] = {
+ { 0x0466, 0x0467, 0x0000, 0x0000 },
+ { 0x1E7C, 0x1E7D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_099[] = {
+ { 0x0162, 0x0163, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_100[] = {
+ { 0x0460, 0x0461, 0x0000, 0x0000 },
+ { 0x1E7A, 0x1E7B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_101[] = {
+ { 0x0164, 0x0165, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_102[] = {
+ { 0x0462, 0x0463, 0x0000, 0x0000 },
+ { 0x1E78, 0x1E79, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_103[] = {
+ { 0x0166, 0x0167, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_104[] = {
+ { 0x046C, 0x046D, 0x0000, 0x0000 },
+ { 0x1E76, 0x1E77, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_105[] = {
+ { 0x0168, 0x0169, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_106[] = {
+ { 0x046E, 0x046F, 0x0000, 0x0000 },
+ { 0x1E74, 0x1E75, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_107[] = {
+ { 0x016A, 0x016B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_108[] = {
+ { 0x0468, 0x0469, 0x0000, 0x0000 },
+ { 0x1E72, 0x1E73, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_109[] = {
+ { 0x016C, 0x016D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_110[] = {
+ { 0x046A, 0x046B, 0x0000, 0x0000 },
+ { 0x1E70, 0x1E71, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_111[] = {
+ { 0x016E, 0x016F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_112[] = {
+ { 0x0474, 0x0475, 0x0000, 0x0000 },
+ { 0x1E6E, 0x1E6F, 0x0000, 0x0000 },
+ { 0x1F6F, 0x1F67, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_113[] = {
+ { 0x0170, 0x0171, 0x0000, 0x0000 },
+ { 0x1F6E, 0x1F66, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_114[] = {
+ { 0x0476, 0x0477, 0x0000, 0x0000 },
+ { 0x1E6C, 0x1E6D, 0x0000, 0x0000 },
+ { 0x1F6D, 0x1F65, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_115[] = {
+ { 0x0172, 0x0173, 0x0000, 0x0000 },
+ { 0x1F6C, 0x1F64, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_116[] = {
+ { 0x0470, 0x0471, 0x0000, 0x0000 },
+ { 0x1E6A, 0x1E6B, 0x0000, 0x0000 },
+ { 0x1F6B, 0x1F63, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_117[] = {
+ { 0x0174, 0x0175, 0x0000, 0x0000 },
+ { 0x1F6A, 0x1F62, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_118[] = {
+ { 0x0472, 0x0473, 0x0000, 0x0000 },
+ { 0x1E68, 0x1E69, 0x0000, 0x0000 },
+ { 0x1F69, 0x1F61, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_119[] = {
+ { 0x0176, 0x0177, 0x0000, 0x0000 },
+ { 0x1F68, 0x1F60, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_120[] = {
+ { 0x0179, 0x017A, 0x0000, 0x0000 },
+ { 0x047C, 0x047D, 0x0000, 0x0000 },
+ { 0x1E66, 0x1E67, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_121[] = {
+ { 0x0178, 0x00FF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_122[] = {
+ { 0x017B, 0x017C, 0x0000, 0x0000 },
+ { 0x047E, 0x047F, 0x0000, 0x0000 },
+ { 0x1E64, 0x1E65, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_124[] = {
+ { 0x017D, 0x017E, 0x0000, 0x0000 },
+ { 0x0478, 0x0479, 0x0000, 0x0000 },
+ { 0x1E62, 0x1E63, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_126[] = {
+ { 0x017F, 0x0073, 0x0000, 0x0000 },
+ { 0x047A, 0x047B, 0x0000, 0x0000 },
+ { 0x1E60, 0x1E61, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_128[] = {
+ { 0x0181, 0x0253, 0x0000, 0x0000 },
+ { 0x1F9F, 0x1F27, 0x03B9, 0x0000 },
+ { 0x2CAC, 0x2CAD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_129[] = {
+ { 0x1F9E, 0x1F26, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_130[] = {
+ { 0x0587, 0x0565, 0x0582, 0x0000 },
+ { 0x1F9D, 0x1F25, 0x03B9, 0x0000 },
+ { 0x2CAE, 0x2CAF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_131[] = {
+ { 0x0182, 0x0183, 0x0000, 0x0000 },
+ { 0x1F9C, 0x1F24, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_132[] = {
+ { 0x0480, 0x0481, 0x0000, 0x0000 },
+ { 0x1E9A, 0x0061, 0x02BE, 0x0000 },
+ { 0x1F9B, 0x1F23, 0x03B9, 0x0000 },
+ { 0x2CA8, 0x2CA9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_133[] = {
+ { 0x0184, 0x0185, 0x0000, 0x0000 },
+ { 0x0386, 0x03AC, 0x0000, 0x0000 },
+ { 0x1E9B, 0x1E61, 0x0000, 0x0000 },
+ { 0x1F9A, 0x1F22, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_134[] = {
+ { 0x0187, 0x0188, 0x0000, 0x0000 },
+ { 0x1E98, 0x0077, 0x030A, 0x0000 },
+ { 0x1F99, 0x1F21, 0x03B9, 0x0000 },
+ { 0x2CAA, 0x2CAB, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_135[] = {
+ { 0x0186, 0x0254, 0x0000, 0x0000 },
+ { 0x1E99, 0x0079, 0x030A, 0x0000 },
+ { 0x1F98, 0x1F20, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_136[] = {
+ { 0x0189, 0x0256, 0x0000, 0x0000 },
+ { 0x048C, 0x048D, 0x0000, 0x0000 },
+ { 0x1E96, 0x0068, 0x0331, 0x0000 },
+ { 0x1F97, 0x1F27, 0x03B9, 0x0000 },
+ { 0x2CA4, 0x2CA5, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_137[] = {
+ { 0x038A, 0x03AF, 0x0000, 0x0000 },
+ { 0x1E97, 0x0074, 0x0308, 0x0000 },
+ { 0x1F96, 0x1F26, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_138[] = {
+ { 0x018B, 0x018C, 0x0000, 0x0000 },
+ { 0x0389, 0x03AE, 0x0000, 0x0000 },
+ { 0x048E, 0x048F, 0x0000, 0x0000 },
+ { 0x1E94, 0x1E95, 0x0000, 0x0000 },
+ { 0x1F95, 0x1F25, 0x03B9, 0x0000 },
+ { 0x2CA6, 0x2CA7, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_139[] = {
+ { 0x018A, 0x0257, 0x0000, 0x0000 },
+ { 0x0388, 0x03AD, 0x0000, 0x0000 },
+ { 0x1F94, 0x1F24, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_140[] = {
+ { 0x038F, 0x03CE, 0x0000, 0x0000 },
+ { 0x1E92, 0x1E93, 0x0000, 0x0000 },
+ { 0x1F93, 0x1F23, 0x03B9, 0x0000 },
+ { 0x2CA0, 0x2CA1, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_141[] = {
+ { 0x038E, 0x03CD, 0x0000, 0x0000 },
+ { 0x1F92, 0x1F22, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_142[] = {
+ { 0x018F, 0x0259, 0x0000, 0x0000 },
+ { 0x048A, 0x048B, 0x0000, 0x0000 },
+ { 0x1E90, 0x1E91, 0x0000, 0x0000 },
+ { 0x1F91, 0x1F21, 0x03B9, 0x0000 },
+ { 0x2CA2, 0x2CA3, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_143[] = {
+ { 0x018E, 0x01DD, 0x0000, 0x0000 },
+ { 0x038C, 0x03CC, 0x0000, 0x0000 },
+ { 0x1F90, 0x1F20, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_144[] = {
+ { 0x0191, 0x0192, 0x0000, 0x0000 },
+ { 0x0393, 0x03B3, 0x0000, 0x0000 },
+ { 0x0494, 0x0495, 0x0000, 0x0000 },
+ { 0x1E8E, 0x1E8F, 0x0000, 0x0000 },
+ { 0x1F8F, 0x1F07, 0x03B9, 0x0000 },
+ { 0x2CBC, 0x2CBD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_145[] = {
+ { 0x0190, 0x025B, 0x0000, 0x0000 },
+ { 0x0392, 0x03B2, 0x0000, 0x0000 },
+ { 0x1F8E, 0x1F06, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_146[] = {
+ { 0x0193, 0x0260, 0x0000, 0x0000 },
+ { 0x0391, 0x03B1, 0x0000, 0x0000 },
+ { 0x0496, 0x0497, 0x0000, 0x0000 },
+ { 0x1E8C, 0x1E8D, 0x0000, 0x0000 },
+ { 0x1F8D, 0x1F05, 0x03B9, 0x0000 },
+ { 0x24B6, 0x24D0, 0x0000, 0x0000 },
+ { 0x2CBE, 0x2CBF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_147[] = {
+ { 0x0390, 0x03B9, 0x0308, 0x0301 },
+ { 0x1F8C, 0x1F04, 0x03B9, 0x0000 },
+ { 0x24B7, 0x24D1, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_148[] = {
+ { 0x0397, 0x03B7, 0x0000, 0x0000 },
+ { 0x0490, 0x0491, 0x0000, 0x0000 },
+ { 0x1E8A, 0x1E8B, 0x0000, 0x0000 },
+ { 0x1F8B, 0x1F03, 0x03B9, 0x0000 },
+ { 0x2CB8, 0x2CB9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_149[] = {
+ { 0x0194, 0x0263, 0x0000, 0x0000 },
+ { 0x0396, 0x03B6, 0x0000, 0x0000 },
+ { 0x1F8A, 0x1F02, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_150[] = {
+ { 0x0197, 0x0268, 0x0000, 0x0000 },
+ { 0x0395, 0x03B5, 0x0000, 0x0000 },
+ { 0x0492, 0x0493, 0x0000, 0x0000 },
+ { 0x1E88, 0x1E89, 0x0000, 0x0000 },
+ { 0x1F89, 0x1F01, 0x03B9, 0x0000 },
+ { 0x2CBA, 0x2CBB, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_151[] = {
+ { 0x0196, 0x0269, 0x0000, 0x0000 },
+ { 0x0394, 0x03B4, 0x0000, 0x0000 },
+ { 0x1F88, 0x1F00, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_152[] = {
+ { 0x039B, 0x03BB, 0x0000, 0x0000 },
+ { 0x049C, 0x049D, 0x0000, 0x0000 },
+ { 0x1E86, 0x1E87, 0x0000, 0x0000 },
+ { 0x1F87, 0x1F07, 0x03B9, 0x0000 },
+ { 0x24BC, 0x24D6, 0x0000, 0x0000 },
+ { 0x2CB4, 0x2CB5, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_153[] = {
+ { 0x0198, 0x0199, 0x0000, 0x0000 },
+ { 0x039A, 0x03BA, 0x0000, 0x0000 },
+ { 0x1F86, 0x1F06, 0x03B9, 0x0000 },
+ { 0x24BD, 0x24D7, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_154[] = {
+ { 0x0399, 0x03B9, 0x0000, 0x0000 },
+ { 0x049E, 0x049F, 0x0000, 0x0000 },
+ { 0x1E84, 0x1E85, 0x0000, 0x0000 },
+ { 0x1F85, 0x1F05, 0x03B9, 0x0000 },
+ { 0x24BE, 0x24D8, 0x0000, 0x0000 },
+ { 0x2CB6, 0x2CB7, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_155[] = {
+ { 0x0398, 0x03B8, 0x0000, 0x0000 },
+ { 0x1F84, 0x1F04, 0x03B9, 0x0000 },
+ { 0x24BF, 0x24D9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_156[] = {
+ { 0x019D, 0x0272, 0x0000, 0x0000 },
+ { 0x039F, 0x03BF, 0x0000, 0x0000 },
+ { 0x0498, 0x0499, 0x0000, 0x0000 },
+ { 0x1E82, 0x1E83, 0x0000, 0x0000 },
+ { 0x1F83, 0x1F03, 0x03B9, 0x0000 },
+ { 0x24B8, 0x24D2, 0x0000, 0x0000 },
+ { 0x2CB0, 0x2CB1, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_157[] = {
+ { 0x019C, 0x026F, 0x0000, 0x0000 },
+ { 0x039E, 0x03BE, 0x0000, 0x0000 },
+ { 0x1F82, 0x1F02, 0x03B9, 0x0000 },
+ { 0x24B9, 0x24D3, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_158[] = {
+ { 0x019F, 0x0275, 0x0000, 0x0000 },
+ { 0x039D, 0x03BD, 0x0000, 0x0000 },
+ { 0x049A, 0x049B, 0x0000, 0x0000 },
+ { 0x1E80, 0x1E81, 0x0000, 0x0000 },
+ { 0x1F81, 0x1F01, 0x03B9, 0x0000 },
+ { 0x24BA, 0x24D4, 0x0000, 0x0000 },
+ { 0x2CB2, 0x2CB3, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_159[] = {
+ { 0x039C, 0x03BC, 0x0000, 0x0000 },
+ { 0x1F80, 0x1F00, 0x03B9, 0x0000 },
+ { 0x24BB, 0x24D5, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_160[] = {
+ { 0x03A3, 0x03C3, 0x0000, 0x0000 },
+ { 0x04A4, 0x04A5, 0x0000, 0x0000 },
+ { 0x10B0, 0x2D10, 0x0000, 0x0000 },
+ { 0x1EBE, 0x1EBF, 0x0000, 0x0000 },
+ { 0x2C8C, 0x2C8D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_161[] = {
+ { 0x01A0, 0x01A1, 0x0000, 0x0000 },
+ { 0x10B1, 0x2D11, 0x0000, 0x0000 },
+ { 0x1FBE, 0x03B9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_162[] = {
+ { 0x03A1, 0x03C1, 0x0000, 0x0000 },
+ { 0x04A6, 0x04A7, 0x0000, 0x0000 },
+ { 0x10B2, 0x2D12, 0x0000, 0x0000 },
+ { 0x1EBC, 0x1EBD, 0x0000, 0x0000 },
+ { 0x2C8E, 0x2C8F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_163[] = {
+ { 0x01A2, 0x01A3, 0x0000, 0x0000 },
+ { 0x03A0, 0x03C0, 0x0000, 0x0000 },
+ { 0x10B3, 0x2D13, 0x0000, 0x0000 },
+ { 0x1FBC, 0x03B1, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_164[] = {
+ { 0x03A7, 0x03C7, 0x0000, 0x0000 },
+ { 0x04A0, 0x04A1, 0x0000, 0x0000 },
+ { 0x10B4, 0x2D14, 0x0000, 0x0000 },
+ { 0x1EBA, 0x1EBB, 0x0000, 0x0000 },
+ { 0x1FBB, 0x1F71, 0x0000, 0x0000 },
+ { 0x2C88, 0x2C89, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_165[] = {
+ { 0x01A4, 0x01A5, 0x0000, 0x0000 },
+ { 0x03A6, 0x03C6, 0x0000, 0x0000 },
+ { 0x10B5, 0x2D15, 0x0000, 0x0000 },
+ { 0x1FBA, 0x1F70, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_166[] = {
+ { 0x01A7, 0x01A8, 0x0000, 0x0000 },
+ { 0x03A5, 0x03C5, 0x0000, 0x0000 },
+ { 0x04A2, 0x04A3, 0x0000, 0x0000 },
+ { 0x10B6, 0x2D16, 0x0000, 0x0000 },
+ { 0x1EB8, 0x1EB9, 0x0000, 0x0000 },
+ { 0x1FB9, 0x1FB1, 0x0000, 0x0000 },
+ { 0x2C8A, 0x2C8B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_167[] = {
+ { 0x01A6, 0x0280, 0x0000, 0x0000 },
+ { 0x03A4, 0x03C4, 0x0000, 0x0000 },
+ { 0x10B7, 0x2D17, 0x0000, 0x0000 },
+ { 0x1FB8, 0x1FB0, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_168[] = {
+ { 0x01A9, 0x0283, 0x0000, 0x0000 },
+ { 0x03AB, 0x03CB, 0x0000, 0x0000 },
+ { 0x04AC, 0x04AD, 0x0000, 0x0000 },
+ { 0x10B8, 0x2D18, 0x0000, 0x0000 },
+ { 0x1EB6, 0x1EB7, 0x0000, 0x0000 },
+ { 0x1FB7, 0x03B1, 0x0342, 0x03B9 },
+ { 0x2C84, 0x2C85, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_169[] = {
+ { 0x03AA, 0x03CA, 0x0000, 0x0000 },
+ { 0x10B9, 0x2D19, 0x0000, 0x0000 },
+ { 0x1FB6, 0x03B1, 0x0342, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_170[] = {
+ { 0x03A9, 0x03C9, 0x0000, 0x0000 },
+ { 0x04AE, 0x04AF, 0x0000, 0x0000 },
+ { 0x10BA, 0x2D1A, 0x0000, 0x0000 },
+ { 0x1EB4, 0x1EB5, 0x0000, 0x0000 },
+ { 0x2C86, 0x2C87, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_171[] = {
+ { 0x03A8, 0x03C8, 0x0000, 0x0000 },
+ { 0x10BB, 0x2D1B, 0x0000, 0x0000 },
+ { 0x1FB4, 0x03AC, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_172[] = {
+ { 0x04A8, 0x04A9, 0x0000, 0x0000 },
+ { 0x10BC, 0x2D1C, 0x0000, 0x0000 },
+ { 0x1EB2, 0x1EB3, 0x0000, 0x0000 },
+ { 0x1FB3, 0x03B1, 0x03B9, 0x0000 },
+ { 0x2C80, 0x2C81, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_173[] = {
+ { 0x01AC, 0x01AD, 0x0000, 0x0000 },
+ { 0x10BD, 0x2D1D, 0x0000, 0x0000 },
+ { 0x1FB2, 0x1F70, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_174[] = {
+ { 0x01AF, 0x01B0, 0x0000, 0x0000 },
+ { 0x04AA, 0x04AB, 0x0000, 0x0000 },
+ { 0x10BE, 0x2D1E, 0x0000, 0x0000 },
+ { 0x1EB0, 0x1EB1, 0x0000, 0x0000 },
+ { 0x2C82, 0x2C83, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_175[] = {
+ { 0x01AE, 0x0288, 0x0000, 0x0000 },
+ { 0x10BF, 0x2D1F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_176[] = {
+ { 0x01B1, 0x028A, 0x0000, 0x0000 },
+ { 0x04B4, 0x04B5, 0x0000, 0x0000 },
+ { 0x10A0, 0x2D00, 0x0000, 0x0000 },
+ { 0x1EAE, 0x1EAF, 0x0000, 0x0000 },
+ { 0x1FAF, 0x1F67, 0x03B9, 0x0000 },
+ { 0x2C9C, 0x2C9D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_177[] = {
+ { 0x10A1, 0x2D01, 0x0000, 0x0000 },
+ { 0x1FAE, 0x1F66, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_178[] = {
+ { 0x01B3, 0x01B4, 0x0000, 0x0000 },
+ { 0x04B6, 0x04B7, 0x0000, 0x0000 },
+ { 0x10A2, 0x2D02, 0x0000, 0x0000 },
+ { 0x1EAC, 0x1EAD, 0x0000, 0x0000 },
+ { 0x1FAD, 0x1F65, 0x03B9, 0x0000 },
+ { 0x2C9E, 0x2C9F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_179[] = {
+ { 0x01B2, 0x028B, 0x0000, 0x0000 },
+ { 0x03B0, 0x03C5, 0x0308, 0x0301 },
+ { 0x10A3, 0x2D03, 0x0000, 0x0000 },
+ { 0x1FAC, 0x1F64, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_180[] = {
+ { 0x01B5, 0x01B6, 0x0000, 0x0000 },
+ { 0x04B0, 0x04B1, 0x0000, 0x0000 },
+ { 0x10A4, 0x2D04, 0x0000, 0x0000 },
+ { 0x1EAA, 0x1EAB, 0x0000, 0x0000 },
+ { 0x1FAB, 0x1F63, 0x03B9, 0x0000 },
+ { 0x2C98, 0x2C99, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_181[] = {
+ { 0x00B5, 0x03BC, 0x0000, 0x0000 },
+ { 0x10A5, 0x2D05, 0x0000, 0x0000 },
+ { 0x1FAA, 0x1F62, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_182[] = {
+ { 0x01B7, 0x0292, 0x0000, 0x0000 },
+ { 0x04B2, 0x04B3, 0x0000, 0x0000 },
+ { 0x10A6, 0x2D06, 0x0000, 0x0000 },
+ { 0x1EA8, 0x1EA9, 0x0000, 0x0000 },
+ { 0x1FA9, 0x1F61, 0x03B9, 0x0000 },
+ { 0x2C9A, 0x2C9B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_183[] = {
+ { 0x10A7, 0x2D07, 0x0000, 0x0000 },
+ { 0x1FA8, 0x1F60, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_184[] = {
+ { 0x04BC, 0x04BD, 0x0000, 0x0000 },
+ { 0x10A8, 0x2D08, 0x0000, 0x0000 },
+ { 0x1EA6, 0x1EA7, 0x0000, 0x0000 },
+ { 0x1FA7, 0x1F67, 0x03B9, 0x0000 },
+ { 0x2C94, 0x2C95, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_185[] = {
+ { 0x01B8, 0x01B9, 0x0000, 0x0000 },
+ { 0x10A9, 0x2D09, 0x0000, 0x0000 },
+ { 0x1FA6, 0x1F66, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_186[] = {
+ { 0x04BE, 0x04BF, 0x0000, 0x0000 },
+ { 0x10AA, 0x2D0A, 0x0000, 0x0000 },
+ { 0x1EA4, 0x1EA5, 0x0000, 0x0000 },
+ { 0x1FA5, 0x1F65, 0x03B9, 0x0000 },
+ { 0x2C96, 0x2C97, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_187[] = {
+ { 0x10AB, 0x2D0B, 0x0000, 0x0000 },
+ { 0x1FA4, 0x1F64, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_188[] = {
+ { 0x04B8, 0x04B9, 0x0000, 0x0000 },
+ { 0x10AC, 0x2D0C, 0x0000, 0x0000 },
+ { 0x1EA2, 0x1EA3, 0x0000, 0x0000 },
+ { 0x1FA3, 0x1F63, 0x03B9, 0x0000 },
+ { 0x2C90, 0x2C91, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_189[] = {
+ { 0x01BC, 0x01BD, 0x0000, 0x0000 },
+ { 0x10AD, 0x2D0D, 0x0000, 0x0000 },
+ { 0x1FA2, 0x1F62, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_190[] = {
+ { 0x04BA, 0x04BB, 0x0000, 0x0000 },
+ { 0x10AE, 0x2D0E, 0x0000, 0x0000 },
+ { 0x1EA0, 0x1EA1, 0x0000, 0x0000 },
+ { 0x1FA1, 0x1F61, 0x03B9, 0x0000 },
+ { 0x2C92, 0x2C93, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_191[] = {
+ { 0x10AF, 0x2D0F, 0x0000, 0x0000 },
+ { 0x1FA0, 0x1F60, 0x03B9, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_192[] = {
+ { 0x00C0, 0x00E0, 0x0000, 0x0000 },
+ { 0x1EDE, 0x1EDF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_193[] = {
+ { 0x00C1, 0x00E1, 0x0000, 0x0000 },
+ { 0x03C2, 0x03C3, 0x0000, 0x0000 },
+ { 0x04C5, 0x04C6, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_194[] = {
+ { 0x00C2, 0x00E2, 0x0000, 0x0000 },
+ { 0x1EDC, 0x1EDD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_195[] = {
+ { 0x00C3, 0x00E3, 0x0000, 0x0000 },
+ { 0x04C7, 0x04C8, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_196[] = {
+ { 0x00C4, 0x00E4, 0x0000, 0x0000 },
+ { 0x01C5, 0x01C6, 0x0000, 0x0000 },
+ { 0x1EDA, 0x1EDB, 0x0000, 0x0000 },
+ { 0x1FDB, 0x1F77, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_197[] = {
+ { 0x00C5, 0x00E5, 0x0000, 0x0000 },
+ { 0x01C4, 0x01C6, 0x0000, 0x0000 },
+ { 0x04C1, 0x04C2, 0x0000, 0x0000 },
+ { 0x1FDA, 0x1F76, 0x0000, 0x0000 },
+ { 0xFF3A, 0xFF5A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_198[] = {
+ { 0x00C6, 0x00E6, 0x0000, 0x0000 },
+ { 0x01C7, 0x01C9, 0x0000, 0x0000 },
+ { 0x1ED8, 0x1ED9, 0x0000, 0x0000 },
+ { 0x1FD9, 0x1FD1, 0x0000, 0x0000 },
+ { 0xFF39, 0xFF59, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_199[] = {
+ { 0x00C7, 0x00E7, 0x0000, 0x0000 },
+ { 0x04C3, 0x04C4, 0x0000, 0x0000 },
+ { 0x1FD8, 0x1FD0, 0x0000, 0x0000 },
+ { 0xFF38, 0xFF58, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_200[] = {
+ { 0x00C8, 0x00E8, 0x0000, 0x0000 },
+ { 0x1ED6, 0x1ED7, 0x0000, 0x0000 },
+ { 0x1FD7, 0x03B9, 0x0308, 0x0342 },
+ { 0xFF37, 0xFF57, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_201[] = {
+ { 0x00C9, 0x00E9, 0x0000, 0x0000 },
+ { 0x01C8, 0x01C9, 0x0000, 0x0000 },
+ { 0x04CD, 0x04CE, 0x0000, 0x0000 },
+ { 0x1FD6, 0x03B9, 0x0342, 0x0000 },
+ { 0xFF36, 0xFF56, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_202[] = {
+ { 0x00CA, 0x00EA, 0x0000, 0x0000 },
+ { 0x01CB, 0x01CC, 0x0000, 0x0000 },
+ { 0x1ED4, 0x1ED5, 0x0000, 0x0000 },
+ { 0xFF35, 0xFF55, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_203[] = {
+ { 0x00CB, 0x00EB, 0x0000, 0x0000 },
+ { 0x01CA, 0x01CC, 0x0000, 0x0000 },
+ { 0xFF34, 0xFF54, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_204[] = {
+ { 0x00CC, 0x00EC, 0x0000, 0x0000 },
+ { 0x01CD, 0x01CE, 0x0000, 0x0000 },
+ { 0x1ED2, 0x1ED3, 0x0000, 0x0000 },
+ { 0x1FD3, 0x03B9, 0x0308, 0x0301 },
+ { 0x2CE0, 0x2CE1, 0x0000, 0x0000 },
+ { 0xFF33, 0xFF53, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_205[] = {
+ { 0x00CD, 0x00ED, 0x0000, 0x0000 },
+ { 0x04C9, 0x04CA, 0x0000, 0x0000 },
+ { 0x1FD2, 0x03B9, 0x0308, 0x0300 },
+ { 0xFF32, 0xFF52, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_206[] = {
+ { 0x00CE, 0x00EE, 0x0000, 0x0000 },
+ { 0x01CF, 0x01D0, 0x0000, 0x0000 },
+ { 0x1ED0, 0x1ED1, 0x0000, 0x0000 },
+ { 0x2CE2, 0x2CE3, 0x0000, 0x0000 },
+ { 0xFF31, 0xFF51, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_207[] = {
+ { 0x00CF, 0x00EF, 0x0000, 0x0000 },
+ { 0x04CB, 0x04CC, 0x0000, 0x0000 },
+ { 0xFF30, 0xFF50, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_208[] = {
+ { 0x00D0, 0x00F0, 0x0000, 0x0000 },
+ { 0x01D1, 0x01D2, 0x0000, 0x0000 },
+ { 0x04D4, 0x04D5, 0x0000, 0x0000 },
+ { 0x10C0, 0x2D20, 0x0000, 0x0000 },
+ { 0x1ECE, 0x1ECF, 0x0000, 0x0000 },
+ { 0xFF2F, 0xFF4F, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_209[] = {
+ { 0x00D1, 0x00F1, 0x0000, 0x0000 },
+ { 0x10C1, 0x2D21, 0x0000, 0x0000 },
+ { 0xFF2E, 0xFF4E, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_210[] = {
+ { 0x00D2, 0x00F2, 0x0000, 0x0000 },
+ { 0x01D3, 0x01D4, 0x0000, 0x0000 },
+ { 0x03D1, 0x03B8, 0x0000, 0x0000 },
+ { 0x04D6, 0x04D7, 0x0000, 0x0000 },
+ { 0x10C2, 0x2D22, 0x0000, 0x0000 },
+ { 0x1ECC, 0x1ECD, 0x0000, 0x0000 },
+ { 0xFF2D, 0xFF4D, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_211[] = {
+ { 0x00D3, 0x00F3, 0x0000, 0x0000 },
+ { 0x03D0, 0x03B2, 0x0000, 0x0000 },
+ { 0x10C3, 0x2D23, 0x0000, 0x0000 },
+ { 0x1FCC, 0x03B7, 0x03B9, 0x0000 },
+ { 0xFF2C, 0xFF4C, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_212[] = {
+ { 0x00D4, 0x00F4, 0x0000, 0x0000 },
+ { 0x01D5, 0x01D6, 0x0000, 0x0000 },
+ { 0x04D0, 0x04D1, 0x0000, 0x0000 },
+ { 0x10C4, 0x2D24, 0x0000, 0x0000 },
+ { 0x1ECA, 0x1ECB, 0x0000, 0x0000 },
+ { 0x1FCB, 0x1F75, 0x0000, 0x0000 },
+ { 0xFF2B, 0xFF4B, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_213[] = {
+ { 0x00D5, 0x00F5, 0x0000, 0x0000 },
+ { 0x03D6, 0x03C0, 0x0000, 0x0000 },
+ { 0x10C5, 0x2D25, 0x0000, 0x0000 },
+ { 0x1FCA, 0x1F74, 0x0000, 0x0000 },
+ { 0xFF2A, 0xFF4A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_214[] = {
+ { 0x00D6, 0x00F6, 0x0000, 0x0000 },
+ { 0x01D7, 0x01D8, 0x0000, 0x0000 },
+ { 0x03D5, 0x03C6, 0x0000, 0x0000 },
+ { 0x04D2, 0x04D3, 0x0000, 0x0000 },
+ { 0x1EC8, 0x1EC9, 0x0000, 0x0000 },
+ { 0x1FC9, 0x1F73, 0x0000, 0x0000 },
+ { 0xFF29, 0xFF49, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_215[] = {
+ { 0x1FC8, 0x1F72, 0x0000, 0x0000 },
+ { 0xFF28, 0xFF48, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_216[] = {
+ { 0x00D8, 0x00F8, 0x0000, 0x0000 },
+ { 0x01D9, 0x01DA, 0x0000, 0x0000 },
+ { 0x04DC, 0x04DD, 0x0000, 0x0000 },
+ { 0x1EC6, 0x1EC7, 0x0000, 0x0000 },
+ { 0x1FC7, 0x03B7, 0x0342, 0x03B9 },
+ { 0xFF27, 0xFF47, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_217[] = {
+ { 0x00D9, 0x00F9, 0x0000, 0x0000 },
+ { 0x03DA, 0x03DB, 0x0000, 0x0000 },
+ { 0x1FC6, 0x03B7, 0x0342, 0x0000 },
+ { 0xFF26, 0xFF46, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_218[] = {
+ { 0x00DA, 0x00FA, 0x0000, 0x0000 },
+ { 0x01DB, 0x01DC, 0x0000, 0x0000 },
+ { 0x04DE, 0x04DF, 0x0000, 0x0000 },
+ { 0x1EC4, 0x1EC5, 0x0000, 0x0000 },
+ { 0xFF25, 0xFF45, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_219[] = {
+ { 0x00DB, 0x00FB, 0x0000, 0x0000 },
+ { 0x03D8, 0x03D9, 0x0000, 0x0000 },
+ { 0x1FC4, 0x03AE, 0x03B9, 0x0000 },
+ { 0xFF24, 0xFF44, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_220[] = {
+ { 0x00DC, 0x00FC, 0x0000, 0x0000 },
+ { 0x04D8, 0x04D9, 0x0000, 0x0000 },
+ { 0x1EC2, 0x1EC3, 0x0000, 0x0000 },
+ { 0x1FC3, 0x03B7, 0x03B9, 0x0000 },
+ { 0xFF23, 0xFF43, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_221[] = {
+ { 0x00DD, 0x00FD, 0x0000, 0x0000 },
+ { 0x03DE, 0x03DF, 0x0000, 0x0000 },
+ { 0x1FC2, 0x1F74, 0x03B9, 0x0000 },
+ { 0xFF22, 0xFF42, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_222[] = {
+ { 0x00DE, 0x00FE, 0x0000, 0x0000 },
+ { 0x04DA, 0x04DB, 0x0000, 0x0000 },
+ { 0x1EC0, 0x1EC1, 0x0000, 0x0000 },
+ { 0xFF21, 0xFF41, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_223[] = {
+ { 0x00DF, 0x0073, 0x0073, 0x0000 },
+ { 0x01DE, 0x01DF, 0x0000, 0x0000 },
+ { 0x03DC, 0x03DD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_224[] = {
+ { 0x04E4, 0x04E5, 0x0000, 0x0000 },
+ { 0x24C4, 0x24DE, 0x0000, 0x0000 },
+ { 0x2CCC, 0x2CCD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_225[] = {
+ { 0x01E0, 0x01E1, 0x0000, 0x0000 },
+ { 0x03E2, 0x03E3, 0x0000, 0x0000 },
+ { 0x24C5, 0x24DF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_226[] = {
+ { 0x04E6, 0x04E7, 0x0000, 0x0000 },
+ { 0x24C6, 0x24E0, 0x0000, 0x0000 },
+ { 0x2CCE, 0x2CCF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_227[] = {
+ { 0x01E2, 0x01E3, 0x0000, 0x0000 },
+ { 0x03E0, 0x03E1, 0x0000, 0x0000 },
+ { 0x1FFC, 0x03C9, 0x03B9, 0x0000 },
+ { 0x24C7, 0x24E1, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_228[] = {
+ { 0x04E0, 0x04E1, 0x0000, 0x0000 },
+ { 0x1FFB, 0x1F7D, 0x0000, 0x0000 },
+ { 0x24C0, 0x24DA, 0x0000, 0x0000 },
+ { 0x2CC8, 0x2CC9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_229[] = {
+ { 0x01E4, 0x01E5, 0x0000, 0x0000 },
+ { 0x03E6, 0x03E7, 0x0000, 0x0000 },
+ { 0x1FFA, 0x1F7C, 0x0000, 0x0000 },
+ { 0x24C1, 0x24DB, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_230[] = {
+ { 0x04E2, 0x04E3, 0x0000, 0x0000 },
+ { 0x1EF8, 0x1EF9, 0x0000, 0x0000 },
+ { 0x1FF9, 0x1F79, 0x0000, 0x0000 },
+ { 0x24C2, 0x24DC, 0x0000, 0x0000 },
+ { 0x2CCA, 0x2CCB, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_231[] = {
+ { 0x01E6, 0x01E7, 0x0000, 0x0000 },
+ { 0x03E4, 0x03E5, 0x0000, 0x0000 },
+ { 0x1FF8, 0x1F78, 0x0000, 0x0000 },
+ { 0x24C3, 0x24DD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_232[] = {
+ { 0x04EC, 0x04ED, 0x0000, 0x0000 },
+ { 0x1EF6, 0x1EF7, 0x0000, 0x0000 },
+ { 0x1FF7, 0x03C9, 0x0342, 0x03B9 },
+ { 0x24CC, 0x24E6, 0x0000, 0x0000 },
+ { 0x2CC4, 0x2CC5, 0x0000, 0x0000 },
+ { 0xFB13, 0x0574, 0x0576, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_233[] = {
+ { 0x01E8, 0x01E9, 0x0000, 0x0000 },
+ { 0x03EA, 0x03EB, 0x0000, 0x0000 },
+ { 0x1FF6, 0x03C9, 0x0342, 0x0000 },
+ { 0x24CD, 0x24E7, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_234[] = {
+ { 0x04EE, 0x04EF, 0x0000, 0x0000 },
+ { 0x1EF4, 0x1EF5, 0x0000, 0x0000 },
+ { 0x24CE, 0x24E8, 0x0000, 0x0000 },
+ { 0x2CC6, 0x2CC7, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_235[] = {
+ { 0x01EA, 0x01EB, 0x0000, 0x0000 },
+ { 0x03E8, 0x03E9, 0x0000, 0x0000 },
+ { 0x1FF4, 0x03CE, 0x03B9, 0x0000 },
+ { 0x24CF, 0x24E9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_236[] = {
+ { 0x04E8, 0x04E9, 0x0000, 0x0000 },
+ { 0x1EF2, 0x1EF3, 0x0000, 0x0000 },
+ { 0x1FF3, 0x03C9, 0x03B9, 0x0000 },
+ { 0x24C8, 0x24E2, 0x0000, 0x0000 },
+ { 0x2CC0, 0x2CC1, 0x0000, 0x0000 },
+ { 0xFB17, 0x0574, 0x056D, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_237[] = {
+ { 0x01EC, 0x01ED, 0x0000, 0x0000 },
+ { 0x03EE, 0x03EF, 0x0000, 0x0000 },
+ { 0x1FF2, 0x1F7C, 0x03B9, 0x0000 },
+ { 0x24C9, 0x24E3, 0x0000, 0x0000 },
+ { 0xFB16, 0x057E, 0x0576, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_238[] = {
+ { 0x04EA, 0x04EB, 0x0000, 0x0000 },
+ { 0x1EF0, 0x1EF1, 0x0000, 0x0000 },
+ { 0x24CA, 0x24E4, 0x0000, 0x0000 },
+ { 0x2CC2, 0x2CC3, 0x0000, 0x0000 },
+ { 0xFB15, 0x0574, 0x056B, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_239[] = {
+ { 0x01EE, 0x01EF, 0x0000, 0x0000 },
+ { 0x03EC, 0x03ED, 0x0000, 0x0000 },
+ { 0x24CB, 0x24E5, 0x0000, 0x0000 },
+ { 0xFB14, 0x0574, 0x0565, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_240[] = {
+ { 0x01F1, 0x01F3, 0x0000, 0x0000 },
+ { 0x04F4, 0x04F5, 0x0000, 0x0000 },
+ { 0x1EEE, 0x1EEF, 0x0000, 0x0000 },
+ { 0x2CDC, 0x2CDD, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_241[] = {
+ { 0x01F0, 0x006A, 0x030C, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_242[] = {
+ { 0x03F1, 0x03C1, 0x0000, 0x0000 },
+ { 0x04F6, 0x04F7, 0x0000, 0x0000 },
+ { 0x1EEC, 0x1EED, 0x0000, 0x0000 },
+ { 0x2CDE, 0x2CDF, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_243[] = {
+ { 0x01F2, 0x01F3, 0x0000, 0x0000 },
+ { 0x03F0, 0x03BA, 0x0000, 0x0000 },
+ { 0x1FEC, 0x1FE5, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_244[] = {
+ { 0x03F7, 0x03F8, 0x0000, 0x0000 },
+ { 0x04F0, 0x04F1, 0x0000, 0x0000 },
+ { 0x1EEA, 0x1EEB, 0x0000, 0x0000 },
+ { 0x1FEB, 0x1F7B, 0x0000, 0x0000 },
+ { 0x2CD8, 0x2CD9, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_245[] = {
+ { 0x01F4, 0x01F5, 0x0000, 0x0000 },
+ { 0x1FEA, 0x1F7A, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_246[] = {
+ { 0x01F7, 0x01BF, 0x0000, 0x0000 },
+ { 0x03F5, 0x03B5, 0x0000, 0x0000 },
+ { 0x04F2, 0x04F3, 0x0000, 0x0000 },
+ { 0x1EE8, 0x1EE9, 0x0000, 0x0000 },
+ { 0x1FE9, 0x1FE1, 0x0000, 0x0000 },
+ { 0x2CDA, 0x2CDB, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_247[] = {
+ { 0x01F6, 0x0195, 0x0000, 0x0000 },
+ { 0x03F4, 0x03B8, 0x0000, 0x0000 },
+ { 0x1FE8, 0x1FE0, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_248[] = {
+ { 0x1EE6, 0x1EE7, 0x0000, 0x0000 },
+ { 0x1FE7, 0x03C5, 0x0308, 0x0342 },
+ { 0x2CD4, 0x2CD5, 0x0000, 0x0000 },
+ { 0xFB03, 0x0066, 0x0066, 0x0069 }
+};
+
+static const CaseFoldMapping case_fold_249[] = {
+ { 0x01F8, 0x01F9, 0x0000, 0x0000 },
+ { 0x03FA, 0x03FB, 0x0000, 0x0000 },
+ { 0x1FE6, 0x03C5, 0x0342, 0x0000 },
+ { 0xFB02, 0x0066, 0x006C, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_250[] = {
+ { 0x03F9, 0x03F2, 0x0000, 0x0000 },
+ { 0x1EE4, 0x1EE5, 0x0000, 0x0000 },
+ { 0x2CD6, 0x2CD7, 0x0000, 0x0000 },
+ { 0xFB01, 0x0066, 0x0069, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_251[] = {
+ { 0x01FA, 0x01FB, 0x0000, 0x0000 },
+ { 0x1FE4, 0x03C1, 0x0313, 0x0000 },
+ { 0xFB00, 0x0066, 0x0066, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_252[] = {
+ { 0x04F8, 0x04F9, 0x0000, 0x0000 },
+ { 0x1EE2, 0x1EE3, 0x0000, 0x0000 },
+ { 0x1FE3, 0x03C5, 0x0308, 0x0301 },
+ { 0x2CD0, 0x2CD1, 0x0000, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_253[] = {
+ { 0x01FC, 0x01FD, 0x0000, 0x0000 },
+ { 0x1FE2, 0x03C5, 0x0308, 0x0300 },
+ { 0xFB06, 0x0073, 0x0074, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_254[] = {
+ { 0x1EE0, 0x1EE1, 0x0000, 0x0000 },
+ { 0x2CD2, 0x2CD3, 0x0000, 0x0000 },
+ { 0xFB05, 0x0073, 0x0074, 0x0000 }
+};
+
+static const CaseFoldMapping case_fold_255[] = {
+ { 0x01FE, 0x01FF, 0x0000, 0x0000 },
+ { 0xFB04, 0x0066, 0x0066, 0x006C }
+};
+
+
+static const CaseFoldHashBucket case_fold_hash[256] = {
+ { __PHYSFS_ARRAYLEN(case_fold_000), case_fold_000 },
+ { __PHYSFS_ARRAYLEN(case_fold_001), case_fold_001 },
+ { __PHYSFS_ARRAYLEN(case_fold_002), case_fold_002 },
+ { __PHYSFS_ARRAYLEN(case_fold_003), case_fold_003 },
+ { __PHYSFS_ARRAYLEN(case_fold_004), case_fold_004 },
+ { __PHYSFS_ARRAYLEN(case_fold_005), case_fold_005 },
+ { __PHYSFS_ARRAYLEN(case_fold_006), case_fold_006 },
+ { __PHYSFS_ARRAYLEN(case_fold_007), case_fold_007 },
+ { __PHYSFS_ARRAYLEN(case_fold_008), case_fold_008 },
+ { __PHYSFS_ARRAYLEN(case_fold_009), case_fold_009 },
+ { __PHYSFS_ARRAYLEN(case_fold_010), case_fold_010 },
+ { __PHYSFS_ARRAYLEN(case_fold_011), case_fold_011 },
+ { __PHYSFS_ARRAYLEN(case_fold_012), case_fold_012 },
+ { __PHYSFS_ARRAYLEN(case_fold_013), case_fold_013 },
+ { __PHYSFS_ARRAYLEN(case_fold_014), case_fold_014 },
+ { __PHYSFS_ARRAYLEN(case_fold_015), case_fold_015 },
+ { __PHYSFS_ARRAYLEN(case_fold_016), case_fold_016 },
+ { __PHYSFS_ARRAYLEN(case_fold_017), case_fold_017 },
+ { __PHYSFS_ARRAYLEN(case_fold_018), case_fold_018 },
+ { __PHYSFS_ARRAYLEN(case_fold_019), case_fold_019 },
+ { __PHYSFS_ARRAYLEN(case_fold_020), case_fold_020 },
+ { __PHYSFS_ARRAYLEN(case_fold_021), case_fold_021 },
+ { __PHYSFS_ARRAYLEN(case_fold_022), case_fold_022 },
+ { __PHYSFS_ARRAYLEN(case_fold_023), case_fold_023 },
+ { __PHYSFS_ARRAYLEN(case_fold_024), case_fold_024 },
+ { __PHYSFS_ARRAYLEN(case_fold_025), case_fold_025 },
+ { __PHYSFS_ARRAYLEN(case_fold_026), case_fold_026 },
+ { __PHYSFS_ARRAYLEN(case_fold_027), case_fold_027 },
+ { __PHYSFS_ARRAYLEN(case_fold_028), case_fold_028 },
+ { __PHYSFS_ARRAYLEN(case_fold_029), case_fold_029 },
+ { __PHYSFS_ARRAYLEN(case_fold_030), case_fold_030 },
+ { __PHYSFS_ARRAYLEN(case_fold_031), case_fold_031 },
+ { __PHYSFS_ARRAYLEN(case_fold_032), case_fold_032 },
+ { __PHYSFS_ARRAYLEN(case_fold_033), case_fold_033 },
+ { __PHYSFS_ARRAYLEN(case_fold_034), case_fold_034 },
+ { __PHYSFS_ARRAYLEN(case_fold_035), case_fold_035 },
+ { __PHYSFS_ARRAYLEN(case_fold_036), case_fold_036 },
+ { __PHYSFS_ARRAYLEN(case_fold_037), case_fold_037 },
+ { __PHYSFS_ARRAYLEN(case_fold_038), case_fold_038 },
+ { __PHYSFS_ARRAYLEN(case_fold_039), case_fold_039 },
+ { __PHYSFS_ARRAYLEN(case_fold_040), case_fold_040 },
+ { __PHYSFS_ARRAYLEN(case_fold_041), case_fold_041 },
+ { __PHYSFS_ARRAYLEN(case_fold_042), case_fold_042 },
+ { __PHYSFS_ARRAYLEN(case_fold_043), case_fold_043 },
+ { __PHYSFS_ARRAYLEN(case_fold_044), case_fold_044 },
+ { __PHYSFS_ARRAYLEN(case_fold_045), case_fold_045 },
+ { __PHYSFS_ARRAYLEN(case_fold_046), case_fold_046 },
+ { __PHYSFS_ARRAYLEN(case_fold_047), case_fold_047 },
+ { __PHYSFS_ARRAYLEN(case_fold_048), case_fold_048 },
+ { __PHYSFS_ARRAYLEN(case_fold_049), case_fold_049 },
+ { __PHYSFS_ARRAYLEN(case_fold_050), case_fold_050 },
+ { __PHYSFS_ARRAYLEN(case_fold_051), case_fold_051 },
+ { __PHYSFS_ARRAYLEN(case_fold_052), case_fold_052 },
+ { __PHYSFS_ARRAYLEN(case_fold_053), case_fold_053 },
+ { __PHYSFS_ARRAYLEN(case_fold_054), case_fold_054 },
+ { __PHYSFS_ARRAYLEN(case_fold_055), case_fold_055 },
+ { __PHYSFS_ARRAYLEN(case_fold_056), case_fold_056 },
+ { __PHYSFS_ARRAYLEN(case_fold_057), case_fold_057 },
+ { __PHYSFS_ARRAYLEN(case_fold_058), case_fold_058 },
+ { __PHYSFS_ARRAYLEN(case_fold_059), case_fold_059 },
+ { __PHYSFS_ARRAYLEN(case_fold_060), case_fold_060 },
+ { __PHYSFS_ARRAYLEN(case_fold_061), case_fold_061 },
+ { __PHYSFS_ARRAYLEN(case_fold_062), case_fold_062 },
+ { __PHYSFS_ARRAYLEN(case_fold_063), case_fold_063 },
+ { __PHYSFS_ARRAYLEN(case_fold_064), case_fold_064 },
+ { __PHYSFS_ARRAYLEN(case_fold_065), case_fold_065 },
+ { __PHYSFS_ARRAYLEN(case_fold_066), case_fold_066 },
+ { __PHYSFS_ARRAYLEN(case_fold_067), case_fold_067 },
+ { __PHYSFS_ARRAYLEN(case_fold_068), case_fold_068 },
+ { __PHYSFS_ARRAYLEN(case_fold_069), case_fold_069 },
+ { __PHYSFS_ARRAYLEN(case_fold_070), case_fold_070 },
+ { __PHYSFS_ARRAYLEN(case_fold_071), case_fold_071 },
+ { __PHYSFS_ARRAYLEN(case_fold_072), case_fold_072 },
+ { __PHYSFS_ARRAYLEN(case_fold_073), case_fold_073 },
+ { __PHYSFS_ARRAYLEN(case_fold_074), case_fold_074 },
+ { __PHYSFS_ARRAYLEN(case_fold_075), case_fold_075 },
+ { __PHYSFS_ARRAYLEN(case_fold_076), case_fold_076 },
+ { __PHYSFS_ARRAYLEN(case_fold_077), case_fold_077 },
+ { __PHYSFS_ARRAYLEN(case_fold_078), case_fold_078 },
+ { __PHYSFS_ARRAYLEN(case_fold_079), case_fold_079 },
+ { __PHYSFS_ARRAYLEN(case_fold_080), case_fold_080 },
+ { __PHYSFS_ARRAYLEN(case_fold_081), case_fold_081 },
+ { __PHYSFS_ARRAYLEN(case_fold_082), case_fold_082 },
+ { __PHYSFS_ARRAYLEN(case_fold_083), case_fold_083 },
+ { __PHYSFS_ARRAYLEN(case_fold_084), case_fold_084 },
+ { __PHYSFS_ARRAYLEN(case_fold_085), case_fold_085 },
+ { __PHYSFS_ARRAYLEN(case_fold_086), case_fold_086 },
+ { __PHYSFS_ARRAYLEN(case_fold_087), case_fold_087 },
+ { __PHYSFS_ARRAYLEN(case_fold_088), case_fold_088 },
+ { __PHYSFS_ARRAYLEN(case_fold_089), case_fold_089 },
+ { __PHYSFS_ARRAYLEN(case_fold_090), case_fold_090 },
+ { __PHYSFS_ARRAYLEN(case_fold_091), case_fold_091 },
+ { __PHYSFS_ARRAYLEN(case_fold_092), case_fold_092 },
+ { __PHYSFS_ARRAYLEN(case_fold_093), case_fold_093 },
+ { __PHYSFS_ARRAYLEN(case_fold_094), case_fold_094 },
+ { __PHYSFS_ARRAYLEN(case_fold_095), case_fold_095 },
+ { __PHYSFS_ARRAYLEN(case_fold_096), case_fold_096 },
+ { __PHYSFS_ARRAYLEN(case_fold_097), case_fold_097 },
+ { __PHYSFS_ARRAYLEN(case_fold_098), case_fold_098 },
+ { __PHYSFS_ARRAYLEN(case_fold_099), case_fold_099 },
+ { __PHYSFS_ARRAYLEN(case_fold_100), case_fold_100 },
+ { __PHYSFS_ARRAYLEN(case_fold_101), case_fold_101 },
+ { __PHYSFS_ARRAYLEN(case_fold_102), case_fold_102 },
+ { __PHYSFS_ARRAYLEN(case_fold_103), case_fold_103 },
+ { __PHYSFS_ARRAYLEN(case_fold_104), case_fold_104 },
+ { __PHYSFS_ARRAYLEN(case_fold_105), case_fold_105 },
+ { __PHYSFS_ARRAYLEN(case_fold_106), case_fold_106 },
+ { __PHYSFS_ARRAYLEN(case_fold_107), case_fold_107 },
+ { __PHYSFS_ARRAYLEN(case_fold_108), case_fold_108 },
+ { __PHYSFS_ARRAYLEN(case_fold_109), case_fold_109 },
+ { __PHYSFS_ARRAYLEN(case_fold_110), case_fold_110 },
+ { __PHYSFS_ARRAYLEN(case_fold_111), case_fold_111 },
+ { __PHYSFS_ARRAYLEN(case_fold_112), case_fold_112 },
+ { __PHYSFS_ARRAYLEN(case_fold_113), case_fold_113 },
+ { __PHYSFS_ARRAYLEN(case_fold_114), case_fold_114 },
+ { __PHYSFS_ARRAYLEN(case_fold_115), case_fold_115 },
+ { __PHYSFS_ARRAYLEN(case_fold_116), case_fold_116 },
+ { __PHYSFS_ARRAYLEN(case_fold_117), case_fold_117 },
+ { __PHYSFS_ARRAYLEN(case_fold_118), case_fold_118 },
+ { __PHYSFS_ARRAYLEN(case_fold_119), case_fold_119 },
+ { __PHYSFS_ARRAYLEN(case_fold_120), case_fold_120 },
+ { __PHYSFS_ARRAYLEN(case_fold_121), case_fold_121 },
+ { __PHYSFS_ARRAYLEN(case_fold_122), case_fold_122 },
+ { 0, NULL },
+ { __PHYSFS_ARRAYLEN(case_fold_124), case_fold_124 },
+ { 0, NULL },
+ { __PHYSFS_ARRAYLEN(case_fold_126), case_fold_126 },
+ { 0, NULL },
+ { __PHYSFS_ARRAYLEN(case_fold_128), case_fold_128 },
+ { __PHYSFS_ARRAYLEN(case_fold_129), case_fold_129 },
+ { __PHYSFS_ARRAYLEN(case_fold_130), case_fold_130 },
+ { __PHYSFS_ARRAYLEN(case_fold_131), case_fold_131 },
+ { __PHYSFS_ARRAYLEN(case_fold_132), case_fold_132 },
+ { __PHYSFS_ARRAYLEN(case_fold_133), case_fold_133 },
+ { __PHYSFS_ARRAYLEN(case_fold_134), case_fold_134 },
+ { __PHYSFS_ARRAYLEN(case_fold_135), case_fold_135 },
+ { __PHYSFS_ARRAYLEN(case_fold_136), case_fold_136 },
+ { __PHYSFS_ARRAYLEN(case_fold_137), case_fold_137 },
+ { __PHYSFS_ARRAYLEN(case_fold_138), case_fold_138 },
+ { __PHYSFS_ARRAYLEN(case_fold_139), case_fold_139 },
+ { __PHYSFS_ARRAYLEN(case_fold_140), case_fold_140 },
+ { __PHYSFS_ARRAYLEN(case_fold_141), case_fold_141 },
+ { __PHYSFS_ARRAYLEN(case_fold_142), case_fold_142 },
+ { __PHYSFS_ARRAYLEN(case_fold_143), case_fold_143 },
+ { __PHYSFS_ARRAYLEN(case_fold_144), case_fold_144 },
+ { __PHYSFS_ARRAYLEN(case_fold_145), case_fold_145 },
+ { __PHYSFS_ARRAYLEN(case_fold_146), case_fold_146 },
+ { __PHYSFS_ARRAYLEN(case_fold_147), case_fold_147 },
+ { __PHYSFS_ARRAYLEN(case_fold_148), case_fold_148 },
+ { __PHYSFS_ARRAYLEN(case_fold_149), case_fold_149 },
+ { __PHYSFS_ARRAYLEN(case_fold_150), case_fold_150 },
+ { __PHYSFS_ARRAYLEN(case_fold_151), case_fold_151 },
+ { __PHYSFS_ARRAYLEN(case_fold_152), case_fold_152 },
+ { __PHYSFS_ARRAYLEN(case_fold_153), case_fold_153 },
+ { __PHYSFS_ARRAYLEN(case_fold_154), case_fold_154 },
+ { __PHYSFS_ARRAYLEN(case_fold_155), case_fold_155 },
+ { __PHYSFS_ARRAYLEN(case_fold_156), case_fold_156 },
+ { __PHYSFS_ARRAYLEN(case_fold_157), case_fold_157 },
+ { __PHYSFS_ARRAYLEN(case_fold_158), case_fold_158 },
+ { __PHYSFS_ARRAYLEN(case_fold_159), case_fold_159 },
+ { __PHYSFS_ARRAYLEN(case_fold_160), case_fold_160 },
+ { __PHYSFS_ARRAYLEN(case_fold_161), case_fold_161 },
+ { __PHYSFS_ARRAYLEN(case_fold_162), case_fold_162 },
+ { __PHYSFS_ARRAYLEN(case_fold_163), case_fold_163 },
+ { __PHYSFS_ARRAYLEN(case_fold_164), case_fold_164 },
+ { __PHYSFS_ARRAYLEN(case_fold_165), case_fold_165 },
+ { __PHYSFS_ARRAYLEN(case_fold_166), case_fold_166 },
+ { __PHYSFS_ARRAYLEN(case_fold_167), case_fold_167 },
+ { __PHYSFS_ARRAYLEN(case_fold_168), case_fold_168 },
+ { __PHYSFS_ARRAYLEN(case_fold_169), case_fold_169 },
+ { __PHYSFS_ARRAYLEN(case_fold_170), case_fold_170 },
+ { __PHYSFS_ARRAYLEN(case_fold_171), case_fold_171 },
+ { __PHYSFS_ARRAYLEN(case_fold_172), case_fold_172 },
+ { __PHYSFS_ARRAYLEN(case_fold_173), case_fold_173 },
+ { __PHYSFS_ARRAYLEN(case_fold_174), case_fold_174 },
+ { __PHYSFS_ARRAYLEN(case_fold_175), case_fold_175 },
+ { __PHYSFS_ARRAYLEN(case_fold_176), case_fold_176 },
+ { __PHYSFS_ARRAYLEN(case_fold_177), case_fold_177 },
+ { __PHYSFS_ARRAYLEN(case_fold_178), case_fold_178 },
+ { __PHYSFS_ARRAYLEN(case_fold_179), case_fold_179 },
+ { __PHYSFS_ARRAYLEN(case_fold_180), case_fold_180 },
+ { __PHYSFS_ARRAYLEN(case_fold_181), case_fold_181 },
+ { __PHYSFS_ARRAYLEN(case_fold_182), case_fold_182 },
+ { __PHYSFS_ARRAYLEN(case_fold_183), case_fold_183 },
+ { __PHYSFS_ARRAYLEN(case_fold_184), case_fold_184 },
+ { __PHYSFS_ARRAYLEN(case_fold_185), case_fold_185 },
+ { __PHYSFS_ARRAYLEN(case_fold_186), case_fold_186 },
+ { __PHYSFS_ARRAYLEN(case_fold_187), case_fold_187 },
+ { __PHYSFS_ARRAYLEN(case_fold_188), case_fold_188 },
+ { __PHYSFS_ARRAYLEN(case_fold_189), case_fold_189 },
+ { __PHYSFS_ARRAYLEN(case_fold_190), case_fold_190 },
+ { __PHYSFS_ARRAYLEN(case_fold_191), case_fold_191 },
+ { __PHYSFS_ARRAYLEN(case_fold_192), case_fold_192 },
+ { __PHYSFS_ARRAYLEN(case_fold_193), case_fold_193 },
+ { __PHYSFS_ARRAYLEN(case_fold_194), case_fold_194 },
+ { __PHYSFS_ARRAYLEN(case_fold_195), case_fold_195 },
+ { __PHYSFS_ARRAYLEN(case_fold_196), case_fold_196 },
+ { __PHYSFS_ARRAYLEN(case_fold_197), case_fold_197 },
+ { __PHYSFS_ARRAYLEN(case_fold_198), case_fold_198 },
+ { __PHYSFS_ARRAYLEN(case_fold_199), case_fold_199 },
+ { __PHYSFS_ARRAYLEN(case_fold_200), case_fold_200 },
+ { __PHYSFS_ARRAYLEN(case_fold_201), case_fold_201 },
+ { __PHYSFS_ARRAYLEN(case_fold_202), case_fold_202 },
+ { __PHYSFS_ARRAYLEN(case_fold_203), case_fold_203 },
+ { __PHYSFS_ARRAYLEN(case_fold_204), case_fold_204 },
+ { __PHYSFS_ARRAYLEN(case_fold_205), case_fold_205 },
+ { __PHYSFS_ARRAYLEN(case_fold_206), case_fold_206 },
+ { __PHYSFS_ARRAYLEN(case_fold_207), case_fold_207 },
+ { __PHYSFS_ARRAYLEN(case_fold_208), case_fold_208 },
+ { __PHYSFS_ARRAYLEN(case_fold_209), case_fold_209 },
+ { __PHYSFS_ARRAYLEN(case_fold_210), case_fold_210 },
+ { __PHYSFS_ARRAYLEN(case_fold_211), case_fold_211 },
+ { __PHYSFS_ARRAYLEN(case_fold_212), case_fold_212 },
+ { __PHYSFS_ARRAYLEN(case_fold_213), case_fold_213 },
+ { __PHYSFS_ARRAYLEN(case_fold_214), case_fold_214 },
+ { __PHYSFS_ARRAYLEN(case_fold_215), case_fold_215 },
+ { __PHYSFS_ARRAYLEN(case_fold_216), case_fold_216 },
+ { __PHYSFS_ARRAYLEN(case_fold_217), case_fold_217 },
+ { __PHYSFS_ARRAYLEN(case_fold_218), case_fold_218 },
+ { __PHYSFS_ARRAYLEN(case_fold_219), case_fold_219 },
+ { __PHYSFS_ARRAYLEN(case_fold_220), case_fold_220 },
+ { __PHYSFS_ARRAYLEN(case_fold_221), case_fold_221 },
+ { __PHYSFS_ARRAYLEN(case_fold_222), case_fold_222 },
+ { __PHYSFS_ARRAYLEN(case_fold_223), case_fold_223 },
+ { __PHYSFS_ARRAYLEN(case_fold_224), case_fold_224 },
+ { __PHYSFS_ARRAYLEN(case_fold_225), case_fold_225 },
+ { __PHYSFS_ARRAYLEN(case_fold_226), case_fold_226 },
+ { __PHYSFS_ARRAYLEN(case_fold_227), case_fold_227 },
+ { __PHYSFS_ARRAYLEN(case_fold_228), case_fold_228 },
+ { __PHYSFS_ARRAYLEN(case_fold_229), case_fold_229 },
+ { __PHYSFS_ARRAYLEN(case_fold_230), case_fold_230 },
+ { __PHYSFS_ARRAYLEN(case_fold_231), case_fold_231 },
+ { __PHYSFS_ARRAYLEN(case_fold_232), case_fold_232 },
+ { __PHYSFS_ARRAYLEN(case_fold_233), case_fold_233 },
+ { __PHYSFS_ARRAYLEN(case_fold_234), case_fold_234 },
+ { __PHYSFS_ARRAYLEN(case_fold_235), case_fold_235 },
+ { __PHYSFS_ARRAYLEN(case_fold_236), case_fold_236 },
+ { __PHYSFS_ARRAYLEN(case_fold_237), case_fold_237 },
+ { __PHYSFS_ARRAYLEN(case_fold_238), case_fold_238 },
+ { __PHYSFS_ARRAYLEN(case_fold_239), case_fold_239 },
+ { __PHYSFS_ARRAYLEN(case_fold_240), case_fold_240 },
+ { __PHYSFS_ARRAYLEN(case_fold_241), case_fold_241 },
+ { __PHYSFS_ARRAYLEN(case_fold_242), case_fold_242 },
+ { __PHYSFS_ARRAYLEN(case_fold_243), case_fold_243 },
+ { __PHYSFS_ARRAYLEN(case_fold_244), case_fold_244 },
+ { __PHYSFS_ARRAYLEN(case_fold_245), case_fold_245 },
+ { __PHYSFS_ARRAYLEN(case_fold_246), case_fold_246 },
+ { __PHYSFS_ARRAYLEN(case_fold_247), case_fold_247 },
+ { __PHYSFS_ARRAYLEN(case_fold_248), case_fold_248 },
+ { __PHYSFS_ARRAYLEN(case_fold_249), case_fold_249 },
+ { __PHYSFS_ARRAYLEN(case_fold_250), case_fold_250 },
+ { __PHYSFS_ARRAYLEN(case_fold_251), case_fold_251 },
+ { __PHYSFS_ARRAYLEN(case_fold_252), case_fold_252 },
+ { __PHYSFS_ARRAYLEN(case_fold_253), case_fold_253 },
+ { __PHYSFS_ARRAYLEN(case_fold_254), case_fold_254 },
+ { __PHYSFS_ARRAYLEN(case_fold_255), case_fold_255 },
+};
+
diff --git a/misc/libphysfs/physfs_internal.h b/misc/libphysfs/physfs_internal.h
new file mode 100644
index 0000000..1dec63f
--- /dev/null
+++ b/misc/libphysfs/physfs_internal.h
@@ -0,0 +1,776 @@
+/*
+ * Internal function/structure declaration. Do NOT include in your
+ * application.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#ifndef _INCLUDE_PHYSFS_INTERNAL_H_
+#define _INCLUDE_PHYSFS_INTERNAL_H_
+
+#ifndef __PHYSICSFS_INTERNAL__
+#error Do not include this header from your applications.
+#endif
+
+#include "physfs.h"
+
+/* The holy trinity. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "physfs_platforms.h"
+
+#include <assert.h>
+
+/* !!! FIXME: remove this when revamping stack allocation code... */
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <malloc.h>
+#endif
+
+#if PHYSFS_PLATFORM_SOLARIS
+#include <alloca.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __GNUC__
+#define PHYSFS_MINIMUM_GCC_VERSION(major, minor) \
+ ( ((__GNUC__ << 16) + __GNUC_MINOR__) >= (((major) << 16) + (minor)) )
+#else
+#define PHYSFS_MINIMUM_GCC_VERSION(major, minor) (0)
+#endif
+
+#ifdef __cplusplus
+ /* C++ always has a real inline keyword. */
+#elif (defined macintosh) && !(defined __MWERKS__)
+# define inline
+#elif (defined _MSC_VER)
+# define inline __inline
+#endif
+
+#if PHYSFS_PLATFORM_LINUX && !defined(_FILE_OFFSET_BITS)
+#define _FILE_OFFSET_BITS 64
+#endif
+
+/*
+ * Interface for small allocations. If you need a little scratch space for
+ * a throwaway buffer or string, use this. It will make small allocations
+ * on the stack if possible, and use allocator.Malloc() if they are too
+ * large. This helps reduce malloc pressure.
+ * There are some rules, though:
+ * NEVER return a pointer from this, as stack-allocated buffers go away
+ * when your function returns.
+ * NEVER allocate in a loop, as stack-allocated pointers will pile up. Call
+ * a function that uses smallAlloc from your loop, so the allocation can
+ * free each time.
+ * NEVER call smallAlloc with any complex expression (it's a macro that WILL
+ * have side effects...it references the argument multiple times). Use a
+ * variable or a literal.
+ * NEVER free a pointer from this with anything but smallFree. It will not
+ * be a valid pointer to the allocator, regardless of where the memory came
+ * from.
+ * NEVER realloc a pointer from this.
+ * NEVER forget to use smallFree: it may not be a pointer from the stack.
+ * NEVER forget to check for NULL...allocation can fail here, of course!
+ */
+#define __PHYSFS_SMALLALLOCTHRESHOLD 256
+void *__PHYSFS_initSmallAlloc(void *ptr, PHYSFS_uint64 len);
+
+#define __PHYSFS_smallAlloc(bytes) ( \
+ __PHYSFS_initSmallAlloc( \
+ (((bytes) < __PHYSFS_SMALLALLOCTHRESHOLD) ? \
+ alloca((size_t)((bytes)+sizeof(void*))) : NULL), (bytes)) \
+)
+
+void __PHYSFS_smallFree(void *ptr);
+
+
+/* Use the allocation hooks. */
+#define malloc(x) Do not use malloc() directly.
+#define realloc(x, y) Do not use realloc() directly.
+#define free(x) Do not use free() directly.
+/* !!! FIXME: add alloca check here. */
+
+#ifndef PHYSFS_SUPPORTS_ZIP
+#define PHYSFS_SUPPORTS_ZIP 1
+#endif
+#ifndef PHYSFS_SUPPORTS_7Z
+#define PHYSFS_SUPPORTS_7Z 0
+#endif
+#ifndef PHYSFS_SUPPORTS_GRP
+#define PHYSFS_SUPPORTS_GRP 0
+#endif
+#ifndef PHYSFS_SUPPORTS_HOG
+#define PHYSFS_SUPPORTS_HOG 0
+#endif
+#ifndef PHYSFS_SUPPORTS_MVL
+#define PHYSFS_SUPPORTS_MVL 0
+#endif
+#ifndef PHYSFS_SUPPORTS_WAD
+#define PHYSFS_SUPPORTS_WAD 0
+#endif
+#ifndef PHYSFS_SUPPORTS_ISO9660
+#define PHYSFS_SUPPORTS_ISO9660 0
+#endif
+
+/* The latest supported PHYSFS_Io::version value. */
+#define CURRENT_PHYSFS_IO_API_VERSION 0
+
+/* Opaque data for file and dir handlers... */
+typedef void PHYSFS_Dir;
+
+typedef struct
+{
+ /*
+ * Basic info about this archiver...
+ */
+ const PHYSFS_ArchiveInfo info;
+
+
+ /*
+ * DIRECTORY ROUTINES:
+ * These functions are for dir handles. Generate a handle with the
+ * openArchive() method, then pass it as the "opaque" PHYSFS_Dir to the
+ * others.
+ *
+ * Symlinks should always be followed (except in stat()); PhysicsFS will
+ * use the stat() method to check for symlinks and make a judgement on
+ * whether to continue to call other methods based on that.
+ */
+
+ /*
+ * Open a dirhandle for dir/archive data provided by (io).
+ * (name) is a filename associated with (io), but doesn't necessarily
+ * map to anything, let alone a real filename. This possibly-
+ * meaningless name is in platform-dependent notation.
+ * (forWrite) is non-zero if this is to be used for
+ * the write directory, and zero if this is to be used for an
+ * element of the search path.
+ * Returns NULL on failure. We ignore any error code you set here.
+ * Returns non-NULL on success. The pointer returned will be
+ * passed as the "opaque" parameter for later calls.
+ */
+ PHYSFS_Dir *(*openArchive)(PHYSFS_Io *io, const char *name, int forWrite);
+
+ /*
+ * List all files in (dirname). Each file is passed to (cb),
+ * where a copy is made if appropriate, so you should dispose of
+ * it properly upon return from the callback.
+ * You should omit symlinks if (omitSymLinks) is non-zero.
+ * If you have a failure, report as much as you can.
+ * (dirname) is in platform-independent notation.
+ */
+ void (*enumerateFiles)(PHYSFS_Dir *opaque, const char *dirname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata);
+
+ /*
+ * Open file for reading.
+ * This filename, (fnm), is in platform-independent notation.
+ * If you can't handle multiple opens of the same file,
+ * you can opt to fail for the second call.
+ * Fail if the file does not exist.
+ * Returns NULL on failure, and calls __PHYSFS_setError().
+ * Returns non-NULL on success. The pointer returned will be
+ * passed as the "opaque" parameter for later file calls.
+ *
+ * Regardless of success or failure, please set *exists to
+ * non-zero if the file existed (even if it's a broken symlink!),
+ * zero if it did not.
+ */
+ PHYSFS_Io *(*openRead)(PHYSFS_Dir *opaque, const char *fnm, int *exists);
+
+ /*
+ * Open file for writing.
+ * If the file does not exist, it should be created. If it exists,
+ * it should be truncated to zero bytes. The writing
+ * offset should be the start of the file.
+ * This filename is in platform-independent notation.
+ * If you can't handle multiple opens of the same file,
+ * you can opt to fail for the second call.
+ * Returns NULL on failure, and calls __PHYSFS_setError().
+ * Returns non-NULL on success. The pointer returned will be
+ * passed as the "opaque" parameter for later file calls.
+ */
+ PHYSFS_Io *(*openWrite)(PHYSFS_Dir *opaque, const char *filename);
+
+ /*
+ * Open file for appending.
+ * If the file does not exist, it should be created. The writing
+ * offset should be the end of the file.
+ * This filename is in platform-independent notation.
+ * If you can't handle multiple opens of the same file,
+ * you can opt to fail for the second call.
+ * Returns NULL on failure, and calls __PHYSFS_setError().
+ * Returns non-NULL on success. The pointer returned will be
+ * passed as the "opaque" parameter for later file calls.
+ */
+ PHYSFS_Io *(*openAppend)(PHYSFS_Dir *opaque, const char *filename);
+
+ /*
+ * Delete a file in the archive/directory.
+ * Return non-zero on success, zero on failure.
+ * This filename is in platform-independent notation.
+ * This method may be NULL.
+ * On failure, call __PHYSFS_setError().
+ */
+ int (*remove)(PHYSFS_Dir *opaque, const char *filename);
+
+ /*
+ * Create a directory in the archive/directory.
+ * If the application is trying to make multiple dirs, PhysicsFS
+ * will split them up into multiple calls before passing them to
+ * your driver.
+ * Return non-zero on success, zero on failure.
+ * This filename is in platform-independent notation.
+ * This method may be NULL.
+ * On failure, call __PHYSFS_setError().
+ */
+ int (*mkdir)(PHYSFS_Dir *opaque, const char *filename);
+
+ /*
+ * Close directories/archives, and free any associated memory,
+ * including the original PHYSFS_Io and (opaque) itself, if
+ * applicable. Implementation can assume that it won't be called if
+ * there are still files open from this archive.
+ */
+ void (*closeArchive)(PHYSFS_Dir *opaque);
+
+ /*
+ * Obtain basic file metadata.
+ * Returns non-zero on success, zero on failure.
+ * On failure, call __PHYSFS_setError().
+ */
+ int (*stat)(PHYSFS_Dir *opaque, const char *fn,
+ int *exists, PHYSFS_Stat *stat);
+} PHYSFS_Archiver;
+
+
+/*
+ * Call this to set the message returned by PHYSFS_getLastError().
+ * Please only use the ERR_* constants above, or add new constants to the
+ * above group, but I want these all in one place.
+ *
+ * Calling this with a NULL argument is a safe no-op.
+ */
+void __PHYSFS_setError(const PHYSFS_ErrorCode err);
+
+
+/* This byteorder stuff was lifted from SDL. http://www.libsdl.org/ */
+#define PHYSFS_LIL_ENDIAN 1234
+#define PHYSFS_BIG_ENDIAN 4321
+
+#if defined(__i386__) || defined(__ia64__) || \
+ defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) || \
+ (defined(__alpha__) || defined(__alpha)) || \
+ defined(__arm__) || defined(ARM) || \
+ (defined(__mips__) && defined(__MIPSEL__)) || \
+ defined(__SYMBIAN32__) || \
+ defined(__x86_64__) || \
+ defined(__LITTLE_ENDIAN__)
+#define PHYSFS_BYTEORDER PHYSFS_LIL_ENDIAN
+#else
+#define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN
+#endif
+
+
+/*
+ * When sorting the entries in an archive, we use a modified QuickSort.
+ * When there are less then PHYSFS_QUICKSORT_THRESHOLD entries left to sort,
+ * we switch over to a BubbleSort for the remainder. Tweak to taste.
+ *
+ * You can override this setting by defining PHYSFS_QUICKSORT_THRESHOLD
+ * before #including "physfs_internal.h".
+ */
+#ifndef PHYSFS_QUICKSORT_THRESHOLD
+#define PHYSFS_QUICKSORT_THRESHOLD 4
+#endif
+
+/*
+ * Sort an array (or whatever) of (max) elements. This uses a mixture of
+ * a QuickSort and BubbleSort internally.
+ * (cmpfn) is used to determine ordering, and (swapfn) does the actual
+ * swapping of elements in the list.
+ *
+ * See zip.c for an example.
+ */
+void __PHYSFS_sort(void *entries, size_t max,
+ int (*cmpfn)(void *, size_t, size_t),
+ void (*swapfn)(void *, size_t, size_t));
+
+/*
+ * This isn't a formal error code, it's just for BAIL_MACRO.
+ * It means: there was an error, but someone else already set it for us.
+ */
+#define ERRPASS PHYSFS_ERR_OK
+
+/* These get used all over for lessening code clutter. */
+#define BAIL_MACRO(e, r) do { if (e) __PHYSFS_setError(e); return r; } while (0)
+#define BAIL_IF_MACRO(c, e, r) do { if (c) { if (e) __PHYSFS_setError(e); return r; } } while (0)
+#define BAIL_MACRO_MUTEX(e, m, r) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0)
+#define BAIL_IF_MACRO_MUTEX(c, e, m, r) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0)
+#define GOTO_MACRO(e, g) do { if (e) __PHYSFS_setError(e); goto g; } while (0)
+#define GOTO_IF_MACRO(c, e, g) do { if (c) { if (e) __PHYSFS_setError(e); goto g; } } while (0)
+#define GOTO_MACRO_MUTEX(e, m, g) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0)
+#define GOTO_IF_MACRO_MUTEX(c, e, m, g) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0)
+
+#define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) )
+
+#ifdef PHYSFS_NO_64BIT_SUPPORT
+#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
+#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
+#elif (defined __GNUC__)
+#define __PHYSFS_SI64(x) x##LL
+#define __PHYSFS_UI64(x) x##ULL
+#elif (defined _MSC_VER)
+#define __PHYSFS_SI64(x) x##i64
+#define __PHYSFS_UI64(x) x##ui64
+#else
+#define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x))
+#define __PHYSFS_UI64(x) ((PHYSFS_uint64) (x))
+#endif
+
+
+/*
+ * Check if a ui64 will fit in the platform's address space.
+ * The initial sizeof check will optimize this macro out entirely on
+ * 64-bit (and larger?!) platforms, and the other condition will
+ * return zero or non-zero if the variable will fit in the platform's
+ * size_t, suitable to pass to malloc. This is kinda messy, but effective.
+ */
+#define __PHYSFS_ui64FitsAddressSpace(s) ( \
+ (sizeof (PHYSFS_uint64) <= sizeof (size_t)) || \
+ ((s) < (__PHYSFS_UI64(0xFFFFFFFFFFFFFFFF) >> (64-(sizeof(size_t)*8)))) \
+)
+
+
+/*
+ * This is a strcasecmp() or stricmp() replacement that expects both strings
+ * to be in UTF-8 encoding. It will do "case folding" to decide if the
+ * Unicode codepoints in the strings match.
+ *
+ * It will report which string is "greater than" the other, but be aware that
+ * this doesn't necessarily mean anything: 'a' may be "less than" 'b', but
+ * a random Kanji codepoint has no meaningful alphabetically relationship to
+ * a Greek Lambda, but being able to assign a reliable "value" makes sorting
+ * algorithms possible, if not entirely sane. Most cases should treat the
+ * return value as "equal" or "not equal".
+ */
+int __PHYSFS_utf8stricmp(const char *s1, const char *s2);
+
+/*
+ * This works like __PHYSFS_utf8stricmp(), but takes a character (NOT BYTE
+ * COUNT) argument, like strcasencmp().
+ */
+int __PHYSFS_utf8strnicmp(const char *s1, const char *s2, PHYSFS_uint32 l);
+
+/*
+ * stricmp() that guarantees to only work with low ASCII. The C runtime
+ * stricmp() might try to apply a locale/codepage/etc, which we don't want.
+ */
+int __PHYSFS_stricmpASCII(const char *s1, const char *s2);
+
+/*
+ * strnicmp() that guarantees to only work with low ASCII. The C runtime
+ * strnicmp() might try to apply a locale/codepage/etc, which we don't want.
+ */
+int __PHYSFS_strnicmpASCII(const char *s1, const char *s2, PHYSFS_uint32 l);
+
+
+/*
+ * The current allocator. Not valid before PHYSFS_init is called!
+ */
+extern PHYSFS_Allocator __PHYSFS_AllocatorHooks;
+
+/* convenience macro to make this less cumbersome internally... */
+#define allocator __PHYSFS_AllocatorHooks
+
+/*
+ * Create a PHYSFS_Io for a file in the physical filesystem.
+ * This path is in platform-dependent notation. (mode) must be 'r', 'w', or
+ * 'a' for Read, Write, or Append.
+ */
+PHYSFS_Io *__PHYSFS_createNativeIo(const char *path, const int mode);
+
+/*
+ * Create a PHYSFS_Io for a buffer of memory (READ-ONLY). If you already
+ * have one of these, just use its duplicate() method, and it'll increment
+ * its refcount without allocating a copy of the buffer.
+ */
+PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
+ void (*destruct)(void *));
+
+
+/*
+ * Read (len) bytes from (io) into (buf). Returns non-zero on success,
+ * zero on i/o error. Literally: "return (io->read(io, buf, len) == len);"
+ */
+int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const PHYSFS_uint64 len);
+
+
+/* These are shared between some archivers. */
+
+typedef struct
+{
+ char name[56];
+ PHYSFS_uint32 startPos;
+ PHYSFS_uint32 size;
+} UNPKentry;
+
+void UNPK_closeArchive(PHYSFS_Dir *opaque);
+PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n);
+void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_EnumFilesCallback cb,
+ const char *origdir, void *callbackdata);
+PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists);
+PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name);
+PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name);
+int UNPK_remove(PHYSFS_Dir *opaque, const char *name);
+int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name);
+int UNPK_stat(PHYSFS_Dir *opaque, const char *fn, int *exist, PHYSFS_Stat *st);
+
+
+/*--------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------*/
+/*------------ ----------------*/
+/*------------ You MUST implement the following functions ----------------*/
+/*------------ if porting to a new platform. ----------------*/
+/*------------ (see platform/unix.c for an example) ----------------*/
+/*------------ ----------------*/
+/*--------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------*/
+
+
+/*
+ * The dir separator; '/' on unix, '\\' on win32, ":" on MacOS, etc...
+ * Obviously, this isn't a function. If you need more than one char for this,
+ * you'll need to pull some old pieces of PhysicsFS out of revision control.
+ */
+#if PHYSFS_PLATFORM_WINDOWS
+#define __PHYSFS_platformDirSeparator '\\'
+#else
+#define __PHYSFS_platformDirSeparator '/'
+#endif
+
+/*
+ * Initialize the platform. This is called when PHYSFS_init() is called from
+ * the application.
+ *
+ * Return zero if there was a catastrophic failure (which prevents you from
+ * functioning at all), and non-zero otherwise.
+ */
+int __PHYSFS_platformInit(void);
+
+
+/*
+ * Deinitialize the platform. This is called when PHYSFS_deinit() is called
+ * from the application. You can use this to clean up anything you've
+ * allocated in your platform driver.
+ *
+ * Return zero if there was a catastrophic failure (which prevents you from
+ * functioning at all), and non-zero otherwise.
+ */
+int __PHYSFS_platformDeinit(void);
+
+
+/*
+ * Open a file for reading. (filename) is in platform-dependent notation. The
+ * file pointer should be positioned on the first byte of the file.
+ *
+ * The return value will be some platform-specific datatype that is opaque to
+ * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32.
+ *
+ * The same file can be opened for read multiple times, and each should have
+ * a unique file handle; this is frequently employed to prevent race
+ * conditions in the archivers.
+ *
+ * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ */
+void *__PHYSFS_platformOpenRead(const char *filename);
+
+
+/*
+ * Open a file for writing. (filename) is in platform-dependent notation. If
+ * the file exists, it should be truncated to zero bytes, and if it doesn't
+ * exist, it should be created as a zero-byte file. The file pointer should
+ * be positioned on the first byte of the file.
+ *
+ * The return value will be some platform-specific datatype that is opaque to
+ * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
+ * etc.
+ *
+ * Opening a file for write multiple times has undefined results.
+ *
+ * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ */
+void *__PHYSFS_platformOpenWrite(const char *filename);
+
+
+/*
+ * Open a file for appending. (filename) is in platform-dependent notation. If
+ * the file exists, the file pointer should be place just past the end of the
+ * file, so that the first write will be one byte after the current end of
+ * the file. If the file doesn't exist, it should be created as a zero-byte
+ * file. The file pointer should be positioned on the first byte of the file.
+ *
+ * The return value will be some platform-specific datatype that is opaque to
+ * the caller; it could be a (FILE *) under Unix, or a (HANDLE *) under win32,
+ * etc.
+ *
+ * Opening a file for append multiple times has undefined results.
+ *
+ * Call __PHYSFS_setError() and return (NULL) if the file can't be opened.
+ */
+void *__PHYSFS_platformOpenAppend(const char *filename);
+
+/*
+ * Read more data from a platform-specific file handle. (opaque) should be
+ * cast to whatever data type your platform uses. Read a maximum of (len)
+ * 8-bit bytes to the area pointed to by (buf). If there isn't enough data
+ * available, return the number of bytes read, and position the file pointer
+ * immediately after those bytes.
+ * On success, return (len) and position the file pointer immediately past
+ * the end of the last read byte. Return (-1) if there is a catastrophic
+ * error, and call __PHYSFS_setError() to describe the problem; the file
+ * pointer should not move in such a case. A partial read is success; only
+ * return (-1) on total failure; presumably, the next read call after a
+ * partial read will fail as such.
+ */
+PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len);
+
+/*
+ * Write more data to a platform-specific file handle. (opaque) should be
+ * cast to whatever data type your platform uses. Write a maximum of (len)
+ * 8-bit bytes from the area pointed to by (buffer). If there is a problem,
+ * return the number of bytes written, and position the file pointer
+ * immediately after those bytes. Return (-1) if there is a catastrophic
+ * error, and call __PHYSFS_setError() to describe the problem; the file
+ * pointer should not move in such a case. A partial write is success; only
+ * return (-1) on total failure; presumably, the next write call after a
+ * partial write will fail as such.
+ */
+PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
+ PHYSFS_uint64 len);
+
+/*
+ * Set the file pointer to a new position. (opaque) should be cast to
+ * whatever data type your platform uses. (pos) specifies the number
+ * of 8-bit bytes to seek to from the start of the file. Seeking past the
+ * end of the file is an error condition, and you should check for it.
+ *
+ * Not all file types can seek; this is to be expected by the caller.
+ *
+ * On error, call __PHYSFS_setError() and return zero. On success, return
+ * a non-zero value.
+ */
+int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos);
+
+
+/*
+ * Get the file pointer's position, in an 8-bit byte offset from the start of
+ * the file. (opaque) should be cast to whatever data type your platform
+ * uses.
+ *
+ * Not all file types can "tell"; this is to be expected by the caller.
+ *
+ * On error, call __PHYSFS_setError() and return -1. On success, return >= 0.
+ */
+PHYSFS_sint64 __PHYSFS_platformTell(void *opaque);
+
+
+/*
+ * Determine the current size of a file, in 8-bit bytes, from an open file.
+ *
+ * The caller expects that this information may not be available for all
+ * file types on all platforms.
+ *
+ * Return -1 if you can't do it, and call __PHYSFS_setError(). Otherwise,
+ * return the file length in 8-bit bytes.
+ */
+PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
+
+
+/*
+ * !!! FIXME: comment me.
+ */
+int __PHYSFS_platformStat(const char *fn, int *exists, PHYSFS_Stat *stat);
+
+/*
+ * Flush any pending writes to disk. (opaque) should be cast to whatever data
+ * type your platform uses. Be sure to check for errors; the caller expects
+ * that this function can fail if there was a flushing error, etc.
+ *
+ * Return zero on failure, non-zero on success.
+ */
+int __PHYSFS_platformFlush(void *opaque);
+
+/*
+ * Close file and deallocate resources. (opaque) should be cast to whatever
+ * data type your platform uses. This should close the file in any scenario:
+ * flushing is a separate function call, and this function should never fail.
+ *
+ * You should clean up all resources associated with (opaque); the pointer
+ * will be considered invalid after this call.
+ */
+void __PHYSFS_platformClose(void *opaque);
+
+/*
+ * Platform implementation of PHYSFS_getCdRomDirsCallback()...
+ * CD directories are discovered and reported to the callback one at a time.
+ * Pointers passed to the callback are assumed to be invalid to the
+ * application after the callback returns, so you can free them or whatever.
+ * Callback does not assume results will be sorted in any meaningful way.
+ */
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
+
+/*
+ * Calculate the base dir, if your platform needs special consideration.
+ * Just return NULL if the standard routines will suffice. (see
+ * calculateBaseDir() in physfs.c ...)
+ * Your string must end with a dir separator if you don't return NULL.
+ * Caller will allocator.Free() the retval if it's not NULL.
+ */
+char *__PHYSFS_platformCalcBaseDir(const char *argv0);
+
+/*
+ * Get the platform-specific user dir.
+ * As of PhysicsFS 2.1, returning NULL means fatal error.
+ * Your string must end with a dir separator if you don't return NULL.
+ * Caller will allocator.Free() the retval if it's not NULL.
+ */
+char *__PHYSFS_platformCalcUserDir(void);
+
+
+/* This is the cached version from PHYSFS_init(). This is a fast call. */
+const char *__PHYSFS_getUserDir(void); /* not deprecated internal version. */
+
+
+/*
+ * Get the platform-specific pref dir.
+ * Returning NULL means fatal error.
+ * Your string must end with a dir separator if you don't return NULL.
+ * Caller will allocator.Free() the retval if it's not NULL.
+ * Caller will make missing directories if necessary; this just reports
+ * the final path.
+ */
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app);
+
+
+/*
+ * Return a pointer that uniquely identifies the current thread.
+ * On a platform without threading, (0x1) will suffice. These numbers are
+ * arbitrary; the only requirement is that no two threads have the same
+ * pointer.
+ */
+void *__PHYSFS_platformGetThreadID(void);
+
+
+/*
+ * Enumerate a directory of files. This follows the rules for the
+ * PHYSFS_Archiver->enumerateFiles() method (see above), except that the
+ * (dirName) that is passed to this function is converted to
+ * platform-DEPENDENT notation by the caller. The PHYSFS_Archiver version
+ * uses platform-independent notation. Note that ".", "..", and other
+ * metaentries should always be ignored.
+ */
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_EnumFilesCallback callback,
+ const char *origdir,
+ void *callbackdata);
+
+/*
+ * Make a directory in the actual filesystem. (path) is specified in
+ * platform-dependent notation. On error, return zero and set the error
+ * message. Return non-zero on success.
+ */
+int __PHYSFS_platformMkDir(const char *path);
+
+
+/*
+ * Remove a file or directory entry in the actual filesystem. (path) is
+ * specified in platform-dependent notation. Note that this deletes files
+ * _and_ directories, so you might need to do some determination.
+ * Non-empty directories should report an error and not delete themselves
+ * or their contents.
+ *
+ * Deleting a symlink should remove the link, not what it points to.
+ *
+ * On error, return zero and set the error message. Return non-zero on success.
+ */
+int __PHYSFS_platformDelete(const char *path);
+
+
+/*
+ * Create a platform-specific mutex. This can be whatever datatype your
+ * platform uses for mutexes, but it is cast to a (void *) for abstractness.
+ *
+ * Return (NULL) if you couldn't create one. Systems without threads can
+ * return any arbitrary non-NULL value.
+ */
+void *__PHYSFS_platformCreateMutex(void);
+
+/*
+ * Destroy a platform-specific mutex, and clean up any resources associated
+ * with it. (mutex) is a value previously returned by
+ * __PHYSFS_platformCreateMutex(). This can be a no-op on single-threaded
+ * platforms.
+ */
+void __PHYSFS_platformDestroyMutex(void *mutex);
+
+/*
+ * Grab possession of a platform-specific mutex. Mutexes should be recursive;
+ * that is, the same thread should be able to call this function multiple
+ * times in a row without causing a deadlock. This function should block
+ * until a thread can gain possession of the mutex.
+ *
+ * Return non-zero if the mutex was grabbed, zero if there was an
+ * unrecoverable problem grabbing it (this should not be a matter of
+ * timing out! We're talking major system errors; block until the mutex
+ * is available otherwise.)
+ *
+ * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
+ * function, you'll cause an infinite recursion. This means you can't
+ * use the BAIL_*MACRO* macros, either.
+ */
+int __PHYSFS_platformGrabMutex(void *mutex);
+
+/*
+ * Relinquish possession of the mutex when this method has been called
+ * once for each time that platformGrabMutex was called. Once possession has
+ * been released, the next thread in line to grab the mutex (if any) may
+ * proceed.
+ *
+ * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this
+ * function, you'll cause an infinite recursion. This means you can't
+ * use the BAIL_*MACRO* macros, either.
+ */
+void __PHYSFS_platformReleaseMutex(void *mutex);
+
+/*
+ * Called at the start of PHYSFS_init() to prepare the allocator, if the user
+ * hasn't selected their own allocator via PHYSFS_setAllocator().
+ * If the platform has a custom allocator, it should fill in the fields of
+ * (a) with the proper function pointers and return non-zero.
+ * If the platform just wants to use malloc()/free()/etc, return zero
+ * immediately and the higher level will handle it. The Init and Deinit
+ * fields of (a) are optional...set them to NULL if you don't need them.
+ * Everything else must be implemented. All rules follow those for
+ * PHYSFS_setAllocator(). If Init isn't NULL, it will be called shortly
+ * after this function returns non-zero.
+ */
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* end of physfs_internal.h ... */
+
diff --git a/misc/libphysfs/physfs_miniz.h b/misc/libphysfs/physfs_miniz.h
new file mode 100644
index 0000000..141a5b9
--- /dev/null
+++ b/misc/libphysfs/physfs_miniz.h
@@ -0,0 +1,698 @@
+/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c)
+ See "unlicense" statement at the end of this file.
+ Rich Geldreich <richgel99 at gmail.com>, last updated May 20, 2011
+ Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
+
+ The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers.
+*/
+#ifndef TINFL_HEADER_INCLUDED
+#define TINFL_HEADER_INCLUDED
+
+typedef PHYSFS_uint8 mz_uint8;
+typedef PHYSFS_sint16 mz_int16;
+typedef PHYSFS_uint16 mz_uint16;
+typedef PHYSFS_uint32 mz_uint32;
+typedef unsigned int mz_uint;
+typedef PHYSFS_uint64 mz_uint64;
+
+/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. */
+typedef unsigned long mz_ulong;
+
+/* Heap allocation callbacks. */
+typedef void *(*mz_alloc_func)(void *opaque, unsigned int items, unsigned int size);
+typedef void (*mz_free_func)(void *opaque, void *address);
+
+#if defined(_M_IX86) || defined(_M_X64)
+/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster). */
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
+#define MINIZ_LITTLE_ENDIAN 1
+#endif
+
+#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
+/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator) */
+#define MINIZ_HAS_64BIT_REGISTERS 1
+#endif
+
+/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
+#ifdef _MSC_VER
+#define MZ_MACRO_END while (0, 0)
+#else
+#define MZ_MACRO_END while (0)
+#endif
+
+/* Decompression flags. */
+enum
+{
+ TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
+ TINFL_FLAG_HAS_MORE_INPUT = 2,
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
+ TINFL_FLAG_COMPUTE_ADLER32 = 8
+};
+
+struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
+
+/* Max size of LZ dictionary. */
+#define TINFL_LZ_DICT_SIZE 32768
+
+/* Return status. */
+typedef enum
+{
+ TINFL_STATUS_BAD_PARAM = -3,
+ TINFL_STATUS_ADLER32_MISMATCH = -2,
+ TINFL_STATUS_FAILED = -1,
+ TINFL_STATUS_DONE = 0,
+ TINFL_STATUS_NEEDS_MORE_INPUT = 1,
+ TINFL_STATUS_HAS_MORE_OUTPUT = 2
+} tinfl_status;
+
+/* Initializes the decompressor to its initial state. */
+#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
+#define tinfl_get_adler32(r) (r)->m_check_adler32
+
+/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
+/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
+static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
+
+/* Internal/private bits follow. */
+enum
+{
+ TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
+};
+
+typedef struct
+{
+ mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
+ mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
+} tinfl_huff_table;
+
+#if MINIZ_HAS_64BIT_REGISTERS
+ #define TINFL_USE_64BIT_BITBUF 1
+#endif
+
+#if TINFL_USE_64BIT_BITBUF
+ typedef mz_uint64 tinfl_bit_buf_t;
+ #define TINFL_BITBUF_SIZE (64)
+#else
+ typedef mz_uint32 tinfl_bit_buf_t;
+ #define TINFL_BITBUF_SIZE (32)
+#endif
+
+struct tinfl_decompressor_tag
+{
+ mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
+ tinfl_bit_buf_t m_bit_buf;
+ size_t m_dist_from_out_buf_start;
+ tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
+ mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
+};
+
+#endif /* #ifdef TINFL_HEADER_INCLUDED */
+
+/* ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) */
+
+#ifndef TINFL_HEADER_FILE_ONLY
+
+#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
+#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
+#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
+ #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
+#else
+ #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
+ #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
+#endif
+
+#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
+#define TINFL_MEMSET(p, c, l) memset(p, c, l)
+
+#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
+#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
+#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
+#define TINFL_CR_FINISH }
+
+/* TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never */
+/* reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. */
+#define TINFL_GET_BYTE(state_index, c) do { \
+ if (pIn_buf_cur >= pIn_buf_end) { \
+ for ( ; ; ) { \
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
+ TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
+ if (pIn_buf_cur < pIn_buf_end) { \
+ c = *pIn_buf_cur++; \
+ break; \
+ } \
+ } else { \
+ c = 0; \
+ break; \
+ } \
+ } \
+ } else c = *pIn_buf_cur++; } MZ_MACRO_END
+
+#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
+#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
+#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
+
+/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
+/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
+/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
+/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
+#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
+ do { \
+ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
+ if (temp >= 0) { \
+ code_len = temp >> 9; \
+ if ((code_len) && (num_bits >= code_len)) \
+ break; \
+ } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
+ } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
+ } while (num_bits < 15);
+
+/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
+/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */
+/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */
+/* The slow path is only executed at the very end of the input buffer. */
+#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
+ int temp; mz_uint code_len, c; \
+ if (num_bits < 15) { \
+ if ((pIn_buf_end - pIn_buf_cur) < 2) { \
+ TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
+ } else { \
+ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
+ } \
+ } \
+ if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
+ code_len = temp >> 9, temp &= 511; \
+ else { \
+ code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
+ } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
+
+static tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
+{
+ static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
+ static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
+ static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
+ static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+ static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
+ static const int s_min_table_sizes[3] = { 257, 1, 4 };
+
+ tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
+ const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
+ mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
+ size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
+
+ /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
+ if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
+
+ num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
+ TINFL_CR_BEGIN
+
+ bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
+ counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
+ if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
+ if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
+ }
+
+ do
+ {
+ TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
+ if (r->m_type == 0)
+ {
+ TINFL_SKIP_BITS(5, num_bits & 7);
+ for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
+ if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
+ while ((counter) && (num_bits))
+ {
+ TINFL_GET_BITS(51, dist, 8);
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = (mz_uint8)dist;
+ counter--;
+ }
+ while (counter)
+ {
+ size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ while (pIn_buf_cur >= pIn_buf_end)
+ {
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
+ {
+ TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
+ }
+ else
+ {
+ TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
+ }
+ }
+ n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
+ TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
+ }
+ }
+ else if (r->m_type == 3)
+ {
+ TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
+ }
+ else
+ {
+ if (r->m_type == 1)
+ {
+ mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
+ r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
+ for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
+ }
+ else
+ {
+ for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
+ MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
+ r->m_table_sizes[2] = 19;
+ }
+ for ( ; (int)r->m_type >= 0; r->m_type--)
+ {
+ int tree_next, tree_cur; tinfl_huff_table *pTable;
+ mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
+ for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
+ used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
+ for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
+ if ((65536 != total) && (used_syms > 1))
+ {
+ TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
+ }
+ for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
+ {
+ mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
+ cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
+ if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
+ if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
+ rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
+ for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
+ {
+ tree_cur -= ((rev_code >>= 1) & 1);
+ if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
+ }
+ tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
+ }
+ if (r->m_type == 2)
+ {
+ for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
+ {
+ mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
+ if ((dist == 16) && (!counter))
+ {
+ TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
+ }
+ num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
+ TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
+ }
+ if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
+ {
+ TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
+ }
+ TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
+ }
+ }
+ for ( ; ; )
+ {
+ mz_uint8 *pSrc;
+ for ( ; ; )
+ {
+ if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
+ {
+ TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
+ if (counter >= 256)
+ break;
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = (mz_uint8)counter;
+ }
+ else
+ {
+ int sym2; mz_uint code_len;
+#if TINFL_USE_64BIT_BITBUF
+ if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
+#else
+ if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
+ }
+ counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
+ if (counter & 256)
+ break;
+
+#if !TINFL_USE_64BIT_BITBUF
+ if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
+#endif
+ if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
+ code_len = sym2 >> 9;
+ else
+ {
+ code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
+ }
+ bit_buf >>= code_len; num_bits -= code_len;
+
+ pOut_buf_cur[0] = (mz_uint8)counter;
+ if (sym2 & 256)
+ {
+ pOut_buf_cur++;
+ counter = sym2;
+ break;
+ }
+ pOut_buf_cur[1] = (mz_uint8)sym2;
+ pOut_buf_cur += 2;
+ }
+ }
+ if ((counter &= 511) == 256) break;
+
+ num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
+ if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
+
+ TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
+ num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
+ if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
+
+ dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
+ if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
+ {
+ TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
+ }
+
+ pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
+
+ if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
+ {
+ while (counter--)
+ {
+ while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
+ *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
+ }
+ continue;
+ }
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+ else if ((counter >= 9) && (counter <= dist))
+ {
+ const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
+ do
+ {
+ ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
+ ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
+ pOut_buf_cur += 8;
+ } while ((pSrc += 8) < pSrc_end);
+ if ((counter &= 7) < 3)
+ {
+ if (counter)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if (counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ continue;
+ }
+ }
+#endif
+ do
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur[2] = pSrc[2];
+ pOut_buf_cur += 3; pSrc += 3;
+ } while ((int)(counter -= 3) > 2);
+ if ((int)counter > 0)
+ {
+ pOut_buf_cur[0] = pSrc[0];
+ if ((int)counter > 1)
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ }
+ }
+ } while (!(r->m_final & 1));
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
+ {
+ TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
+ }
+ TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
+ TINFL_CR_FINISH
+
+common_exit:
+ r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
+ *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
+ if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
+ {
+ const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
+ mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
+ while (buf_len)
+ {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
+ {
+ s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
+ }
+ for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
+ }
+ r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
+ }
+ return status;
+}
+
+/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other stuff is for advanced use. */
+enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
+
+/* Return status codes. MZ_PARAM_ERROR is non-standard. */
+enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
+
+/* Compression levels. */
+enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_DEFAULT_COMPRESSION = -1 };
+
+/* Window bits */
+#define MZ_DEFAULT_WINDOW_BITS 15
+
+struct mz_internal_state;
+
+/* Compression/decompression stream struct. */
+typedef struct mz_stream_s
+{
+ const unsigned char *next_in; /* pointer to next byte to read */
+ unsigned int avail_in; /* number of bytes available at next_in */
+ mz_ulong total_in; /* total number of bytes consumed so far */
+
+ unsigned char *next_out; /* pointer to next byte to write */
+ unsigned int avail_out; /* number of bytes that can be written to next_out */
+ mz_ulong total_out; /* total number of bytes produced so far */
+
+ char *msg; /* error msg (unused) */
+ struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */
+
+ mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */
+ mz_free_func zfree; /* optional heap free function (defaults to free) */
+ void *opaque; /* heap alloc function user pointer */
+
+ int data_type; /* data_type (unused) */
+ mz_ulong adler; /* adler32 of the source or uncompressed data */
+ mz_ulong reserved; /* not used */
+} mz_stream;
+
+typedef mz_stream *mz_streamp;
+
+
+typedef struct
+{
+ tinfl_decompressor m_decomp;
+ mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
+ mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
+ tinfl_status m_last_status;
+} inflate_state;
+
+static int mz_inflateInit2(mz_streamp pStream, int window_bits)
+{
+ inflate_state *pDecomp;
+ if (!pStream) return MZ_STREAM_ERROR;
+ if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = 0;
+ pStream->msg = NULL;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ pStream->reserved = 0;
+ /* if (!pStream->zalloc) pStream->zalloc = def_alloc_func; */
+ /* if (!pStream->zfree) pStream->zfree = def_free_func; */
+
+ pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
+ if (!pDecomp) return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pDecomp;
+
+ tinfl_init(&pDecomp->m_decomp);
+ pDecomp->m_dict_ofs = 0;
+ pDecomp->m_dict_avail = 0;
+ pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
+ pDecomp->m_first_call = 1;
+ pDecomp->m_has_flushed = 0;
+ pDecomp->m_window_bits = window_bits;
+
+ return MZ_OK;
+}
+
+static int mz_inflate(mz_streamp pStream, int flush)
+{
+ inflate_state* pState;
+ mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
+ size_t in_bytes, out_bytes, orig_avail_in;
+ tinfl_status status;
+
+ if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
+ if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
+ if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
+
+ pState = (inflate_state*)pStream->state;
+ if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
+ orig_avail_in = pStream->avail_in;
+
+ first_call = pState->m_first_call; pState->m_first_call = 0;
+ if (pState->m_last_status < 0) return MZ_DATA_ERROR;
+
+ if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
+ pState->m_has_flushed |= (flush == MZ_FINISH);
+
+ if ((flush == MZ_FINISH) && (first_call))
+ {
+ /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
+ decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
+ in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+ pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+ pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
+
+ if (status < 0)
+ return MZ_DATA_ERROR;
+ else if (status != TINFL_STATUS_DONE)
+ {
+ pState->m_last_status = TINFL_STATUS_FAILED;
+ return MZ_BUF_ERROR;
+ }
+ return MZ_STREAM_END;
+ }
+ /* flush != MZ_FINISH then we must assume there's more input. */
+ if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
+
+ if (pState->m_dict_avail)
+ {
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
+ pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+ return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+ }
+
+ for ( ; ; )
+ {
+ in_bytes = pStream->avail_in;
+ out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
+
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+
+ pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+
+ pState->m_dict_avail = (mz_uint)out_bytes;
+
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
+ pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+
+ if (status < 0)
+ return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
+ else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
+ return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
+ else if (flush == MZ_FINISH)
+ {
+ /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
+ if (status == TINFL_STATUS_DONE)
+ return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
+ /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
+ else if (!pStream->avail_out)
+ return MZ_BUF_ERROR;
+ }
+ else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
+ break;
+ }
+
+ return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
+}
+
+static int mz_inflateEnd(mz_streamp pStream)
+{
+ if (!pStream)
+ return MZ_STREAM_ERROR;
+ if (pStream->state)
+ {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+/* make this a drop-in replacement for zlib... */
+ #define voidpf void*
+ #define uInt unsigned int
+ #define z_stream mz_stream
+ #define inflateInit2 mz_inflateInit2
+ #define inflate mz_inflate
+ #define inflateEnd mz_inflateEnd
+ #define Z_SYNC_FLUSH MZ_SYNC_FLUSH
+ #define Z_FINISH MZ_FINISH
+ #define Z_OK MZ_OK
+ #define Z_STREAM_END MZ_STREAM_END
+ #define Z_NEED_DICT MZ_NEED_DICT
+ #define Z_ERRNO MZ_ERRNO
+ #define Z_STREAM_ERROR MZ_STREAM_ERROR
+ #define Z_DATA_ERROR MZ_DATA_ERROR
+ #define Z_MEM_ERROR MZ_MEM_ERROR
+ #define Z_BUF_ERROR MZ_BUF_ERROR
+ #define Z_VERSION_ERROR MZ_VERSION_ERROR
+ #define MAX_WBITS 15
+
+#endif /* #ifndef TINFL_HEADER_FILE_ONLY */
+
+/*
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to <http://unlicense.org/>
+*/
diff --git a/misc/libphysfs/physfs_platforms.h b/misc/libphysfs/physfs_platforms.h
new file mode 100644
index 0000000..1baf6fc
--- /dev/null
+++ b/misc/libphysfs/physfs_platforms.h
@@ -0,0 +1,58 @@
+#ifndef _INCL_PHYSFS_PLATFORMS
+#define _INCL_PHYSFS_PLATFORMS
+
+#ifndef __PHYSICSFS_INTERNAL__
+#error Do not include this header from your applications.
+#endif
+
+/*
+ * These only define the platforms to determine which files in the platforms
+ * directory should be compiled. For example, technically BeOS can be called
+ * a "unix" system, but since it doesn't use unix.c, we don't define
+ * PHYSFS_PLATFORM_UNIX on that system.
+ */
+
+#if (defined __HAIKU__)
+# define PHYSFS_PLATFORM_HAIKU 1
+# define PHYSFS_PLATFORM_BEOS 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif ((defined __BEOS__) || (defined __beos__))
+# define PHYSFS_PLATFORM_BEOS 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif (defined _WIN32_WCE) || (defined _WIN64_WCE)
+# error PocketPC support was dropped from PhysicsFS 2.1. Sorry.
+#elif (((defined _WIN32) || (defined _WIN64)) && (!defined __CYGWIN__))
+# define PHYSFS_PLATFORM_WINDOWS 1
+#elif (defined OS2)
+# error OS/2 support was dropped from PhysicsFS 2.1. Sorry.
+#elif ((defined __MACH__) && (defined __APPLE__))
+/* To check if iphone or not, we need to include this file */
+# include <TargetConditionals.h>
+# if ((TARGET_IPHONE_SIMULATOR) || (TARGET_OS_IPHONE))
+# define PHYSFS_NO_CDROM_SUPPORT 1
+# endif
+# define PHYSFS_PLATFORM_MACOSX 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif defined(macintosh)
+# error Classic Mac OS support was dropped from PhysicsFS 2.0. Move to OS X.
+#elif defined(__linux)
+# define PHYSFS_PLATFORM_LINUX 1
+# define PHYSFS_PLATFORM_UNIX 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif defined(__sun) || defined(sun)
+# define PHYSFS_PLATFORM_SOLARIS 1
+# define PHYSFS_PLATFORM_UNIX 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
+# define PHYSFS_PLATFORM_BSD 1
+# define PHYSFS_PLATFORM_UNIX 1
+# define PHYSFS_PLATFORM_POSIX 1
+#elif defined(unix) || defined(__unix__)
+# define PHYSFS_PLATFORM_UNIX 1
+# define PHYSFS_PLATFORM_POSIX 1
+#else
+# error Unknown platform.
+#endif
+
+#endif /* include-once blocker. */
+
diff --git a/misc/libphysfs/physfs_unicode.c b/misc/libphysfs/physfs_unicode.c
new file mode 100644
index 0000000..628c899
--- /dev/null
+++ b/misc/libphysfs/physfs_unicode.c
@@ -0,0 +1,528 @@
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+
+/*
+ * From rfc3629, the UTF-8 spec:
+ * http://www.ietf.org/rfc/rfc3629.txt
+ *
+ * Char. number range | UTF-8 octet sequence
+ * (hexadecimal) | (binary)
+ * --------------------+---------------------------------------------
+ * 0000 0000-0000 007F | 0xxxxxxx
+ * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+ * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+ * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ */
+
+
+/*
+ * This may not be the best value, but it's one that isn't represented
+ * in Unicode (0x10FFFF is the largest codepoint value). We return this
+ * value from utf8codepoint() if there's bogus bits in the
+ * stream. utf8codepoint() will turn this value into something
+ * reasonable (like a question mark), for text that wants to try to recover,
+ * whereas utf8valid() will use the value to determine if a string has bad
+ * bits.
+ */
+#define UNICODE_BOGUS_CHAR_VALUE 0xFFFFFFFF
+
+/*
+ * This is the codepoint we currently return when there was bogus bits in a
+ * UTF-8 string. May not fly in Asian locales?
+ */
+#define UNICODE_BOGUS_CHAR_CODEPOINT '?'
+
+static PHYSFS_uint32 utf8codepoint(const char **_str)
+{
+ const char *str = *_str;
+ PHYSFS_uint32 retval = 0;
+ PHYSFS_uint32 octet = (PHYSFS_uint32) ((PHYSFS_uint8) *str);
+ PHYSFS_uint32 octet2, octet3, octet4;
+
+ if (octet == 0) /* null terminator, end of string. */
+ return 0;
+
+ else if (octet < 128) /* one octet char: 0 to 127 */
+ {
+ (*_str)++; /* skip to next possible start of codepoint. */
+ return octet;
+ } /* else if */
+
+ else if ((octet > 127) && (octet < 192)) /* bad (starts with 10xxxxxx). */
+ {
+ /*
+ * Apparently each of these is supposed to be flagged as a bogus
+ * char, instead of just resyncing to the next valid codepoint.
+ */
+ (*_str)++; /* skip to next possible start of codepoint. */
+ return UNICODE_BOGUS_CHAR_VALUE;
+ } /* else if */
+
+ else if (octet < 224) /* two octets */
+ {
+ (*_str)++; /* advance at least one byte in case of an error */
+ octet -= (128+64);
+ octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ *_str += 1; /* skip to next possible start of codepoint. */
+ retval = ((octet << 6) | (octet2 - 128));
+ if ((retval >= 0x80) && (retval <= 0x7FF))
+ return retval;
+ } /* else if */
+
+ else if (octet < 240) /* three octets */
+ {
+ (*_str)++; /* advance at least one byte in case of an error */
+ octet -= (128+64+32);
+ octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ *_str += 2; /* skip to next possible start of codepoint. */
+ retval = ( ((octet << 12)) | ((octet2-128) << 6) | ((octet3-128)) );
+
+ /* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
+ switch (retval)
+ {
+ case 0xD800:
+ case 0xDB7F:
+ case 0xDB80:
+ case 0xDBFF:
+ case 0xDC00:
+ case 0xDF80:
+ case 0xDFFF:
+ return UNICODE_BOGUS_CHAR_VALUE;
+ } /* switch */
+
+ /* 0xFFFE and 0xFFFF are illegal, too, so we check them at the edge. */
+ if ((retval >= 0x800) && (retval <= 0xFFFD))
+ return retval;
+ } /* else if */
+
+ else if (octet < 248) /* four octets */
+ {
+ (*_str)++; /* advance at least one byte in case of an error */
+ octet -= (128+64+32+16);
+ octet2 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet2 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet3 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet3 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet4 = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet4 & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ *_str += 3; /* skip to next possible start of codepoint. */
+ retval = ( ((octet << 18)) | ((octet2 - 128) << 12) |
+ ((octet3 - 128) << 6) | ((octet4 - 128)) );
+ if ((retval >= 0x10000) && (retval <= 0x10FFFF))
+ return retval;
+ } /* else if */
+
+ /*
+ * Five and six octet sequences became illegal in rfc3629.
+ * We throw the codepoint away, but parse them to make sure we move
+ * ahead the right number of bytes and don't overflow the buffer.
+ */
+
+ else if (octet < 252) /* five octets */
+ {
+ (*_str)++; /* advance at least one byte in case of an error */
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ *_str += 4; /* skip to next possible start of codepoint. */
+ return UNICODE_BOGUS_CHAR_VALUE;
+ } /* else if */
+
+ else /* six octets */
+ {
+ (*_str)++; /* advance at least one byte in case of an error */
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ octet = (PHYSFS_uint32) ((PHYSFS_uint8) *(++str));
+ if ((octet & (128+64)) != 128) /* Format isn't 10xxxxxx? */
+ return UNICODE_BOGUS_CHAR_VALUE;
+
+ *_str += 6; /* skip to next possible start of codepoint. */
+ return UNICODE_BOGUS_CHAR_VALUE;
+ } /* else if */
+
+ return UNICODE_BOGUS_CHAR_VALUE;
+} /* utf8codepoint */
+
+
+void PHYSFS_utf8ToUcs4(const char *src, PHYSFS_uint32 *dst, PHYSFS_uint64 len)
+{
+ len -= sizeof (PHYSFS_uint32); /* save room for null char. */
+ while (len >= sizeof (PHYSFS_uint32))
+ {
+ PHYSFS_uint32 cp = utf8codepoint(&src);
+ if (cp == 0)
+ break;
+ else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ *(dst++) = cp;
+ len -= sizeof (PHYSFS_uint32);
+ } /* while */
+
+ *dst = 0;
+} /* PHYSFS_utf8ToUcs4 */
+
+
+void PHYSFS_utf8ToUcs2(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+{
+ len -= sizeof (PHYSFS_uint16); /* save room for null char. */
+ while (len >= sizeof (PHYSFS_uint16))
+ {
+ PHYSFS_uint32 cp = utf8codepoint(&src);
+ if (cp == 0)
+ break;
+ else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+
+ if (cp > 0xFFFF) /* UTF-16 surrogates (bogus chars in UCS-2) */
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+
+ *(dst++) = cp;
+ len -= sizeof (PHYSFS_uint16);
+ } /* while */
+
+ *dst = 0;
+} /* PHYSFS_utf8ToUcs2 */
+
+
+void PHYSFS_utf8ToUtf16(const char *src, PHYSFS_uint16 *dst, PHYSFS_uint64 len)
+{
+ len -= sizeof (PHYSFS_uint16); /* save room for null char. */
+ while (len >= sizeof (PHYSFS_uint16))
+ {
+ PHYSFS_uint32 cp = utf8codepoint(&src);
+ if (cp == 0)
+ break;
+ else if (cp == UNICODE_BOGUS_CHAR_VALUE)
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+
+ if (cp > 0xFFFF) /* encode as surrogate pair */
+ {
+ if (len < (sizeof (PHYSFS_uint16) * 2))
+ break; /* not enough room for the pair, stop now. */
+
+ cp -= 0x10000; /* Make this a 20-bit value */
+
+ *(dst++) = 0xD800 + ((cp >> 10) & 0x3FF);
+ len -= sizeof (PHYSFS_uint16);
+
+ cp = 0xDC00 + (cp & 0x3FF);
+ } /* if */
+
+ *(dst++) = cp;
+ len -= sizeof (PHYSFS_uint16);
+ } /* while */
+
+ *dst = 0;
+} /* PHYSFS_utf8ToUtf16 */
+
+static void utf8fromcodepoint(PHYSFS_uint32 cp, char **_dst, PHYSFS_uint64 *_len)
+{
+ char *dst = *_dst;
+ PHYSFS_uint64 len = *_len;
+
+ if (len == 0)
+ return;
+
+ if (cp > 0x10FFFF)
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ else if ((cp == 0xFFFE) || (cp == 0xFFFF)) /* illegal values. */
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ else
+ {
+ /* There are seven "UTF-16 surrogates" that are illegal in UTF-8. */
+ switch (cp)
+ {
+ case 0xD800:
+ case 0xDB7F:
+ case 0xDB80:
+ case 0xDBFF:
+ case 0xDC00:
+ case 0xDF80:
+ case 0xDFFF:
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ } /* switch */
+ } /* else */
+
+ /* Do the encoding... */
+ if (cp < 0x80)
+ {
+ *(dst++) = (char) cp;
+ len--;
+ } /* if */
+
+ else if (cp < 0x800)
+ {
+ if (len < 2)
+ len = 0;
+ else
+ {
+ *(dst++) = (char) ((cp >> 6) | 128 | 64);
+ *(dst++) = (char) (cp & 0x3F) | 128;
+ len -= 2;
+ } /* else */
+ } /* else if */
+
+ else if (cp < 0x10000)
+ {
+ if (len < 3)
+ len = 0;
+ else
+ {
+ *(dst++) = (char) ((cp >> 12) | 128 | 64 | 32);
+ *(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
+ *(dst++) = (char) (cp & 0x3F) | 128;
+ len -= 3;
+ } /* else */
+ } /* else if */
+
+ else
+ {
+ if (len < 4)
+ len = 0;
+ else
+ {
+ *(dst++) = (char) ((cp >> 18) | 128 | 64 | 32 | 16);
+ *(dst++) = (char) ((cp >> 12) & 0x3F) | 128;
+ *(dst++) = (char) ((cp >> 6) & 0x3F) | 128;
+ *(dst++) = (char) (cp & 0x3F) | 128;
+ len -= 4;
+ } /* else if */
+ } /* else */
+
+ *_dst = dst;
+ *_len = len;
+} /* utf8fromcodepoint */
+
+#define UTF8FROMTYPE(typ, src, dst, len) \
+ if (len == 0) return; \
+ len--; \
+ while (len) \
+ { \
+ const PHYSFS_uint32 cp = (PHYSFS_uint32) ((typ) (*(src++))); \
+ if (cp == 0) break; \
+ utf8fromcodepoint(cp, &dst, &len); \
+ } \
+ *dst = '\0'; \
+
+void PHYSFS_utf8FromUcs4(const PHYSFS_uint32 *src, char *dst, PHYSFS_uint64 len)
+{
+ UTF8FROMTYPE(PHYSFS_uint32, src, dst, len);
+} /* PHYSFS_utf8FromUcs4 */
+
+void PHYSFS_utf8FromUcs2(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+{
+ UTF8FROMTYPE(PHYSFS_uint64, src, dst, len);
+} /* PHYSFS_utf8FromUcs2 */
+
+/* latin1 maps to unicode codepoints directly, we just utf-8 encode it. */
+void PHYSFS_utf8FromLatin1(const char *src, char *dst, PHYSFS_uint64 len)
+{
+ UTF8FROMTYPE(PHYSFS_uint8, src, dst, len);
+} /* PHYSFS_utf8FromLatin1 */
+
+#undef UTF8FROMTYPE
+
+
+void PHYSFS_utf8FromUtf16(const PHYSFS_uint16 *src, char *dst, PHYSFS_uint64 len)
+{
+ if (len == 0)
+ return;
+
+ len--;
+ while (len)
+ {
+ PHYSFS_uint32 cp = (PHYSFS_uint32) *(src++);
+ if (cp == 0)
+ break;
+
+ /* Orphaned second half of surrogate pair? */
+ if ((cp >= 0xDC00) && (cp <= 0xDFFF))
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ else if ((cp >= 0xD800) && (cp <= 0xDBFF)) /* start surrogate pair! */
+ {
+ const PHYSFS_uint32 pair = (PHYSFS_uint32) *src;
+ if ((pair < 0xDC00) || (pair > 0xDFFF))
+ cp = UNICODE_BOGUS_CHAR_CODEPOINT;
+ else
+ {
+ src++; /* eat the other surrogate. */
+ cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
+ } /* else */
+ } /* else if */
+
+ utf8fromcodepoint(cp, &dst, &len);
+ } /* while */
+
+ *dst = '\0';
+} /* PHYSFS_utf8FromUtf16 */
+
+
+typedef struct CaseFoldMapping
+{
+ PHYSFS_uint32 from;
+ PHYSFS_uint32 to0;
+ PHYSFS_uint32 to1;
+ PHYSFS_uint32 to2;
+} CaseFoldMapping;
+
+typedef struct CaseFoldHashBucket
+{
+ const PHYSFS_uint8 count;
+ const CaseFoldMapping *list;
+} CaseFoldHashBucket;
+
+#include "physfs_casefolding.h"
+
+static void locate_case_fold_mapping(const PHYSFS_uint32 from,
+ PHYSFS_uint32 *to)
+{
+ PHYSFS_uint32 i;
+ const PHYSFS_uint8 hashed = ((from ^ (from >> 8)) & 0xFF);
+ const CaseFoldHashBucket *bucket = &case_fold_hash[hashed];
+ const CaseFoldMapping *mapping = bucket->list;
+
+ for (i = 0; i < bucket->count; i++, mapping++)
+ {
+ if (mapping->from == from)
+ {
+ to[0] = mapping->to0;
+ to[1] = mapping->to1;
+ to[2] = mapping->to2;
+ return;
+ } /* if */
+ } /* for */
+
+ /* Not found...there's no remapping for this codepoint. */
+ to[0] = from;
+ to[1] = 0;
+ to[2] = 0;
+} /* locate_case_fold_mapping */
+
+
+static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
+{
+ PHYSFS_uint32 folded1[3], folded2[3];
+ locate_case_fold_mapping(cp1, folded1);
+ locate_case_fold_mapping(cp2, folded2);
+ return ( (folded1[0] == folded2[0]) &&
+ (folded1[1] == folded2[1]) &&
+ (folded1[2] == folded2[2]) );
+} /* utf8codepointcmp */
+
+
+int __PHYSFS_utf8stricmp(const char *str1, const char *str2)
+{
+ while (1)
+ {
+ const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
+ const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
+ if (!utf8codepointcmp(cp1, cp2)) break;
+ if (cp1 == 0) return 1;
+ } /* while */
+
+ return 0;
+} /* __PHYSFS_utf8stricmp */
+
+
+int __PHYSFS_utf8strnicmp(const char *str1, const char *str2, PHYSFS_uint32 n)
+{
+ while (n > 0)
+ {
+ const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
+ const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
+ if (!utf8codepointcmp(cp1, cp2)) return 0;
+ if (cp1 == 0) return 1;
+ n--;
+ } /* while */
+
+ return 1; /* matched to n chars. */
+} /* __PHYSFS_utf8strnicmp */
+
+
+int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
+{
+ while (1)
+ {
+ const char ch1 = *(str1++);
+ const char ch2 = *(str2++);
+ const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
+ const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
+ if (cp1 < cp2)
+ return -1;
+ else if (cp1 > cp2)
+ return 1;
+ else if (cp1 == 0) /* they're both null chars? */
+ break;
+ } /* while */
+
+ return 0;
+} /* __PHYSFS_stricmpASCII */
+
+
+int __PHYSFS_strnicmpASCII(const char *str1, const char *str2, PHYSFS_uint32 n)
+{
+ while (n-- > 0)
+ {
+ const char ch1 = *(str1++);
+ const char ch2 = *(str2++);
+ const char cp1 = ((ch1 >= 'A') && (ch1 <= 'Z')) ? (ch1+32) : ch1;
+ const char cp2 = ((ch2 >= 'A') && (ch2 <= 'Z')) ? (ch2+32) : ch2;
+ if (cp1 < cp2)
+ return -1;
+ else if (cp1 > cp2)
+ return 1;
+ else if (cp1 == 0) /* they're both null chars? */
+ return 0;
+ } /* while */
+
+ return 0;
+} /* __PHYSFS_strnicmpASCII */
+
+
+/* end of physfs_unicode.c ... */
+
diff --git a/misc/libphysfs/platform_beos.cpp b/misc/libphysfs/platform_beos.cpp
new file mode 100644
index 0000000..fd4bbd5
--- /dev/null
+++ b/misc/libphysfs/platform_beos.cpp
@@ -0,0 +1,239 @@
+/*
+ * BeOS platform-dependent support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_BEOS
+
+#ifdef PHYSFS_PLATFORM_HAIKU
+#include <os/kernel/OS.h>
+#include <os/app/Roster.h>
+#include <os/storage/Volume.h>
+#include <os/storage/VolumeRoster.h>
+#include <os/storage/Directory.h>
+#include <os/storage/Entry.h>
+#include <os/storage/Path.h>
+#include <os/kernel/fs_info.h>
+#include <os/device/scsi.h>
+#include <os/support/Locker.h>
+#else
+#include <be/kernel/OS.h>
+#include <be/app/Roster.h>
+#include <be/storage/Volume.h>
+#include <be/storage/VolumeRoster.h>
+#include <be/storage/Directory.h>
+#include <be/storage/Entry.h>
+#include <be/storage/Path.h>
+#include <be/kernel/fs_info.h>
+#include <be/device/scsi.h>
+#include <be/support/Locker.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "physfs_internal.h"
+
+int __PHYSFS_platformInit(void)
+{
+ return 1; /* always succeed. */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+ return 1; /* always succeed. */
+} /* __PHYSFS_platformDeinit */
+
+
+static char *getMountPoint(const char *devname, char *buf, size_t bufsize)
+{
+ BVolumeRoster mounts;
+ BVolume vol;
+
+ mounts.Rewind();
+ while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
+ {
+ fs_info fsinfo;
+ fs_stat_dev(vol.Device(), &fsinfo);
+ if (strcmp(devname, fsinfo.device_name) == 0)
+ {
+ BDirectory directory;
+ BEntry entry;
+ BPath path;
+ const char *str;
+
+ if ( (vol.GetRootDirectory(&directory) < B_OK) ||
+ (directory.GetEntry(&entry) < B_OK) ||
+ (entry.GetPath(&path) < B_OK) ||
+ ( (str = path.Path()) == NULL) )
+ return NULL;
+
+ strncpy(buf, str, bufsize-1);
+ buf[bufsize-1] = '\0';
+ return buf;
+ } /* if */
+ } /* while */
+
+ return NULL;
+} /* getMountPoint */
+
+
+ /*
+ * This function is lifted from Simple Directmedia Layer (SDL):
+ * http://www.libsdl.org/ ... this is zlib-licensed code, too.
+ */
+static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
+{
+ BDirectory dir;
+ dir.SetTo(d);
+ if (dir.InitCheck() != B_NO_ERROR)
+ return;
+
+ dir.Rewind();
+ BEntry entry;
+ while (dir.GetNextEntry(&entry) >= 0)
+ {
+ BPath path;
+ const char *name;
+ entry_ref e;
+
+ if (entry.GetPath(&path) != B_NO_ERROR)
+ continue;
+
+ name = path.Path();
+
+ if (entry.GetRef(&e) != B_NO_ERROR)
+ continue;
+
+ if (entry.IsDirectory())
+ {
+ if (strcmp(e.name, "floppy") != 0)
+ tryDir(name, callback, data);
+ continue;
+ } /* if */
+
+ if (strcmp(e.name, "raw") != 0) /* ignore partitions. */
+ continue;
+
+ const int devfd = open(name, O_RDONLY);
+ if (devfd < 0)
+ continue;
+
+ device_geometry g;
+ const int rc = ioctl(devfd, B_GET_GEOMETRY, &g, sizeof (g));
+ close(devfd);
+ if (rc < 0)
+ continue;
+
+ if (g.device_type != B_CD)
+ continue;
+
+ char mntpnt[B_FILE_NAME_LENGTH];
+ if (getMountPoint(name, mntpnt, sizeof (mntpnt)))
+ callback(data, mntpnt);
+ } /* while */
+} /* tryDir */
+
+
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+ tryDir("/dev/disk", cb, data);
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+static team_id getTeamID(void)
+{
+ thread_info info;
+ thread_id tid = find_thread(NULL);
+ get_thread_info(tid, &info);
+ return info.team;
+} /* getTeamID */
+
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+ image_info info;
+ int32 cookie = 0;
+
+ while (get_next_image_info(0, &cookie, &info) == B_OK)
+ {
+ if (info.type == B_APP_IMAGE)
+ break;
+ } /* while */
+
+ BEntry entry(info.name, true);
+ BPath path;
+ status_t rc = entry.GetPath(&path); /* (path) now has binary's path. */
+ assert(rc == B_OK);
+ rc = path.GetParent(&path); /* chop filename, keep directory. */
+ assert(rc == B_OK);
+ const char *str = path.Path();
+ assert(str != NULL);
+ const size_t len = strlen(str);
+ char *retval = (char *) allocator.Malloc(len + 2);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ strcpy(retval, str);
+ retval[len] = '/';
+ retval[len+1] = '\0';
+ return retval;
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+ const char *userdir = __PHYSFS_getUserDir();
+ const char *append = "config/settings/";
+ const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
+ char *retval = allocator.Malloc(len);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ snprintf(retval, len, "%s%s%s/", userdir, append, app);
+ return retval;
+} /* __PHYSFS_platformCalcPrefDir */
+
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+ return (void *) find_thread(NULL);
+} /* __PHYSFS_platformGetThreadID */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+ return new BLocker("PhysicsFS lock", true);
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+ delete ((BLocker *) mutex);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+ return ((BLocker *) mutex)->Lock() ? 1 : 0;
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+ ((BLocker *) mutex)->Unlock();
+} /* __PHYSFS_platformReleaseMutex */
+
+
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+ return 0; /* just use malloc() and friends. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+#endif /* PHYSFS_PLATFORM_BEOS */
+
+/* end of beos.cpp ... */
+
diff --git a/misc/libphysfs/platform_macosx.c b/misc/libphysfs/platform_macosx.c
new file mode 100644
index 0000000..12d8a8c
--- /dev/null
+++ b/misc/libphysfs/platform_macosx.c
@@ -0,0 +1,345 @@
+/*
+ * Mac OS X support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_MACOSX
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#if !defined(PHYSFS_NO_CDROM_SUPPORT)
+#include <Carbon/Carbon.h> /* !!! FIXME */
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/storage/IOCDMedia.h>
+#include <IOKit/storage/IODVDMedia.h>
+#include <sys/mount.h>
+#endif
+
+/* Seems to get defined in some system header... */
+#ifdef Free
+#undef Free
+#endif
+
+#include "physfs_internal.h"
+
+
+#if defined(__APPLE__)
+#if defined(TARGET_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
+/* __eprintf shouldn't have been made visible from libstdc++, or anywhere, but
+ on Mac OS X 10.4 it was defined in libstdc++.6.0.3.dylib; so on that platform
+ we have to keep defining it to keep binary compatibility.
+ We can't just put the libgcc version in the export list, because that
+ doesn't work; once a symbol is marked as hidden, it stays that way. */
+
+void __eprintf (const char *string, const char *expression,
+ unsigned int line, const char *filename)
+{
+ fprintf(stderr, string, expression, line, filename);
+ fflush(stderr);
+ abort();
+}
+#endif
+#endif /* __APPLE__ */
+
+
+/* Wrap PHYSFS_Allocator in a CFAllocator... */
+static CFAllocatorRef cfallocator = NULL;
+
+static CFStringRef cfallocDesc(const void *info)
+{
+ return CFStringCreateWithCString(cfallocator, "PhysicsFS",
+ kCFStringEncodingASCII);
+} /* cfallocDesc */
+
+
+static void *cfallocMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
+{
+ return allocator.Malloc(allocSize);
+} /* cfallocMalloc */
+
+
+static void cfallocFree(void *ptr, void *info)
+{
+ allocator.Free(ptr);
+} /* cfallocFree */
+
+
+static void *cfallocRealloc(void *ptr, CFIndex newsize,
+ CFOptionFlags hint, void *info)
+{
+ if ((ptr == NULL) || (newsize <= 0))
+ return NULL; /* ADC docs say you should always return NULL here. */
+ return allocator.Realloc(ptr, newsize);
+} /* cfallocRealloc */
+
+
+int __PHYSFS_platformInit(void)
+{
+ /* set up a CFAllocator, so Carbon can use the physfs allocator, too. */
+ CFAllocatorContext ctx;
+ memset(&ctx, '\0', sizeof (ctx));
+ ctx.copyDescription = cfallocDesc;
+ ctx.allocate = cfallocMalloc;
+ ctx.reallocate = cfallocRealloc;
+ ctx.deallocate = cfallocFree;
+ cfallocator = CFAllocatorCreate(kCFAllocatorUseContext, &ctx);
+ BAIL_IF_MACRO(!cfallocator, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ return 1; /* success. */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+ CFRelease(cfallocator);
+ cfallocator = NULL;
+ return 1; /* always succeed. */
+} /* __PHYSFS_platformDeinit */
+
+
+
+/* CD-ROM detection code... */
+
+/*
+ * Code based on sample from Apple Developer Connection:
+ * http://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
+ */
+
+#if !defined(PHYSFS_NO_CDROM_SUPPORT)
+
+static int darwinIsWholeMedia(io_service_t service)
+{
+ int retval = 0;
+ CFTypeRef wholeMedia;
+
+ if (!IOObjectConformsTo(service, kIOMediaClass))
+ return 0;
+
+ wholeMedia = IORegistryEntryCreateCFProperty(service,
+ CFSTR(kIOMediaWholeKey),
+ cfallocator, 0);
+ if (wholeMedia == NULL)
+ return 0;
+
+ retval = CFBooleanGetValue(wholeMedia);
+ CFRelease(wholeMedia);
+
+ return retval;
+} /* darwinIsWholeMedia */
+
+
+static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
+{
+ int retval = 0;
+ CFMutableDictionaryRef matchingDict;
+ kern_return_t rc;
+ io_iterator_t iter;
+ io_service_t service;
+
+ if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
+ return 0;
+
+ rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
+ if ((rc != KERN_SUCCESS) || (!iter))
+ return 0;
+
+ service = IOIteratorNext(iter);
+ IOObjectRelease(iter);
+ if (!service)
+ return 0;
+
+ rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
+ kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
+
+ if (!iter)
+ return 0;
+
+ if (rc != KERN_SUCCESS)
+ {
+ IOObjectRelease(iter);
+ return 0;
+ } /* if */
+
+ IOObjectRetain(service); /* add an extra object reference... */
+
+ do
+ {
+ if (darwinIsWholeMedia(service))
+ {
+ if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
+ (IOObjectConformsTo(service, kIODVDMediaClass)) )
+ {
+ retval = 1;
+ } /* if */
+ } /* if */
+ IOObjectRelease(service);
+ } while ((service = IOIteratorNext(iter)) && (!retval));
+
+ IOObjectRelease(iter);
+ IOObjectRelease(service);
+
+ return retval;
+} /* darwinIsMountedDisc */
+
+#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
+
+
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+#if !defined(PHYSFS_NO_CDROM_SUPPORT)
+ const char *devPrefix = "/dev/";
+ const int prefixLen = strlen(devPrefix);
+ mach_port_t masterPort = 0;
+ struct statfs *mntbufp;
+ int i, mounts;
+
+ if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
+ BAIL_MACRO(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
+
+ mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
+ for (i = 0; i < mounts; i++)
+ {
+ char *dev = mntbufp[i].f_mntfromname;
+ char *mnt = mntbufp[i].f_mntonname;
+ if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
+ continue;
+
+ dev += prefixLen;
+ if (darwinIsMountedDisc(dev, masterPort))
+ cb(data, mnt);
+ } /* for */
+#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+static char *convertCFString(CFStringRef cfstr)
+{
+ CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
+ kCFStringEncodingUTF8) + 1;
+ char *retval = (char *) allocator.Malloc(len);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+
+ if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8))
+ {
+ /* shrink overallocated buffer if possible... */
+ CFIndex newlen = strlen(retval) + 1;
+ if (newlen < len)
+ {
+ void *ptr = allocator.Realloc(retval, newlen);
+ if (ptr != NULL)
+ retval = (char *) ptr;
+ } /* if */
+ } /* if */
+
+ else /* probably shouldn't fail, but just in case... */
+ {
+ allocator.Free(retval);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* else */
+
+ return retval;
+} /* convertCFString */
+
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+ CFURLRef cfurl = NULL;
+ CFStringRef cfstr = NULL;
+ CFMutableStringRef cfmutstr = NULL;
+ char *retval = NULL;
+
+ cfurl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ BAIL_IF_MACRO(cfurl == NULL, PHYSFS_ERR_OS_ERROR, NULL);
+ cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
+ CFRelease(cfurl);
+ BAIL_IF_MACRO(!cfstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ cfmutstr = CFStringCreateMutableCopy(cfallocator, 0, cfstr);
+ CFRelease(cfstr);
+ BAIL_IF_MACRO(!cfmutstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ CFStringAppendCString(cfmutstr, "/", kCFStringEncodingUTF8);
+ retval = convertCFString(cfmutstr);
+ CFRelease(cfmutstr);
+
+ return retval; /* whew. */
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+ /* !!! FIXME: there's a real API to determine this */
+ const char *userdir = __PHYSFS_getUserDir();
+ const char *append = "Library/Application Support/";
+ const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
+ char *retval = allocator.Malloc(len);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ snprintf(retval, len, "%s%s%s/", userdir, append, app);
+ return retval;
+} /* __PHYSFS_platformCalcPrefDir */
+
+
+/* Platform allocator uses default CFAllocator at PHYSFS_init() time. */
+
+static CFAllocatorRef cfallocdef = NULL;
+
+static int macosxAllocatorInit(void)
+{
+ int retval = 0;
+ cfallocdef = CFAllocatorGetDefault();
+ retval = (cfallocdef != NULL);
+ if (retval)
+ CFRetain(cfallocdef);
+ return retval;
+} /* macosxAllocatorInit */
+
+
+static void macosxAllocatorDeinit(void)
+{
+ if (cfallocdef != NULL)
+ {
+ CFRelease(cfallocdef);
+ cfallocdef = NULL;
+ } /* if */
+} /* macosxAllocatorDeinit */
+
+
+static void *macosxAllocatorMalloc(PHYSFS_uint64 s)
+{
+ if (!__PHYSFS_ui64FitsAddressSpace(s))
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ return CFAllocatorAllocate(cfallocdef, (CFIndex) s, 0);
+} /* macosxAllocatorMalloc */
+
+
+static void *macosxAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
+{
+ if (!__PHYSFS_ui64FitsAddressSpace(s))
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ return CFAllocatorReallocate(cfallocdef, ptr, (CFIndex) s, 0);
+} /* macosxAllocatorRealloc */
+
+
+static void macosxAllocatorFree(void *ptr)
+{
+ CFAllocatorDeallocate(cfallocdef, ptr);
+} /* macosxAllocatorFree */
+
+
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+ allocator.Init = macosxAllocatorInit;
+ allocator.Deinit = macosxAllocatorDeinit;
+ allocator.Malloc = macosxAllocatorMalloc;
+ allocator.Realloc = macosxAllocatorRealloc;
+ allocator.Free = macosxAllocatorFree;
+ return 1; /* return non-zero: we're supplying custom allocator. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+#endif /* PHYSFS_PLATFORM_MACOSX */
+
+/* end of macosx.c ... */
+
diff --git a/misc/libphysfs/platform_posix.c b/misc/libphysfs/platform_posix.c
new file mode 100644
index 0000000..b358fdf
--- /dev/null
+++ b/misc/libphysfs/platform_posix.c
@@ -0,0 +1,479 @@
+/*
+ * Posix-esque support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+/* !!! FIXME: check for EINTR? */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_POSIX
+
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#if ((!defined PHYSFS_NO_THREAD_SUPPORT) && (!defined PHYSFS_PLATFORM_BEOS))
+#include <pthread.h>
+#endif
+
+#include "physfs_internal.h"
+
+
+static PHYSFS_ErrorCode errcodeFromErrnoError(const int err)
+{
+ switch (err)
+ {
+ case 0: return PHYSFS_ERR_OK;
+ case EACCES: return PHYSFS_ERR_PERMISSION;
+ case EPERM: return PHYSFS_ERR_PERMISSION;
+ case EDQUOT: return PHYSFS_ERR_NO_SPACE;
+ case EIO: return PHYSFS_ERR_IO;
+ case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP;
+ case EMLINK: return PHYSFS_ERR_NO_SPACE;
+ case ENAMETOOLONG: return PHYSFS_ERR_BAD_FILENAME;
+ case ENOENT: return PHYSFS_ERR_NO_SUCH_PATH;
+ case ENOSPC: return PHYSFS_ERR_NO_SPACE;
+ case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH;
+ case EISDIR: return PHYSFS_ERR_NOT_A_FILE;
+ case EROFS: return PHYSFS_ERR_READ_ONLY;
+ case ETXTBSY: return PHYSFS_ERR_BUSY;
+ case EBUSY: return PHYSFS_ERR_BUSY;
+ case ENOMEM: return PHYSFS_ERR_OUT_OF_MEMORY;
+ case ENOTEMPTY: return PHYSFS_ERR_DIR_NOT_EMPTY;
+ default: return PHYSFS_ERR_OS_ERROR;
+ } /* switch */
+} /* errcodeFromErrnoError */
+
+
+static inline PHYSFS_ErrorCode errcodeFromErrno(void)
+{
+ return errcodeFromErrnoError(errno);
+} /* errcodeFromErrno */
+
+
+static char *getUserDirByUID(void)
+{
+ uid_t uid = getuid();
+ struct passwd *pw;
+ char *retval = NULL;
+
+ pw = getpwuid(uid);
+ if ((pw != NULL) && (pw->pw_dir != NULL) && (*pw->pw_dir != '\0'))
+ {
+ const size_t dlen = strlen(pw->pw_dir);
+ const size_t add_dirsep = (pw->pw_dir[dlen-1] != '/') ? 1 : 0;
+ retval = (char *) allocator.Malloc(dlen + 1 + add_dirsep);
+ if (retval != NULL)
+ {
+ strcpy(retval, pw->pw_dir);
+ if (add_dirsep)
+ {
+ retval[dlen] = '/';
+ retval[dlen+1] = '\0';
+ } /* if */
+ } /* if */
+ } /* if */
+
+ return retval;
+} /* getUserDirByUID */
+
+
+char *__PHYSFS_platformCalcUserDir(void)
+{
+ char *retval = NULL;
+ char *envr = getenv("HOME");
+
+ /* if the environment variable was set, make sure it's really a dir. */
+ if (envr != NULL)
+ {
+ struct stat statbuf;
+ if ((stat(envr, &statbuf) != -1) && (S_ISDIR(statbuf.st_mode)))
+ {
+ const size_t envrlen = strlen(envr);
+ const size_t add_dirsep = (envr[envrlen-1] != '/') ? 1 : 0;
+ retval = allocator.Malloc(envrlen + 1 + add_dirsep);
+ if (retval)
+ {
+ strcpy(retval, envr);
+ if (add_dirsep)
+ {
+ retval[envrlen] = '/';
+ retval[envrlen+1] = '\0';
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* if */
+
+ if (retval == NULL)
+ retval = getUserDirByUID();
+
+ return retval;
+} /* __PHYSFS_platformCalcUserDir */
+
+
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_EnumFilesCallback callback,
+ const char *origdir,
+ void *callbackdata)
+{
+ DIR *dir;
+ struct dirent *ent;
+ int bufsize = 0;
+ char *buf = NULL;
+ int dlen = 0;
+
+ if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
+ {
+ dlen = strlen(dirname);
+ bufsize = dlen + 256;
+ buf = (char *) allocator.Malloc(bufsize);
+ if (buf == NULL)
+ return;
+ strcpy(buf, dirname);
+ if (buf[dlen - 1] != '/')
+ {
+ buf[dlen++] = '/';
+ buf[dlen] = '\0';
+ } /* if */
+ } /* if */
+
+ errno = 0;
+ dir = opendir(dirname);
+ if (dir == NULL)
+ {
+ allocator.Free(buf);
+ return;
+ } /* if */
+
+ while ((ent = readdir(dir)) != NULL)
+ {
+ if (strcmp(ent->d_name, ".") == 0)
+ continue;
+
+ if (strcmp(ent->d_name, "..") == 0)
+ continue;
+
+ if (omitSymLinks)
+ {
+ PHYSFS_Stat statbuf;
+ int exists = 0;
+ char *p;
+ int len = strlen(ent->d_name) + dlen + 1;
+ if (len > bufsize)
+ {
+ p = (char *) allocator.Realloc(buf, len);
+ if (p == NULL)
+ continue;
+ buf = p;
+ bufsize = len;
+ } /* if */
+
+ strcpy(buf + dlen, ent->d_name);
+
+ if (!__PHYSFS_platformStat(buf, &exists, &statbuf))
+ continue;
+ else if (!exists)
+ continue; /* probably can't happen, but just in case. */
+ else if (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)
+ continue;
+ } /* if */
+
+ callback(callbackdata, origdir, ent->d_name);
+ } /* while */
+
+ allocator.Free(buf);
+ closedir(dir);
+} /* __PHYSFS_platformEnumerateFiles */
+
+
+int __PHYSFS_platformMkDir(const char *path)
+{
+ const int rc = mkdir(path, S_IRWXU);
+ BAIL_IF_MACRO(rc == -1, errcodeFromErrno(), 0);
+ return 1;
+} /* __PHYSFS_platformMkDir */
+
+
+static void *doOpen(const char *filename, int mode)
+{
+ const int appending = (mode & O_APPEND);
+ int fd;
+ int *retval;
+ errno = 0;
+
+ /* O_APPEND doesn't actually behave as we'd like. */
+ mode &= ~O_APPEND;
+
+ fd = open(filename, mode, S_IRUSR | S_IWUSR);
+ BAIL_IF_MACRO(fd < 0, errcodeFromErrno(), NULL);
+
+ if (appending)
+ {
+ if (lseek(fd, 0, SEEK_END) < 0)
+ {
+ const int err = errno;
+ close(fd);
+ BAIL_MACRO(errcodeFromErrnoError(err), NULL);
+ } /* if */
+ } /* if */
+
+ retval = (int *) allocator.Malloc(sizeof (int));
+ if (!retval)
+ {
+ close(fd);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ *retval = fd;
+ return ((void *) retval);
+} /* doOpen */
+
+
+void *__PHYSFS_platformOpenRead(const char *filename)
+{
+ return doOpen(filename, O_RDONLY);
+} /* __PHYSFS_platformOpenRead */
+
+
+void *__PHYSFS_platformOpenWrite(const char *filename)
+{
+ return doOpen(filename, O_WRONLY | O_CREAT | O_TRUNC);
+} /* __PHYSFS_platformOpenWrite */
+
+
+void *__PHYSFS_platformOpenAppend(const char *filename)
+{
+ return doOpen(filename, O_WRONLY | O_CREAT | O_APPEND);
+} /* __PHYSFS_platformOpenAppend */
+
+
+PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
+ PHYSFS_uint64 len)
+{
+ const int fd = *((int *) opaque);
+ ssize_t rc = 0;
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ rc = read(fd, buffer, (size_t) len);
+ BAIL_IF_MACRO(rc == -1, errcodeFromErrno(), -1);
+ assert(rc >= 0);
+ assert(rc <= len);
+ return (PHYSFS_sint64) rc;
+} /* __PHYSFS_platformRead */
+
+
+PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ const int fd = *((int *) opaque);
+ ssize_t rc = 0;
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ rc = write(fd, (void *) buffer, (size_t) len);
+ BAIL_IF_MACRO(rc == -1, errcodeFromErrno(), rc);
+ assert(rc >= 0);
+ assert(rc <= len);
+ return (PHYSFS_sint64) rc;
+} /* __PHYSFS_platformWrite */
+
+
+int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+{
+ const int fd = *((int *) opaque);
+ const int rc = lseek(fd, (off_t) pos, SEEK_SET);
+ BAIL_IF_MACRO(rc == -1, errcodeFromErrno(), 0);
+ return 1;
+} /* __PHYSFS_platformSeek */
+
+
+PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+{
+ const int fd = *((int *) opaque);
+ PHYSFS_sint64 retval;
+ retval = (PHYSFS_sint64) lseek(fd, 0, SEEK_CUR);
+ BAIL_IF_MACRO(retval == -1, errcodeFromErrno(), -1);
+ return retval;
+} /* __PHYSFS_platformTell */
+
+
+PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
+{
+ const int fd = *((int *) opaque);
+ struct stat statbuf;
+ BAIL_IF_MACRO(fstat(fd, &statbuf) == -1, errcodeFromErrno(), -1);
+ return ((PHYSFS_sint64) statbuf.st_size);
+} /* __PHYSFS_platformFileLength */
+
+
+int __PHYSFS_platformFlush(void *opaque)
+{
+ const int fd = *((int *) opaque);
+ BAIL_IF_MACRO(fsync(fd) == -1, errcodeFromErrno(), 0);
+ return 1;
+} /* __PHYSFS_platformFlush */
+
+
+void __PHYSFS_platformClose(void *opaque)
+{
+ const int fd = *((int *) opaque);
+ (void) close(fd); /* we don't check this. You should have used flush! */
+ allocator.Free(opaque);
+} /* __PHYSFS_platformClose */
+
+
+int __PHYSFS_platformDelete(const char *path)
+{
+ BAIL_IF_MACRO(remove(path) == -1, errcodeFromErrno(), 0);
+ return 1;
+} /* __PHYSFS_platformDelete */
+
+
+int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *st)
+{
+ struct stat statbuf;
+
+ if (lstat(filename, &statbuf) == -1)
+ {
+ *exists = (errno != ENOENT);
+ BAIL_MACRO(errcodeFromErrno(), 0);
+ } /* if */
+
+ *exists = 1;
+
+ if (S_ISREG(statbuf.st_mode))
+ {
+ st->filetype = PHYSFS_FILETYPE_REGULAR;
+ st->filesize = statbuf.st_size;
+ } /* if */
+
+ else if(S_ISDIR(statbuf.st_mode))
+ {
+ st->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ st->filesize = 0;
+ } /* else if */
+
+ else
+ {
+ st->filetype = PHYSFS_FILETYPE_OTHER;
+ st->filesize = statbuf.st_size;
+ } /* else */
+
+ st->modtime = statbuf.st_mtime;
+ st->createtime = statbuf.st_ctime;
+ st->accesstime = statbuf.st_atime;
+
+ /* !!! FIXME: maybe we should just report full permissions? */
+ st->readonly = access(filename, W_OK);
+ return 1;
+} /* __PHYSFS_platformStat */
+
+
+#ifndef PHYSFS_PLATFORM_BEOS /* BeOS has its own code in platform_beos.cpp */
+#if (defined PHYSFS_NO_THREAD_SUPPORT)
+
+void *__PHYSFS_platformGetThreadID(void) { return ((void *) 0x0001); }
+void *__PHYSFS_platformCreateMutex(void) { return ((void *) 0x0001); }
+void __PHYSFS_platformDestroyMutex(void *mutex) {}
+int __PHYSFS_platformGrabMutex(void *mutex) { return 1; }
+void __PHYSFS_platformReleaseMutex(void *mutex) {}
+
+#else
+
+typedef struct
+{
+ pthread_mutex_t mutex;
+ pthread_t owner;
+ PHYSFS_uint32 count;
+} PthreadMutex;
+
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+ return ( (void *) ((size_t) pthread_self()) );
+} /* __PHYSFS_platformGetThreadID */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+ int rc;
+ PthreadMutex *m = (PthreadMutex *) allocator.Malloc(sizeof (PthreadMutex));
+ BAIL_IF_MACRO(!m, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ rc = pthread_mutex_init(&m->mutex, NULL);
+ if (rc != 0)
+ {
+ allocator.Free(m);
+ BAIL_MACRO(PHYSFS_ERR_OS_ERROR, NULL);
+ } /* if */
+
+ m->count = 0;
+ m->owner = (pthread_t) 0xDEADBEEF;
+ return ((void *) m);
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+ PthreadMutex *m = (PthreadMutex *) mutex;
+
+ /* Destroying a locked mutex is a bug, but we'll try to be helpful. */
+ if ((m->owner == pthread_self()) && (m->count > 0))
+ pthread_mutex_unlock(&m->mutex);
+
+ pthread_mutex_destroy(&m->mutex);
+ allocator.Free(m);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+ PthreadMutex *m = (PthreadMutex *) mutex;
+ pthread_t tid = pthread_self();
+ if (m->owner != tid)
+ {
+ if (pthread_mutex_lock(&m->mutex) != 0)
+ return 0;
+ m->owner = tid;
+ } /* if */
+
+ m->count++;
+ return 1;
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+ PthreadMutex *m = (PthreadMutex *) mutex;
+ assert(m->owner == pthread_self()); /* catch programming errors. */
+ assert(m->count > 0); /* catch programming errors. */
+ if (m->owner == pthread_self())
+ {
+ if (--m->count == 0)
+ {
+ m->owner = (pthread_t) 0xDEADBEEF;
+ pthread_mutex_unlock(&m->mutex);
+ } /* if */
+ } /* if */
+} /* __PHYSFS_platformReleaseMutex */
+
+#endif /* !PHYSFS_NO_THREAD_SUPPORT */
+#endif /* !PHYSFS_PLATFORM_BEOS */
+
+#endif /* PHYSFS_PLATFORM_POSIX */
+
+/* end of posix.c ... */
+
diff --git a/misc/libphysfs/platform_unix.c b/misc/libphysfs/platform_unix.c
new file mode 100644
index 0000000..51af43a
--- /dev/null
+++ b/misc/libphysfs/platform_unix.c
@@ -0,0 +1,344 @@
+/*
+ * Unix support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_UNIX
+
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <time.h>
+#include <errno.h>
+
+#if PHYSFS_PLATFORM_LINUX && !defined(PHYSFS_HAVE_MNTENT_H)
+#define PHYSFS_HAVE_MNTENT_H 1
+#elif PHYSFS_PLATFORM_SOLARIS && !defined(PHYSFS_HAVE_SYS_MNTTAB_H)
+#define PHYSFS_HAVE_SYS_MNTTAB_H 1
+#elif PHYSFS_PLATFORM_BSD && !defined(PHYSFS_HAVE_SYS_UCRED_H)
+#define PHYSFS_HAVE_SYS_UCRED_H 1
+#endif
+
+#ifdef PHYSFS_HAVE_SYS_UCRED_H
+# ifdef PHYSFS_HAVE_MNTENT_H
+# undef PHYSFS_HAVE_MNTENT_H /* don't do both... */
+# endif
+# include <sys/mount.h>
+# include <sys/ucred.h>
+#endif
+
+#ifdef PHYSFS_HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+
+#ifdef PHYSFS_HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+
+#include "physfs_internal.h"
+
+int __PHYSFS_platformInit(void)
+{
+ return 1; /* always succeed. */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+ return 1; /* always succeed. */
+} /* __PHYSFS_platformDeinit */
+
+
+/* Stub version for platforms without CD-ROM support. */
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+#if (defined PHYSFS_NO_CDROM_SUPPORT)
+ /* no-op. */
+
+#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
+ int i;
+ struct statfs *mntbufp = NULL;
+ int mounts = getmntinfo(&mntbufp, MNT_WAIT);
+
+ for (i = 0; i < mounts; i++)
+ {
+ int add_it = 0;
+
+ if (strcmp(mntbufp[i].f_fstypename, "iso9660") == 0)
+ add_it = 1;
+ else if (strcmp( mntbufp[i].f_fstypename, "cd9660") == 0)
+ add_it = 1;
+
+ /* add other mount types here */
+
+ if (add_it)
+ cb(data, mntbufp[i].f_mntonname);
+ } /* for */
+
+#elif (defined PHYSFS_HAVE_MNTENT_H)
+ FILE *mounts = NULL;
+ struct mntent *ent = NULL;
+
+ mounts = setmntent("/etc/mtab", "r");
+ BAIL_IF_MACRO(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
+
+ while ( (ent = getmntent(mounts)) != NULL )
+ {
+ int add_it = 0;
+ if (strcmp(ent->mnt_type, "iso9660") == 0)
+ add_it = 1;
+ else if (strcmp(ent->mnt_type, "udf") == 0)
+ add_it = 1;
+
+ /* !!! FIXME: these might pick up floppy drives, right? */
+ else if (strcmp(ent->mnt_type, "auto") == 0)
+ add_it = 1;
+ else if (strcmp(ent->mnt_type, "supermount") == 0)
+ add_it = 1;
+
+ /* !!! FIXME: udf? automount? */
+
+ /* add other mount types here */
+
+ if (add_it)
+ cb(data, ent->mnt_dir);
+ } /* while */
+
+ endmntent(mounts);
+
+#elif (defined PHYSFS_HAVE_SYS_MNTTAB_H)
+ FILE *mounts = fopen(MNTTAB, "r");
+ struct mnttab ent;
+
+ BAIL_IF_MACRO(mounts == NULL, PHYSFS_ERR_IO, /*return void*/);
+ while (getmntent(mounts, &ent) == 0)
+ {
+ int add_it = 0;
+ if (strcmp(ent.mnt_fstype, "hsfs") == 0)
+ add_it = 1;
+
+ /* add other mount types here */
+
+ if (add_it)
+ cb(data, ent.mnt_mountp);
+ } /* while */
+
+ fclose(mounts);
+
+#else
+#error Unknown platform. Should have defined PHYSFS_NO_CDROM_SUPPORT, perhaps.
+#endif
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+/*
+ * See where program (bin) resides in the $PATH specified by (envr).
+ * returns a copy of the first element in envr that contains it, or NULL
+ * if it doesn't exist or there were other problems. PHYSFS_SetError() is
+ * called if we have a problem.
+ *
+ * (envr) will be scribbled over, and you are expected to allocator.Free() the
+ * return value when you're done with it.
+ */
+static char *findBinaryInPath(const char *bin, char *envr)
+{
+ size_t alloc_size = 0;
+ char *exe = NULL;
+ char *start = envr;
+ char *ptr;
+
+ assert(bin != NULL);
+ assert(envr != NULL);
+
+ do
+ {
+ size_t size;
+ size_t binlen;
+
+ ptr = strchr(start, ':'); /* find next $PATH separator. */
+ if (ptr)
+ *ptr = '\0';
+
+ binlen = strlen(bin);
+ size = strlen(start) + binlen + 2;
+ if (size > alloc_size)
+ {
+ char *x = (char *) allocator.Realloc(exe, size);
+ if (!x)
+ {
+ if (exe != NULL)
+ allocator.Free(exe);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ alloc_size = size;
+ exe = x;
+ } /* if */
+
+ /* build full binary path... */
+ strcpy(exe, start);
+ if ((exe[0] == '\0') || (exe[strlen(exe) - 1] != '/'))
+ strcat(exe, "/");
+ strcat(exe, bin);
+
+ if (access(exe, X_OK) == 0) /* Exists as executable? We're done. */
+ {
+ exe[size - binlen] = '\0'; /* chop off filename, leave '/' */
+ return exe;
+ } /* if */
+
+ start = ptr + 1; /* start points to beginning of next element. */
+ } while (ptr != NULL);
+
+ if (exe != NULL)
+ allocator.Free(exe);
+
+ return NULL; /* doesn't exist in path. */
+} /* findBinaryInPath */
+
+
+static char *readSymLink(const char *path)
+{
+ ssize_t len = 64;
+ ssize_t rc = -1;
+ char *retval = NULL;
+
+ while (1)
+ {
+ char *ptr = (char *) allocator.Realloc(retval, (size_t) len);
+ if (ptr == NULL)
+ break; /* out of memory. */
+ retval = ptr;
+
+ rc = readlink(path, retval, len);
+ if (rc == -1)
+ break; /* not a symlink, i/o error, etc. */
+
+ else if (rc < len)
+ {
+ retval[rc] = '\0'; /* readlink doesn't null-terminate. */
+ return retval; /* we're good to go. */
+ } /* else if */
+
+ len *= 2; /* grow buffer, try again. */
+ } /* while */
+
+ if (retval != NULL)
+ allocator.Free(retval);
+ return NULL;
+} /* readSymLink */
+
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+ char *retval = NULL;
+ const char *envr = NULL;
+
+ /*
+ * Try to avoid using argv0 unless forced to. If there's a Linux-like
+ * /proc filesystem, you can get the full path to the current process from
+ * the /proc/self/exe symlink.
+ */
+ retval = readSymLink("/proc/self/exe");
+ if (retval == NULL)
+ {
+ /* older kernels don't have /proc/self ... try PID version... */
+ const unsigned long long pid = (unsigned long long) getpid();
+ char path[64];
+ const int rc = (int) snprintf(path,sizeof(path),"/proc/%llu/exe",pid);
+ if ( (rc > 0) && (rc < sizeof(path)) )
+ retval = readSymLink(path);
+ } /* if */
+
+ if (retval != NULL) /* chop off filename. */
+ {
+ char *ptr = strrchr(retval, '/');
+ if (ptr != NULL)
+ *(ptr+1) = '\0';
+ else /* shouldn't happen, but just in case... */
+ {
+ allocator.Free(retval);
+ retval = NULL;
+ } /* else */
+ } /* if */
+
+ /* No /proc/self/exe, but we have an argv[0] we can parse? */
+ if ((retval == NULL) && (argv0 != NULL))
+ {
+ /* fast path: default behaviour can handle this. */
+ if (strchr(argv0, '/') != NULL)
+ return NULL; /* higher level parses out real path from argv0. */
+
+ /* If there's no dirsep on argv0, then look through $PATH for it. */
+ envr = getenv("PATH");
+ if (envr != NULL)
+ {
+ char *path = (char *) __PHYSFS_smallAlloc(strlen(envr) + 1);
+ BAIL_IF_MACRO(!path, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ strcpy(path, envr);
+ retval = findBinaryInPath(argv0, path);
+ __PHYSFS_smallFree(path);
+ } /* if */
+ } /* if */
+
+ if (retval != NULL)
+ {
+ /* try to shrink buffer... */
+ char *ptr = (char *) allocator.Realloc(retval, strlen(retval) + 1);
+ if (ptr != NULL)
+ retval = ptr; /* oh well if it failed. */
+ } /* if */
+
+ return retval;
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+ /*
+ * We use XDG's base directory spec, even if you're not on Linux.
+ * This isn't strictly correct, but the results are relatively sane
+ * in any case.
+ *
+ * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ */
+ const char *envr = getenv("XDG_DATA_HOME");
+ const char *append = "/";
+ char *retval = NULL;
+ size_t len = 0;
+
+ if (!envr)
+ {
+ /* You end up with "$HOME/.local/share/Game Name 2" */
+ envr = __PHYSFS_getUserDir();
+ BAIL_IF_MACRO(!envr, ERRPASS, NULL); /* oh well. */
+ append = ".local/share/";
+ } /* if */
+
+ len = strlen(envr) + strlen(append) + strlen(app) + 2;
+ retval = (char *) allocator.Malloc(len);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ snprintf(retval, len, "%s%s%s/", envr, append, app);
+ return retval;
+} /* __PHYSFS_platformCalcPrefDir */
+
+
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+ return 0; /* just use malloc() and friends. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+#endif /* PHYSFS_PLATFORM_UNIX */
+
+/* end of unix.c ... */
+
diff --git a/misc/libphysfs/platform_windows.c b/misc/libphysfs/platform_windows.c
new file mode 100644
index 0000000..f6079b6
--- /dev/null
+++ b/misc/libphysfs/platform_windows.c
@@ -0,0 +1,936 @@
+/*
+ * Windows support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Ryan C. Gordon, and made sane by Gregory S. Read.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_platforms.h"
+
+#ifdef PHYSFS_PLATFORM_WINDOWS
+
+/* Forcibly disable UNICODE macro, since we manage this ourselves. */
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#include <userenv.h>
+#include <shlobj.h>
+#include <dbt.h>
+#include <errno.h>
+#include <ctype.h>
+#include <time.h>
+
+#include "physfs_internal.h"
+
+#define LOWORDER_UINT64(pos) ((PHYSFS_uint32) (pos & 0xFFFFFFFF))
+#define HIGHORDER_UINT64(pos) ((PHYSFS_uint32) ((pos >> 32) & 0xFFFFFFFF))
+
+/*
+ * Users without the platform SDK don't have this defined. The original docs
+ * for SetFilePointer() just said to compare with 0xFFFFFFFF, so this should
+ * work as desired.
+ */
+#define PHYSFS_INVALID_SET_FILE_POINTER 0xFFFFFFFF
+
+/* just in case... */
+#define PHYSFS_INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
+
+/* Not defined before the Vista SDK. */
+#define PHYSFS_IO_REPARSE_TAG_SYMLINK 0xA000000C
+
+
+#define UTF8_TO_UNICODE_STACK_MACRO(w_assignto, str) { \
+ if (str == NULL) \
+ w_assignto = NULL; \
+ else { \
+ const PHYSFS_uint64 len = (PHYSFS_uint64) ((strlen(str) + 1) * 2); \
+ w_assignto = (WCHAR *) __PHYSFS_smallAlloc(len); \
+ if (w_assignto != NULL) \
+ PHYSFS_utf8ToUtf16(str, (PHYSFS_uint16 *) w_assignto, len); \
+ } \
+} \
+
+/* Note this counts WCHARs, not codepoints! */
+static PHYSFS_uint64 wStrLen(const WCHAR *wstr)
+{
+ PHYSFS_uint64 len = 0;
+ while (*(wstr++))
+ len++;
+ return len;
+} /* wStrLen */
+
+static char *unicodeToUtf8Heap(const WCHAR *w_str)
+{
+ char *retval = NULL;
+ if (w_str != NULL)
+ {
+ void *ptr = NULL;
+ const PHYSFS_uint64 len = (wStrLen(w_str) * 4) + 1;
+ retval = allocator.Malloc(len);
+ BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ PHYSFS_utf8FromUtf16((const PHYSFS_uint16 *) w_str, retval, len);
+ ptr = allocator.Realloc(retval, strlen(retval) + 1); /* shrink. */
+ if (ptr != NULL)
+ retval = (char *) ptr;
+ } /* if */
+ return retval;
+} /* unicodeToUtf8Heap */
+
+/* !!! FIXME: do we really need readonly? If not, do we need this struct? */
+typedef struct
+{
+ HANDLE handle;
+ int readonly;
+} WinApiFile;
+
+static HANDLE detectCDThreadHandle = NULL;
+static HWND detectCDHwnd = 0;
+static volatile int initialDiscDetectionComplete = 0;
+static volatile DWORD drivesWithMediaBitmap = 0;
+
+
+static PHYSFS_ErrorCode errcodeFromWinApiError(const DWORD err)
+{
+ /*
+ * win32 error codes are sort of a tricky thing; Microsoft intentionally
+ * doesn't list which ones a given API might trigger, there are several
+ * with overlapping and unclear meanings...and there's 16 thousand of
+ * them in Windows 7. It looks like the ones we care about are in the
+ * first 500, but I can't say this list is perfect; we might miss
+ * important values or misinterpret others.
+ *
+ * Don't treat this list as anything other than a work in progress.
+ */
+ switch (err)
+ {
+ case ERROR_SUCCESS: return PHYSFS_ERR_OK;
+ case ERROR_ACCESS_DENIED: return PHYSFS_ERR_PERMISSION;
+ case ERROR_NETWORK_ACCESS_DENIED: return PHYSFS_ERR_PERMISSION;
+ case ERROR_NOT_READY: return PHYSFS_ERR_IO;
+ case ERROR_CRC: return PHYSFS_ERR_IO;
+ case ERROR_SEEK: return PHYSFS_ERR_IO;
+ case ERROR_SECTOR_NOT_FOUND: return PHYSFS_ERR_IO;
+ case ERROR_NOT_DOS_DISK: return PHYSFS_ERR_IO;
+ case ERROR_WRITE_FAULT: return PHYSFS_ERR_IO;
+ case ERROR_READ_FAULT: return PHYSFS_ERR_IO;
+ case ERROR_DEV_NOT_EXIST: return PHYSFS_ERR_IO;
+ /* !!! FIXME: ?? case ELOOP: return PHYSFS_ERR_SYMLINK_LOOP; */
+ case ERROR_BUFFER_OVERFLOW: return PHYSFS_ERR_BAD_FILENAME;
+ case ERROR_INVALID_NAME: return PHYSFS_ERR_BAD_FILENAME;
+ case ERROR_BAD_PATHNAME: return PHYSFS_ERR_BAD_FILENAME;
+ case ERROR_DIRECTORY: return PHYSFS_ERR_BAD_FILENAME;
+ case ERROR_FILE_NOT_FOUND: return PHYSFS_ERR_NO_SUCH_PATH;
+ case ERROR_PATH_NOT_FOUND: return PHYSFS_ERR_NO_SUCH_PATH;
+ case ERROR_DELETE_PENDING: return PHYSFS_ERR_NO_SUCH_PATH;
+ case ERROR_INVALID_DRIVE: return PHYSFS_ERR_NO_SUCH_PATH;
+ case ERROR_HANDLE_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
+ case ERROR_DISK_FULL: return PHYSFS_ERR_NO_SPACE;
+ /* !!! FIXME: ?? case ENOTDIR: return PHYSFS_ERR_NO_SUCH_PATH; */
+ /* !!! FIXME: ?? case EISDIR: return PHYSFS_ERR_NOT_A_FILE; */
+ case ERROR_WRITE_PROTECT: return PHYSFS_ERR_READ_ONLY;
+ case ERROR_LOCK_VIOLATION: return PHYSFS_ERR_BUSY;
+ case ERROR_SHARING_VIOLATION: return PHYSFS_ERR_BUSY;
+ case ERROR_CURRENT_DIRECTORY: return PHYSFS_ERR_BUSY;
+ case ERROR_DRIVE_LOCKED: return PHYSFS_ERR_BUSY;
+ case ERROR_PATH_BUSY: return PHYSFS_ERR_BUSY;
+ case ERROR_BUSY: return PHYSFS_ERR_BUSY;
+ case ERROR_NOT_ENOUGH_MEMORY: return PHYSFS_ERR_OUT_OF_MEMORY;
+ case ERROR_OUTOFMEMORY: return PHYSFS_ERR_OUT_OF_MEMORY;
+ case ERROR_DIR_NOT_EMPTY: return PHYSFS_ERR_DIR_NOT_EMPTY;
+ default: return PHYSFS_ERR_OS_ERROR;
+ } /* switch */
+} /* errcodeFromWinApiError */
+
+static inline PHYSFS_ErrorCode errcodeFromWinApi(void)
+{
+ return errcodeFromWinApiError(GetLastError());
+} /* errcodeFromWinApi */
+
+
+typedef BOOL (WINAPI *fnSTEM)(DWORD, LPDWORD b);
+
+static DWORD pollDiscDrives(void)
+{
+ /* Try to use SetThreadErrorMode(), which showed up in Windows 7. */
+ HANDLE lib = LoadLibraryA("kernel32.dll");
+ fnSTEM stem = NULL;
+ char drive[4] = { 'x', ':', '\\', '\0' };
+ DWORD oldErrorMode = 0;
+ DWORD drives = 0;
+ DWORD i;
+
+ if (lib)
+ stem = (fnSTEM) GetProcAddress(lib, "SetThreadErrorMode");
+
+ if (stem)
+ stem(SEM_FAILCRITICALERRORS, &oldErrorMode);
+ else
+ oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+ /* Do detection. This may block if a disc is spinning up. */
+ for (i = 'A'; i <= 'Z'; i++)
+ {
+ DWORD tmp = 0;
+ drive[0] = (char) i;
+ if (GetDriveTypeA(drive) != DRIVE_CDROM)
+ continue;
+
+ /* If this function succeeds, there's media in the drive */
+ if (GetVolumeInformationA(drive, NULL, 0, NULL, NULL, &tmp, NULL, 0))
+ drives |= (1 << (i - 'A'));
+ } /* for */
+
+ if (stem)
+ stem(oldErrorMode, NULL);
+ else
+ SetErrorMode(oldErrorMode);
+
+ if (lib)
+ FreeLibrary(lib);
+
+ return drives;
+} /* pollDiscDrives */
+
+
+static LRESULT CALLBACK detectCDWndProc(HWND hwnd, UINT msg,
+ WPARAM wp, LPARAM lparam)
+{
+ PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lparam;
+ PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lparam;
+ const int removed = (wp == DBT_DEVICEREMOVECOMPLETE);
+
+ if (msg == WM_DESTROY)
+ return 0;
+ else if ((msg != WM_DEVICECHANGE) ||
+ ((wp != DBT_DEVICEARRIVAL) && (wp != DBT_DEVICEREMOVECOMPLETE)) ||
+ (lpdb->dbch_devicetype != DBT_DEVTYP_VOLUME) ||
+ ((lpdbv->dbcv_flags & DBTF_MEDIA) == 0))
+ {
+ return DefWindowProcW(hwnd, msg, wp, lparam);
+ } /* else if */
+
+ if (removed)
+ drivesWithMediaBitmap &= ~lpdbv->dbcv_unitmask;
+ else
+ drivesWithMediaBitmap |= lpdbv->dbcv_unitmask;
+
+ return TRUE;
+} /* detectCDWndProc */
+
+
+static DWORD WINAPI detectCDThread(LPVOID lpParameter)
+{
+ const char *classname = "PhysicsFSDetectCDCatcher";
+ const char *winname = "PhysicsFSDetectCDMsgWindow";
+ HINSTANCE hInstance = GetModuleHandleW(NULL);
+ ATOM class_atom = 0;
+ WNDCLASSEXA wce;
+ MSG msg;
+
+ memset(&wce, '\0', sizeof (wce));
+ wce.cbSize = sizeof (wce);
+ wce.lpfnWndProc = detectCDWndProc;
+ wce.lpszClassName = classname;
+ wce.hInstance = hInstance;
+ class_atom = RegisterClassExA(&wce);
+ if (class_atom == 0)
+ {
+ initialDiscDetectionComplete = 1; /* let main thread go on. */
+ return 0;
+ } /* if */
+
+ detectCDHwnd = CreateWindowExA(0, classname, winname, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, HWND_DESKTOP, NULL, hInstance, NULL);
+
+ if (detectCDHwnd == NULL)
+ {
+ initialDiscDetectionComplete = 1; /* let main thread go on. */
+ UnregisterClassA(classname, hInstance);
+ return 0;
+ } /* if */
+
+ /* We'll get events when discs come and go from now on. */
+
+ /* Do initial detection, possibly blocking awhile... */
+ drivesWithMediaBitmap = pollDiscDrives();
+ initialDiscDetectionComplete = 1; /* let main thread go on. */
+
+ do
+ {
+ const BOOL rc = GetMessageW(&msg, detectCDHwnd, 0, 0);
+ if ((rc == 0) || (rc == -1))
+ break; /* don't care if WM_QUIT or error break this loop. */
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ } while (1);
+
+ /* we've been asked to quit. */
+ DestroyWindow(detectCDHwnd);
+
+ do
+ {
+ const BOOL rc = GetMessage(&msg, detectCDHwnd, 0, 0);
+ if ((rc == 0) || (rc == -1))
+ break;
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ } while (1);
+
+ UnregisterClassA(classname, hInstance);
+
+ return 0;
+} /* detectCDThread */
+
+
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+ char drive_str[4] = { 'x', ':', '\\', '\0' };
+ DWORD drives = 0;
+ DWORD i;
+
+ /*
+ * If you poll a drive while a user is inserting a disc, the OS will
+ * block this thread until the drive has spun up. So we swallow the risk
+ * once for initial detection, and spin a thread that will get device
+ * events thereafter, for apps that use this interface to poll for
+ * disc insertion.
+ */
+ if (!detectCDThreadHandle)
+ {
+ initialDiscDetectionComplete = 0;
+ detectCDThreadHandle = CreateThread(NULL,0,detectCDThread,NULL,0,NULL);
+ if (detectCDThreadHandle == NULL)
+ return; /* oh well. */
+
+ while (!initialDiscDetectionComplete)
+ Sleep(50);
+ } /* if */
+
+ drives = drivesWithMediaBitmap; /* whatever the thread has seen, we take. */
+ for (i = 'A'; i <= 'Z'; i++)
+ {
+ if (drives & (1 << (i - 'A')))
+ {
+ drive_str[0] = (char) i;
+ cb(data, drive_str);
+ } /* if */
+ } /* for */
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+ DWORD buflen = 64;
+ LPWSTR modpath = NULL;
+ char *retval = NULL;
+
+ while (1)
+ {
+ DWORD rc;
+ void *ptr;
+
+ if ( (ptr = allocator.Realloc(modpath, buflen*sizeof(WCHAR))) == NULL )
+ {
+ allocator.Free(modpath);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+ modpath = (LPWSTR) ptr;
+
+ rc = GetModuleFileNameW(NULL, modpath, buflen);
+ if (rc == 0)
+ {
+ allocator.Free(modpath);
+ BAIL_MACRO(errcodeFromWinApi(), NULL);
+ } /* if */
+
+ if (rc < buflen)
+ {
+ buflen = rc;
+ break;
+ } /* if */
+
+ buflen *= 2;
+ } /* while */
+
+ if (buflen > 0) /* just in case... */
+ {
+ WCHAR *ptr = (modpath + buflen) - 1;
+ while (ptr != modpath)
+ {
+ if (*ptr == '\\')
+ break;
+ ptr--;
+ } /* while */
+
+ if ((ptr == modpath) && (*ptr != '\\'))
+ __PHYSFS_setError(PHYSFS_ERR_OTHER_ERROR); /* oh well. */
+ else
+ {
+ *(ptr+1) = '\0'; /* chop off filename. */
+ retval = unicodeToUtf8Heap(modpath);
+ } /* else */
+ } /* else */
+ allocator.Free(modpath);
+
+ return retval; /* w00t. */
+} /* __PHYSFS_platformCalcBaseDir */
+
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+ /*
+ * Vista and later has a new API for this, but SHGetFolderPath works there,
+ * and apparently just wraps the new API. This is the new way to do it:
+ *
+ * SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE,
+ * NULL, &wszPath);
+ */
+
+ WCHAR path[MAX_PATH];
+ char *utf8 = NULL;
+ size_t len = 0;
+ char *retval = NULL;
+
+ if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
+ NULL, 0, path)))
+ BAIL_MACRO(PHYSFS_ERR_OS_ERROR, NULL);
+
+ utf8 = unicodeToUtf8Heap(path);
+ BAIL_IF_MACRO(!utf8, ERRPASS, NULL);
+ len = strlen(utf8) + strlen(org) + strlen(app) + 4;
+ retval = allocator.Malloc(len);
+ if (!retval)
+ {
+ allocator.Free(utf8);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ sprintf(retval, "%s\\%s\\%s\\", utf8, org, app);
+ return retval;
+} /* __PHYSFS_platformCalcPrefDir */
+
+
+char *__PHYSFS_platformCalcUserDir(void)
+{
+ typedef BOOL (WINAPI *fnGetUserProfDirW)(HANDLE, LPWSTR, LPDWORD);
+ fnGetUserProfDirW pGetDir = NULL;
+ HANDLE lib = NULL;
+ HANDLE accessToken = NULL; /* Security handle to process */
+ char *retval = NULL;
+
+ lib = LoadLibraryA("userenv.dll");
+ BAIL_IF_MACRO(!lib, errcodeFromWinApi(), NULL);
+ pGetDir=(fnGetUserProfDirW) GetProcAddress(lib,"GetUserProfileDirectoryW");
+ GOTO_IF_MACRO(!pGetDir, errcodeFromWinApi(), done);
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &accessToken))
+ GOTO_MACRO(errcodeFromWinApi(), done);
+ else
+ {
+ DWORD psize = 0;
+ WCHAR dummy = 0;
+ LPWSTR wstr = NULL;
+ BOOL rc = 0;
+
+ /*
+ * Should fail. Will write the size of the profile path in
+ * psize. Also note that the second parameter can't be
+ * NULL or the function fails.
+ */
+ rc = pGetDir(accessToken, &dummy, &psize);
+ assert(!rc); /* !!! FIXME: handle this gracefully. */
+ (void) rc;
+
+ /* Allocate memory for the profile directory */
+ wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
+ if (wstr != NULL)
+ {
+ if (pGetDir(accessToken, wstr, &psize))
+ {
+ /* Make sure it ends in a dirsep. We allocated +1 for this. */
+ if (wstr[psize - 2] != '\\')
+ {
+ wstr[psize - 1] = '\\';
+ wstr[psize - 0] = '\0';
+ } /* if */
+ retval = unicodeToUtf8Heap(wstr);
+ } /* if */
+ __PHYSFS_smallFree(wstr);
+ } /* if */
+
+ CloseHandle(accessToken);
+ } /* if */
+
+done:
+ FreeLibrary(lib);
+ return retval; /* We made it: hit the showers. */
+} /* __PHYSFS_platformCalcUserDir */
+
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+ return ( (void *) ((size_t) GetCurrentThreadId()) );
+} /* __PHYSFS_platformGetThreadID */
+
+
+static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
+{
+ return ( (attr & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ (tag == PHYSFS_IO_REPARSE_TAG_SYMLINK) );
+} /* isSymlinkAttrs */
+
+
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_EnumFilesCallback callback,
+ const char *origdir,
+ void *callbackdata)
+{
+ HANDLE dir = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATAW entw;
+ size_t len = strlen(dirname);
+ char *searchPath = NULL;
+ WCHAR *wSearchPath = NULL;
+
+ /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
+ searchPath = (char *) __PHYSFS_smallAlloc(len + 3);
+ if (searchPath == NULL)
+ return;
+
+ /* Copy current dirname */
+ strcpy(searchPath, dirname);
+
+ /* if there's no '\\' at the end of the path, stick one in there. */
+ if (searchPath[len - 1] != '\\')
+ {
+ searchPath[len++] = '\\';
+ searchPath[len] = '\0';
+ } /* if */
+
+ /* Append the "*" to the end of the string */
+ strcat(searchPath, "*");
+
+ UTF8_TO_UNICODE_STACK_MACRO(wSearchPath, searchPath);
+ if (!wSearchPath)
+ return; /* oh well. */
+
+ dir = FindFirstFileW(wSearchPath, &entw);
+
+ __PHYSFS_smallFree(wSearchPath);
+ __PHYSFS_smallFree(searchPath);
+ if (dir == INVALID_HANDLE_VALUE)
+ return;
+
+ do
+ {
+ const DWORD attr = entw.dwFileAttributes;
+ const DWORD tag = entw.dwReserved0;
+ const WCHAR *fn = entw.cFileName;
+ char *utf8;
+
+ if ((fn[0] == '.') && (fn[1] == '\0'))
+ continue;
+ if ((fn[0] == '.') && (fn[1] == '.') && (fn[2] == '\0'))
+ continue;
+ if ((omitSymLinks) && (isSymlinkAttrs(attr, tag)))
+ continue;
+
+ utf8 = unicodeToUtf8Heap(fn);
+ if (utf8 != NULL)
+ {
+ callback(callbackdata, origdir, utf8);
+ allocator.Free(utf8);
+ } /* if */
+ } while (FindNextFileW(dir, &entw) != 0);
+
+ FindClose(dir);
+} /* __PHYSFS_platformEnumerateFiles */
+
+
+int __PHYSFS_platformMkDir(const char *path)
+{
+ WCHAR *wpath;
+ DWORD rc;
+ UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
+ rc = CreateDirectoryW(wpath, NULL);
+ __PHYSFS_smallFree(wpath);
+ BAIL_IF_MACRO(rc == 0, errcodeFromWinApi(), 0);
+ return 1;
+} /* __PHYSFS_platformMkDir */
+
+
+int __PHYSFS_platformInit(void)
+{
+ return 1; /* It's all good */
+} /* __PHYSFS_platformInit */
+
+
+int __PHYSFS_platformDeinit(void)
+{
+ if (detectCDThreadHandle)
+ {
+ if (detectCDHwnd)
+ PostMessageW(detectCDHwnd, WM_QUIT, 0, 0);
+ CloseHandle(detectCDThreadHandle);
+ detectCDThreadHandle = NULL;
+ initialDiscDetectionComplete = 0;
+ drivesWithMediaBitmap = 0;
+ } /* if */
+
+ return 1; /* It's all good */
+} /* __PHYSFS_platformDeinit */
+
+
+static void *doOpen(const char *fname, DWORD mode, DWORD creation, int rdonly)
+{
+ HANDLE fileh;
+ WinApiFile *retval;
+ WCHAR *wfname;
+
+ UTF8_TO_UNICODE_STACK_MACRO(wfname, fname);
+ BAIL_IF_MACRO(!wfname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ fileh = CreateFileW(wfname, mode, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
+ __PHYSFS_smallFree(wfname);
+
+ BAIL_IF_MACRO(fileh == INVALID_HANDLE_VALUE,errcodeFromWinApi(), NULL);
+
+ retval = (WinApiFile *) allocator.Malloc(sizeof (WinApiFile));
+ if (!retval)
+ {
+ CloseHandle(fileh);
+ BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ } /* if */
+
+ retval->readonly = rdonly;
+ retval->handle = fileh;
+ return retval;
+} /* doOpen */
+
+
+void *__PHYSFS_platformOpenRead(const char *filename)
+{
+ return doOpen(filename, GENERIC_READ, OPEN_EXISTING, 1);
+} /* __PHYSFS_platformOpenRead */
+
+
+void *__PHYSFS_platformOpenWrite(const char *filename)
+{
+ return doOpen(filename, GENERIC_WRITE, CREATE_ALWAYS, 0);
+} /* __PHYSFS_platformOpenWrite */
+
+
+void *__PHYSFS_platformOpenAppend(const char *filename)
+{
+ void *retval = doOpen(filename, GENERIC_WRITE, OPEN_ALWAYS, 0);
+ if (retval != NULL)
+ {
+ HANDLE h = ((WinApiFile *) retval)->handle;
+ DWORD rc = SetFilePointer(h, 0, NULL, FILE_END);
+ if (rc == PHYSFS_INVALID_SET_FILE_POINTER)
+ {
+ const PHYSFS_ErrorCode err = errcodeFromWinApi();
+ CloseHandle(h);
+ allocator.Free(retval);
+ BAIL_MACRO(err, NULL);
+ } /* if */
+ } /* if */
+
+ return retval;
+} /* __PHYSFS_platformOpenAppend */
+
+
+PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ PHYSFS_sint64 totalRead = 0;
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ while (len > 0)
+ {
+ const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD) len;
+ DWORD numRead = 0;
+ if (!ReadFile(Handle, buf, thislen, &numRead, NULL))
+ BAIL_MACRO(errcodeFromWinApi(), -1);
+ len -= (PHYSFS_uint64) numRead;
+ totalRead += (PHYSFS_sint64) numRead;
+ if (numRead != thislen)
+ break;
+ } /* while */
+
+ return totalRead;
+} /* __PHYSFS_platformRead */
+
+
+PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
+ PHYSFS_uint64 len)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ PHYSFS_sint64 totalWritten = 0;
+
+ if (!__PHYSFS_ui64FitsAddressSpace(len))
+ BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
+
+ while (len > 0)
+ {
+ const DWORD thislen = (len > 0xFFFFFFFF) ? 0xFFFFFFFF : (DWORD) len;
+ DWORD numWritten = 0;
+ if (!WriteFile(Handle, buffer, thislen, &numWritten, NULL))
+ BAIL_MACRO(errcodeFromWinApi(), -1);
+ len -= (PHYSFS_uint64) numWritten;
+ totalWritten += (PHYSFS_sint64) numWritten;
+ if (numWritten != thislen)
+ break;
+ } /* while */
+
+ return totalWritten;
+} /* __PHYSFS_platformWrite */
+
+
+int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ LONG HighOrderPos;
+ PLONG pHighOrderPos;
+ DWORD rc;
+
+ /* Get the high order 32-bits of the position */
+ HighOrderPos = HIGHORDER_UINT64(pos);
+
+ /*
+ * MSDN: "If you do not need the high-order 32 bits, this
+ * pointer must be set to NULL."
+ */
+ pHighOrderPos = (HighOrderPos) ? &HighOrderPos : NULL;
+
+ /* Move pointer "pos" count from start of file */
+ rc = SetFilePointer(Handle, LOWORDER_UINT64(pos),
+ pHighOrderPos, FILE_BEGIN);
+
+ if ( (rc == PHYSFS_INVALID_SET_FILE_POINTER) &&
+ (GetLastError() != NO_ERROR) )
+ {
+ BAIL_MACRO(errcodeFromWinApi(), 0);
+ } /* if */
+
+ return 1; /* No error occured */
+} /* __PHYSFS_platformSeek */
+
+
+PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ LONG HighPos = 0;
+ DWORD LowPos;
+ PHYSFS_sint64 retval;
+
+ /* Get current position */
+ LowPos = SetFilePointer(Handle, 0, &HighPos, FILE_CURRENT);
+ if ( (LowPos == PHYSFS_INVALID_SET_FILE_POINTER) &&
+ (GetLastError() != NO_ERROR) )
+ {
+ BAIL_MACRO(errcodeFromWinApi(), -1);
+ } /* if */
+ else
+ {
+ /* Combine the high/low order to create the 64-bit position value */
+ retval = (((PHYSFS_uint64) HighPos) << 32) | LowPos;
+ assert(retval >= 0);
+ } /* else */
+
+ return retval;
+} /* __PHYSFS_platformTell */
+
+
+PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ DWORD SizeHigh;
+ DWORD SizeLow;
+ PHYSFS_sint64 retval;
+
+ SizeLow = GetFileSize(Handle, &SizeHigh);
+ if ( (SizeLow == PHYSFS_INVALID_SET_FILE_POINTER) &&
+ (GetLastError() != NO_ERROR) )
+ {
+ BAIL_MACRO(errcodeFromWinApi(), -1);
+ } /* if */
+ else
+ {
+ /* Combine the high/low order to create the 64-bit position value */
+ retval = (((PHYSFS_uint64) SizeHigh) << 32) | SizeLow;
+ assert(retval >= 0);
+ } /* else */
+
+ return retval;
+} /* __PHYSFS_platformFileLength */
+
+
+int __PHYSFS_platformFlush(void *opaque)
+{
+ WinApiFile *fh = ((WinApiFile *) opaque);
+ if (!fh->readonly)
+ BAIL_IF_MACRO(!FlushFileBuffers(fh->handle), errcodeFromWinApi(), 0);
+
+ return 1;
+} /* __PHYSFS_platformFlush */
+
+
+void __PHYSFS_platformClose(void *opaque)
+{
+ HANDLE Handle = ((WinApiFile *) opaque)->handle;
+ (void) CloseHandle(Handle); /* ignore errors. You should have flushed! */
+ allocator.Free(opaque);
+} /* __PHYSFS_platformClose */
+
+
+static int doPlatformDelete(LPWSTR wpath)
+{
+ const int isdir = (GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY);
+ const BOOL rc = (isdir) ? RemoveDirectoryW(wpath) : DeleteFileW(wpath);
+ BAIL_IF_MACRO(!rc, errcodeFromWinApi(), 0);
+ return 1; /* if you made it here, it worked. */
+} /* doPlatformDelete */
+
+
+int __PHYSFS_platformDelete(const char *path)
+{
+ int retval = 0;
+ LPWSTR wpath = NULL;
+ UTF8_TO_UNICODE_STACK_MACRO(wpath, path);
+ BAIL_IF_MACRO(!wpath, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ retval = doPlatformDelete(wpath);
+ __PHYSFS_smallFree(wpath);
+ return retval;
+} /* __PHYSFS_platformDelete */
+
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+ LPCRITICAL_SECTION lpcs;
+ lpcs = (LPCRITICAL_SECTION) allocator.Malloc(sizeof (CRITICAL_SECTION));
+ BAIL_IF_MACRO(!lpcs, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ InitializeCriticalSection(lpcs);
+ return lpcs;
+} /* __PHYSFS_platformCreateMutex */
+
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+ DeleteCriticalSection((LPCRITICAL_SECTION) mutex);
+ allocator.Free(mutex);
+} /* __PHYSFS_platformDestroyMutex */
+
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+ EnterCriticalSection((LPCRITICAL_SECTION) mutex);
+ return 1;
+} /* __PHYSFS_platformGrabMutex */
+
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+ LeaveCriticalSection((LPCRITICAL_SECTION) mutex);
+} /* __PHYSFS_platformReleaseMutex */
+
+
+static PHYSFS_sint64 FileTimeToPhysfsTime(const FILETIME *ft)
+{
+ SYSTEMTIME st_utc;
+ SYSTEMTIME st_localtz;
+ TIME_ZONE_INFORMATION tzi;
+ DWORD tzid;
+ PHYSFS_sint64 retval;
+ struct tm tm;
+ BOOL rc;
+
+ BAIL_IF_MACRO(!FileTimeToSystemTime(ft, &st_utc), errcodeFromWinApi(), -1);
+ tzid = GetTimeZoneInformation(&tzi);
+ BAIL_IF_MACRO(tzid == TIME_ZONE_ID_INVALID, errcodeFromWinApi(), -1);
+ rc = SystemTimeToTzSpecificLocalTime(&tzi, &st_utc, &st_localtz);
+ BAIL_IF_MACRO(!rc, errcodeFromWinApi(), -1);
+
+ /* Convert to a format that mktime() can grok... */
+ tm.tm_sec = st_localtz.wSecond;
+ tm.tm_min = st_localtz.wMinute;
+ tm.tm_hour = st_localtz.wHour;
+ tm.tm_mday = st_localtz.wDay;
+ tm.tm_mon = st_localtz.wMonth - 1;
+ tm.tm_year = st_localtz.wYear - 1900;
+ tm.tm_wday = -1 /*st_localtz.wDayOfWeek*/;
+ tm.tm_yday = -1;
+ tm.tm_isdst = -1;
+
+ /* Convert to a format PhysicsFS can grok... */
+ retval = (PHYSFS_sint64) mktime(&tm);
+ BAIL_IF_MACRO(retval == -1, PHYSFS_ERR_OS_ERROR, -1);
+ return retval;
+} /* FileTimeToPhysfsTime */
+
+int __PHYSFS_platformStat(const char *filename, int *exists, PHYSFS_Stat *stat)
+{
+ WIN32_FILE_ATTRIBUTE_DATA winstat;
+ WCHAR *wstr = NULL;
+ DWORD err = 0;
+ BOOL rc = 0;
+
+ UTF8_TO_UNICODE_STACK_MACRO(wstr, filename);
+ BAIL_IF_MACRO(!wstr, PHYSFS_ERR_OUT_OF_MEMORY, 0);
+ rc = GetFileAttributesExW(wstr, GetFileExInfoStandard, &winstat);
+ err = (!rc) ? GetLastError() : 0;
+ *exists = ((err != ERROR_FILE_NOT_FOUND) && (err != ERROR_PATH_NOT_FOUND));
+ __PHYSFS_smallFree(wstr);
+ BAIL_IF_MACRO(!rc, errcodeFromWinApiError(err), 0);
+
+ stat->modtime = FileTimeToPhysfsTime(&winstat.ftLastWriteTime);
+ stat->accesstime = FileTimeToPhysfsTime(&winstat.ftLastAccessTime);
+ stat->createtime = FileTimeToPhysfsTime(&winstat.ftCreationTime);
+
+ if(winstat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+ stat->filesize = 0;
+ } /* if */
+
+ else if(winstat.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_DEVICE))
+ {
+ /* !!! FIXME: what are reparse points? */
+ stat->filetype = PHYSFS_FILETYPE_OTHER;
+ /* !!! FIXME: don't rely on this */
+ stat->filesize = 0;
+ } /* else if */
+
+ /* !!! FIXME: check for symlinks on Vista. */
+
+ else
+ {
+ stat->filetype = PHYSFS_FILETYPE_REGULAR;
+ stat->filesize = (((PHYSFS_uint64) winstat.nFileSizeHigh) << 32) | winstat.nFileSizeLow;
+ } /* else */
+
+ stat->readonly = ((winstat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
+
+ return 1;
+} /* __PHYSFS_platformStat */
+
+
+/* !!! FIXME: Don't use C runtime for allocators? */
+int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+{
+ return 0; /* just use malloc() and friends. */
+} /* __PHYSFS_platformSetDefaultAllocator */
+
+#endif /* PHYSFS_PLATFORM_WINDOWS */
+
+/* end of windows.c ... */
+
+
diff --git a/misc/libphyslayer/Android.mk b/misc/libphyslayer/Android.mk
new file mode 100644
index 0000000..e94a643
--- /dev/null
+++ b/misc/libphyslayer/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := physlayer
+
+LOCAL_CFLAGS := -O2
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH) $(MISC_DIR)/liblua $(MISC_DIR)/liblua $(JNI_DIR)/SDL/include
+
+LOCAL_SRC_FILES := hwpacksmounter.c \
+ physfslualoader.c \
+ physfsrwops.c \
+
+LOCAL_SHARED_LIBRARIES += SDL lua
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/misc/libphyslayer/CMakeLists.txt b/misc/libphyslayer/CMakeLists.txt
new file mode 100644
index 0000000..978fc15
--- /dev/null
+++ b/misc/libphyslayer/CMakeLists.txt
@@ -0,0 +1,36 @@
+
+find_package(SDL REQUIRED)
+include_directories(${PHYSFS_INCLUDE_DIR})
+include_directories(${SDL_INCLUDE_DIR})
+include_directories(${LUA_INCLUDE_DIR})
+
+## extra functions needed by Hedgewars
+## TODO: maybe it's better to have them in a separate library?
+set(PHYSLAYER_SRCS
+ physfsrwops.c
+ physfslualoader.c
+ hwpacksmounter.c
+)
+
+set(build_type STATIC)
+set(lib_prefix ${CMAKE_STATIC_LIBRARY_PREFIX})
+set(lib_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX})
+
+if(WIN32)
+ set(build_type SHARED)
+ set(lib_prefix ${CMAKE_SHARED_LIBRARY_PREFIX})
+ set(lib_suffix ${CMAKE_SHARED_LIBRARY_SUFFIX})
+endif(WIN32)
+
+#compiles and links actual library
+add_library (physlayer ${build_type} ${PHYSLAYER_SRCS})
+
+if(WIN32)
+ target_link_libraries(physlayer ${SDL_LIBRARY} ${LUA_LIBRARY} ${PHYSFS_LIBRARY})
+ install(TARGETS physlayer RUNTIME DESTINATION ${target_library_install_dir})
+endif()
+
+## added standard variables (FORCE or cmake won't pick 'em)
+set(PHYSLAYER_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/misc/libphyslayer/ CACHE STRING "" FORCE)
+set(PHYSLAYER_LIBRARY ${LIBRARY_OUTPUT_PATH}/${lib_prefix}physlayer${lib_suffix} CACHE STRING "" FORCE)
+
diff --git a/misc/libphyslayer/Xcode/Physlayer.xcodeproj/project.pbxproj b/misc/libphyslayer/Xcode/Physlayer.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..5e8bc38
--- /dev/null
+++ b/misc/libphyslayer/Xcode/Physlayer.xcodeproj/project.pbxproj
@@ -0,0 +1,256 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 617D793D16D933880091D4D6 /* hwpacksmounter.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D793816D933880091D4D6 /* hwpacksmounter.c */; };
+ 617D793E16D933880091D4D6 /* hwpacksmounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D793916D933880091D4D6 /* hwpacksmounter.h */; };
+ 617D793F16D933880091D4D6 /* physfslualoader.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D793A16D933880091D4D6 /* physfslualoader.c */; };
+ 617D794016D933880091D4D6 /* physfsrwops.c in Sources */ = {isa = PBXBuildFile; fileRef = 617D793B16D933880091D4D6 /* physfsrwops.c */; };
+ 617D794116D933880091D4D6 /* physfsrwops.h in Headers */ = {isa = PBXBuildFile; fileRef = 617D793C16D933880091D4D6 /* physfsrwops.h */; };
+ AA747D9F0F9514B9006C5449 /* Physlayer_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Physlayer_Prefix.pch */; };
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 617D793816D933880091D4D6 /* hwpacksmounter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hwpacksmounter.c; path = ../hwpacksmounter.c; sourceTree = SOURCE_ROOT; };
+ 617D793916D933880091D4D6 /* hwpacksmounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hwpacksmounter.h; path = ../hwpacksmounter.h; sourceTree = SOURCE_ROOT; };
+ 617D793A16D933880091D4D6 /* physfslualoader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = physfslualoader.c; path = ../physfslualoader.c; sourceTree = SOURCE_ROOT; };
+ 617D793B16D933880091D4D6 /* physfsrwops.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = physfsrwops.c; path = ../physfsrwops.c; sourceTree = SOURCE_ROOT; };
+ 617D793C16D933880091D4D6 /* physfsrwops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = physfsrwops.h; path = ../physfsrwops.h; sourceTree = SOURCE_ROOT; };
+ AA747D9E0F9514B9006C5449 /* Physlayer_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Physlayer_Prefix.pch; sourceTree = SOURCE_ROOT; };
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ D2AAC07E0554694100DB518D /* libPhyslayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPhyslayer.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D2AAC07C0554694100DB518D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 034768DFFF38A50411DB9C8B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D2AAC07E0554694100DB518D /* libPhyslayer.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 0867D691FE84028FC02AAC07 /* Physlayer */ = {
+ isa = PBXGroup;
+ children = (
+ 08FB77AEFE84172EC02AAC07 /* Sources */,
+ 32C88DFF0371C24200C91783 /* Other Sources */,
+ 0867D69AFE84028FC02AAC07 /* Frameworks */,
+ 034768DFFF38A50411DB9C8B /* Products */,
+ );
+ name = Physlayer;
+ sourceTree = "<group>";
+ };
+ 0867D69AFE84028FC02AAC07 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AACBBE490F95108600F1A2B1 /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 08FB77AEFE84172EC02AAC07 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 617D793816D933880091D4D6 /* hwpacksmounter.c */,
+ 617D793916D933880091D4D6 /* hwpacksmounter.h */,
+ 617D793A16D933880091D4D6 /* physfslualoader.c */,
+ 617D793B16D933880091D4D6 /* physfsrwops.c */,
+ 617D793C16D933880091D4D6 /* physfsrwops.h */,
+ );
+ name = Sources;
+ sourceTree = "<group>";
+ };
+ 32C88DFF0371C24200C91783 /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ AA747D9E0F9514B9006C5449 /* Physlayer_Prefix.pch */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ D2AAC07A0554694100DB518D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AA747D9F0F9514B9006C5449 /* Physlayer_Prefix.pch in Headers */,
+ 617D793E16D933880091D4D6 /* hwpacksmounter.h in Headers */,
+ 617D794116D933880091D4D6 /* physfsrwops.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ D2AAC07D0554694100DB518D /* Physlayer */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Physlayer" */;
+ buildPhases = (
+ D2AAC07A0554694100DB518D /* Headers */,
+ D2AAC07B0554694100DB518D /* Sources */,
+ D2AAC07C0554694100DB518D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Physlayer;
+ productName = Physlayer;
+ productReference = D2AAC07E0554694100DB518D /* libPhyslayer.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 0867D690FE84028FC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physlayer" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 0867D691FE84028FC02AAC07 /* Physlayer */;
+ productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D2AAC07D0554694100DB518D /* Physlayer */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D2AAC07B0554694100DB518D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 617D793D16D933880091D4D6 /* hwpacksmounter.c in Sources */,
+ 617D793F16D933880091D4D6 /* physfslualoader.c in Sources */,
+ 617D794016D933880091D4D6 /* physfsrwops.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB921F08733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ COPY_PHASE_STRIP = NO;
+ DSTROOT = /tmp/Physlayer.dst;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Physlayer_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Physlayer;
+ };
+ name = Debug;
+ };
+ 1DEB922008733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ DSTROOT = /tmp/Physlayer.dst;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Physlayer_Prefix.pch;
+ INSTALL_PATH = /usr/local/lib;
+ PRODUCT_NAME = Physlayer;
+ };
+ name = Release;
+ };
+ 1DEB922308733DC00010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../libphysfs\"",
+ "\"$(SRCROOT)/../../liblua\"",
+ "\"$(SRCROOT)/../../../../Library/SDL/include\"",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 1DEB922408733DC00010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../libphysfs\"",
+ "\"$(SRCROOT)/../../liblua\"",
+ "\"$(SRCROOT)/../../../../Library/SDL/include\"",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PREBINDING = NO;
+ SDKROOT = iphoneos;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "Physlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB921F08733DC00010E9CD /* Debug */,
+ 1DEB922008733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Physlayer" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB922308733DC00010E9CD /* Debug */,
+ 1DEB922408733DC00010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch b/misc/libphyslayer/Xcode/Physlayer_Prefix.pch
similarity index 100%
copy from misc/libfreetype/Xcode-iOS/Freetype_Prefix.pch
copy to misc/libphyslayer/Xcode/Physlayer_Prefix.pch
diff --git a/misc/libphyslayer/hwpacksmounter.c b/misc/libphyslayer/hwpacksmounter.c
new file mode 100644
index 0000000..cf9b75c
--- /dev/null
+++ b/misc/libphyslayer/hwpacksmounter.c
@@ -0,0 +1,56 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "hwpacksmounter.h"
+
+PHYSFS_DECL void hedgewarsMountPackages()
+{
+ char ** filesList = PHYSFS_enumerateFiles("/");
+ char **i;
+
+ for (i = filesList; *i != NULL; i++)
+ {
+ char * fileName = *i;
+ int fileNameLength = strlen(fileName);
+ if (fileNameLength > 4)
+ if (strcmp(fileName + fileNameLength - 4, ".hwp") == 0)
+ {
+ const char * dir = PHYSFS_getRealDir(fileName);
+ if(dir)
+ {
+ char * fullPath = (char *)malloc(strlen(dir) + fileNameLength + 2);
+ strcpy(fullPath, dir);
+ strcat(fullPath, "/");
+ strcat(fullPath, fileName);
+
+ PHYSFS_mount(fullPath, NULL, 0);
+
+ free(fullPath);
+ }
+ }
+ }
+
+ PHYSFS_freeList(filesList);
+}
+
+PHYSFS_DECL void hedgewarsMountPackage(char * fileName)
+{
+ int fileNameLength = strlen(fileName);
+ if (fileNameLength > 4)
+ if (strcmp(fileName + fileNameLength - 4, ".hwp") == 0)
+ {
+ const char * dir = PHYSFS_getRealDir(fileName);
+ if(dir)
+ {
+ char * fullPath = (char *)malloc(strlen(dir) + fileNameLength + 2);
+ strcpy(fullPath, dir);
+ strcat(fullPath, "/");
+ strcat(fullPath, fileName);
+
+ PHYSFS_mount(fullPath, NULL, 0);
+
+ free(fullPath);
+ }
+ }
+}
diff --git a/misc/libphyslayer/hwpacksmounter.h b/misc/libphyslayer/hwpacksmounter.h
new file mode 100644
index 0000000..9d7180d
--- /dev/null
+++ b/misc/libphyslayer/hwpacksmounter.h
@@ -0,0 +1,17 @@
+#ifndef HEDGEWARS_PACKAGES_MOUNTER_H
+#define HEDGEWARS_PACKAGES_MOUNTER_H
+
+#include "physfs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PHYSFS_DECL void hedgewarsMountPackages();
+PHYSFS_DECL void hedgewarsMountPackage(char * fileName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/misc/libphyslayer/physfslualoader.c b/misc/libphyslayer/physfslualoader.c
new file mode 100644
index 0000000..eda92da
--- /dev/null
+++ b/misc/libphyslayer/physfslualoader.c
@@ -0,0 +1,30 @@
+#include "lua.h"
+#include "physfs.h"
+
+#define BUFSIZE 1024
+
+void *physfsReaderBuffer;
+
+PHYSFS_DECL const char * physfsReader(lua_State *L, PHYSFS_File *f, size_t *size)
+{
+
+ if(PHYSFS_eof(f))
+ {
+ return NULL;
+ }
+ else
+ {
+ *size = PHYSFS_readBytes(f, physfsReaderBuffer, BUFSIZE);
+
+ if(*size == 0)
+ return NULL;
+ else
+ return physfsReaderBuffer;
+ }
+}
+
+PHYSFS_DECL void physfsReaderSetBuffer(void *buffer)
+{
+ physfsReaderBuffer = buffer;
+}
+
diff --git a/misc/libphyslayer/physfsrwops.c b/misc/libphyslayer/physfsrwops.c
new file mode 100644
index 0000000..aff5f9b
--- /dev/null
+++ b/misc/libphyslayer/physfsrwops.c
@@ -0,0 +1,219 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes. This code has
+ * NO WARRANTY.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
+ * Please see LICENSE.txt in the root of the source tree.
+ *
+ * SDL 1.2 falls under the LGPL license. SDL 1.3+ is zlib, like PhysicsFS.
+ * You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus at icculus.org).
+ */
+
+#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
+#include "physfsrwops.h"
+
+/* SDL's RWOPS interface changed a little in SDL 1.3... */
+#if defined(SDL_VERSION_ATLEAST)
+#if SDL_VERSION_ATLEAST(1, 3, 0)
+#define TARGET_SDL13 1
+#endif
+#endif
+
+#if TARGET_SDL13
+static long SDLCALL physfsrwops_seek(struct SDL_RWops *rw, long offset, int whence)
+#else
+static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
+#endif
+{
+ PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
+ PHYSFS_sint64 pos = 0;
+
+ if (whence == SEEK_SET)
+ pos = (PHYSFS_sint64) offset;
+
+ else if (whence == SEEK_CUR)
+ {
+ const PHYSFS_sint64 current = PHYSFS_tell(handle);
+ if (current == -1)
+ {
+ SDL_SetError("Can't find position in file: %s",
+ PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ if (offset == 0) /* this is a "tell" call. We're done. */
+ {
+ #if TARGET_SDL13
+ return (long) current;
+ #else
+ return (int) current;
+ #endif
+ } /* if */
+
+ pos = current + ((PHYSFS_sint64) offset);
+ } /* else if */
+
+ else if (whence == SEEK_END)
+ {
+ const PHYSFS_sint64 len = PHYSFS_fileLength(handle);
+ if (len == -1)
+ {
+ SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ pos = len + ((PHYSFS_sint64) offset);
+ } /* else if */
+
+ else
+ {
+ SDL_SetError("Invalid 'whence' parameter.");
+ return -1;
+ } /* else */
+
+ if ( pos < 0 )
+ {
+ SDL_SetError("Attempt to seek past start of file.");
+ return -1;
+ } /* if */
+
+ if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ #if TARGET_SDL13
+ return (long) pos;
+ #else
+ return (int) pos;
+ #endif
+} /* physfsrwops_seek */
+
+
+#if TARGET_SDL13
+static size_t SDLCALL physfsrwops_read(struct SDL_RWops *rw, void *ptr,
+ size_t size, size_t maxnum)
+#else
+static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
+#endif
+{
+ PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
+ const PHYSFS_uint64 readlen = (PHYSFS_uint64) (maxnum * size);
+ const PHYSFS_sint64 rc = PHYSFS_readBytes(handle, ptr, readlen);
+ if (rc != ((PHYSFS_sint64) readlen))
+ {
+ if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ } /* if */
+
+ #if TARGET_SDL13
+ return (size_t) rc;
+ #else
+ return (int) rc;
+ #endif
+} /* physfsrwops_read */
+
+
+#if TARGET_SDL13
+static size_t SDLCALL physfsrwops_write(struct SDL_RWops *rw, const void *ptr,
+ size_t size, size_t num)
+#else
+static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
+#endif
+{
+ PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
+ const PHYSFS_uint64 writelen = (PHYSFS_uint64) (num * size);
+ const PHYSFS_sint64 rc = PHYSFS_writeBytes(handle, ptr, writelen);
+ if (rc != ((PHYSFS_sint64) writelen))
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+
+ #if TARGET_SDL13
+ return (size_t) rc;
+ #else
+ return (int) rc;
+ #endif
+} /* physfsrwops_write */
+
+
+static int physfsrwops_close(SDL_RWops *rw)
+{
+ PHYSFS_File *handle = (PHYSFS_File *) rw->hidden.unknown.data1;
+ if (!PHYSFS_close(handle))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ SDL_FreeRW(rw);
+ return 0;
+} /* physfsrwops_close */
+
+
+static SDL_RWops *create_rwops(PHYSFS_File *handle)
+{
+ SDL_RWops *retval = NULL;
+
+ if (handle == NULL)
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ else
+ {
+ retval = SDL_AllocRW();
+ if (retval != NULL)
+ {
+ retval->seek = physfsrwops_seek;
+ retval->read = physfsrwops_read;
+ retval->write = physfsrwops_write;
+ retval->close = physfsrwops_close;
+ retval->hidden.unknown.data1 = handle;
+ } /* if */
+ } /* else */
+
+ return retval;
+} /* create_rwops */
+
+
+SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle)
+{
+ SDL_RWops *retval = NULL;
+ if (handle == NULL)
+ SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
+ else
+ retval = create_rwops(handle);
+
+ return retval;
+} /* PHYSFSRWOPS_makeRWops */
+
+
+SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
+{
+ return create_rwops(PHYSFS_openRead(fname));
+} /* PHYSFSRWOPS_openRead */
+
+
+SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
+{
+ return create_rwops(PHYSFS_openWrite(fname));
+} /* PHYSFSRWOPS_openWrite */
+
+
+SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
+{
+ return create_rwops(PHYSFS_openAppend(fname));
+} /* PHYSFSRWOPS_openAppend */
+
+
+/* end of physfsrwops.c ... */
+
diff --git a/misc/libphyslayer/physfsrwops.h b/misc/libphyslayer/physfsrwops.h
new file mode 100644
index 0000000..e44ec83
--- /dev/null
+++ b/misc/libphyslayer/physfsrwops.h
@@ -0,0 +1,88 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes. This code has
+ * NO WARRANTY.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
+ * Please see LICENSE.txt in the root of the source tree.
+ *
+ * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus at icculus.org).
+ */
+
+#ifndef _INCLUDE_PHYSFSRWOPS_H_
+#define _INCLUDE_PHYSFSRWOPS_H_
+
+#include "physfs.h"
+#include "SDL.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Open a platform-independent filename for reading, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
+
+/**
+ * Open a platform-independent filename for writing, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
+
+/**
+ * Open a platform-independent filename for appending, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
+
+/**
+ * Make a SDL_RWops from an existing PhysicsFS file handle. You should
+ * dispose of any references to the handle after successful creation of
+ * the RWops. The actual PhysicsFS handle will be destroyed when the
+ * RWops is closed.
+ *
+ * @param handle a valid PhysicsFS file handle.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+PHYSFS_DECL SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_File *handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* include-once blocker */
+
+/* end of physfsrwops.h ... */
+
diff --git a/misc/libtremor/tremor/Version_script.in b/misc/libtremor/tremor/Version_script.in
new file mode 100644
index 0000000..2eb1d87
--- /dev/null
+++ b/misc/libtremor/tremor/Version_script.in
@@ -0,0 +1,49 @@
+#
+# Export file for libvorbisidec
+#
+# Only the symbols listed in the global section will be callable from
+# applications linking to libvorbisidec.
+#
+
+ at PACKAGE@.so.1
+{
+ global:
+ ov_clear;
+ ov_open;
+ ov_open_callbacks;
+ ov_test;
+ ov_test_callbacks;
+ ov_test_open;
+ ov_bitrate;
+ ov_bitrate_instant;
+ ov_streams;
+ ov_seekable;
+ ov_serialnumber;
+ ov_raw_total;
+ ov_pcm_total;
+ ov_time_total;
+ ov_raw_seek;
+ ov_pcm_seek;
+ ov_pcm_seek_page;
+ ov_time_seek;
+ ov_time_seek_page;
+ ov_raw_tell;
+ ov_pcm_tell;
+ ov_time_tell;
+ ov_info;
+ ov_comment;
+ ov_read;
+
+ vorbis_info_init;
+ vorbis_info_clear;
+ vorbis_info_blocksize;
+ vorbis_comment_init;
+ vorbis_comment_add;
+ vorbis_comment_add_tag;
+ vorbis_comment_query;
+ vorbis_comment_query_count;
+ vorbis_comment_clear;
+
+ local:
+ *;
+};
diff --git a/misc/libtremor/tremor/backends.h b/misc/libtremor/tremor/backends.h
new file mode 100644
index 0000000..269d9b8
--- /dev/null
+++ b/misc/libtremor/tremor/backends.h
@@ -0,0 +1,130 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: backend and mapping structures
+
+ ********************************************************************/
+
+/* this is exposed up here because we need it for static modes.
+ Lookups for each backend aren't exposed because there's no reason
+ to do so */
+
+#ifndef _vorbis_backend_h_
+#define _vorbis_backend_h_
+
+#include "codec_internal.h"
+
+/* this would all be simpler/shorter with templates, but.... */
+/* Transform backend generic *************************************/
+
+/* only mdct right now. Flesh it out more if we ever transcend mdct
+ in the transform domain */
+
+/* Floor backend generic *****************************************/
+typedef struct{
+ vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_floor *);
+ void (*free_info) (vorbis_info_floor *);
+ void (*free_look) (vorbis_look_floor *);
+ void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *);
+ int (*inverse2) (struct vorbis_block *,vorbis_look_floor *,
+ void *buffer,ogg_int32_t *);
+} vorbis_func_floor;
+
+typedef struct{
+ int order;
+ long rate;
+ long barkmap;
+
+ int ampbits;
+ int ampdB;
+
+ int numbooks; /* <= 16 */
+ int books[16];
+
+} vorbis_info_floor0;
+
+#define VIF_POSIT 63
+#define VIF_CLASS 16
+#define VIF_PARTS 31
+typedef struct{
+ int partitions; /* 0 to 31 */
+ int partitionclass[VIF_PARTS]; /* 0 to 15 */
+
+ int class_dim[VIF_CLASS]; /* 1 to 8 */
+ int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */
+ int class_book[VIF_CLASS]; /* subs ^ dim entries */
+ int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */
+
+
+ int mult; /* 1 2 3 or 4 */
+ int postlist[VIF_POSIT+2]; /* first two implicit */
+
+} vorbis_info_floor1;
+
+/* Residue backend generic *****************************************/
+typedef struct{
+ vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_residue *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_residue *);
+ void (*free_info) (vorbis_info_residue *);
+ void (*free_look) (vorbis_look_residue *);
+ int (*inverse) (struct vorbis_block *,vorbis_look_residue *,
+ ogg_int32_t **,int *,int);
+} vorbis_func_residue;
+
+typedef struct vorbis_info_residue0{
+/* block-partitioned VQ coded straight residue */
+ long begin;
+ long end;
+
+ /* first stage (lossless partitioning) */
+ int grouping; /* group n vectors per partition */
+ int partitions; /* possible codebooks for a partition */
+ int groupbook; /* huffbook for partitioning */
+ int secondstages[64]; /* expanded out to pointers in lookup */
+ int booklist[256]; /* list of second stage books */
+} vorbis_info_residue0;
+
+/* Mapping backend generic *****************************************/
+typedef struct{
+ vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *);
+ vorbis_look_mapping *(*look) (vorbis_dsp_state *,vorbis_info_mode *,
+ vorbis_info_mapping *);
+ void (*free_info) (vorbis_info_mapping *);
+ void (*free_look) (vorbis_look_mapping *);
+ int (*inverse) (struct vorbis_block *vb,vorbis_look_mapping *);
+} vorbis_func_mapping;
+
+typedef struct vorbis_info_mapping0{
+ int submaps; /* <= 16 */
+ int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */
+
+ int floorsubmap[16]; /* [mux] submap to floors */
+ int residuesubmap[16]; /* [mux] submap to residue */
+
+ int psy[2]; /* by blocktype; impulse/padding for short,
+ transition/normal for long */
+
+ int coupling_steps;
+ int coupling_mag[256];
+ int coupling_ang[256];
+} vorbis_info_mapping0;
+
+#endif
+
+
+
+
+
diff --git a/misc/libtremor/tremor/block.c b/misc/libtremor/tremor/block.c
new file mode 100644
index 0000000..361de9f
--- /dev/null
+++ b/misc/libtremor/tremor/block.c
@@ -0,0 +1,453 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: PCM data vector blocking, windowing and dis/reassembly
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ogg.h"
+#include "ivorbiscodec.h"
+#include "codec_internal.h"
+
+#include "window.h"
+#include "registry.h"
+#include "misc.h"
+
+static int ilog(unsigned int v){
+ int ret=0;
+ if(v)--v;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+/* pcm accumulator examples (not exhaustive):
+
+ <-------------- lW ---------------->
+ <--------------- W ---------------->
+: .....|..... _______________ |
+: .''' | '''_--- | |\ |
+:.....''' |_____--- '''......| | \_______|
+:.................|__________________|_______|__|______|
+ |<------ Sl ------>| > Sr < |endW
+ |beginSl |endSl | |endSr
+ |beginW |endlW |beginSr
+
+
+ |< lW >|
+ <--------------- W ---------------->
+ | | .. ______________ |
+ | | ' `/ | ---_ |
+ |___.'___/`. | ---_____|
+ |_______|__|_______|_________________|
+ | >|Sl|< |<------ Sr ----->|endW
+ | | |endSl |beginSr |endSr
+ |beginW | |endlW
+ mult[0] |beginSl mult[n]
+
+ <-------------- lW ----------------->
+ |<--W-->|
+: .............. ___ | |
+: .''' |`/ \ | |
+:.....''' |/`....\|...|
+:.........................|___|___|___|
+ |Sl |Sr |endW
+ | | |endSr
+ | |beginSr
+ | |endSl
+ |beginSl
+ |beginW
+*/
+
+/* block abstraction setup *********************************************/
+
+#ifndef WORD_ALIGN
+#define WORD_ALIGN 8
+#endif
+
+int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
+ memset(vb,0,sizeof(*vb));
+ vb->vd=v;
+ vb->localalloc=0;
+ vb->localstore=NULL;
+
+ return(0);
+}
+
+void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
+ bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
+ if(bytes+vb->localtop>vb->localalloc){
+ /* can't just _ogg_realloc... there are outstanding pointers */
+ if(vb->localstore){
+ struct alloc_chain *link=(struct alloc_chain *)_ogg_malloc(sizeof(*link));
+ vb->totaluse+=vb->localtop;
+ link->next=vb->reap;
+ link->ptr=vb->localstore;
+ vb->reap=link;
+ }
+ /* highly conservative */
+ vb->localalloc=bytes;
+ vb->localstore=_ogg_malloc(vb->localalloc);
+ vb->localtop=0;
+ }
+ {
+ void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
+ vb->localtop+=bytes;
+ return ret;
+ }
+}
+
+/* reap the chain, pull the ripcord */
+void _vorbis_block_ripcord(vorbis_block *vb){
+ /* reap the chain */
+ struct alloc_chain *reap=vb->reap;
+ while(reap){
+ struct alloc_chain *next=reap->next;
+ _ogg_free(reap->ptr);
+ memset(reap,0,sizeof(*reap));
+ _ogg_free(reap);
+ reap=next;
+ }
+ /* consolidate storage */
+ if(vb->totaluse){
+ vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
+ vb->localalloc+=vb->totaluse;
+ vb->totaluse=0;
+ }
+
+ /* pull the ripcord */
+ vb->localtop=0;
+ vb->reap=NULL;
+}
+
+int vorbis_block_clear(vorbis_block *vb){
+ _vorbis_block_ripcord(vb);
+ if(vb->localstore)_ogg_free(vb->localstore);
+
+ memset(vb,0,sizeof(*vb));
+ return(0);
+}
+
+static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
+ int i;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ private_state *b=NULL;
+
+ memset(v,0,sizeof(*v));
+ b=(private_state *)(v->backend_state=_ogg_calloc(1,sizeof(*b)));
+
+ v->vi=vi;
+ b->modebits=ilog(ci->modes);
+
+ /* Vorbis I uses only window type 0 */
+ b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
+ b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
+
+ /* finish the codebooks */
+ if(!ci->fullbooks){
+ ci->fullbooks=(codebook *)_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
+ for(i=0;i<ci->books;i++){
+ vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
+ /* decode codebooks are now standalone after init */
+ vorbis_staticbook_destroy(ci->book_param[i]);
+ ci->book_param[i]=NULL;
+ }
+ }
+
+ v->pcm_storage=ci->blocksizes[1];
+ v->pcm=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcm));
+ v->pcmret=(ogg_int32_t **)_ogg_malloc(vi->channels*sizeof(*v->pcmret));
+ for(i=0;i<vi->channels;i++)
+ v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
+
+ /* all 1 (large block) or 0 (small block) */
+ /* explicitly set for the sake of clarity */
+ v->lW=0; /* previous window size */
+ v->W=0; /* current window size */
+
+ /* initialize all the mapping/backend lookups */
+ b->mode=(vorbis_look_mapping **)_ogg_calloc(ci->modes,sizeof(*b->mode));
+ for(i=0;i<ci->modes;i++){
+ int mapnum=ci->mode_param[i]->mapping;
+ int maptype=ci->map_type[mapnum];
+ b->mode[i]=_mapping_P[maptype]->look(v,ci->mode_param[i],
+ ci->map_param[mapnum]);
+ }
+ return(0);
+}
+
+int vorbis_synthesis_restart(vorbis_dsp_state *v){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci;
+
+ if(!v->backend_state)return -1;
+ if(!vi)return -1;
+ ci=vi->codec_setup;
+ if(!ci)return -1;
+
+ v->centerW=ci->blocksizes[1]/2;
+ v->pcm_current=v->centerW;
+
+ v->pcm_returned=-1;
+ v->granulepos=-1;
+ v->sequence=-1;
+ ((private_state *)(v->backend_state))->sample_count=-1;
+
+ return(0);
+}
+
+int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
+ _vds_init(v,vi);
+ vorbis_synthesis_restart(v);
+
+ return(0);
+}
+
+void vorbis_dsp_clear(vorbis_dsp_state *v){
+ int i;
+ if(v){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
+ private_state *b=(private_state *)v->backend_state;
+
+ if(v->pcm){
+ for(i=0;i<vi->channels;i++)
+ if(v->pcm[i])_ogg_free(v->pcm[i]);
+ _ogg_free(v->pcm);
+ if(v->pcmret)_ogg_free(v->pcmret);
+ }
+
+ /* free mode lookups; these are actually vorbis_look_mapping structs */
+ if(ci){
+ for(i=0;i<ci->modes;i++){
+ int mapnum=ci->mode_param[i]->mapping;
+ int maptype=ci->map_type[mapnum];
+ if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
+ }
+ }
+
+ if(b){
+ if(b->mode)_ogg_free(b->mode);
+ _ogg_free(b);
+ }
+
+ memset(v,0,sizeof(*v));
+ }
+}
+
+/* Unlike in analysis, the window is only partially applied for each
+ block. The time domain envelope is not yet handled at the point of
+ calling (as it relies on the previous block). */
+
+int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
+ vorbis_info *vi=v->vi;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ private_state *b=v->backend_state;
+ int i,j;
+
+ if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
+
+ v->lW=v->W;
+ v->W=vb->W;
+ v->nW=-1;
+
+ if((v->sequence==-1)||
+ (v->sequence+1 != vb->sequence)){
+ v->granulepos=-1; /* out of sequence; lose count */
+ b->sample_count=-1;
+ }
+
+ v->sequence=vb->sequence;
+
+ if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
+ was called on block */
+ int n=ci->blocksizes[v->W]/2;
+ int n0=ci->blocksizes[0]/2;
+ int n1=ci->blocksizes[1]/2;
+
+ int thisCenter;
+ int prevCenter;
+
+ if(v->centerW){
+ thisCenter=n1;
+ prevCenter=0;
+ }else{
+ thisCenter=0;
+ prevCenter=n1;
+ }
+
+ /* v->pcm is now used like a two-stage double buffer. We don't want
+ to have to constantly shift *or* adjust memory usage. Don't
+ accept a new block until the old is shifted out */
+
+ /* overlap/add PCM */
+
+ for(j=0;j<vi->channels;j++){
+ /* the overlap/add section */
+ if(v->lW){
+ if(v->W){
+ /* large/large */
+ ogg_int32_t *pcm=v->pcm[j]+prevCenter;
+ ogg_int32_t *p=vb->pcm[j];
+ for(i=0;i<n1;i++)
+ pcm[i]+=p[i];
+ }else{
+ /* large/small */
+ ogg_int32_t *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
+ ogg_int32_t *p=vb->pcm[j];
+ for(i=0;i<n0;i++)
+ pcm[i]+=p[i];
+ }
+ }else{
+ if(v->W){
+ /* small/large */
+ ogg_int32_t *pcm=v->pcm[j]+prevCenter;
+ ogg_int32_t *p=vb->pcm[j]+n1/2-n0/2;
+ for(i=0;i<n0;i++)
+ pcm[i]+=p[i];
+ for(;i<n1/2+n0/2;i++)
+ pcm[i]=p[i];
+ }else{
+ /* small/small */
+ ogg_int32_t *pcm=v->pcm[j]+prevCenter;
+ ogg_int32_t *p=vb->pcm[j];
+ for(i=0;i<n0;i++)
+ pcm[i]+=p[i];
+ }
+ }
+
+ /* the copy section */
+ {
+ ogg_int32_t *pcm=v->pcm[j]+thisCenter;
+ ogg_int32_t *p=vb->pcm[j]+n;
+ for(i=0;i<n;i++)
+ pcm[i]=p[i];
+ }
+ }
+
+ if(v->centerW)
+ v->centerW=0;
+ else
+ v->centerW=n1;
+
+ /* deal with initial packet state; we do this using the explicit
+ pcm_returned==-1 flag otherwise we're sensitive to first block
+ being short or long */
+
+ if(v->pcm_returned==-1){
+ v->pcm_returned=thisCenter;
+ v->pcm_current=thisCenter;
+ }else{
+ v->pcm_returned=prevCenter;
+ v->pcm_current=prevCenter+
+ ci->blocksizes[v->lW]/4+
+ ci->blocksizes[v->W]/4;
+ }
+
+ }
+
+ /* track the frame number... This is for convenience, but also
+ making sure our last packet doesn't end with added padding. If
+ the last packet is partial, the number of samples we'll have to
+ return will be past the vb->granulepos.
+
+ This is not foolproof! It will be confused if we begin
+ decoding at the last page after a seek or hole. In that case,
+ we don't have a starting point to judge where the last frame
+ is. For this reason, vorbisfile will always try to make sure
+ it reads the last two marked pages in proper sequence */
+
+ if(b->sample_count==-1){
+ b->sample_count=0;
+ }else{
+ b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
+ }
+
+ if(v->granulepos==-1){
+ if(vb->granulepos!=-1){ /* only set if we have a position to set to */
+
+ v->granulepos=vb->granulepos;
+
+ /* is this a short page? */
+ if(b->sample_count>v->granulepos){
+ /* corner case; if this is both the first and last audio page,
+ then spec says the end is cut, not beginning */
+ if(vb->eofflag){
+ /* trim the end */
+ /* no preceeding granulepos; assume we started at zero (we'd
+ have to in a short single-page stream) */
+ /* granulepos could be -1 due to a seek, but that would result
+ in a long coun`t, not short count */
+
+ v->pcm_current-=(b->sample_count-v->granulepos);
+ }else{
+ /* trim the beginning */
+ v->pcm_returned+=(b->sample_count-v->granulepos);
+ if(v->pcm_returned>v->pcm_current)
+ v->pcm_returned=v->pcm_current;
+ }
+
+ }
+
+ }
+ }else{
+ v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
+ if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
+
+ if(v->granulepos>vb->granulepos){
+ long extra=v->granulepos-vb->granulepos;
+
+ if(extra)
+ if(vb->eofflag){
+ /* partial last frame. Strip the extra samples off */
+ v->pcm_current-=extra;
+ } /* else {Shouldn't happen *unless* the bitstream is out of
+ spec. Either way, believe the bitstream } */
+ } /* else {Shouldn't happen *unless* the bitstream is out of
+ spec. Either way, believe the bitstream } */
+ v->granulepos=vb->granulepos;
+ }
+ }
+
+ /* Update, cleanup */
+
+ if(vb->eofflag)v->eofflag=1;
+ return(0);
+}
+
+/* pcm==NULL indicates we just want the pending samples, no more */
+int vorbis_synthesis_pcmout(vorbis_dsp_state *v,ogg_int32_t ***pcm){
+ vorbis_info *vi=v->vi;
+ if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
+ if(pcm){
+ int i;
+ for(i=0;i<vi->channels;i++)
+ v->pcmret[i]=v->pcm[i]+v->pcm_returned;
+ *pcm=v->pcmret;
+ }
+ return(v->pcm_current-v->pcm_returned);
+ }
+ return(0);
+}
+
+int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
+ if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL);
+ v->pcm_returned+=bytes;
+ return(0);
+}
+
diff --git a/misc/libtremor/tremor/block.h b/misc/libtremor/tremor/block.h
new file mode 100644
index 0000000..62b1bff
--- /dev/null
+++ b/misc/libtremor/tremor/block.h
@@ -0,0 +1,26 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2008 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: shared block functions
+
+ ********************************************************************/
+
+#ifndef _V_BLOCK_
+#define _V_BLOCK_
+
+#include "ivorbiscodec.h"
+
+extern void _vorbis_block_ripcord(vorbis_block *vb);
+extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
+
+#endif
diff --git a/misc/libtremor/tremor/registry.c b/misc/libtremor/tremor/registry.c
new file mode 100644
index 0000000..c0b5fec
--- /dev/null
+++ b/misc/libtremor/tremor/registry.c
@@ -0,0 +1,50 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: registry for floor, res backends and channel mappings
+
+ ********************************************************************/
+
+#include "ivorbiscodec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "misc.h"
+
+
+/* seems like major overkill now; the backend numbers will grow into
+ the infrastructure soon enough */
+
+extern vorbis_func_floor floor0_exportbundle;
+extern vorbis_func_floor floor1_exportbundle;
+extern vorbis_func_residue residue0_exportbundle;
+extern vorbis_func_residue residue1_exportbundle;
+extern vorbis_func_residue residue2_exportbundle;
+extern vorbis_func_mapping mapping0_exportbundle;
+
+vorbis_func_floor *_floor_P[]={
+ &floor0_exportbundle,
+ &floor1_exportbundle,
+};
+
+vorbis_func_residue *_residue_P[]={
+ &residue0_exportbundle,
+ &residue1_exportbundle,
+ &residue2_exportbundle,
+};
+
+vorbis_func_mapping *_mapping_P[]={
+ &mapping0_exportbundle,
+};
+
+
+
diff --git a/misc/libtremor/tremor/registry.h b/misc/libtremor/tremor/registry.h
new file mode 100644
index 0000000..2bc8068
--- /dev/null
+++ b/misc/libtremor/tremor/registry.h
@@ -0,0 +1,40 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: registry for time, floor, res backends and channel mappings
+
+ ********************************************************************/
+
+#ifndef _V_REG_H_
+#define _V_REG_H_
+
+#define VI_TRANSFORMB 1
+#define VI_WINDOWB 1
+#define VI_TIMEB 1
+#define VI_FLOORB 2
+#define VI_RESB 3
+#define VI_MAPB 1
+
+#include "backends.h"
+
+#if defined(_WIN32) && defined(VORBISDLL_IMPORT)
+# define EXTERN __declspec(dllimport) extern
+#else
+# define EXTERN extern
+#endif
+
+EXTERN vorbis_func_floor *_floor_P[];
+EXTERN vorbis_func_residue *_residue_P[];
+EXTERN vorbis_func_mapping *_mapping_P[];
+
+#endif
diff --git a/misc/libtremor/tremor/sharedbook.c b/misc/libtremor/tremor/sharedbook.c
new file mode 100644
index 0000000..8e07492
--- /dev/null
+++ b/misc/libtremor/tremor/sharedbook.c
@@ -0,0 +1,439 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: basic shared codebook operations
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "ogg.h"
+#include "misc.h"
+#include "ivorbiscodec.h"
+#include "codebook.h"
+
+/**** pack/unpack helpers ******************************************/
+int _ilog(unsigned int v){
+ int ret=0;
+ while(v){
+ ret++;
+ v>>=1;
+ }
+ return(ret);
+}
+
+/* 32 bit float (not IEEE; nonnormalized mantissa +
+ biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
+ Why not IEEE? It's just not that important here. */
+
+#define VQ_FEXP 10
+#define VQ_FMAN 21
+#define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
+
+static ogg_int32_t _float32_unpack(long val,int *point){
+ long mant=val&0x1fffff;
+ int sign=val&0x80000000;
+ long exp =(val&0x7fe00000L)>>VQ_FMAN;
+
+ exp-=(VQ_FMAN-1)+VQ_FEXP_BIAS;
+
+ if(mant){
+ while(!(mant&0x40000000)){
+ mant<<=1;
+ exp-=1;
+ }
+
+ if(sign)mant= -mant;
+ }else{
+ sign=0;
+ exp=-9999;
+ }
+
+ *point=exp;
+ return mant;
+}
+
+/* given a list of word lengths, generate a list of codewords. Works
+ for length ordered or unordered, always assigns the lowest valued
+ codewords first. Extended to handle unused entries (length 0) */
+ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
+ long i,j,count=0;
+ ogg_uint32_t marker[33];
+ ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
+ memset(marker,0,sizeof(marker));
+
+ for(i=0;i<n;i++){
+ long length=l[i];
+ if(length>0){
+ ogg_uint32_t entry=marker[length];
+
+ /* when we claim a node for an entry, we also claim the nodes
+ below it (pruning off the imagined tree that may have dangled
+ from it) as well as blocking the use of any nodes directly
+ above for leaves */
+
+ /* update ourself */
+ if(length<32 && (entry>>length)){
+ /* error condition; the lengths must specify an overpopulated tree */
+ _ogg_free(r);
+ return(NULL);
+ }
+ r[count++]=entry;
+
+ /* Look to see if the next shorter marker points to the node
+ above. if so, update it and repeat. */
+ {
+ for(j=length;j>0;j--){
+
+ if(marker[j]&1){
+ /* have to jump branches */
+ if(j==1)
+ marker[1]++;
+ else
+ marker[j]=marker[j-1]<<1;
+ break; /* invariant says next upper marker would already
+ have been moved if it was on the same path */
+ }
+ marker[j]++;
+ }
+ }
+
+ /* prune the tree; the implicit invariant says all the longer
+ markers were dangling from our just-taken node. Dangle them
+ from our *new* node. */
+ for(j=length+1;j<33;j++)
+ if((marker[j]>>1) == entry){
+ entry=marker[j];
+ marker[j]=marker[j-1]<<1;
+ }else
+ break;
+ }else
+ if(sparsecount==0)count++;
+ }
+
+ /* bitreverse the words because our bitwise packer/unpacker is LSb
+ endian */
+ for(i=0,count=0;i<n;i++){
+ ogg_uint32_t temp=0;
+ for(j=0;j<l[i];j++){
+ temp<<=1;
+ temp|=(r[count]>>j)&1;
+ }
+
+ if(sparsecount){
+ if(l[i])
+ r[count++]=temp;
+ }else
+ r[count++]=temp;
+ }
+
+ return(r);
+}
+
+/* there might be a straightforward one-line way to do the below
+ that's portable and totally safe against roundoff, but I haven't
+ thought of it. Therefore, we opt on the side of caution */
+long _book_maptype1_quantvals(const static_codebook *b){
+ /* get us a starting hint, we'll polish it below */
+ int bits=_ilog(b->entries);
+ int vals=b->entries>>((bits-1)*(b->dim-1)/b->dim);
+
+ while(1){
+ long acc=1;
+ long acc1=1;
+ int i;
+ for(i=0;i<b->dim;i++){
+ acc*=vals;
+ acc1*=vals+1;
+ }
+ if(acc<=b->entries && acc1>b->entries){
+ return(vals);
+ }else{
+ if(acc>b->entries){
+ vals--;
+ }else{
+ vals++;
+ }
+ }
+ }
+}
+
+/* different than what _book_unquantize does for mainline:
+ we repack the book in a fixed point format that shares the same
+ binary point. Upon first use, we can shift point if needed */
+
+/* we need to deal with two map types: in map type 1, the values are
+ generated algorithmically (each column of the vector counts through
+ the values in the quant vector). in map type 2, all the values came
+ in in an explicit list. Both value lists must be unpacked */
+
+ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
+ int *maxpoint){
+ long j,k,count=0;
+ if(b->maptype==1 || b->maptype==2){
+ int quantvals;
+ int minpoint,delpoint;
+ ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint);
+ ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint);
+ ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r));
+ int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp));
+
+ *maxpoint=minpoint;
+
+ /* maptype 1 and 2 both use a quantized value vector, but
+ different sizes */
+ switch(b->maptype){
+ case 1:
+ /* most of the time, entries%dimensions == 0, but we need to be
+ well defined. We define that the possible vales at each
+ scalar is values == entries/dim. If entries%dim != 0, we'll
+ have 'too few' values (values*dim<entries), which means that
+ we'll have 'left over' entries; left over entries use zeroed
+ values (and are wasted). So don't generate codebooks like
+ that */
+ quantvals=_book_maptype1_quantvals(b);
+ for(j=0;j<b->entries;j++){
+ if((sparsemap && b->lengthlist[j]) || !sparsemap){
+ ogg_int32_t last=0;
+ int lastpoint=0;
+ int indexdiv=1;
+ for(k=0;k<b->dim;k++){
+ int index= (j/indexdiv)%quantvals;
+ int point=0;
+ int val=VFLOAT_MULTI(delta,delpoint,
+ abs(b->quantlist[index]),&point);
+
+ val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
+ val=VFLOAT_ADD(last,lastpoint,val,point,&point);
+
+ if(b->q_sequencep){
+ last=val;
+ lastpoint=point;
+ }
+
+ if(sparsemap){
+ r[sparsemap[count]*b->dim+k]=val;
+ rp[sparsemap[count]*b->dim+k]=point;
+ }else{
+ r[count*b->dim+k]=val;
+ rp[count*b->dim+k]=point;
+ }
+ if(*maxpoint<point)*maxpoint=point;
+ indexdiv*=quantvals;
+ }
+ count++;
+ }
+
+ }
+ break;
+ case 2:
+ for(j=0;j<b->entries;j++){
+ if((sparsemap && b->lengthlist[j]) || !sparsemap){
+ ogg_int32_t last=0;
+ int lastpoint=0;
+
+ for(k=0;k<b->dim;k++){
+ int point=0;
+ int val=VFLOAT_MULTI(delta,delpoint,
+ abs(b->quantlist[j*b->dim+k]),&point);
+
+ val=VFLOAT_ADD(mindel,minpoint,val,point,&point);
+ val=VFLOAT_ADD(last,lastpoint,val,point,&point);
+
+ if(b->q_sequencep){
+ last=val;
+ lastpoint=point;
+ }
+
+ if(sparsemap){
+ r[sparsemap[count]*b->dim+k]=val;
+ rp[sparsemap[count]*b->dim+k]=point;
+ }else{
+ r[count*b->dim+k]=val;
+ rp[count*b->dim+k]=point;
+ }
+ if(*maxpoint<point)*maxpoint=point;
+ }
+ count++;
+ }
+ }
+ break;
+ }
+
+ for(j=0;j<n*b->dim;j++)
+ if(rp[j]<*maxpoint)
+ r[j]>>=*maxpoint-rp[j];
+
+ _ogg_free(rp);
+ return(r);
+ }
+ return(NULL);
+}
+
+void vorbis_staticbook_clear(static_codebook *b){
+ if(b->quantlist)_ogg_free(b->quantlist);
+ if(b->lengthlist)_ogg_free(b->lengthlist);
+ memset(b,0,sizeof(*b));
+
+}
+
+void vorbis_staticbook_destroy(static_codebook *b){
+ vorbis_staticbook_clear(b);
+ _ogg_free(b);
+}
+
+void vorbis_book_clear(codebook *b){
+ /* static book is not cleared; we're likely called on the lookup and
+ the static codebook belongs to the info struct */
+ if(b->valuelist)_ogg_free(b->valuelist);
+ if(b->codelist)_ogg_free(b->codelist);
+
+ if(b->dec_index)_ogg_free(b->dec_index);
+ if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
+ if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
+
+ memset(b,0,sizeof(*b));
+}
+
+static ogg_uint32_t bitreverse(ogg_uint32_t x){
+ x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
+ x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
+ x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
+ x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
+ return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
+}
+
+static int sort32a(const void *a,const void *b){
+ return (**(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
+ (**(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
+}
+
+/* decode codebook arrangement is more heavily optimized than encode */
+int vorbis_book_init_decode(codebook *c,const static_codebook *s){
+ int i,j,n=0,tabn;
+ int *sortindex;
+ memset(c,0,sizeof(*c));
+
+ /* count actually used entries */
+ for(i=0;i<s->entries;i++)
+ if(s->lengthlist[i]>0)
+ n++;
+
+ c->entries=s->entries;
+ c->used_entries=n;
+ c->dim=s->dim;
+
+ if(n>0){
+ /* two different remappings go on here.
+
+ First, we collapse the likely sparse codebook down only to
+ actually represented values/words. This collapsing needs to be
+ indexed as map-valueless books are used to encode original entry
+ positions as integers.
+
+ Second, we reorder all vectors, including the entry index above,
+ by sorted bitreversed codeword to allow treeless decode. */
+
+ /* perform sort */
+ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
+ ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n);
+
+ if(codes==NULL)goto err_out;
+
+ for(i=0;i<n;i++){
+ codes[i]=bitreverse(codes[i]);
+ codep[i]=codes+i;
+ }
+
+ qsort(codep,n,sizeof(*codep),sort32a);
+
+ sortindex=(int *)alloca(n*sizeof(*sortindex));
+ c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
+ /* the index is a reverse index */
+ for(i=0;i<n;i++){
+ int position=codep[i]-codes;
+ sortindex[position]=i;
+ }
+
+ for(i=0;i<n;i++)
+ c->codelist[sortindex[i]]=codes[i];
+ _ogg_free(codes);
+
+
+
+ c->valuelist=_book_unquantize(s,n,sortindex,&c->binarypoint);
+ c->dec_index=(int *)_ogg_malloc(n*sizeof(*c->dec_index));
+
+ for(n=0,i=0;i<s->entries;i++)
+ if(s->lengthlist[i]>0)
+ c->dec_index[sortindex[n++]]=i;
+
+ c->dec_codelengths=(char *)_ogg_malloc(n*sizeof(*c->dec_codelengths));
+ for(n=0,i=0;i<s->entries;i++)
+ if(s->lengthlist[i]>0)
+ c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
+
+ c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
+ if(c->dec_firsttablen<5)c->dec_firsttablen=5;
+ if(c->dec_firsttablen>8)c->dec_firsttablen=8;
+
+ tabn=1<<c->dec_firsttablen;
+ c->dec_firsttable=(ogg_uint32_t *)_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
+ c->dec_maxlength=0;
+
+ for(i=0;i<n;i++){
+ if(c->dec_maxlength<c->dec_codelengths[i])
+ c->dec_maxlength=c->dec_codelengths[i];
+ if(c->dec_codelengths[i]<=c->dec_firsttablen){
+ ogg_uint32_t orig=bitreverse(c->codelist[i]);
+ for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
+ c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
+ }
+ }
+
+ /* now fill in 'unused' entries in the firsttable with hi/lo search
+ hints for the non-direct-hits */
+ {
+ ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
+ long lo=0,hi=0;
+
+ for(i=0;i<tabn;i++){
+ ogg_uint32_t word=i<<(32-c->dec_firsttablen);
+ if(c->dec_firsttable[bitreverse(word)]==0){
+ while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
+ while( hi<n && word>=(c->codelist[hi]&mask))hi++;
+
+ /* we only actually have 15 bits per hint to play with here.
+ In order to overflow gracefully (nothing breaks, efficiency
+ just drops), encode as the difference from the extremes. */
+ {
+ unsigned long loval=lo;
+ unsigned long hival=n-hi;
+
+ if(loval>0x7fff)loval=0x7fff;
+ if(hival>0x7fff)hival=0x7fff;
+ c->dec_firsttable[bitreverse(word)]=
+ 0x80000000UL | (loval<<15) | hival;
+ }
+ }
+ }
+ }
+ }
+
+ return(0);
+ err_out:
+ vorbis_book_clear(c);
+ return(-1);
+}
+
diff --git a/misc/libtremor/tremor/synthesis.c b/misc/libtremor/tremor/synthesis.c
new file mode 100644
index 0000000..962c730
--- /dev/null
+++ b/misc/libtremor/tremor/synthesis.c
@@ -0,0 +1,113 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: single-block PCM synthesis
+ last mod: $Id: synthesis.c,v 1.4 2003/03/29 03:07:21 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include "ogg.h"
+#include "ivorbiscodec.h"
+#include "codec_internal.h"
+#include "registry.h"
+#include "misc.h"
+#include "block.h"
+
+int vorbis_synthesis(vorbis_block *vb,ogg_packet *op,int decodep){
+ vorbis_dsp_state *vd=vb->vd;
+ private_state *b=(private_state *)vd->backend_state;
+ vorbis_info *vi=vd->vi;
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ oggpack_buffer *opb=&vb->opb;
+ int type,mode,i;
+
+ /* first things first. Make sure decode is ready */
+ _vorbis_block_ripcord(vb);
+ oggpack_readinit(opb,op->packet);
+
+ /* Check the packet type */
+ if(oggpack_read(opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return(OV_ENOTAUDIO);
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(opb,b->modebits);
+ if(mode==-1)return(OV_EBADPACKET);
+
+ vb->mode=mode;
+ vb->W=ci->mode_param[mode]->blockflag;
+ if(vb->W){
+ vb->lW=oggpack_read(opb,1);
+ vb->nW=oggpack_read(opb,1);
+ if(vb->nW==-1) return(OV_EBADPACKET);
+ }else{
+ vb->lW=0;
+ vb->nW=0;
+ }
+
+ /* more setup */
+ vb->granulepos=op->granulepos;
+ vb->sequence=op->packetno-3; /* first block is third packet */
+ vb->eofflag=op->e_o_s;
+
+ if(decodep){
+ /* alloc pcm passback storage */
+ vb->pcmend=ci->blocksizes[vb->W];
+ vb->pcm=(ogg_int32_t **)_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
+ for(i=0;i<vi->channels;i++)
+ vb->pcm[i]=(ogg_int32_t *)_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
+
+ /* unpack_header enforces range checking */
+ type=ci->map_type[ci->mode_param[mode]->mapping];
+
+ return(_mapping_P[type]->inverse(vb,b->mode[mode]));
+ }else{
+ /* no pcm */
+ vb->pcmend=0;
+ vb->pcm=NULL;
+
+ return(0);
+ }
+}
+
+long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
+ codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
+ oggpack_buffer opb;
+ int mode;
+
+ oggpack_readinit(&opb,op->packet);
+
+ /* Check the packet type */
+ if(oggpack_read(&opb,1)!=0){
+ /* Oops. This is not an audio data packet */
+ return(OV_ENOTAUDIO);
+ }
+
+ {
+ int modebits=0;
+ int v=ci->modes;
+ while(v>1){
+ modebits++;
+ v>>=1;
+ }
+
+ /* read our mode and pre/post windowsize */
+ mode=oggpack_read(&opb,modebits);
+ }
+ if(mode==-1)return(OV_EBADPACKET);
+ return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
+}
+
+
diff --git a/misc/libtremor/tremor/vorbisfile.c b/misc/libtremor/tremor/vorbisfile.c
index 7af5b8d..6745b4a 100644
--- a/misc/libtremor/tremor/vorbisfile.c
+++ b/misc/libtremor/tremor/vorbisfile.c
@@ -740,7 +740,7 @@ int ov_clear(OggVorbis_File *vf){
ogg_sync_destroy(vf->oy);
if(vf->datasource && vf->callbacks.close_func)
- (vf->callbacks.close_func)(vf->datasource);
+ (vf->callbacks.close_func)(vf->datasource);
memset(vf,0,sizeof(*vf));
}
#ifdef DEBUG_LEAKS
diff --git a/misc/libtremor/tremor/window.c b/misc/libtremor/tremor/window.c
new file mode 100644
index 0000000..006a1ee
--- /dev/null
+++ b/misc/libtremor/tremor/window.c
@@ -0,0 +1,83 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: window functions
+
+ ********************************************************************/
+
+#include <stdlib.h>
+#include <math.h>
+#include "misc.h"
+#include "window.h"
+#include "window_lookup.h"
+
+const void *_vorbis_window(int type, int left){
+
+ switch(type){
+ case 0:
+
+ switch(left){
+ case 32:
+ return vwin64;
+ case 64:
+ return vwin128;
+ case 128:
+ return vwin256;
+ case 256:
+ return vwin512;
+ case 512:
+ return vwin1024;
+ case 1024:
+ return vwin2048;
+ case 2048:
+ return vwin4096;
+ case 4096:
+ return vwin8192;
+ default:
+ return(0);
+ }
+ break;
+ default:
+ return(0);
+ }
+}
+
+void _vorbis_apply_window(ogg_int32_t *d,const void *window_p[2],
+ long *blocksizes,
+ int lW,int W,int nW){
+
+ LOOKUP_T *window[2]={window_p[0],window_p[1]};
+ long n=blocksizes[W];
+ long ln=blocksizes[lW];
+ long rn=blocksizes[nW];
+
+ long leftbegin=n/4-ln/4;
+ long leftend=leftbegin+ln/2;
+
+ long rightbegin=n/2+n/4-rn/4;
+ long rightend=rightbegin+rn/2;
+
+ int i,p;
+
+ for(i=0;i<leftbegin;i++)
+ d[i]=0;
+
+ for(p=0;i<leftend;i++,p++)
+ d[i]=MULT31(d[i],window[lW][p]);
+
+ for(i=rightbegin,p=rn/2-1;i<rightend;i++,p--)
+ d[i]=MULT31(d[i],window[nW][p]);
+
+ for(;i<n;i++)
+ d[i]=0;
+}
diff --git a/misc/libtremor/tremor/window.h b/misc/libtremor/tremor/window.h
new file mode 100644
index 0000000..27647fe
--- /dev/null
+++ b/misc/libtremor/tremor/window.h
@@ -0,0 +1,27 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
+ * *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
+ * *
+ * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
+ * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: window functions
+
+ ********************************************************************/
+
+#ifndef _V_WINDOW_
+#define _V_WINDOW_
+
+extern const void *_vorbis_window(int type,int left);
+extern void _vorbis_apply_window(ogg_int32_t *d,const void *window[2],
+ long *blocksizes,
+ int lW,int W,int nW);
+
+
+#endif
diff --git a/misc/loc_gen.txt b/misc/loc_gen.txt
index 3ec30d4..13c0c88 100644
--- a/misc/loc_gen.txt
+++ b/misc/loc_gen.txt
@@ -1,10 +1,10 @@
# this is inefficient and clunky, but, figured it might as well be kept somewhere so people are aware of it
# Is how I'm currently updated the locale files.
# collect strings - run in Data
-grep -F 'loc("' */*/*.lua | sed 's/)/)\n/g' | sed 's/.*loc(/loc(/;s/).*/)/' | grep loc | sort | uniq > loc.txt
+grep -F 'loc("' */*/*.lua | sed 's/")/")\n/g' | sed 's/.*loc("/loc("/;s/").*/")/' | grep loc | sort | uniq > loc.txt
# Update locale files - run in Locale
for i in *.lua;do cat ../loc.txt | while read f;do STR=$(echo "$f" | sed 's/loc("//;s/")\s*$//;s/"/\\"/g');MAPS=$(grep -F -l -- "loc(\"${STR}\")" ../*/*/*.lua ../*/*/*/*.lua | sed 's/.*\/\([^\/]*\)\/map.lua/\1/;s/.*Campaign\/\([^\/]*\)\//\1:/;s/.*\///;s/.lua//;s/ /_/g' | xargs | sed 's/ /, /g');C=$(echo $MAPS | sed 's/,/\n/' | wc -l);grep -Fq -- "[\"${STR}\"]" $i;if(($?));then if((C>0));then echo "-- [\"${STR}\"] = \"\", -- $MAPS" >> $i;else echo "-- [\"${STR}\"] = \"\"," >> $i;fi;fi;done;done
# sort - run in Locale
-for i in *.lua;do rm temphead temptail templua;cat $i | grep -Ev "}|{" | grep -Ev "^[[:space:]]*$" | sort > templua;echo "locale = {" > temphead;echo " }" > temptail;cat temphead templua temptail > $i;done
+for i in *.lua;do rm temphead temptail templua;cat $i | grep -Ev "}|{" | grep -Ev "^[[:space:]]*$" | sort | uniq > templua;echo "locale = {" > temphead;echo " }" > temptail;cat temphead templua temptail > $i;done
# drop unused - run in Locale
-cat stub.lua | grep '"] =' | while read f;do PHRASE=$(echo "$f" | sed 's/[^[]*\["//;s/"] =.*//;s/"/\\"/g');CNT=$(grep -Frc "loc(\"$PHRASE\")" ../*/*/*.lua ../*/*/*/*.lua | grep -v ":0" | wc -l);if(($CNT==0));then echo "|$PHRASE|";sed -i "s/.*\[\"$PHRASE\"].*//" *.lua;fi;done
+cat stub.lua | grep '"] =' | while read f;do PHRASE=$(echo "$f" | sed 's/[^[]*\["//;s/"] =.*//;s/"/\\"/g');CNT=$(grep -Frc "loc(\"$PHRASE\")" ../*/*/*.lua ../*/*/*/*.lua | grep -v ":0" | wc -l);if(($CNT==0));then echo "|$PHRASE|";PHRASE=$(echo "$PHRASE" | sed 's/\\/\\\\/g;s/\[/\\[/g;s/\]/\\]/g;s/\//\\\//g');sed -i "s/.*\[\"$PHRASE\"\].*//" *.lua;fi;done
diff --git a/misc/quazip/CMakeLists.txt b/misc/quazip/CMakeLists.txt
deleted file mode 100644
index 51b8d8a..0000000
--- a/misc/quazip/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-set(QT_USE_QTCORE TRUE)
-
-find_package(Qt4 REQUIRED)
-if(NOT CROSSAPPLE)
- include(${QT_USE_FILE})
-endif()
-
-
-file(GLOB SRCS "*.c" "*.cpp")
-file(GLOB PUBLIC_HEADERS "*.h")
-qt4_wrap_cpp(MOC_SRCS "quazipfile.h")
-set(SRCS ${SRCS} ${MOC_SRCS})
-
-add_library(quazip STATIC ${SRCS})
diff --git a/misc/quazip/JlCompress.cpp b/misc/quazip/JlCompress.cpp
deleted file mode 100644
index 20845d2..0000000
--- a/misc/quazip/JlCompress.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-#include "JlCompress.h"
-#include <QDebug>
-/**OK
- * Comprime il file fileName, nell'oggetto zip, con il nome fileDest.
- *
- * La funzione fallisce se:
- * * zip==NULL;
- * * l'oggetto zip è stato aperto in una modalità non compatibile con l'aggiunta di file;
- * * non è possibile aprire il file d'origine;
- * * non è possibile creare il file all'interno dell'oggetto zip;
- * * si è rilevato un errore nella copia dei dati;
- * * non è stato possibile chiudere il file all'interno dell'oggetto zip;
- */
-bool JlCompress::compressFile(QuaZip* zip, QString fileName, QString fileDest) {
- // zip: oggetto dove aggiungere il file
- // fileName: nome del file reale
- // fileDest: nome del file all'interno del file compresso
-
- // Controllo l'apertura dello zip
- if (!zip) return false;
- if (zip->getMode()!=QuaZip::mdCreate &&
- zip->getMode()!=QuaZip::mdAppend &&
- zip->getMode()!=QuaZip::mdAdd) return false;
-
- // Apro il file originale
- QFile inFile;
- inFile.setFileName(fileName);
- if(!inFile.open(QIODevice::ReadOnly)) return false;
-
- // Apro il file risulato
- QuaZipFile outFile(zip);
- if(!outFile.open(QIODevice::WriteOnly, QuaZipNewInfo(fileDest, inFile.fileName()))) return false;
-
- // Copio i dati
- char c;
- while(inFile.getChar(&c)&&outFile.putChar(c));
- if(outFile.getZipError()!=UNZ_OK) return false;
-
- // Chiudo i file
- outFile.close();
- if (outFile.getZipError()!=UNZ_OK) return false;
- inFile.close();
-
- return true;
-}
-
-/**OK
- * Comprime la cartella dir nel file fileCompressed, se recursive è true allora
- * comprime anche le sotto cartelle. I nomi dei file preceduti dal path creato
- * togliendo il pat della cartella origDir al path della cartella dir.
- * Se la funzione fallisce restituisce false e cancella il file che si è tentato
- * di creare.
- *
- * La funzione fallisce se:
- * * zip==NULL;
- * * l'oggetto zip è stato aperto in una modalità non compatibile con l'aggiunta di file;
- * * la cartella dir non esiste;
- * * la compressione di una sotto cartella fallisce (1);
- * * la compressione di un file fallisce;
- * (1) La funzione si richiama in maniera ricorsiva per comprimere le sotto cartelle
- * dunque gli errori di compressione di una sotto cartella sono gli stessi di questa
- * funzione.
- */
-bool JlCompress::compressSubDir(QuaZip* zip, QString dir, QString origDir, bool recursive) {
- // zip: oggetto dove aggiungere il file
- // dir: cartella reale corrente
- // origDir: cartella reale originale
- // (path(dir)-path(origDir)) = path interno all'oggetto zip
-
- // Controllo l'apertura dello zip
- if (!zip) return false;
- if (zip->getMode()!=QuaZip::mdCreate &&
- zip->getMode()!=QuaZip::mdAppend &&
- zip->getMode()!=QuaZip::mdAdd) return false;
-
- // Controllo la cartella
- QDir directory(dir);
- if (!directory.exists()) return false;
-
- // Se comprimo anche le sotto cartelle
- if (recursive) {
- // Per ogni sotto cartella
- QFileInfoList files = directory.entryInfoList(QDir::AllDirs|QDir::NoDotAndDotDot);
- foreach (QFileInfo file, files) {
- // Comprimo la sotto cartella
- if(!compressSubDir(zip,file.absoluteFilePath(),origDir,recursive)) return false;
- }
- }
-
- // Per ogni file nella cartella
- QFileInfoList files = directory.entryInfoList(QDir::Files);
- QDir origDirectory(origDir);
- foreach (QFileInfo file, files) {
- // Se non è un file o è il file compresso che sto creando
- if(!file.isFile()||file.absoluteFilePath()==zip->getZipName()) continue;
-
- // Creo il nome relativo da usare all'interno del file compresso
- QString filename = origDirectory.relativeFilePath(file.absoluteFilePath());
-
- // Comprimo il file
- if (!compressFile(zip,file.absoluteFilePath(),filename)) return false;
- }
-
- return true;
-}
-
-/**OK
- * Estrae il file fileName, contenuto nell'oggetto zip, con il nome fileDest.
- * Se la funzione fallisce restituisce false e cancella il file che si è tentato di estrarre.
- *
- * La funzione fallisce se:
- * * zip==NULL;
- * * l'oggetto zip è stato aperto in una modalità non compatibile con l'estrazione di file;
- * * non è possibile aprire il file all'interno dell'oggetto zip;
- * * non è possibile creare il file estratto;
- * * si è rilevato un errore nella copia dei dati (1);
- * * non è stato possibile chiudere il file all'interno dell'oggetto zip (1);
- *
- * (1): prima di uscire dalla funzione cancella il file estratto.
- */
-bool JlCompress::extractFile(QuaZip* zip, QString fileName, QString fileDest) {
- // zip: oggetto dove aggiungere il file
- // filename: nome del file reale
- // fileincompress: nome del file all'interno del file compresso
-
- // Controllo l'apertura dello zip
- if (!zip) return false;
- if (zip->getMode()!=QuaZip::mdUnzip) return false;
-
- // Apro il file compresso
- zip->setCurrentFile(fileName);
- QuaZipFile inFile(zip);
- if(!inFile.open(QIODevice::ReadOnly) || inFile.getZipError()!=UNZ_OK) return false;
-
- // Controllo esistenza cartella file risultato
- QDir().mkpath(QFileInfo(fileDest).absolutePath());
-
- // Apro il file risultato
- QFile outFile;
- outFile.setFileName(fileDest);
- if(!outFile.open(QIODevice::WriteOnly)) return false;
-
- // Copio i dati
- char c;
- while(inFile.getChar(&c)) outFile.putChar(c);
- if (inFile.getZipError()!=UNZ_OK) {
- removeFile(QStringList(fileDest));
- return false;
- }
-
- // Chiudo i file
- inFile.close();
- if (inFile.getZipError()!=UNZ_OK) {
- removeFile(QStringList(fileDest));
- return false;
- }
- outFile.close();
-
- return true;
-}
-
-/**
- * Rimuove i file il cui nome è specificato all'interno di listFile.
- * Restituisce true se tutti i file sono stati cancellati correttamente, attenzione
- * perchè può restituire false anche se alcuni file non esistevano e si è tentato
- * di cancellarli.
- */
-bool JlCompress::removeFile(QStringList listFile) {
- bool ret = true;
- // Per ogni file
- for (int i=0; i<listFile.count(); i++) {
- // Lo elimino
- ret = ret && QFile::remove(listFile.at(i));
- }
- return ret;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-/**OK
- * Comprime il file fileName nel file fileCompressed.
- * Se la funzione fallisce restituisce false e cancella il file che si è tentato
- * di creare.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * la compressione del file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-bool JlCompress::compressFile(QString fileCompressed, QString file) {
- // Creo lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
- if(!zip->open(QuaZip::mdCreate)) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
-
- // Aggiungo il file
- if (!compressFile(zip,file,QFileInfo(file).fileName())) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
- delete zip;
-
- return true;
-}
-
-/**OK
- * Comprime i file specificati in files nel file fileCompressed.
- * Se la funzione fallisce restituisce false e cancella il file che si è tentato
- * di creare.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * la compressione di un file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-bool JlCompress::compressFiles(QString fileCompressed, QStringList files) {
- // Creo lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
- if(!zip->open(QuaZip::mdCreate)) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
-
- // Comprimo i file
- QFileInfo info;
- foreach (QString file, files) {
- info.setFile(file);
- if (!info.exists() || !compressFile(zip,file,info.fileName())) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
- delete zip;
-
- return true;
-}
-
-/**OK
- * Comprime la cartella dir nel file fileCompressed, se recursive è true allora
- * comprime anche le sotto cartelle.
- * Se la funzione fallisce restituisce false e cancella il file che si è tentato
- * di creare.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * la compressione di un file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-bool JlCompress::compressDir(QString fileCompressed, QString dir, bool recursive) {
- // Creo lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
- if(!zip->open(QuaZip::mdCreate)) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
-
- // Aggiungo i file e le sotto cartelle
- if (!compressSubDir(zip,dir,dir,recursive)<0) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- QFile::remove(fileCompressed);
- return false;
- }
- delete zip;
-
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-/**OK
- * Estrae il file fileName, contenuto nel file fileCompressed, con il nome fileDest.
- * Se fileDest = "" allora il file viene estratto con lo stesso nome con cui è
- * stato compresso.
- * Se la funzione fallisce cancella il file che si è tentato di estrarre.
- * Restituisce il nome assoluto del file estratto.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * l'estrazione del file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-QString JlCompress::extractFile(QString fileCompressed, QString fileName, QString fileDest) {
- // Apro lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- if(!zip->open(QuaZip::mdUnzip)) {
- delete zip;
- return QString();
- }
-
- // Estraggo il file
- if (fileDest.isEmpty()) fileDest = fileName;
- if (!extractFile(zip,fileName,fileDest)) {
- delete zip;
- return QString();
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- removeFile(QStringList(fileDest));
- return QString();
- }
- delete zip;
-
- return QFileInfo(fileDest).absoluteFilePath();
-}
-
-/**OK
- * Estrae i file specificati in files, contenuti nel file fileCompressed, nella
- * cartella dir. La struttura a cartelle del file compresso viene rispettata.
- * Se dir = "" allora il file viene estratto nella cartella corrente.
- * Se la funzione fallisce cancella i file che si è tentato di estrarre.
- * Restituisce i nomi assoluti dei file estratti.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * l'estrazione di un file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-QStringList JlCompress::extractFiles(QString fileCompressed, QStringList files, QString dir) {
- // Creo lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- if(!zip->open(QuaZip::mdUnzip)) {
- delete zip;
- return QStringList();
- }
-
- // Estraggo i file
- for (int i=0; i<files.count(); i++) {
- if (!extractFile(zip, files.at(i), QDir(dir).absoluteFilePath(files.at(i)))) {
- delete zip;
- removeFile(files);
- return QStringList();
- }
- files[i] = QDir(dir).absoluteFilePath(files.at(i));
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- removeFile(files);
- return QStringList();
- }
- delete zip;
-
- return files;
-}
-
-/**OK
- * Estrae il file fileCompressed nella cartella dir.
- * Se dir = "" allora il file viene estratto nella cartella corrente.
- * Se la funzione fallisce cancella i file che si è tentato di estrarre.
- * Restituisce i nomi assoluti dei file estratti.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * la compressione di un file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-QStringList JlCompress::extractDir(QString fileCompressed, QString dir) {
- // Apro lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- if(!zip->open(QuaZip::mdUnzip)) {
- delete zip;
- return QStringList();
- }
-
- // Estraggo i file
- QStringList lst = getFileList(fileCompressed);
-
- QDir directory(dir);
- for (int i=0; i<lst.count(); i++) {
- QString absFilePath = directory.absoluteFilePath(lst.at(i));
- if (!extractFile(zip, lst.at(i), absFilePath)) {
- delete zip;
- removeFile(lst);
- return QStringList();
- }
- lst[i] = absFilePath;
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- removeFile(lst);
- return QStringList();
- }
- delete zip;
-
- return lst;
-}
-
-/**OK
- * Restituisce la lista dei file resenti nel file compresso fileCompressed.
- * Se la funzione fallisce, restituisce un elenco vuoto.
- *
- * La funzione fallisce se:
- * * non si riesce ad aprire l'oggetto zip;
- * * la richiesta di informazioni di un file fallisce;
- * * non si riesce a chiudere l'oggetto zip;
- */
-QStringList JlCompress::getFileList(QString fileCompressed) {
- // Apro lo zip
- QuaZip* zip = new QuaZip(QFileInfo(fileCompressed).absoluteFilePath());
- if(!zip->open(QuaZip::mdUnzip)) {
- delete zip;
- return QStringList();
- }
-
- // Estraggo i nomi dei file
- QStringList lst;
- QuaZipFileInfo info;
- for(bool more=zip->goToFirstFile(); more; more=zip->goToNextFile()) {
- if(!zip->getCurrentFileInfo(&info)) {
- delete zip;
- return QStringList();
- }
- lst << info.name;
- //info.name.toLocal8Bit().constData()
- }
-
- // Chiudo il file zip
- zip->close();
- if(zip->getZipError()!=0) {
- delete zip;
- return QStringList();
- }
- delete zip;
-
- return lst;
-}
-
diff --git a/misc/quazip/JlCompress.h b/misc/quazip/JlCompress.h
deleted file mode 100644
index c5bfd46..0000000
--- a/misc/quazip/JlCompress.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef JLCOMPRESSFOLDER_H_
-#define JLCOMPRESSFOLDER_H_
-
-#include "quazip.h"
-#include "quazipfile.h"
-#include "quazipfileinfo.h"
-#include <QString>
-#include <QDir>
-#include <QFileInfo>
-#include <QFile>
-
-class QUAZIP_EXPORT JlCompress {
-private:
- static bool compressFile(QuaZip* zip, QString fileName, QString fileDest);
- static bool compressSubDir(QuaZip* parentZip, QString dir, QString parentDir, bool recursive = true);
- static bool extractFile(QuaZip* zip, QString fileName, QString fileDest);
-
- static bool removeFile(QStringList listFile);
-
-public:
- static bool compressFile(QString fileCompressed, QString file);
- static bool compressFiles(QString fileCompressed, QStringList files);
- static bool compressDir(QString fileCompressed, QString dir = QString(), bool recursive = true);
-
-public:
- static QString extractFile(QString fileCompressed, QString file, QString fileDest = QString());
- static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString());
- static QStringList extractDir(QString fileCompressed, QString dir = QString());
- static QStringList getFileList(QString fileCompressed);
-};
-
-#endif /* JLCOMPRESSFOLDER_H_ */
diff --git a/misc/quazip/crypt.h b/misc/quazip/crypt.h
deleted file mode 100644
index 1d6da62..0000000
--- a/misc/quazip/crypt.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This code is a modified version of crypting code in Infozip distribution
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
-
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
-
- If you don't need crypting in your application, just define symbols
- NOCRYPT and NOUNCRYPT.
-
- This code support the "Traditional PKWARE Encryption".
-
- The new AES encryption added on Zip format by Winzip (see the page
- http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
- Encryption is not supported.
-*/
-
-#include "quazip_global.h"
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab UNUSED)
-{
- //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
- unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
- * unpredictable manner on 16-bit systems; not a problem
- * with any known compiler so far, though */
-
- temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
- return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
-{
- (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
- (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
- (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
- {
- register int keyshift = (int)((*(pkeys+1)) >> 24);
- (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
- }
- return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
-{
- *(pkeys+0) = 305419896L;
- *(pkeys+1) = 591751049L;
- *(pkeys+2) = 878082192L;
- while (*passwd != '\0') {
- update_keys(pkeys,pcrc_32_tab,(int)*passwd);
- passwd++;
- }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
- (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
- (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN 12
- /* "last resort" source for second part of crypt seed pattern */
-# ifndef ZCR_SEED2
-# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
-# endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
- const char *passwd; /* password string */
- unsigned char *buf; /* where to write header */
- int bufSize;
- unsigned long* pkeys;
- const unsigned long* pcrc_32_tab;
- unsigned long crcForCrypting;
-{
- int n; /* index in random header */
- int t; /* temporary */
- int c; /* random byte */
- unsigned char header[RAND_HEAD_LEN-2]; /* random header */
- static unsigned calls = 0; /* ensure different random header each time */
-
- if (bufSize<RAND_HEAD_LEN)
- return 0;
-
- /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
- * output of rand() to get less predictability, since rand() is
- * often poorly implemented.
- */
- if (++calls == 1)
- {
- srand((unsigned)(time(NULL) ^ ZCR_SEED2));
- }
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- c = (rand() >> 7) & 0xff;
- header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
- }
- /* Encrypt random header (last two bytes is high word of crc) */
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
- }
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
- return n;
-}
-
-#endif
diff --git a/misc/quazip/doc/faq.dox b/misc/quazip/doc/faq.dox
deleted file mode 100644
index dfd367c..0000000
--- a/misc/quazip/doc/faq.dox
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * \page faq QuaZip FAQ
- *
- * <!--
- * \ref faq-GPL "Q. Is it possible to release an LGPL version of the QuaZip?"
- *
- * \ref faq-non-QIODevice "Q. Is there any way to use QuaZipFile in Qt where you are supposed to use normal (non-zipped) file, but not through QIODevice API?"
- * -->
- *
- * \anchor faq-GPL Q. Is it possible to release an LGPL version of the
- * QuaZip?
- *
- * A. I do not know much about licensing, so I can answer for sure, but
- * QuaZip was developed using Open Source edition of Qt, so I see no
- * way it could be released under anything except GPL.
- *
- * \anchor faq-non-QIODevice Q. Is there any way to use QuaZipFile in Qt
- * where you are supposed to use normal (non-zipped) file, but not
- * through QIODevice API?
- *
- * A. Usually not. For example, if you are passing file name to some
- * database driver (like SQLite), Qt usually just passes this name down
- * to the 3rd-party library, which is usually does not know anything
- * about QIODevice and therefore there is no way to pass QuaZipFile as
- * normal file. However, if we are talking about some place where you
- * pass file name, and then indirectly use QFile to open it, then it is
- * a good idea to make overloaded method, which accepts QIODevice
- * pointer. Then you would be able to pass QuaZipFile as well as many
- * other nice things such as QBuffer or QProcess.
- **/
diff --git a/misc/quazip/doc/index.dox b/misc/quazip/doc/index.dox
deleted file mode 100644
index b9692dc..0000000
--- a/misc/quazip/doc/index.dox
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * \mainpage QuaZIP - Qt/C++ wrapper for ZIP/UNZIP package
- *
-\htmlonly
-<a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=142688&type=7" style="width:210; height:62; border:none; float:right;" alt="Powered by SourceForge.net" /></a>
-\endhtmlonly
- * \section overview Overview
- *
- * QuaZIP is a simple C++ wrapper over <a
- * href="http://www.winimage.com/zLibDll/unzip.html">Gilles Vollant's ZIP/UNZIP
- * package</a> that can be used to access ZIP archives. It uses <a
- * href="http://www.trolltech.com/products/qt/index.html">Trolltech's
- * Qt toolkit</a>.
- *
- * If you do not know what Qt is, you have two options:
- * - Just forget about QuaZIP.
- * - Learn more about Qt by downloading it and/or reading excellent <a
- * href="http://doc.trolltech.com/">official Qt documentation</a>
- *
- * The choice is yours, but if you are really interested in
- * cross-platform (Windows/Linux/BSD/UNIX/Mac/Others) software
- * development, I would definitely recommend you the second choice ^_^
- *
- * QuaZIP allows you to access files inside ZIP archives using QIODevice
- * API, and - yes! - that means that you can also use QTextStream,
- * QDataStream or whatever you would like to use on your zipped files.
- *
- * QuaZIP provides complete abstraction of the ZIP/UNZIP API, for both
- * reading from and writing to ZIP archives.
- *
- * \section platforms Platforms supported
- *
- * QuaZIP has been currently tested with Qt 4.0.0 on the following
- * platforms:
- * - linux-g++
- * - freebsd-g++
- * - hpux-acc
- * - win32-g++ (MinGW)
- *
- * No testing has been done on other systems. Of course, patches to
- * make it work on any platform that it currently does not work on are
- * always welcome!
- *
- * \section whats-new What is new in this version of QuaZIP?
- *
- * See NEWS file supplied with the distribution.
- *
- * \section getting Getting latest version of QuaZIP
- *
- * Check <a href="http://sourceforge.net/projects/quazip/">QuaZIP
- * project's page at SourceForge.net</a>. Also, you may wish to read
- * latest version documentation available at the <a
- * href="http://quazip.sourceforge.net/">QuaZIP web site</a>.
- *
- * \section Requirements
- *
- * Just <a href="http://www.zlib.org/">zlib</a> and Qt 4. Well, Qt 4
- * depends on zlib anyway.
- *
- * \section building Building, testing and installing
- *
- * \note Instructions given in this section assume that you are
- * using some UNIX dialect, but the build process should be very similar
- * on win32-g++ platform too. Sorry, but other platforms are
- * undocumented. I do not think it is a big deal, though - it is
- * standard usage of the Qt's qmake, so you most probably already know
- * everything that is required.
- *
- * To build it on some UNIX dialect:
-\verbatim
-$ cd /wherever/quazip/source/is/quazip-x.y.z/quazip
-$ qmake [PREFIX=where-to-install]
-$ make
-\endverbatim
- *
- * Make sure that you have Qt 4 installed with all required headers and
- * utilities (not just library) and that you run qmake utility of the Qt
- * 4, not some other version you may have already installed (you may
- * need to type full path to qmake like /usr/local/qt4/bin/qmake).
- *
- * To reconfigure (with another PREFIX, for example), just run qmake
- * with appropriate arguments again.
- *
- * If you need to specify additional include path or libraries, use
- * qmake features (see qmake reference in the Qt documentation). For
- * example:
- *
-\verbatim
-$ qmake LIBS+=-L/usr/local/zlib/lib INCLUDEPATH+=/usr/local/zlib/include
-\endverbatim
- * (note abscence of "-I" before include path)
- *
- * To check if QuaZIP's basic features work ok on your platform, you may
- * wish to compile simple test programs provided in test directory.
- * Look in the sources of the tests to find out about their
- * requirements. Typically, the test looks something like this:
-\verbatim
-$ cd /wherever/quazip/source/is/quazip-x.y.z/test/zip
-$ qmake
-$ make
-$ ./zip
-$ cd ../unzip
-$ cp ../zip/test.zip ./test.zip
-$ mkdir out
-$ qmake
-$ make
-$ ./unzip
-\endverbatim
- *
- * You should see the zip contents with details as the output of the
- * "./unzip". Ignore message saying you should check the file name for
- * testCase() if you do not want to test
- * \link QuaZip::CaseSensitivity locale-aware case-insensitivity\endlink.
- * Otherwise, see the sources. In any case, this message appearing means
- * that everything else was fine. Otherwise, you will get some other error
- * message instead. Investigate it or send bug report including message,
- * platform and QuaZIP version used.
- *
- * To install compiled library:
-\verbatim
-$ make install
-\endverbatim
- *
- * By default, QuaZIP compiles as static library, but you have other
- * options:
- * - Just copy appropriate source files to your project and use them;
- * - Compile QuaZIP as shared library by changing "staticlib" in
- * quazip/quazip.pro to "dll".
- *
- * Latter is not recommended because future versions of QuaZIP most
- * probably will be binary incompatible.
- *
- * \section using Using
- *
- * See \ref usage "usage page".
- *
- * \section bugs Bugs
- *
- * QuaZIP is currently at the initial development stage. Therefore,
- * there are may be plenty of bugs and other bad things. Bug reports and
- * patches are always welcome (see "contacts" below).
- *
- * \section contacts Authors and contacts
- *
- * This wrapper has been written by Sergey A. Tachenov, AKA Alqualos.
- * This is my first open source project, so it may suck, but I did not
- * find anything like that, so I just had no other choice but to write
- * it.
- *
- * If you have anything to say to me about QuaZIP library, feel free to
- * do so (read the \ref faq first, though). I can not promise,
- * though, that I fix all the bugs you report in, add any features you
- * want, or respond to your critics, or respond to your feedback at all.
- * I may be busy, I may be tired of working on QuaZIP, I may be even
- * dead already (you never know...). But regardless of this remark, any
- * feedback is always welcome. This may seem like a paradox to you, but
- * you do not have to understand it to write feedback.
- *
- * To report bugs or to post ideas about what should be done, use
- * SourceForge.net's <a
- * href="http://sourceforge.net/tracker/?group_id=142688">trackers</a>.
- * If you want to send me a private message, use my e-mail address
- * laerel at yandex dot ru (but do not you dare to put it somewhere on
- * the Web or wherever).
- *
- * Do not use e-mail to report bugs, please. Reporting bugs and problems
- * with the SourceForge.net's bug report system has that advantage that
- * it is visible to public.
- *
- * \section other-projects My other projects
- *
- * As of this moment, I did not write any other useful open source
- * software (well, I am too lazy to do it) except for one little thing:
- *
- * <a href="http://brededor.narod.ru/progs/arcanum50patch.htm">Arcanum
- * universal cap remover</a>. Arcanum is the old but very good game,
- * which has one stupid limit: your character maximum level is 50, which
- * is too low for many players including me. So I wrote this simple
- * patch to increase this stupid limit to something acceptable.
- *
- * Also, my first Web project, which can be of any interest to you only
- * if you can read Russian and you are crazy ^_- This is a web site with
- * the main topic of it being The Delirium. It is totally meaningless
- * and it was purposely made to be such. Do not ask me why - I do not
- * know either. I just did that. If you are interested, then welcome to
- * <a href="http://brededor.narod.ru/">The Brededor</a>. It does not get
- * updated lately because I have become even lazier than I ever was. But
- * I do not plan to destroy The Brededor no matter what, because I think
- * it is fun.
- *
- * Copyright (C) 2005-2007 Sergey A. Tachenov
- **/
diff --git a/misc/quazip/doc/usage.dox b/misc/quazip/doc/usage.dox
deleted file mode 100644
index 02fd3a8..0000000
--- a/misc/quazip/doc/usage.dox
+++ /dev/null
@@ -1,69 +0,0 @@
-/** \page usage Usage
- *
- * This page provides general information on QuaZIP usage. See classes
- * QuaZip and QuaZipFile for the detailed documentation on what can
- * QuaZIP do and what can not. Also, reading comments in the zip.h and
- * unzip.h files (taken from the original ZIP/UNZIP package) is always a
- * good idea too. After all, QuaZIP is just a wrapper with a few
- * convenience extensions and reimplementations.
- *
- * QuaZip is a class representing ZIP archive, QuaZipFile represents a
- * file inside archive and subclasses QIODevice as well.
- *
- * \section terminology Terminology
- *
- * "QuaZIP" means whole this library, while "QuaZip" (not case
- * difference) is just one class in it.
- *
- * "ZIP/UNZIP API" means the original API of the Gilles Vollant's
- * ZIP/UNZIP package. I did not alter it in any way to make it easier to
- * port to the future ZIP/UNZIP versions.
- *
- * "ZIP", "ZIP archive" or "ZIP file" means any ZIP archive. Typically
- * this is a plain file with ".zip" (or ".ZIP") file name suffix.
- *
- * "A file inside archive", "a file inside ZIP" or something like that
- * means file either being read or written from/to some ZIP archive.
- *
- * \section error-handling Error handling
- *
- * Almost any call to ZIP/UNZIP API return some error code. Most of the
- * original API's error checking could be done in this wrapper as well,
- * but it would cause unnecessary code bloating without any benefit. So,
- * QuaZIP only checks for situations that ZIP/UNZIP API can not check
- * for. For example, ZIP/UNZIP API has no "ZIP open mode" concept
- * because read and write modes are completely separated. On the other
- * hand, to avoid creating classes like "QuaZipReader", "QuaZipWriter"
- * or something like that, QuaZIP introduces "ZIP open mode" concept
- * instead, thus making it possible to use one class (QuaZip) for both
- * reading and writing. But this leads to additional open mode checks
- * which are not done in ZIP/UNZIP package.
- *
- * Therefore, error checking is two-level (QuaZIP's level and ZIP/UNZIP
- * API level), which sometimes can be confusing, so here are some
- * advices on how the error checking should be properly done:
- *
- * - Both QuaZip and QuaZipFile have getZipError() function, which return
- * error code of the last ZIP/UNZIP API call. Most function calls
- * reset error code to UNZ_OK on success and set error code on
- * failure. Some functions do not reset error code. Most of them are
- * \c const and do not access ZIP archive in any way. Some, on the
- * other hand, \em do access ZIP archive, but do not reset or set
- * error code. For example, QuaZipFile::pos() function. Such functions
- * are explicitly marked in the documentation.
- * - Most functions have its own way to report errors, by returning a
- * null string, negative value or \c false. If such a function returns
- * error value, call getZipError() to get more information about
- * error. See "zip.h" and "unzip.h" of the ZIP/UNZIP package for error
- * codes.
- * - If the function returns error-stating value (like \c false), but
- * getZipError() returns UNZ_OK, it means that you did something
- * obviously wrong. For example, tried to write in the archive open
- * for reading or not open at all. You better just do not do that!
- * Most functions also issue a warning using qWarning() function in
- * such cases. See documentation for a specific function for details
- * on when it should not be called.
- *
- * I know that this is somewhat messy, but I could not find a better way
- * to do all the error handling.
- **/
diff --git a/misc/quazip/ioapi.h b/misc/quazip/ioapi.h
deleted file mode 100644
index f4c2180..0000000
--- a/misc/quazip/ioapi.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ (1)
-#define ZLIB_FILEFUNC_MODE_WRITE (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
- open_file_func zopen_file;
- read_file_func zread_file;
- write_file_func zwrite_file;
- tell_file_func ztell_file;
- seek_file_func zseek_file;
- close_file_func zclose_file;
- testerror_file_func zerror_file;
- voidpf opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/misc/quazip/qioapi.cpp b/misc/quazip/qioapi.cpp
deleted file mode 100644
index 49cb02e..0000000
--- a/misc/quazip/qioapi.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-#include "quazip_global.h"
-#include <QIODevice>
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-voidpf ZCALLBACK qiodevice_open_file_func (
- voidpf opaque UNUSED,
- voidpf file,
- int mode)
-{
- QIODevice *iodevice = reinterpret_cast<QIODevice*>(file);
- if(iodevice->isSequential())
- return NULL;
- if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
- iodevice->open(QIODevice::ReadOnly);
- else
- if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
- iodevice->open(QIODevice::ReadWrite);
- else
- if (mode & ZLIB_FILEFUNC_MODE_CREATE)
- iodevice->open(QIODevice::WriteOnly);
-
- if(iodevice->isOpen())
- return iodevice;
- else
- return NULL;
-}
-
-
-uLong ZCALLBACK qiodevice_read_file_func (
- voidpf opaque UNUSED,
- voidpf stream,
- void* buf,
- uLong size)
-{
- uLong ret;
- ret = (uLong)((QIODevice*)stream)->read((char*)buf,size);
- return ret;
-}
-
-
-uLong ZCALLBACK qiodevice_write_file_func (
- voidpf opaque UNUSED,
- voidpf stream,
- const void* buf,
- uLong size)
-{
- uLong ret;
- ret = (uLong)((QIODevice*)stream)->write((char*)buf,size);
- return ret;
-}
-
-uLong ZCALLBACK qiodevice_tell_file_func (
- voidpf opaque UNUSED,
- voidpf stream)
-{
- uLong ret;
- ret = ((QIODevice*)stream)->pos();
- return ret;
-}
-
-int ZCALLBACK qiodevice_seek_file_func (
- voidpf opaque UNUSED,
- voidpf stream,
- uLong offset,
- int origin)
-{
- uLong qiodevice_seek_result=0;
- int ret;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- qiodevice_seek_result = ((QIODevice*)stream)->size() - offset;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- qiodevice_seek_result = offset;
- break;
- default: return -1;
- }
- ret = !((QIODevice*)stream)->seek(qiodevice_seek_result);
- return ret;
-}
-
-int ZCALLBACK qiodevice_close_file_func (
- voidpf opaque UNUSED,
- voidpf stream)
-{
- ((QIODevice*)stream)->close();
- return 0;
-}
-
-int ZCALLBACK qiodevice_error_file_func (
- voidpf opaque UNUSED,
- voidpf stream)
-{
- return !((QIODevice*)stream)->errorString().isEmpty();
-}
-
-void fill_qiodevice_filefunc (
- zlib_filefunc_def* pzlib_filefunc_def)
-{
- pzlib_filefunc_def->zopen_file = qiodevice_open_file_func;
- pzlib_filefunc_def->zread_file = qiodevice_read_file_func;
- pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func;
- pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func;
- pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func;
- pzlib_filefunc_def->zclose_file = qiodevice_close_file_func;
- pzlib_filefunc_def->zerror_file = qiodevice_error_file_func;
- pzlib_filefunc_def->opaque = NULL;
-}
diff --git a/misc/quazip/quaadler32.cpp b/misc/quazip/quaadler32.cpp
deleted file mode 100644
index 097899f..0000000
--- a/misc/quazip/quaadler32.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "quaadler32.h"
-
-#include "zlib.h"
-
-QuaAdler32::QuaAdler32()
-{
- reset();
-}
-
-quint32 QuaAdler32::calculate(const QByteArray &data)
-{
- return adler32( adler32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() );
-}
-
-void QuaAdler32::reset()
-{
- checksum = adler32(0L, Z_NULL, 0);
-}
-
-void QuaAdler32::update(const QByteArray &buf)
-{
- checksum = adler32( checksum, (const Bytef*)buf.data(), buf.size() );
-}
-
-quint32 QuaAdler32::value()
-{
- return checksum;
-}
diff --git a/misc/quazip/quaadler32.h b/misc/quazip/quaadler32.h
deleted file mode 100644
index b25e806..0000000
--- a/misc/quazip/quaadler32.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef QUAADLER32_H
-#define QUAADLER32_H
-
-#include <QByteArray>
-
-#include "quachecksum32.h"
-
-/// Adler32 checksum
-/** \class QuaAdler32 quaadler32.h <quazip/quaadler32.h>
- * This class wrappers the adler32 function with the QuaChecksum32 interface.
- * See QuaChecksum32 for more info.
- */
-class QuaAdler32 : public QuaChecksum32
-{
-
-public:
- QuaAdler32();
-
- quint32 calculate(const QByteArray &data);
-
- void reset();
- void update(const QByteArray &buf);
- quint32 value();
-
-private:
- quint32 checksum;
-};
-
-#endif //QUAADLER32_H
diff --git a/misc/quazip/quachecksum32.h b/misc/quazip/quachecksum32.h
deleted file mode 100644
index 6837d26..0000000
--- a/misc/quazip/quachecksum32.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef QUACHECKSUM32_H
-#define QUACHECKSUM32_H
-
-#include <QByteArray>
-#include "quazip_global.h"
-
-/// Checksum interface.
-/** \class QuaChecksum32 quachecksum32.h <quazip/quachecksum32.h>
- * This is an interface for 32 bit checksums.
- * Classes implementing this interface can calcunate a certin
- * checksum in a single step:
- * \code
- * QChecksum32 *crc32 = new QuaCrc32();
- * rasoult = crc32->calculate(data);
- * \endcode
- * or by streaming the data:
- * \code
- * QChecksum32 *crc32 = new QuaCrc32();
- * while(!fileA.atEnd())
- * crc32->update(fileA.read(bufSize));
- * resoultA = crc32->value();
- * crc32->reset();
- * while(!fileB.atEnd())
- * crc32->update(fileB.read(bufSize));
- * resoultB = crc32->value();
- * \endcode
- */
-class QUAZIP_EXPORT QuaChecksum32
-{
-
-public:
- ///Calculates the checksum for data.
- /** \a data source data
- * \return data checksum
- *
- * This function has no efect on the value returned by value().
- */
- virtual quint32 calculate(const QByteArray &data) = 0;
-
- ///Resets the calculation on a checksun for a stream.
- virtual void reset() = 0;
-
- ///Updates the calculated checksum for the stream
- /** \a buf next portion of data from the stream
- */
- virtual void update(const QByteArray &buf) = 0;
-
- ///Value of the checksum calculated for the stream passed throw update().
- /** \return checksum
- */
- virtual quint32 value() = 0;
-};
-
-#endif //QUACHECKSUM32_H
diff --git a/misc/quazip/quacrc32.cpp b/misc/quazip/quacrc32.cpp
deleted file mode 100644
index 9381f24..0000000
--- a/misc/quazip/quacrc32.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "quacrc32.h"
-
-#include "zlib.h"
-
-QuaCrc32::QuaCrc32()
-{
- reset();
-}
-
-quint32 QuaCrc32::calculate(const QByteArray &data)
-{
- return crc32( crc32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() );
-}
-
-void QuaCrc32::reset()
-{
- checksum = crc32(0L, Z_NULL, 0);
-}
-
-void QuaCrc32::update(const QByteArray &buf)
-{
- checksum = crc32( checksum, (const Bytef*)buf.data(), buf.size() );
-}
-
-quint32 QuaCrc32::value()
-{
- return checksum;
-}
diff --git a/misc/quazip/quacrc32.h b/misc/quazip/quacrc32.h
deleted file mode 100644
index 4c86d56..0000000
--- a/misc/quazip/quacrc32.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef QUACRC32_H
-#define QUACRC32_H
-
-#include "quachecksum32.h"
-
-///CRC32 checksum
-/** \class QuaCrc32 quacrc32.h <quazip/quacrc32.h>
-* This class wrappers the crc32 function with the QuaChecksum32 interface.
-* See QuaChecksum32 for more info.
-*/
-class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 {
-
-public:
- QuaCrc32();
-
- quint32 calculate(const QByteArray &data);
-
- void reset();
- void update(const QByteArray &buf);
- quint32 value();
-
-private:
- quint32 checksum;
-};
-
-#endif //QUACRC32_H
diff --git a/misc/quazip/quazip.cpp b/misc/quazip/quazip.cpp
deleted file mode 100644
index 06e63fd..0000000
--- a/misc/quazip/quazip.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include <QFile>
-
-#include "quazip.h"
-
-class QuaZipPrivate {
- friend class QuaZip;
- private:
- QTextCodec *fileNameCodec, *commentCodec;
- QString zipName;
- QIODevice *ioDevice;
- QString comment;
- QuaZip::Mode mode;
- union {
- unzFile unzFile_f;
- zipFile zipFile_f;
- };
- bool hasCurrentFile_f;
- int zipError;
- inline QuaZipPrivate():
- fileNameCodec(QTextCodec::codecForLocale()),
- commentCodec(QTextCodec::codecForLocale()),
- ioDevice(NULL),
- mode(QuaZip::mdNotOpen),
- hasCurrentFile_f(false),
- zipError(UNZ_OK) {}
- inline QuaZipPrivate(const QString &zipName):
- fileNameCodec(QTextCodec::codecForLocale()),
- commentCodec(QTextCodec::codecForLocale()),
- zipName(zipName),
- ioDevice(NULL),
- mode(QuaZip::mdNotOpen),
- hasCurrentFile_f(false),
- zipError(UNZ_OK) {}
- inline QuaZipPrivate(QIODevice *ioDevice):
- fileNameCodec(QTextCodec::codecForLocale()),
- commentCodec(QTextCodec::codecForLocale()),
- ioDevice(ioDevice),
- mode(QuaZip::mdNotOpen),
- hasCurrentFile_f(false),
- zipError(UNZ_OK) {}
-};
-
-QuaZip::QuaZip():
- p(new QuaZipPrivate())
-{
-}
-
-QuaZip::QuaZip(const QString& zipName):
- p(new QuaZipPrivate(zipName))
-{
-}
-
-QuaZip::QuaZip(QIODevice *ioDevice):
- p(new QuaZipPrivate(ioDevice))
-{
-}
-
-QuaZip::~QuaZip()
-{
- if(isOpen())
- close();
- delete p;
-}
-
-bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi)
-{
- p->zipError=UNZ_OK;
- if(isOpen()) {
- qWarning("QuaZip::open(): ZIP already opened");
- return false;
- }
- QIODevice *ioDevice = p->ioDevice;
- if (ioDevice == NULL) {
- if (p->zipName.isEmpty()) {
- qWarning("QuaZip::open(): set either ZIP file name or IO device first");
- return false;
- } else {
- ioDevice = new QFile(p->zipName);
- }
- }
- switch(mode) {
- case mdUnzip:
- p->unzFile_f=unzOpen2(ioDevice, ioApi);
- if(p->unzFile_f!=NULL) {
- p->mode=mode;
- p->ioDevice = ioDevice;
- return true;
- } else {
- p->zipError=UNZ_OPENERROR;
- if (!p->zipName.isEmpty())
- delete ioDevice;
- return false;
- }
- case mdCreate:
- case mdAppend:
- case mdAdd:
- p->zipFile_f=zipOpen2(ioDevice,
- mode==mdCreate?APPEND_STATUS_CREATE:
- mode==mdAppend?APPEND_STATUS_CREATEAFTER:
- APPEND_STATUS_ADDINZIP,
- NULL,
- ioApi);
- if(p->zipFile_f!=NULL) {
- p->mode=mode;
- p->ioDevice = ioDevice;
- return true;
- } else {
- p->zipError=UNZ_OPENERROR;
- if (!p->zipName.isEmpty())
- delete ioDevice;
- return false;
- }
- default:
- qWarning("QuaZip::open(): unknown mode: %d", (int)mode);
- if (!p->zipName.isEmpty())
- delete ioDevice;
- return false;
- break;
- }
-}
-
-void QuaZip::close()
-{
- p->zipError=UNZ_OK;
- switch(p->mode) {
- case mdNotOpen:
- qWarning("QuaZip::close(): ZIP is not open");
- return;
- case mdUnzip:
- p->zipError=unzClose(p->unzFile_f);
- break;
- case mdCreate:
- case mdAppend:
- case mdAdd:
- p->zipError=zipClose(p->zipFile_f, p->commentCodec->fromUnicode(p->comment).constData());
- break;
- default:
- qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode);
- return;
- }
- // opened by name, need to delete the internal IO device
- if (!p->zipName.isEmpty())
- delete p->ioDevice;
- if(p->zipError==UNZ_OK)
- p->mode=mdNotOpen;
-}
-
-void QuaZip::setZipName(const QString& zipName)
-{
- if(isOpen()) {
- qWarning("QuaZip::setZipName(): ZIP is already open!");
- return;
- }
- p->zipName=zipName;
- p->ioDevice = NULL;
-}
-
-void QuaZip::setIoDevice(QIODevice *ioDevice)
-{
- if(isOpen()) {
- qWarning("QuaZip::setIoDevice(): ZIP is already open!");
- return;
- }
- p->ioDevice = ioDevice;
- p->zipName = QString();
-}
-
-int QuaZip::getEntriesCount()const
-{
- QuaZip *fakeThis=(QuaZip*)this; // non-const
- fakeThis->p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode");
- return -1;
- }
- unz_global_info globalInfo;
- if((fakeThis->p->zipError=unzGetGlobalInfo(p->unzFile_f, &globalInfo))!=UNZ_OK)
- return p->zipError;
- return (int)globalInfo.number_entry;
-}
-
-QString QuaZip::getComment()const
-{
- QuaZip *fakeThis=(QuaZip*)this; // non-const
- fakeThis->p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode");
- return QString();
- }
- unz_global_info globalInfo;
- QByteArray comment;
- if((fakeThis->p->zipError=unzGetGlobalInfo(p->unzFile_f, &globalInfo))!=UNZ_OK)
- return QString();
- comment.resize(globalInfo.size_comment);
- if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0)
- return QString();
- fakeThis->p->zipError = UNZ_OK;
- return p->commentCodec->toUnicode(comment);
-}
-
-bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs)
-{
- p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode");
- return false;
- }
- if(fileName.isEmpty()) {
- p->hasCurrentFile_f=false;
- return true;
- }
- // Unicode-aware reimplementation of the unzLocateFile function
- if(p->unzFile_f==NULL) {
- p->zipError=UNZ_PARAMERROR;
- return false;
- }
- if(fileName.length()>MAX_FILE_NAME_LENGTH) {
- p->zipError=UNZ_PARAMERROR;
- return false;
- }
- bool sens;
- if(cs==csDefault) {
-#ifdef Q_WS_WIN
- sens=false;
-#else
- sens=true;
-#endif
- } else sens=cs==csSensitive;
- QString lower, current;
- if(!sens) lower=fileName.toLower();
- p->hasCurrentFile_f=false;
- for(bool more=goToFirstFile(); more; more=goToNextFile()) {
- current=getCurrentFileName();
- if(current.isEmpty()) return false;
- if(sens) {
- if(current==fileName) break;
- } else {
- if(current.toLower()==lower) break;
- }
- }
- return p->hasCurrentFile_f;
-}
-
-bool QuaZip::goToFirstFile()
-{
- p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
- return false;
- }
- p->zipError=unzGoToFirstFile(p->unzFile_f);
- p->hasCurrentFile_f=p->zipError==UNZ_OK;
- return p->hasCurrentFile_f;
-}
-
-bool QuaZip::goToNextFile()
-{
- p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode");
- return false;
- }
- p->zipError=unzGoToNextFile(p->unzFile_f);
- p->hasCurrentFile_f=p->zipError==UNZ_OK;
- if(p->zipError==UNZ_END_OF_LIST_OF_FILE)
- p->zipError=UNZ_OK;
- return p->hasCurrentFile_f;
-}
-
-bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const
-{
- QuaZip *fakeThis=(QuaZip*)this; // non-const
- fakeThis->p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode");
- return false;
- }
- unz_file_info info_z;
- QByteArray fileName;
- QByteArray extra;
- QByteArray comment;
- if(info==NULL) return false;
- if(!isOpen()||!hasCurrentFile()) return false;
- if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, &info_z, NULL, 0, NULL, 0, NULL, 0))!=UNZ_OK)
- return false;
- fileName.resize(info_z.size_filename);
- extra.resize(info_z.size_file_extra);
- comment.resize(info_z.size_file_comment);
- if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, NULL,
- fileName.data(), fileName.size(),
- extra.data(), extra.size(),
- comment.data(), comment.size()))!=UNZ_OK)
- return false;
- info->versionCreated=info_z.version;
- info->versionNeeded=info_z.version_needed;
- info->flags=info_z.flag;
- info->method=info_z.compression_method;
- info->crc=info_z.crc;
- info->compressedSize=info_z.compressed_size;
- info->uncompressedSize=info_z.uncompressed_size;
- info->diskNumberStart=info_z.disk_num_start;
- info->internalAttr=info_z.internal_fa;
- info->externalAttr=info_z.external_fa;
- info->name=p->fileNameCodec->toUnicode(fileName);
- info->comment=p->commentCodec->toUnicode(comment);
- info->extra=extra;
- info->dateTime=QDateTime(
- QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday),
- QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec));
- return true;
-}
-
-QString QuaZip::getCurrentFileName()const
-{
- QuaZip *fakeThis=(QuaZip*)this; // non-const
- fakeThis->p->zipError=UNZ_OK;
- if(p->mode!=mdUnzip) {
- qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode");
- return QString();
- }
- if(!isOpen()||!hasCurrentFile()) return QString();
- QByteArray fileName(MAX_FILE_NAME_LENGTH, 0);
- if((fakeThis->p->zipError=unzGetCurrentFileInfo(p->unzFile_f, NULL, fileName.data(), fileName.size(),
- NULL, 0, NULL, 0))!=UNZ_OK)
- return QString();
- return p->fileNameCodec->toUnicode(fileName.constData());
-}
-
-void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec)
-{
- p->fileNameCodec=fileNameCodec;
-}
-
-void QuaZip::setFileNameCodec(const char *fileNameCodecName)
-{
- p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName);
-}
-
-QTextCodec *QuaZip::getFileNameCodec()const
-{
- return p->fileNameCodec;
-}
-
-void QuaZip::setCommentCodec(QTextCodec *commentCodec)
-{
- p->commentCodec=commentCodec;
-}
-
-void QuaZip::setCommentCodec(const char *commentCodecName)
-{
- p->commentCodec=QTextCodec::codecForName(commentCodecName);
-}
-
-QTextCodec *QuaZip::getCommentCodec()const
-{
- return p->commentCodec;
-}
-
-QString QuaZip::getZipName() const
-{
- return p->zipName;
-}
-
-QIODevice *QuaZip::getIoDevice() const
-{
- if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice
- return NULL;
- return p->ioDevice;
-}
-
-QuaZip::Mode QuaZip::getMode()const
-{
- return p->mode;
-}
-
-bool QuaZip::isOpen()const
-{
- return p->mode!=mdNotOpen;
-}
-
-int QuaZip::getZipError() const
-{
- return p->zipError;
-}
-
-void QuaZip::setComment(const QString& comment)
-{
- p->comment=comment;
-}
-
-bool QuaZip::hasCurrentFile()const
-{
- return p->hasCurrentFile_f;
-}
-
-unzFile QuaZip::getUnzFile()
-{
- return p->unzFile_f;
-}
-
-zipFile QuaZip::getZipFile()
-{
- return p->zipFile_f;
-}
diff --git a/misc/quazip/quazip.h b/misc/quazip/quazip.h
deleted file mode 100644
index a21fb92..0000000
--- a/misc/quazip/quazip.h
+++ /dev/null
@@ -1,359 +0,0 @@
-#ifndef QUA_ZIP_H
-#define QUA_ZIP_H
-
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include <QString>
-#include <QTextCodec>
-
-#include "zip.h"
-#include "unzip.h"
-
-#include "quazip_global.h"
-#include "quazipfileinfo.h"
-
-// just in case it will be defined in the later versions of the ZIP/UNZIP
-#ifndef UNZ_OPENERROR
-// define additional error code
-#define UNZ_OPENERROR -1000
-#endif
-
-class QuaZipPrivate;
-
-/// ZIP archive.
-/** \class QuaZip quazip.h <quazip/quazip.h>
- * This class implements basic interface to the ZIP archive. It can be
- * used to read table contents of the ZIP archive and retreiving
- * information about the files inside it.
- *
- * You can also use this class to open files inside archive by passing
- * pointer to the instance of this class to the constructor of the
- * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*)
- * for the possible pitfalls.
- *
- * This class is indended to provide interface to the ZIP subpackage of
- * the ZIP/UNZIP package as well as to the UNZIP subpackage. But
- * currently it supports only UNZIP.
- *
- * The use of this class is simple - just create instance using
- * constructor, then set ZIP archive file name using setFile() function
- * (if you did not passed the name to the constructor), then open() and
- * then use different functions to work with it! Well, if you are
- * paranoid, you may also wish to call close before destructing the
- * instance, to check for errors on close.
- *
- * You may also use getUnzFile() and getZipFile() functions to get the
- * ZIP archive handle and use it with ZIP/UNZIP package API directly.
- *
- * This class supports localized file names inside ZIP archive, but you
- * have to set up proper codec with setCodec() function. By default,
- * locale codec will be used, which is probably ok for UNIX systems, but
- * will almost certainly fail with ZIP archives created in Windows. This
- * is because Windows ZIP programs have strange habit of using DOS
- * encoding for file names in ZIP archives. For example, ZIP archive
- * with cyrillic names created in Windows will have file names in \c
- * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one
- * function is not much trouble, but for true platform independency it
- * would be nice to have some mechanism for file name encoding auto
- * detection using locale information. Does anyone know a good way to do
- * it?
- **/
-class QUAZIP_EXPORT QuaZip {
- friend class QuaZipPrivate;
- public:
- /// Useful constants.
- enum Constants {
- MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from
- \c UNZ_MAXFILENAMEINZIP constant in
- unzip.c. */
- };
- /// Open mode of the ZIP file.
- enum Mode {
- mdNotOpen, ///< ZIP file is not open. This is the initial mode.
- mdUnzip, ///< ZIP file is open for reading files inside it.
- mdCreate, ///< ZIP file was created with open() call.
- mdAppend, /**< ZIP file was opened in append mode. This refers to
- * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package
- * and means that zip is appended to some existing file
- * what is useful when that file contains
- * self-extractor code. This is obviously \em not what
- * you whant to use to add files to the existing ZIP
- * archive.
- **/
- mdAdd ///< ZIP file was opened for adding files in the archive.
- };
- /// Case sensitivity for the file names.
- /** This is what you specify when accessing files in the archive.
- * Works perfectly fine with any characters thanks to Qt's great
- * unicode support. This is different from ZIP/UNZIP API, where
- * only US-ASCII characters was supported.
- **/
- enum CaseSensitivity {
- csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows.
- csSensitive=1, ///< Case sensitive.
- csInsensitive=2 ///< Case insensitive.
- };
- private:
- QuaZipPrivate *p;
- // not (and will not be) implemented
- QuaZip(const QuaZip& that);
- // not (and will not be) implemented
- QuaZip& operator=(const QuaZip& that);
- public:
- /// Constructs QuaZip object.
- /** Call setName() before opening constructed object. */
- QuaZip();
- /// Constructs QuaZip object associated with ZIP file \a zipName.
- QuaZip(const QString& zipName);
- /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice.
- /** The IO device must be seekable, otherwise an error will occur when opening. */
- QuaZip(QIODevice *ioDevice);
- /// Destroys QuaZip object.
- /** Calls close() if necessary. */
- ~QuaZip();
- /// Opens ZIP file.
- /**
- * Argument \a mode specifies open mode of the ZIP archive. See Mode
- * for details. Note that there is zipOpen2() function in the
- * ZIP/UNZIP API which accepts \a globalcomment argument, but it
- * does not use it anywhere, so this open() function does not have this
- * argument. See setComment() if you need to set global comment.
- *
- * If the ZIP file is accessed via explicitly set QIODevice, then
- * this device is opened in the necessary mode. If the device was
- * already opened by some other means, then the behaviour is defined by
- * the device implementation, but generally it is not a very good
- * idea. For example, QFile will at least issue a warning.
- *
- * \return \c true if successful, \c false otherwise.
- *
- * \note ZIP/UNZIP API open calls do not return error code - they
- * just return \c NULL indicating an error. But to make things
- * easier, quazip.h header defines additional error code \c
- * UNZ_ERROROPEN and getZipError() will return it if the open call
- * of the ZIP/UNZIP API returns \c NULL.
- *
- * Argument \a ioApi specifies IO function set for ZIP/UNZIP
- * package to use. See unzip.h, zip.h and ioapi.h for details. Note
- * that IO API for QuaZip is different from the original package.
- * The file path argument was changed to be of type \c voidpf, and
- * QuaZip passes a QIODevice pointer there. This QIODevice is either
- * set explicitly via setIoDevice() or the QuaZip(QIODevice*)
- * constructor, or it is created internally when opening the archive
- * by its file name. The default API (qioapi.cpp) just delegates
- * everything to the QIODevice API. Not only this allows to use a
- * QIODevice instead of file name, but also has a nice side effect
- * of raising the file size limit from 2G to 4G.
- *
- * In short: just forget about the \a ioApi argument and you'll be
- * fine.
- **/
- bool open(Mode mode, zlib_filefunc_def *ioApi =NULL);
- /// Closes ZIP file.
- /** Call getZipError() to determine if the close was successful. The
- * underlying QIODevice is also closed, regardless of whether it was
- * set explicitly or not. */
- void close();
- /// Sets the codec used to encode/decode file names inside archive.
- /** This is necessary to access files in the ZIP archive created
- * under Windows with non-latin characters in file names. For
- * example, file names with cyrillic letters will be in \c IBM866
- * encoding.
- **/
- void setFileNameCodec(QTextCodec *fileNameCodec);
- /// Sets the codec used to encode/decode file names inside archive.
- /** \overload
- * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName));
- **/
- void setFileNameCodec(const char *fileNameCodecName);
- /// Returns the codec used to encode/decode comments inside archive.
- QTextCodec* getFileNameCodec() const;
- /// Sets the codec used to encode/decode comments inside archive.
- /** This codec defaults to locale codec, which is probably ok.
- **/
- void setCommentCodec(QTextCodec *commentCodec);
- /// Sets the codec used to encode/decode comments inside archive.
- /** \overload
- * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName));
- **/
- void setCommentCodec(const char *commentCodecName);
- /// Returns the codec used to encode/decode comments inside archive.
- QTextCodec* getCommentCodec() const;
- /// Returns the name of the ZIP file.
- /** Returns null string if no ZIP file name has been set, for
- * example when the QuaZip instance is set up to use a QIODevice
- * instead.
- * \sa setZipName(), setIoDevice(), getIoDevice()
- **/
- QString getZipName() const;
- /// Sets the name of the ZIP file.
- /** Does nothing if the ZIP file is open.
- *
- * Does not reset error code returned by getZipError().
- * \sa setIoDevice(), getIoDevice(), getZipName()
- **/
- void setZipName(const QString& zipName);
- /// Returns the device representing this ZIP file.
- /** Returns null string if no device has been set explicitly, for
- * example when opening a ZIP file by name.
- * \sa setIoDevice(), getZipName(), setZipName()
- **/
- QIODevice *getIoDevice() const;
- /// Sets the device representing the ZIP file.
- /** Does nothing if the ZIP file is open.
- *
- * Does not reset error code returned by getZipError().
- * \sa getIoDevice(), getZipName(), setZipName()
- **/
- void setIoDevice(QIODevice *ioDevice);
- /// Returns the mode in which ZIP file was opened.
- Mode getMode() const;
- /// Returns \c true if ZIP file is open, \c false otherwise.
- bool isOpen() const;
- /// Returns the error code of the last operation.
- /** Returns \c UNZ_OK if the last operation was successful.
- *
- * Error code resets to \c UNZ_OK every time you call any function
- * that accesses something inside ZIP archive, even if it is \c
- * const (like getEntriesCount()). open() and close() calls reset
- * error code too. See documentation for the specific functions for
- * details on error detection.
- **/
- int getZipError() const;
- /// Returns number of the entries in the ZIP central directory.
- /** Returns negative error code in the case of error. The same error
- * code will be returned by subsequent getZipError() call.
- **/
- int getEntriesCount() const;
- /// Returns global comment in the ZIP file.
- QString getComment() const;
- /// Sets global comment in the ZIP file.
- /** Comment will be written to the archive on close operation.
- *
- * \sa open()
- **/
- void setComment(const QString& comment);
- /// Sets the current file to the first file in the archive.
- /** Returns \c true on success, \c false otherwise. Call
- * getZipError() to get the error code.
- **/
- bool goToFirstFile();
- /// Sets the current file to the next file in the archive.
- /** Returns \c true on success, \c false otherwise. Call
- * getZipError() to determine if there was an error.
- *
- * Should be used only in QuaZip::mdUnzip mode.
- *
- * \note If the end of file was reached, getZipError() will return
- * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make
- * things like this easier:
- * \code
- * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
- * // do something
- * }
- * if(zip.getZipError()==UNZ_OK) {
- * // ok, there was no error
- * }
- * \endcode
- **/
- bool goToNextFile();
- /// Sets current file by its name.
- /** Returns \c true if successful, \c false otherwise. Argument \a
- * cs specifies case sensitivity of the file name. Call
- * getZipError() in the case of a failure to get error code.
- *
- * This is not a wrapper to unzLocateFile() function. That is
- * because I had to implement locale-specific case-insensitive
- * comparison.
- *
- * Here are the differences from the original implementation:
- *
- * - If the file was not found, error code is \c UNZ_OK, not \c
- * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()).
- * - If this function fails, it unsets the current file rather than
- * resetting it back to what it was before the call.
- *
- * If \a fileName is null string then this function unsets the
- * current file and return \c true. Note that you should close the
- * file first if it is open! See
- * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details.
- *
- * Should be used only in QuaZip::mdUnzip mode.
- *
- * \sa setFileNameCodec(), CaseSensitivity
- **/
- bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault);
- /// Returns \c true if the current file has been set.
- bool hasCurrentFile() const;
- /// Retrieves information about the current file.
- /** Fills the structure pointed by \a info. Returns \c true on
- * success, \c false otherwise. In the latter case structure pointed
- * by \a info remains untouched. If there was an error,
- * getZipError() returns error code.
- *
- * Should be used only in QuaZip::mdUnzip mode.
- *
- * Does nothing and returns \c false in any of the following cases.
- * - ZIP is not open;
- * - ZIP does not have current file;
- * - \a info is \c NULL;
- *
- * In all these cases getZipError() returns \c UNZ_OK since there
- * is no ZIP/UNZIP API call.
- **/
- bool getCurrentFileInfo(QuaZipFileInfo* info)const;
- /// Returns the current file name.
- /** Equivalent to calling getCurrentFileInfo() and then getting \c
- * name field of the QuaZipFileInfo structure, but faster and more
- * convenient.
- *
- * Should be used only in QuaZip::mdUnzip mode.
- **/
- QString getCurrentFileName()const;
- /// Returns \c unzFile handle.
- /** You can use this handle to directly call UNZIP part of the
- * ZIP/UNZIP package functions (see unzip.h).
- *
- * \warning When using the handle returned by this function, please
- * keep in mind that QuaZip class is unable to detect any changes
- * you make in the ZIP file state (e. g. changing current file, or
- * closing the handle). So please do not do anything with this
- * handle that is possible to do with the functions of this class.
- * Or at least return the handle in the original state before
- * calling some another function of this class (including implicit
- * destructor calls and calls from the QuaZipFile objects that refer
- * to this QuaZip instance!). So if you have changed the current
- * file in the ZIP archive - then change it back or you may
- * experience some strange behavior or even crashes.
- **/
- unzFile getUnzFile();
- /// Returns \c zipFile handle.
- /** You can use this handle to directly call ZIP part of the
- * ZIP/UNZIP package functions (see zip.h). Warnings about the
- * getUnzFile() function also apply to this function.
- **/
- zipFile getZipFile();
-};
-
-#endif
diff --git a/misc/quazip/quazip.pri b/misc/quazip/quazip.pri
deleted file mode 100644
index a402f28..0000000
--- a/misc/quazip/quazip.pri
+++ /dev/null
@@ -1,23 +0,0 @@
-INCLUDEPATH += $$PWD
-DEPENDPATH += $$PWD
-HEADERS += $$PWD/crypt.h \
- $$PWD/ioapi.h \
- $$PWD/JlCompress.h \
- $$PWD/quaadler32.h \
- $$PWD/quachecksum32.h \
- $$PWD/quacrc32.h \
- $$PWD/quazip.h \
- $$PWD/quazipfile.h \
- $$PWD/quazipfileinfo.h \
- $$PWD/quazipnewinfo.h \
- $$PWD/unzip.h \
- $$PWD/zip.h
-SOURCES += $$PWD/qioapi.cpp \
- $$PWD/JlCompress.cpp \
- $$PWD/quaadler32.cpp \
- $$PWD/quacrc32.cpp \
- $$PWD/quazip.cpp \
- $$PWD/quazipfile.cpp \
- $$PWD/quazipnewinfo.cpp \
- $$PWD/unzip.c \
- $$PWD/zip.c
diff --git a/misc/quazip/quazip.pro b/misc/quazip/quazip.pro
deleted file mode 100644
index 4f5173a..0000000
--- a/misc/quazip/quazip.pro
+++ /dev/null
@@ -1,77 +0,0 @@
-TEMPLATE = lib
-CONFIG += qt warn_on
-QT -= gui
-DEPENDPATH += .
-INCLUDEPATH += .
-
-# Input
-HEADERS += \
- crypt.h\
- ioapi.h\
- JlCompress.h\
- quaadler32.h\
- quachecksum32.h\
- quacrc32.h\
- quazip.h\
- quazipfile.h\
- quazipfileinfo.h\
- quazipnewinfo.h\
- quazip_global.h\
- unzip.h\
- zip.h\
-
-SOURCES += *.c *.cpp
-
-unix:!symbian {
- headers.path=$$PREFIX/include/quazip
- headers.files=$$HEADERS
- target.path=$$PREFIX/lib
- INSTALLS += headers target
-
- OBJECTS_DIR=.obj
- MOC_DIR=.moc
-
- LIBS += -lz
-}
-
-win32 {
- headers.path=$$PREFIX/include/quazip
- headers.files=$$HEADERS
- target.path=$$PREFIX/lib
- INSTALLS += headers target
-
- *-g++*: LIBS += -lz.dll
- *-msvc*: LIBS += -lzlib
- *-msvc*: QMAKE_LFLAGS += /IMPLIB:$$DESTDIR\\quazip.lib
-}
-
-
-symbian {
-
- # Note, on Symbian you may run into troubles with LGPL.
- # The point is, if your application uses some version of QuaZip,
- # and a newer binary compatible version of QuaZip is released, then
- # the users of your application must be able to relink it with the
- # new QuaZip version. For example, to take advantage of some QuaZip
- # bug fixes.
-
- # This is probably best achieved by building QuaZip as a static
- # library and providing linkable object files of your application,
- # so users can relink it.
-
- CONFIG += staticlib
- CONFIG += debug_and_release
-
- LIBS += -lezip
-
- #Export headers to SDK Epoc32/include directory
- exportheaders.sources = $$HEADERS
- exportheaders.path = quazip
- for(header, exportheaders.sources) {
- BLD_INF_RULES.prj_exports += "$$header $$exportheaders.path/$$basename(header)"
- }
-}
-
-
-
-DEFINES += QUAZIP_BUILD
diff --git a/misc/quazip/quazip_global.h b/misc/quazip/quazip_global.h
deleted file mode 100644
index de50210..0000000
--- a/misc/quazip/quazip_global.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- */
-
-#ifndef QUAZIP_GLOBAL_H
-#define QUAZIP_GLOBAL_H
-
-#include <QtCore/qglobal.h>
-/**
- * When building the library with MSVC, QUAZIP_BUILD must be defined.
- * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc.
- */
-
-#define QUAZIP_EXPORT
-
-#ifdef __GNUC__
-#define UNUSED __attribute__((__unused__))
-#else
-#define UNUSED
-#endif
-
-#endif // QUAZIP_GLOBAL_H
diff --git a/misc/quazip/quazipfile.cpp b/misc/quazip/quazipfile.cpp
deleted file mode 100644
index d422ad2..0000000
--- a/misc/quazip/quazipfile.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include "quazipfile.h"
-
-using namespace std;
-
-class QuaZipFilePrivate {
- friend class QuaZipFile;
- private:
- QuaZipFile *q;
- QuaZip *zip;
- QString fileName;
- QuaZip::CaseSensitivity caseSensitivity;
- bool raw;
- qint64 writePos;
- // these two are for writing raw files
- ulong uncompressedSize;
- quint32 crc;
- bool internal;
- int zipError;
- inline void resetZipError() const {setZipError(UNZ_OK);}
- // const, but sets zipError!
- void setZipError(int zipError) const;
- inline QuaZipFilePrivate(QuaZipFile *q):
- q(q), zip(NULL), internal(true), zipError(UNZ_OK) {}
- inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName):
- q(q), internal(true), zipError(UNZ_OK)
- {
- zip=new QuaZip(zipName);
- }
- inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName,
- QuaZip::CaseSensitivity cs):
- q(q), internal(true), zipError(UNZ_OK)
- {
- zip=new QuaZip(zipName);
- this->fileName=fileName;
- this->caseSensitivity=cs;
- }
- inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip):
- q(q), zip(zip), internal(false), zipError(UNZ_OK) {}
- inline ~QuaZipFilePrivate()
- {
- if (internal)
- delete zip;
- }
-};
-
-QuaZipFile::QuaZipFile():
- p(new QuaZipFilePrivate(this))
-{
-}
-
-QuaZipFile::QuaZipFile(QObject *parent):
- QIODevice(parent),
- p(new QuaZipFilePrivate(this))
-{
-}
-
-QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent):
- QIODevice(parent),
- p(new QuaZipFilePrivate(this, zipName))
-{
-}
-
-QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName,
- QuaZip::CaseSensitivity cs, QObject *parent):
- QIODevice(parent),
- p(new QuaZipFilePrivate(this, zipName, fileName, cs))
-{
-}
-
-QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent):
- QIODevice(parent),
- p(new QuaZipFilePrivate(this, zip))
-{
-}
-
-QuaZipFile::~QuaZipFile()
-{
- if (isOpen())
- close();
- delete p;
-}
-
-QString QuaZipFile::getZipName() const
-{
- return p->zip==NULL ? QString() : p->zip->getZipName();
-}
-
-QString QuaZipFile::getActualFileName()const
-{
- p->setZipError(UNZ_OK);
- if (p->zip == NULL || (openMode() & WriteOnly))
- return QString();
- QString name=p->zip->getCurrentFileName();
- if(name.isNull())
- p->setZipError(p->zip->getZipError());
- return name;
-}
-
-void QuaZipFile::setZipName(const QString& zipName)
-{
- if(isOpen()) {
- qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name");
- return;
- }
- if(p->zip!=NULL && p->internal)
- delete p->zip;
- p->zip=new QuaZip(zipName);
- p->internal=true;
-}
-
-void QuaZipFile::setZip(QuaZip *zip)
-{
- if(isOpen()) {
- qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP");
- return;
- }
- if(p->zip!=NULL && p->internal)
- delete p->zip;
- p->zip=zip;
- p->fileName=QString();
- p->internal=false;
-}
-
-void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs)
-{
- if(p->zip==NULL) {
- qWarning("QuaZipFile::setFileName(): call setZipName() first");
- return;
- }
- if(!p->internal) {
- qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip");
- return;
- }
- if(isOpen()) {
- qWarning("QuaZipFile::setFileName(): can not set file name for already opened file");
- return;
- }
- p->fileName=fileName;
- p->caseSensitivity=cs;
-}
-
-void QuaZipFilePrivate::setZipError(int zipError) const
-{
- QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
- fakeThis->zipError=zipError;
- if(zipError==UNZ_OK)
- q->setErrorString(QString());
- else
- q->setErrorString(q->tr("ZIP/UNZIP API error %1").arg(zipError));
-}
-
-bool QuaZipFile::open(OpenMode mode)
-{
- return open(mode, NULL);
-}
-
-bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password)
-{
- p->resetZipError();
- if(isOpen()) {
- qWarning("QuaZipFile::open(): already opened");
- return false;
- }
- if(mode&Unbuffered) {
- qWarning("QuaZipFile::open(): Unbuffered mode is not supported");
- return false;
- }
- if((mode&ReadOnly)&&!(mode&WriteOnly)) {
- if(p->internal) {
- if(!p->zip->open(QuaZip::mdUnzip)) {
- p->setZipError(p->zip->getZipError());
- return false;
- }
- if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) {
- p->setZipError(p->zip->getZipError());
- p->zip->close();
- return false;
- }
- } else {
- if(p->zip==NULL) {
- qWarning("QuaZipFile::open(): zip is NULL");
- return false;
- }
- if(p->zip->getMode()!=QuaZip::mdUnzip) {
- qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
- (int)mode, (int)p->zip->getMode());
- return false;
- }
- if(!p->zip->hasCurrentFile()) {
- qWarning("QuaZipFile::open(): zip does not have current file");
- return false;
- }
- }
- p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password));
- if(p->zipError==UNZ_OK) {
- setOpenMode(mode);
- p->raw=raw;
- return true;
- } else
- return false;
- }
- qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
- return false;
-}
-
-bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info,
- const char *password, quint32 crc,
- int method, int level, bool raw,
- int windowBits, int memLevel, int strategy)
-{
- zip_fileinfo info_z;
- p->resetZipError();
- if(isOpen()) {
- qWarning("QuaZipFile::open(): already opened");
- return false;
- }
- if((mode&WriteOnly)&&!(mode&ReadOnly)) {
- if(p->internal) {
- qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach");
- return false;
- }
- if(p->zip==NULL) {
- qWarning("QuaZipFile::open(): zip is NULL");
- return false;
- }
- if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) {
- qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d",
- (int)mode, (int)p->zip->getMode());
- return false;
- }
- info_z.tmz_date.tm_year=info.dateTime.date().year();
- info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1;
- info_z.tmz_date.tm_mday=info.dateTime.date().day();
- info_z.tmz_date.tm_hour=info.dateTime.time().hour();
- info_z.tmz_date.tm_min=info.dateTime.time().minute();
- info_z.tmz_date.tm_sec=info.dateTime.time().second();
- info_z.dosDate = 0;
- info_z.internal_fa=(uLong)info.internalAttr;
- info_z.external_fa=(uLong)info.externalAttr;
- p->setZipError(zipOpenNewFileInZip3(p->zip->getZipFile(),
- p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), &info_z,
- info.extraLocal.constData(), info.extraLocal.length(),
- info.extraGlobal.constData(), info.extraGlobal.length(),
- p->zip->getCommentCodec()->fromUnicode(info.comment).constData(),
- method, level, (int)raw,
- windowBits, memLevel, strategy,
- password, (uLong)crc));
- if(p->zipError==UNZ_OK) {
- p->writePos=0;
- setOpenMode(mode);
- p->raw=raw;
- if(raw) {
- p->crc=crc;
- p->uncompressedSize=info.uncompressedSize;
- }
- return true;
- } else
- return false;
- }
- qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode);
- return false;
-}
-
-bool QuaZipFile::isSequential()const
-{
- return true;
-}
-
-qint64 QuaZipFile::pos()const
-{
- if(p->zip==NULL) {
- qWarning("QuaZipFile::pos(): call setZipName() or setZip() first");
- return -1;
- }
- if(!isOpen()) {
- qWarning("QuaZipFile::pos(): file is not open");
- return -1;
- }
- if(openMode()&ReadOnly)
- return unztell(p->zip->getUnzFile());
- else
- return p->writePos;
-}
-
-bool QuaZipFile::atEnd()const
-{
- if(p->zip==NULL) {
- qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first");
- return false;
- }
- if(!isOpen()) {
- qWarning("QuaZipFile::atEnd(): file is not open");
- return false;
- }
- if(openMode()&ReadOnly)
- return unzeof(p->zip->getUnzFile())==1;
- else
- return true;
-}
-
-qint64 QuaZipFile::size()const
-{
- if(!isOpen()) {
- qWarning("QuaZipFile::atEnd(): file is not open");
- return -1;
- }
- if(openMode()&ReadOnly)
- return p->raw?csize():usize();
- else
- return p->writePos;
-}
-
-qint64 QuaZipFile::csize()const
-{
- unz_file_info info_z;
- p->setZipError(UNZ_OK);
- if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
- p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
- if(p->zipError!=UNZ_OK)
- return -1;
- return info_z.compressed_size;
-}
-
-qint64 QuaZipFile::usize()const
-{
- unz_file_info info_z;
- p->setZipError(UNZ_OK);
- if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return -1;
- p->setZipError(unzGetCurrentFileInfo(p->zip->getUnzFile(), &info_z, NULL, 0, NULL, 0, NULL, 0));
- if(p->zipError!=UNZ_OK)
- return -1;
- return info_z.uncompressed_size;
-}
-
-bool QuaZipFile::getFileInfo(QuaZipFileInfo *info)
-{
- if(p->zip==NULL||p->zip->getMode()!=QuaZip::mdUnzip) return false;
- p->zip->getCurrentFileInfo(info);
- p->setZipError(p->zip->getZipError());
- return p->zipError==UNZ_OK;
-}
-
-void QuaZipFile::close()
-{
- p->resetZipError();
- if(p->zip==NULL||!p->zip->isOpen()) return;
- if(!isOpen()) {
- qWarning("QuaZipFile::close(): file isn't open");
- return;
- }
- if(openMode()&ReadOnly)
- p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile()));
- else if(openMode()&WriteOnly)
- if(isRaw()) p->setZipError(zipCloseFileInZipRaw(p->zip->getZipFile(), p->uncompressedSize, p->crc));
- else p->setZipError(zipCloseFileInZip(p->zip->getZipFile()));
- else {
- qWarning("Wrong open mode: %d", (int)openMode());
- return;
- }
- if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen);
- else return;
- if(p->internal) {
- p->zip->close();
- p->setZipError(p->zip->getZipError());
- }
-}
-
-qint64 QuaZipFile::readData(char *data, qint64 maxSize)
-{
- p->setZipError(UNZ_OK);
- qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize);
- if(bytesRead<0) p->setZipError((int)bytesRead);
- return bytesRead;
-}
-
-qint64 QuaZipFile::writeData(const char* data, qint64 maxSize)
-{
- p->setZipError(ZIP_OK);
- p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize));
- if(p->zipError!=ZIP_OK) return -1;
- else {
- p->writePos+=maxSize;
- return maxSize;
- }
-}
-
-QString QuaZipFile::getFileName() const
-{
- return p->fileName;
-}
-
-QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const
-{
- return p->caseSensitivity;
-}
-
-bool QuaZipFile::isRaw() const
-{
- return p->raw;
-}
-
-int QuaZipFile::getZipError() const
-{
- return p->zipError;
-}
diff --git a/misc/quazip/quazipfile.h b/misc/quazip/quazipfile.h
deleted file mode 100644
index 62dc7ae..0000000
--- a/misc/quazip/quazipfile.h
+++ /dev/null
@@ -1,433 +0,0 @@
-#ifndef QUA_ZIPFILE_H
-#define QUA_ZIPFILE_H
-
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include <QIODevice>
-
-#include "quazip_global.h"
-#include "quazip.h"
-#include "quazipnewinfo.h"
-
-class QuaZipFilePrivate;
-
-/// A file inside ZIP archive.
-/** \class QuaZipFile quazipfile.h <quazip/quazipfile.h>
- * This is the most interesting class. Not only it provides C++
- * interface to the ZIP/UNZIP package, but also integrates it with Qt by
- * subclassing QIODevice. This makes possible to access files inside ZIP
- * archive using QTextStream or QDataStream, for example. Actually, this
- * is the main purpose of the whole QuaZIP library.
- *
- * You can either use existing QuaZip instance to create instance of
- * this class or pass ZIP archive file name to this class, in which case
- * it will create internal QuaZip object. See constructors' descriptions
- * for details. Writing is only possible with the existing instance.
- *
- * Note that due to the underlying library's limitation it is not
- * possible to use multiple QuaZipFile instances to open several files
- * in the same archive at the same time. If you need to write to
- * multiple files in parallel, then you should write to temporary files
- * first, then pack them all at once when you have finished writing. If
- * you need to read multiple files inside the same archive in parallel,
- * you should extract them all into a temporary directory first.
- *
- * \section quazipfile-sequential Sequential or random-access?
- *
- * At the first thought, QuaZipFile has fixed size, the start and the
- * end and should be therefore considered random-access device. But
- * there is one major obstacle to making it random-access: ZIP/UNZIP API
- * does not support seek() operation and the only way to implement it is
- * through reopening the file and re-reading to the required position,
- * but this is prohibitively slow.
- *
- * Therefore, QuaZipFile is considered to be a sequential device. This
- * has advantage of availability of the ungetChar() operation (QIODevice
- * does not implement it properly for non-sequential devices unless they
- * support seek()). Disadvantage is a somewhat strange behaviour of the
- * size() and pos() functions. This should be kept in mind while using
- * this class.
- *
- **/
-class QUAZIP_EXPORT QuaZipFile: public QIODevice {
- friend class QuaZipFilePrivate;
- Q_OBJECT
- private:
- QuaZipFilePrivate *p;
- // these are not supported nor implemented
- QuaZipFile(const QuaZipFile& that);
- QuaZipFile& operator=(const QuaZipFile& that);
- protected:
- /// Implementation of the QIODevice::readData().
- qint64 readData(char *data, qint64 maxSize);
- /// Implementation of the QIODevice::writeData().
- qint64 writeData(const char *data, qint64 maxSize);
- public:
- /// Constructs a QuaZipFile instance.
- /** You should use setZipName() and setFileName() or setZip() before
- * trying to call open() on the constructed object.
- **/
- QuaZipFile();
- /// Constructs a QuaZipFile instance.
- /** \a parent argument specifies this object's parent object.
- *
- * You should use setZipName() and setFileName() or setZip() before
- * trying to call open() on the constructed object.
- **/
- QuaZipFile(QObject *parent);
- /// Constructs a QuaZipFile instance.
- /** \a parent argument specifies this object's parent object and \a
- * zipName specifies ZIP archive file name.
- *
- * You should use setFileName() before trying to call open() on the
- * constructed object.
- *
- * QuaZipFile constructed by this constructor can be used for read
- * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
- **/
- QuaZipFile(const QString& zipName, QObject *parent =NULL);
- /// Constructs a QuaZipFile instance.
- /** \a parent argument specifies this object's parent object, \a
- * zipName specifies ZIP archive file name and \a fileName and \a cs
- * specify a name of the file to open inside archive.
- *
- * QuaZipFile constructed by this constructor can be used for read
- * only access. Use QuaZipFile(QuaZip*,QObject*) for writing.
- *
- * \sa QuaZip::setCurrentFile()
- **/
- QuaZipFile(const QString& zipName, const QString& fileName,
- QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =NULL);
- /// Constructs a QuaZipFile instance.
- /** \a parent argument specifies this object's parent object.
- *
- * \a zip is the pointer to the existing QuaZip object. This
- * QuaZipFile object then can be used to read current file in the
- * \a zip or to write to the file inside it.
- *
- * \warning Using this constructor for reading current file can be
- * tricky. Let's take the following example:
- * \code
- * QuaZip zip("archive.zip");
- * zip.open(QuaZip::mdUnzip);
- * zip.setCurrentFile("file-in-archive");
- * QuaZipFile file(&zip);
- * file.open(QIODevice::ReadOnly);
- * // ok, now we can read from the file
- * file.read(somewhere, some);
- * zip.setCurrentFile("another-file-in-archive"); // oops...
- * QuaZipFile anotherFile(&zip);
- * anotherFile.open(QIODevice::ReadOnly);
- * anotherFile.read(somewhere, some); // this is still ok...
- * file.read(somewhere, some); // and this is NOT
- * \endcode
- * So, what exactly happens here? When we change current file in the
- * \c zip archive, \c file that references it becomes invalid
- * (actually, as far as I understand ZIP/UNZIP sources, it becomes
- * closed, but QuaZipFile has no means to detect it).
- *
- * Summary: do not close \c zip object or change its current file as
- * long as QuaZipFile is open. Even better - use another constructors
- * which create internal QuaZip instances, one per object, and
- * therefore do not cause unnecessary trouble. This constructor may
- * be useful, though, if you already have a QuaZip instance and do
- * not want to access several files at once. Good example:
- * \code
- * QuaZip zip("archive.zip");
- * zip.open(QuaZip::mdUnzip);
- * // first, we need some information about archive itself
- * QByteArray comment=zip.getComment();
- * // and now we are going to access files inside it
- * QuaZipFile file(&zip);
- * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) {
- * file.open(QIODevice::ReadOnly);
- * // do something cool with file here
- * file.close(); // do not forget to close!
- * }
- * zip.close();
- * \endcode
- **/
- QuaZipFile(QuaZip *zip, QObject *parent =NULL);
- /// Destroys a QuaZipFile instance.
- /** Closes file if open, destructs internal QuaZip object (if it
- * exists and \em is internal, of course).
- **/
- virtual ~QuaZipFile();
- /// Returns the ZIP archive file name.
- /** If this object was created by passing QuaZip pointer to the
- * constructor, this function will return that QuaZip's file name
- * (or null string if that object does not have file name yet).
- *
- * Otherwise, returns associated ZIP archive file name or null
- * string if there are no name set yet.
- *
- * \sa setZipName() getFileName()
- **/
- QString getZipName()const;
- /// Returns a pointer to the associated QuaZip object.
- /** Returns \c NULL if there is no associated QuaZip or it is
- * internal (so you will not mess with it).
- **/
- QuaZip* getZip()const;
- /// Returns file name.
- /** This function returns file name you passed to this object either
- * by using
- * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
- * or by calling setFileName(). Real name of the file may differ in
- * case if you used case-insensitivity.
- *
- * Returns null string if there is no file name set yet. This is the
- * case when this QuaZipFile operates on the existing QuaZip object
- * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used).
- *
- * \sa getActualFileName
- **/
- QString getFileName() const;
- /// Returns case sensitivity of the file name.
- /** This function returns case sensitivity argument you passed to
- * this object either by using
- * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*)
- * or by calling setFileName().
- *
- * Returns unpredictable value if getFileName() returns null string
- * (this is the case when you did not used setFileName() or
- * constructor above).
- *
- * \sa getFileName
- **/
- QuaZip::CaseSensitivity getCaseSensitivity() const;
- /// Returns the actual file name in the archive.
- /** This is \em not a ZIP archive file name, but a name of file inside
- * archive. It is not necessary the same name that you have passed
- * to the
- * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*),
- * setFileName() or QuaZip::setCurrentFile() - this is the real file
- * name inside archive, so it may differ in case if the file name
- * search was case-insensitive.
- *
- * Equivalent to calling getCurrentFileName() on the associated
- * QuaZip object. Returns null string if there is no associated
- * QuaZip object or if it does not have a current file yet. And this
- * is the case if you called setFileName() but did not open the
- * file yet. So this is perfectly fine:
- * \code
- * QuaZipFile file("somezip.zip");
- * file.setFileName("somefile");
- * QString name=file.getName(); // name=="somefile"
- * QString actual=file.getActualFileName(); // actual is null string
- * file.open(QIODevice::ReadOnly);
- * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows
- * \endcode
- *
- * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity
- **/
- QString getActualFileName()const;
- /// Sets the ZIP archive file name.
- /** Automatically creates internal QuaZip object and destroys
- * previously created internal QuaZip object, if any.
- *
- * Will do nothing if this file is already open. You must close() it
- * first.
- **/
- void setZipName(const QString& zipName);
- /// Returns \c true if the file was opened in raw mode.
- /** If the file is not open, the returned value is undefined.
- *
- * \sa open(OpenMode,int*,int*,bool,const char*)
- **/
- bool isRaw() const;
- /// Binds to the existing QuaZip instance.
- /** This function destroys internal QuaZip object, if any, and makes
- * this QuaZipFile to use current file in the \a zip object for any
- * further operations. See QuaZipFile(QuaZip*,QObject*) for the
- * possible pitfalls.
- *
- * Will do nothing if the file is currently open. You must close()
- * it first.
- **/
- void setZip(QuaZip *zip);
- /// Sets the file name.
- /** Will do nothing if at least one of the following conditions is
- * met:
- * - ZIP name has not been set yet (getZipName() returns null
- * string).
- * - This QuaZipFile is associated with external QuaZip. In this
- * case you should call that QuaZip's setCurrentFile() function
- * instead!
- * - File is already open so setting the name is meaningless.
- *
- * \sa QuaZip::setCurrentFile
- **/
- void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault);
- /// Opens a file for reading.
- /** Returns \c true on success, \c false otherwise.
- * Call getZipError() to get error code.
- *
- * \note Since ZIP/UNZIP API provides buffered reading only,
- * QuaZipFile does not support unbuffered reading. So do not pass
- * QIODevice::Unbuffered flag in \a mode, or open will fail.
- **/
- virtual bool open(OpenMode mode);
- /// Opens a file for reading.
- /** \overload
- * Argument \a password specifies a password to decrypt the file. If
- * it is NULL then this function behaves just like open(OpenMode).
- **/
- inline bool open(OpenMode mode, const char *password)
- {return open(mode, NULL, NULL, false, password);}
- /// Opens a file for reading.
- /** \overload
- * Argument \a password specifies a password to decrypt the file.
- *
- * An integers pointed by \a method and \a level will receive codes
- * of the compression method and level used. See unzip.h.
- *
- * If raw is \c true then no decompression is performed.
- *
- * \a method should not be \c NULL. \a level can be \c NULL if you
- * don't want to know the compression level.
- **/
- bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =NULL);
- /// Opens a file for writing.
- /** \a info argument specifies information about file. It should at
- * least specify a correct file name. Also, it is a good idea to
- * specify correct timestamp (by default, current time will be
- * used). See QuaZipNewInfo.
- *
- * Arguments \a password and \a crc provide necessary information
- * for crypting. Note that you should specify both of them if you
- * need crypting. If you do not, pass \c NULL as password, but you
- * still need to specify \a crc if you are going to use raw mode
- * (see below).
- *
- * Arguments \a method and \a level specify compression method and
- * level.
- *
- * If \a raw is \c true, no compression is performed. In this case,
- * \a crc and uncompressedSize field of the \a info are required.
- *
- * Arguments \a windowBits, \a memLevel, \a strategy provide zlib
- * algorithms tuning. See deflateInit2() in zlib.
- **/
- bool open(OpenMode mode, const QuaZipNewInfo& info,
- const char *password =NULL, quint32 crc =0,
- int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false,
- int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY);
- /// Returns \c true, but \ref quazipfile-sequential "beware"!
- virtual bool isSequential()const;
- /// Returns current position in the file.
- /** Implementation of the QIODevice::pos(). When reading, this
- * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is
- * unable to keep track of the ungetChar() calls (which is
- * non-virtual and therefore is dangerous to reimplement). So if you
- * are using ungetChar() feature of the QIODevice, this function
- * reports incorrect value until you get back characters which you
- * ungot.
- *
- * When writing, pos() returns number of bytes already written
- * (uncompressed unless you use raw mode).
- *
- * \note Although
- * \ref quazipfile-sequential "QuaZipFile is a sequential device"
- * and therefore pos() should always return zero, it does not,
- * because it would be misguiding. Keep this in mind.
- *
- * This function returns -1 if the file or archive is not open.
- *
- * Error code returned by getZipError() is not affected by this
- * function call.
- **/
- virtual qint64 pos()const;
- /// Returns \c true if the end of file was reached.
- /** This function returns \c false in the case of error. This means
- * that you called this function on either not open file, or a file
- * in the not open archive or even on a QuaZipFile instance that
- * does not even have QuaZip instance associated. Do not do that
- * because there is no means to determine whether \c false is
- * returned because of error or because end of file was reached.
- * Well, on the other side you may interpret \c false return value
- * as "there is no file open to check for end of file and there is
- * no end of file therefore".
- *
- * When writing, this function always returns \c true (because you
- * are always writing to the end of file).
- *
- * Error code returned by getZipError() is not affected by this
- * function call.
- **/
- virtual bool atEnd()const;
- /// Returns file size.
- /** This function returns csize() if the file is open for reading in
- * raw mode, usize() if it is open for reading in normal mode and
- * pos() if it is open for writing.
- *
- * Returns -1 on error, call getZipError() to get error code.
- *
- * \note This function returns file size despite that
- * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device",
- * for which size() should return bytesAvailable() instead. But its
- * name would be very misguiding otherwise, so just keep in mind
- * this inconsistence.
- **/
- virtual qint64 size()const;
- /// Returns compressed file size.
- /** Equivalent to calling getFileInfo() and then getting
- * compressedSize field, but more convenient and faster.
- *
- * File must be open for reading before calling this function.
- *
- * Returns -1 on error, call getZipError() to get error code.
- **/
- qint64 csize()const;
- /// Returns uncompressed file size.
- /** Equivalent to calling getFileInfo() and then getting
- * uncompressedSize field, but more convenient and faster. See
- * getFileInfo() for a warning.
- *
- * File must be open for reading before calling this function.
- *
- * Returns -1 on error, call getZipError() to get error code.
- **/
- qint64 usize()const;
- /// Gets information about current file.
- /** This function does the same thing as calling
- * QuaZip::getCurrentFileInfo() on the associated QuaZip object,
- * but you can not call getCurrentFileInfo() if the associated
- * QuaZip is internal (because you do not have access to it), while
- * you still can call this function in that case.
- *
- * File must be open for reading before calling this function.
- *
- * Returns \c false in the case of an error.
- **/
- bool getFileInfo(QuaZipFileInfo *info);
- /// Closes the file.
- /** Call getZipError() to determine if the close was successful.
- **/
- virtual void close();
- /// Returns the error code returned by the last ZIP/UNZIP API call.
- int getZipError() const;
-};
-
-#endif
diff --git a/misc/quazip/quazipfileinfo.h b/misc/quazip/quazipfileinfo.h
deleted file mode 100644
index 9954022..0000000
--- a/misc/quazip/quazipfileinfo.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef QUA_ZIPFILEINFO_H
-#define QUA_ZIPFILEINFO_H
-
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include <QByteArray>
-#include <QDateTime>
-
-#include "quazip_global.h"
-
-/// Information about a file inside archive.
-/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to
- * fill this structure. */
-struct QUAZIP_EXPORT QuaZipFileInfo {
- /// File name.
- QString name;
- /// Version created by.
- quint16 versionCreated;
- /// Version needed to extract.
- quint16 versionNeeded;
- /// General purpose flags.
- quint16 flags;
- /// Compression method.
- quint16 method;
- /// Last modification date and time.
- QDateTime dateTime;
- /// CRC.
- quint32 crc;
- /// Compressed file size.
- quint32 compressedSize;
- /// Uncompressed file size.
- quint32 uncompressedSize;
- /// Disk number start.
- quint16 diskNumberStart;
- /// Internal file attributes.
- quint16 internalAttr;
- /// External file attributes.
- quint32 externalAttr;
- /// Comment.
- QString comment;
- /// Extra field.
- QByteArray extra;
-};
-
-#endif
diff --git a/misc/quazip/quazipnewinfo.cpp b/misc/quazip/quazipnewinfo.cpp
deleted file mode 100644
index ed57e09..0000000
--- a/misc/quazip/quazipnewinfo.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
-*/
-
-#include <QFileInfo>
-
-#include "quazipnewinfo.h"
-
-
-QuaZipNewInfo::QuaZipNewInfo(const QString& name):
- name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0)
-{
-}
-
-QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file):
- name(name), internalAttr(0), externalAttr(0)
-{
- QFileInfo info(file);
- QDateTime lm = info.lastModified();
- if (!info.exists())
- dateTime = QDateTime::currentDateTime();
- else
- dateTime = lm;
-}
-
-void QuaZipNewInfo::setFileDateTime(const QString& file)
-{
- QFileInfo info(file);
- QDateTime lm = info.lastModified();
- if (info.exists())
- dateTime = lm;
-}
diff --git a/misc/quazip/quazipnewinfo.h b/misc/quazip/quazipnewinfo.h
deleted file mode 100644
index 62159ea..0000000
--- a/misc/quazip/quazipnewinfo.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef QUA_ZIPNEWINFO_H
-#define QUA_ZIPNEWINFO_H
-
-/*
-Copyright (C) 2005-2011 Sergey A. Tachenov
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-General Public License for more details.
-
-You should have received a copy of the GNU Lesser 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
-
-See COPYING file for the full LGPL text.
-
-Original ZIP package is copyrighted by Gilles Vollant, see
-quazip/(un)zip.h files for details, basically it's zlib license.
- **/
-
-#include <QDateTime>
-#include <QString>
-
-#include "quazip_global.h"
-
-/// Information about a file to be created.
-/** This structure holds information about a file to be created inside
- * ZIP archive. At least name should be set to something correct before
- * passing this structure to
- * QuaZipFile::open(OpenMode,const QuaZipNewInfo&,int,int,bool).
- **/
-struct QUAZIP_EXPORT QuaZipNewInfo {
- /// File name.
- /** This field holds file name inside archive, including path relative
- * to archive root.
- **/
- QString name;
- /// File timestamp.
- /** This is the last file modification date and time. Will be stored
- * in the archive central directory. It is a good practice to set it
- * to the source file timestamp instead of archive creating time. Use
- * setFileDateTime() or QuaZipNewInfo(const QString&, const QString&).
- **/
- QDateTime dateTime;
- /// File internal attributes.
- quint16 internalAttr;
- /// File external attributes.
- quint32 externalAttr;
- /// File comment.
- /** Will be encoded using QuaZip::getCommentCodec().
- **/
- QString comment;
- /// File local extra field.
- QByteArray extraLocal;
- /// File global extra field.
- QByteArray extraGlobal;
- /// Uncompressed file size.
- /** This is only needed if you are using raw file zipping mode, i. e.
- * adding precompressed file in the zip archive.
- **/
- ulong uncompressedSize;
- /// Constructs QuaZipNewInfo instance.
- /** Initializes name with \a name, dateTime with current date and
- * time. Attributes are initialized with zeros, comment and extra
- * field with null values.
- **/
- QuaZipNewInfo(const QString& name);
- /// Constructs QuaZipNewInfo instance.
- /** Initializes name with \a name and dateTime with timestamp of the
- * file named \a file. If the \a file does not exists or its timestamp
- * is inaccessible (e. g. you do not have read permission for the
- * directory file in), uses current date and time. Attributes are
- * initialized with zeros, comment and extra field with null values.
- *
- * \sa setFileDateTime()
- **/
- QuaZipNewInfo(const QString& name, const QString& file);
- /// Sets the file timestamp from the existing file.
- /** Use this function to set the file timestamp from the existing
- * file. Use it like this:
- * \code
- * QuaZipFile zipFile(&zip);
- * QFile file("file-to-add");
- * file.open(QIODevice::ReadOnly);
- * QuaZipNewInfo info("file-name-in-archive");
- * info.setFileDateTime("file-to-add"); // take the timestamp from file
- * zipFile.open(QIODevice::WriteOnly, info);
- * \endcode
- *
- * This function does not change dateTime if some error occured (e. g.
- * file is inaccessible).
- **/
- void setFileDateTime(const QString& file);
-};
-
-#endif
diff --git a/misc/quazip/unzip.c b/misc/quazip/unzip.c
deleted file mode 100644
index 4ab1bd3..0000000
--- a/misc/quazip/unzip.c
+++ /dev/null
@@ -1,1603 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read unzip.h for more info
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
-
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
- crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-# define CASESENSITIVITYDEFAULT_NO
-# endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
- " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- int raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
- int encrypted;
-# ifndef NOUNCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
-# endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
- "zlib/zlib114.zip".
- If the zipfile cannot be opened (file doesn't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (file, pzlib_filefunc_def)
- voidpf file;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- if (pzlib_filefunc_def==NULL)
- fill_qiodevice_filefunc(&us.z_filefunc);
- else
- us.z_filefunc = *pzlib_filefunc_def;
-
- us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
- file,
- ZLIB_FILEFUNC_MODE_READ |
- ZLIB_FILEFUNC_MODE_EXISTING);
- if (us.filestream==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (ZSEEK(us.z_filefunc, us.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
- (err==UNZ_OK))
- err=UNZ_BADZIPFILE;
-
- if (err!=UNZ_OK)
- {
- ZCLOSE(us.z_filefunc, us.filestream);
- return NULL;
- }
-
- us.byte_before_the_zipfile = central_pos -
- (us.offset_central_dir+us.size_central_dir);
- us.central_pos = central_pos;
- us.pfile_in_zip_read = NULL;
- us.encrypted = 0;
-
-
- s=(unz_s*)ALLOC(sizeof(unz_s));
- *s=us;
- unzGoToFirstFile((unzFile)s);
- return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen (file)
- voidpf file;
-{
- return unzOpen2(file, NULL);
-}
-
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
- unzFile file;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- if (s->pfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- ZCLOSE(s->z_filefunc, s->filestream);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- uLong uSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pos_in_central_dir+s->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK) {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x02014b50)
- err=UNZ_BADZIPFILE;
- }
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- uSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
- }
- else
- uSizeRead = fileNameBufferSize;
-
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- uSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extra<extraFieldBufferSize)
- uSizeRead = file_info.size_file_extra;
- else
- uSizeRead = extraFieldBufferSize;
-
- if (uSeek!=0) {
- if (ZSEEK(s->z_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- uSeek=0;
- else
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- uSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- uSeek+=file_info.size_file_extra;
-
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
- *(szComment+file_info.size_file_comment)='\0';
- uSizeRead = file_info.size_file_comment;
- }
- else
- uSizeRead = commentBufferSize;
-
- if (uSeek!=0) {
- if (ZSEEK(s->z_filefunc, s->filestream,uSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- uSeek=0;
- else
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- uSeek+=file_info.size_file_comment - uSizeRead;
- }
- else
- uSeek+=file_info.size_file_comment;
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
- /* We remember the 'current' position in the file so that we can jump
- * back there if we fail.
- */
- unz_file_info cur_file_infoSaved;
- unz_file_info_internal cur_file_info_internalSaved;
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- /* Save the current state */
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
- cur_file_infoSaved = s->cur_file_info;
- cur_file_info_internalSaved = s->cur_file_info_internal;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- err = unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (err == UNZ_OK)
- {
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
- }
-
- /* We failed, so restore the state of the 'current file' to where we
- * were.
- */
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- s->cur_file_info = cur_file_infoSaved;
- s->cur_file_info_internal = cur_file_info_internalSaved;
- return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; // offset in file
- uLong num_of_file; // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- file_pos->pos_in_zip_directory = s->pos_in_central_dir;
- file_pos->num_of_file = s->num_file;
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- /* jump to the right spot */
- s->pos_in_central_dir = file_pos->pos_in_zip_directory;
- s->num_file = file_pos->num_of_file;
-
- /* set the current file */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- /* return results */
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK) {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
- }
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
- unzFile file;
- int* method;
- int* level;
- int raw;
- const char* password;
-{
- int err=UNZ_OK;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-# ifndef NOUNCRYPT
- char source[12];
-# else
- if (password != NULL)
- return UNZ_PARAMERROR;
-# endif
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
- pfile_in_zip_read_info->raw=raw;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if (method!=NULL)
- *method = (int)s->cur_file_info.compression_method;
-
- if (level!=NULL)
- {
- *level = 6;
- switch (s->cur_file_info.flag & 0x06)
- {
- case 6 : *level = 1; break;
- case 4 : *level = 2; break;
- case 2 : *level = 9; break;
- }
- }
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->filestream=s->filestream;
- pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
- (!raw))
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
- pfile_in_zip_read_info->stream.next_in = (voidpf)0;
- pfile_in_zip_read_info->stream.avail_in = 0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- else
- {
- TRYFREE(pfile_in_zip_read_info);
- return err;
- }
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-# ifndef NOUNCRYPT
- if (password != NULL)
- {
- int i;
- s->pcrc_32_tab = get_crc_table();
- init_keys(password,s->keys,s->pcrc_32_tab);
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pfile_in_zip_read->pos_in_zipfile +
- s->pfile_in_zip_read->byte_before_the_zipfile,
- SEEK_SET)!=0)
- return UNZ_INTERNALERROR;
- if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
- return UNZ_INTERNALERROR;
-
- for (i = 0; i<12; i++)
- zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
- s->pfile_in_zip_read->pos_in_zipfile+=12;
- s->encrypted=1;
- }
-# endif
-
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
- unzFile file;
- const char* password;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
- unzFile file;
- int* method;
- int* level;
- int raw;
-{
- return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->read_buffer == NULL))
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
- (!(pfile_in_zip_read_info->raw)))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- if ((len>pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in) &&
- (pfile_in_zip_read_info->raw))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
- uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->read_buffer,
- uReadThis)!=uReadThis)
- return UNZ_ERRNO;
-
-
-# ifndef NOUNCRYPT
- if(s->encrypted)
- {
- uInt i;
- for(i=0;i<uReadThis;i++)
- pfile_in_zip_read_info->read_buffer[i] =
- zdecode(s->keys,s->pcrc_32_tab,
- pfile_in_zip_read_info->read_buffer[i]);
- }
-# endif
-
-
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
- {
- uInt uDoCopy,i ;
-
- if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- return (iRead==0) ? UNZ_EOF : iRead;
-
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;i<uDoCopy;i++)
- *(pfile_in_zip_read_info->stream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
- err = Z_DATA_ERROR;
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- buf,read_now)!=read_now)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
- (!pfile_in_zip_read_info->raw))
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern uLong ZEXPORT unzGetOffset (file)
- unzFile file;
-{
- unz_s* s;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return 0;
- if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
- if (s->num_file==s->gi.number_entry)
- return 0;
- return s->pos_in_central_dir;
-}
-
-extern int ZEXPORT unzSetOffset (file, pos)
- unzFile file;
- uLong pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- s->pos_in_central_dir = pos;
- s->num_file = s->gi.number_entry; /* hack */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
diff --git a/misc/quazip/unzip.h b/misc/quazip/unzip.h
deleted file mode 100644
index 33c9dc1..0000000
--- a/misc/quazip/unzip.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
-
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
-
-
- I WAIT FEEDBACK at mail info at winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _unz_H
-#define _unz_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
-typedef unzFile__ *unzFile;
-#else
-typedef voidp unzFile;
-#endif
-
-
-#define UNZ_OK (0)
-#define UNZ_END_OF_LIST_OF_FILE (-100)
-#define UNZ_ERRNO (Z_ERRNO)
-#define UNZ_EOF (0)
-#define UNZ_PARAMERROR (-102)
-#define UNZ_BADZIPFILE (-103)
-#define UNZ_INTERNALERROR (-104)
-#define UNZ_CRCERROR (-105)
-
-/* tm_unz contain date/time info */
-typedef struct tm_unz_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_unz;
-
-/* unz_global_info structure contain global data about the ZIPfile
- These data comes from the end of central dir */
-typedef struct unz_global_info_s
-{
- uLong number_entry; /* total number of entries in
- the central dir on this disk */
- uLong size_comment; /* size of the global comment of the zipfile */
-} unz_global_info;
-
-
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_info_s
-{
- uLong version; /* version made by 2 bytes */
- uLong version_needed; /* version needed to extract 2 bytes */
- uLong flag; /* general purpose bit flag 2 bytes */
- uLong compression_method; /* compression method 2 bytes */
- uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
- uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
- uLong size_filename; /* filename length 2 bytes */
- uLong size_file_extra; /* extra field length 2 bytes */
- uLong size_file_comment; /* file comment length 2 bytes */
-
- uLong disk_num_start; /* disk number start 2 bytes */
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-
- tm_unz tmu_date;
-} unz_file_info;
-
-extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
- const char* fileName2,
- int iCaseSensitivity));
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-*/
-
-
-extern unzFile ZEXPORT unzOpen OF((voidpf file));
-/*
- Open a Zip file. path contain whatever zopen_file from the IO API
- accepts. For Qt implementation it is a pointer to QIODevice, for
- fopen() implementation it's a file name.
- If the zipfile cannot be opened (file don't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-
-extern unzFile ZEXPORT unzOpen2 OF((voidpf file,
- zlib_filefunc_def* pzlib_filefunc_def));
-/*
- Open a Zip file, like unzOpen, but provide a set of file low level API
- for read/write the zip file (see ioapi.h)
-*/
-
-extern int ZEXPORT unzClose OF((unzFile file));
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-
-extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
- unz_global_info *pglobal_info));
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-
-
-extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
- char *szComment,
- uLong uSizeBuf));
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-
-
-/***************************************************************************/
-/* Unzip package allow you browse the directory of the zipfile */
-
-extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-
-extern int ZEXPORT unzGoToNextFile OF((unzFile file));
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-
-extern int ZEXPORT unzLocateFile OF((unzFile file,
- const char *szFileName,
- int iCaseSensitivity));
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-
-
-/* ****************************************** */
-/* Ryan supplied functions */
-/* unz_file_info contain information about a file in the zipfile */
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; /* offset in zip file directory */
- uLong num_of_file; /* # of file */
-} unz_file_pos;
-
-extern int ZEXPORT unzGetFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-extern int ZEXPORT unzGoToFilePos(
- unzFile file,
- unz_file_pos* file_pos);
-
-/* ****************************************** */
-
-extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
- unz_file_info *pfile_info,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-/*
- Get Info about the current file
- if pfile_info!=NULL, the *pfile_info structure will contain somes info about
- the current file
- if szFileName!=NULL, the filemane string will be copied in szFileName
- (fileNameBufferSize is the size of the buffer)
- if extraField!=NULL, the extra field information will be copied in extraField
- (extraFieldBufferSize is the size of the buffer).
- This is the Central-header version of the extra field
- if szComment!=NULL, the comment string of the file will be copied in szComment
- (commentBufferSize is the size of the buffer)
-*/
-
-/***************************************************************************/
-/* for reading the content of the current zipfile, you can open it, read data
- from it, and close it (you can close it before reading all the file)
- */
-
-extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
-/*
- Open for reading data the current file in the zipfile.
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
- const char* password));
-/*
- Open for reading data the current file in the zipfile.
- password is a crypting password
- If there is no error, the return value is UNZ_OK.
-*/
-
-extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
- int* method,
- int* level,
- int raw));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
- int* method,
- int* level,
- int raw,
- const char* password));
-/*
- Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
- if raw==1
- *method will receive method of compression, *level will receive level of
- compression
- note : you can set level parameter as NULL (if you did not want known level,
- but you CANNOT set method parameter as NULL
-*/
-
-
-extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
-/*
- Close the file in zip opened with unzOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read bytes from the current file (opened by unzOpenCurrentFile)
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-
-extern z_off_t ZEXPORT unztell OF((unzFile file));
-/*
- Give the current position in uncompressed data
-*/
-
-extern int ZEXPORT unzeof OF((unzFile file));
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-
-extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
- voidp buf,
- unsigned len));
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-
-/***************************************************************************/
-
-/* Get the current file offset */
-extern uLong ZEXPORT unzGetOffset (unzFile file);
-
-/* Set the current file offset */
-extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _unz_H */
diff --git a/misc/quazip/zconf.h b/misc/quazip/zconf.h
deleted file mode 100644
index 03a9431..0000000
--- a/misc/quazip/zconf.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef ZCONF_H
-#define ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-# define deflateInit_ z_deflateInit_
-# define deflate z_deflate
-# define deflateEnd z_deflateEnd
-# define inflateInit_ z_inflateInit_
-# define inflate z_inflate
-# define inflateEnd z_inflateEnd
-# define deflateInit2_ z_deflateInit2_
-# define deflateSetDictionary z_deflateSetDictionary
-# define deflateCopy z_deflateCopy
-# define deflateReset z_deflateReset
-# define deflateParams z_deflateParams
-# define deflateBound z_deflateBound
-# define deflatePrime z_deflatePrime
-# define inflateInit2_ z_inflateInit2_
-# define inflateSetDictionary z_inflateSetDictionary
-# define inflateSync z_inflateSync
-# define inflateSyncPoint z_inflateSyncPoint
-# define inflateCopy z_inflateCopy
-# define inflateReset z_inflateReset
-# define inflateBack z_inflateBack
-# define inflateBackEnd z_inflateBackEnd
-# define compress z_compress
-# define compress2 z_compress2
-# define compressBound z_compressBound
-# define uncompress z_uncompress
-# define adler32 z_adler32
-# define crc32 z_crc32
-# define get_crc_table z_get_crc_table
-# define zError z_zError
-
-# define alloc_func z_alloc_func
-# define free_func z_free_func
-# define in_func z_in_func
-# define out_func z_out_func
-# define Byte z_Byte
-# define uInt z_uInt
-# define uLong z_uLong
-# define Bytef z_Bytef
-# define charf z_charf
-# define intf z_intf
-# define uIntf z_uIntf
-# define uLongf z_uLongf
-# define voidpf z_voidpf
-# define voidp z_voidp
-#endif
-
-#if defined(__MSDOS__) && !defined(MSDOS)
-# define MSDOS
-#endif
-#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
-# define OS2
-#endif
-#if defined(_WINDOWS) && !defined(WINDOWS)
-# define WINDOWS
-#endif
-#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
-# ifndef WIN32
-# define WIN32
-# endif
-#endif
-#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
-# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
-# ifndef SYS16BIT
-# define SYS16BIT
-# endif
-# endif
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#ifdef SYS16BIT
-# define MAXSEG_64K
-#endif
-#ifdef MSDOS
-# define UNALIGNED_OK
-#endif
-
-#ifdef __STDC_VERSION__
-# ifndef STDC
-# define STDC
-# endif
-# if __STDC_VERSION__ >= 199901L
-# ifndef STDC99
-# define STDC99
-# endif
-# endif
-#endif
-#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
-# define STDC
-#endif
-#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
-# define STDC
-#endif
-
-#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
-# define STDC
-#endif
-
-#ifndef STDC
-# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-# define const /* note: need a more gentle solution here */
-# endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
-# define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- (1 << (windowBits+2)) + (1 << (memLevel+9))
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#ifdef SYS16BIT
-# if defined(M_I86SM) || defined(M_I86MM)
- /* MSC small or medium model */
-# define SMALL_MEDIUM
-# ifdef _MSC_VER
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-# if (defined(__SMALL__) || defined(__MEDIUM__))
- /* Turbo C small or medium model */
-# define SMALL_MEDIUM
-# ifdef __BORLANDC__
-# define FAR _far
-# else
-# define FAR far
-# endif
-# endif
-#endif
-
-#if defined(WINDOWS) || defined(WIN32)
- /* If building or using zlib as a DLL, define ZLIB_DLL.
- * This is not mandatory, but it offers a little performance increase.
- */
-# ifdef ZLIB_DLL
-# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
-# ifdef ZLIB_INTERNAL
-# define ZEXTERN extern __declspec(dllexport)
-# else
-# define ZEXTERN extern __declspec(dllimport)
-# endif
-# endif
-# endif /* ZLIB_DLL */
- /* If building or using zlib with the WINAPI/WINAPIV calling convention,
- * define ZLIB_WINAPI.
- * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
- */
-# ifdef ZLIB_WINAPI
-# ifdef FAR
-# undef FAR
-# endif
-# include <windows.h>
- /* No need for _export, use ZLIB.DEF instead. */
- /* For complete Windows compatibility, use WINAPI, not __stdcall. */
-# define ZEXPORT WINAPI
-# ifdef WIN32
-# define ZEXPORTVA WINAPIV
-# else
-# define ZEXPORTVA FAR CDECL
-# endif
-# endif
-#endif
-
-#if defined (__BEOS__)
-# ifdef ZLIB_DLL
-# ifdef ZLIB_INTERNAL
-# define ZEXPORT __declspec(dllexport)
-# define ZEXPORTVA __declspec(dllexport)
-# else
-# define ZEXPORT __declspec(dllimport)
-# define ZEXPORTVA __declspec(dllimport)
-# endif
-# endif
-#endif
-
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-#if !defined(__MACTYPES__)
-typedef unsigned char Byte; /* 8 bits */
-#endif
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-#ifdef SMALL_MEDIUM
- /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-# define Bytef Byte FAR
-#else
- typedef Byte FAR Bytef;
-#endif
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void const *voidpc;
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte const *voidpc;
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
-# include <sys/types.h> /* for off_t */
-# include <unistd.h> /* for SEEK_* and off_t */
-# ifdef VMS
-# include <unixio.h> /* for off_t */
-# endif
-# define z_off_t off_t
-#endif
-#ifndef SEEK_SET
-# define SEEK_SET 0 /* Seek from beginning of file. */
-# define SEEK_CUR 1 /* Seek from current position. */
-# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-#endif
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-#if defined(__OS400__)
-# define NO_vsnprintf
-#endif
-
-#if defined(__MVS__)
-# define NO_vsnprintf
-# ifdef FAR
-# undef FAR
-# endif
-#endif
-
-/* MVS linker does not support external names larger than 8 bytes */
-#if defined(__MVS__)
-# pragma map(deflateInit_,"DEIN")
-# pragma map(deflateInit2_,"DEIN2")
-# pragma map(deflateEnd,"DEEND")
-# pragma map(deflateBound,"DEBND")
-# pragma map(inflateInit_,"ININ")
-# pragma map(inflateInit2_,"ININ2")
-# pragma map(inflateEnd,"INEND")
-# pragma map(inflateSync,"INSY")
-# pragma map(inflateSetDictionary,"INSEDI")
-# pragma map(compressBound,"CMBND")
-# pragma map(inflate_table,"INTABL")
-# pragma map(inflate_fast,"INFA")
-# pragma map(inflate_copyright,"INCOPY")
-#endif
-
-#endif /* ZCONF_H */
diff --git a/misc/quazip/zip.c b/misc/quazip/zip.c
deleted file mode 100644
index 314c7a5..0000000
--- a/misc/quazip/zip.c
+++ /dev/null
@@ -1,1243 +0,0 @@
-/* zip.c -- IO on .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- 27 Dec 2004 Rolf Kalbermatter
- Modification to zipOpen2 to support globalComment retrieval.
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read zip.h for more info
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-*/
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "zlib.h"
-#include "zip.h"
-#include "quazip_global.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-#ifndef VERSIONMADEBY
-# define VERSIONMADEBY (0x031e) /* best for standard pkware crypt */
-#endif
-
-#ifndef Z_BUFSIZE
-#define Z_BUFSIZE (16384)
-#endif
-
-#ifndef Z_MAXFILENAMEINZIP
-#define Z_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-/*
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-*/
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef DEF_MEM_LEVEL
-#if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-#else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-#endif
-#endif
-const char zip_copyright[] =
- " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-
-#define SIZEDATA_INDATABLOCK (4096-(4*4))
-
-#define LOCALHEADERMAGIC (0x04034b50)
-#define DESCRIPTORHEADERMAGIC (0x08074b50)
-#define CENTRALHEADERMAGIC (0x02014b50)
-#define ENDHEADERMAGIC (0x06054b50)
-
-#define FLAG_LOCALHEADER_OFFSET (0x06)
-#define CRC_LOCALHEADER_OFFSET (0x0e)
-
-#define SIZECENTRALHEADER (0x2e) /* 46 */
-
-typedef struct linkedlist_datablock_internal_s
-{
- struct linkedlist_datablock_internal_s* next_datablock;
- uLong avail_in_this_block;
- uLong filled_in_this_block;
- uLong unused; /* for future use and alignement */
- unsigned char data[SIZEDATA_INDATABLOCK];
-} linkedlist_datablock_internal;
-
-typedef struct linkedlist_data_s
-{
- linkedlist_datablock_internal* first_block;
- linkedlist_datablock_internal* last_block;
-} linkedlist_data;
-
-
-typedef struct
-{
- z_stream stream; /* zLib stream structure for inflate */
- int stream_initialised; /* 1 is stream is initialised */
- uInt pos_in_buffered_data; /* last written byte in buffered_data */
-
- uLong pos_local_header; /* offset of the local header of the file
- currenty writing */
- char* central_header; /* central header data for the current file */
- uLong size_centralheader; /* size of the central header for cur file */
- uLong flag; /* flag of the file currently writing */
-
- int method; /* compression method of file currenty wr.*/
- int raw; /* 1 for directly writing raw data */
- Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
- uLong dosDate;
- uLong crc32;
- int encrypt;
-#ifndef NOCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const unsigned long* pcrc_32_tab;
- int crypt_header_size;
-#endif
-} curfile_info;
-
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- linkedlist_data central_dir;/* datablock with central dir in construction*/
- int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
- curfile_info ci; /* info on the file curretly writing */
-
- uLong begin_pos; /* position of the beginning of the zipfile */
- uLong add_position_when_writting_offset;
- uLong number_entry;
-#ifndef NO_ADDFILEINEXISTINGZIP
- char *globalcomment;
-#endif
-} zip_internal;
-
-
-
-#ifndef NOCRYPT
-#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-#include "crypt.h"
-#endif
-
-local linkedlist_datablock_internal* allocate_new_datablock()
-{
- linkedlist_datablock_internal* ldi;
- ldi = (linkedlist_datablock_internal*)
- ALLOC(sizeof(linkedlist_datablock_internal));
- if (ldi!=NULL)
- {
- ldi->next_datablock = NULL ;
- ldi->filled_in_this_block = 0 ;
- ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
- }
- return ldi;
-}
-
-local void free_datablock(ldi)
- linkedlist_datablock_internal* ldi;
-{
- while (ldi!=NULL)
- {
- linkedlist_datablock_internal* ldinext = ldi->next_datablock;
- TRYFREE(ldi);
- ldi = ldinext;
- }
-}
-
-local void init_linkedlist(ll)
- linkedlist_data* ll;
-{
- ll->first_block = ll->last_block = NULL;
-}
-
-#if 0 // unused
-local void free_linkedlist(ll)
- linkedlist_data* ll;
-{
- free_datablock(ll->first_block);
- ll->first_block = ll->last_block = NULL;
-}
-#endif
-
-local int add_data_in_datablock(ll,buf,len)
- linkedlist_data* ll;
- const void* buf;
- uLong len;
-{
- linkedlist_datablock_internal* ldi;
- const unsigned char* from_copy;
-
- if (ll==NULL)
- return ZIP_INTERNALERROR;
-
- if (ll->last_block == NULL)
- {
- ll->first_block = ll->last_block = allocate_new_datablock();
- if (ll->first_block == NULL)
- return ZIP_INTERNALERROR;
- }
-
- ldi = ll->last_block;
- from_copy = (unsigned char*)buf;
-
- while (len>0)
- {
- uInt copy_this;
- uInt i;
- unsigned char* to_copy;
-
- if (ldi->avail_in_this_block==0)
- {
- ldi->next_datablock = allocate_new_datablock();
- if (ldi->next_datablock == NULL)
- return ZIP_INTERNALERROR;
- ldi = ldi->next_datablock ;
- ll->last_block = ldi;
- }
-
- if (ldi->avail_in_this_block < len)
- copy_this = (uInt)ldi->avail_in_this_block;
- else
- copy_this = (uInt)len;
-
- to_copy = &(ldi->data[ldi->filled_in_this_block]);
-
- for (i=0;i<copy_this;i++)
- *(to_copy+i)=*(from_copy+i);
-
- ldi->filled_in_this_block += copy_this;
- ldi->avail_in_this_block -= copy_this;
- from_copy += copy_this ;
- len -= copy_this;
- }
- return ZIP_OK;
-}
-
-
-
-/****************************************************************************/
-
-#ifndef NO_ADDFILEINEXISTINGZIP
-/* ===========================================================================
- Inputs a long in LSB order to the given file
- nbByte == 1, 2 or 4 (byte, short or long)
-*/
-
-local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream, uLong x, int nbByte));
-local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong x;
- int nbByte;
-{
- unsigned char buf[4];
- int n;
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
- if (x != 0)
- { /* data overflow - hack for ZIP64 (X Roche) */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-
- if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
- return ZIP_ERRNO;
- else
- return ZIP_OK;
-}
-
-local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
-local void ziplocal_putValue_inmemory (dest, x, nbByte)
- void* dest;
- uLong x;
- int nbByte;
-{
- unsigned char* buf=(unsigned char*)dest;
- int n;
- for (n = 0; n < nbByte; n++) {
- buf[n] = (unsigned char)(x & 0xff);
- x >>= 8;
- }
-
- if (x != 0)
- { /* data overflow - hack for ZIP64 */
- for (n = 0; n < nbByte; n++)
- {
- buf[n] = 0xff;
- }
- }
-}
-
-/****************************************************************************/
-
-
-local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
- const tm_zip* ptm;
- uLong dosDate UNUSED;
-{
- uLong year = (uLong)ptm->tm_year;
- if (year>1980)
- year-=1980;
- else if (year>80)
- year-=80;
- return
- (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
- ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
-}
-
-
-/****************************************************************************/
-
-local int ziplocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return ZIP_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return ZIP_ERRNO;
- else
- return ZIP_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int ziplocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int ziplocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i;
- int err;
-
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==ZIP_OK)
- err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==ZIP_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong ziplocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-#endif /* !NO_ADDFILEINEXISTINGZIP*/
-
-/************************************************************/
-extern zipFile ZEXPORT zipOpen2 (file, append, globalcomment, pzlib_filefunc_def)
- voidpf file;
- int append;
- zipcharpc* globalcomment;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- zip_internal ziinit;
- zip_internal* zi;
- int err=ZIP_OK;
-
-
- if (pzlib_filefunc_def==NULL)
- fill_qiodevice_filefunc(&ziinit.z_filefunc);
- else
- ziinit.z_filefunc = *pzlib_filefunc_def;
-
- ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
- (ziinit.z_filefunc.opaque,
- file,
- (append == APPEND_STATUS_CREATE) ?
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
- (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
-
- if (ziinit.filestream == NULL)
- return NULL;
- ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
- ziinit.in_opened_file_inzip = 0;
- ziinit.ci.stream_initialised = 0;
- ziinit.number_entry = 0;
- ziinit.add_position_when_writting_offset = 0;
- init_linkedlist(&(ziinit.central_dir));
-
-
- zi = (zip_internal*)ALLOC(sizeof(zip_internal));
- if (zi==NULL)
- {
- ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
- return NULL;
- }
-
- /* now we add file in a zipfile */
-# ifndef NO_ADDFILEINEXISTINGZIP
- ziinit.globalcomment = NULL;
- if (append == APPEND_STATUS_ADDINZIP)
- {
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory */
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry;
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
- uLong size_comment;
-
- central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
- if (central_pos==0)
- err=ZIP_ERRNO;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
-
- /* the signature, already checked */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* total number of entries in the central dir */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((number_entry_CD!=number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=ZIP_BADZIPFILE;
-
- /* size of the central directory */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- /* zipfile global comment length */
- if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
- err=ZIP_ERRNO;
-
- if ((central_pos<offset_central_dir+size_central_dir) &&
- (err==ZIP_OK))
- err=ZIP_BADZIPFILE;
-
- if (err!=ZIP_OK)
- {
- ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
- return NULL;
- }
-
- if (size_comment>0)
- {
- ziinit.globalcomment = ALLOC(size_comment+1);
- if (ziinit.globalcomment)
- {
- size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
- ziinit.globalcomment[size_comment]=0;
- }
- }
-
- byte_before_the_zipfile = central_pos -
- (offset_central_dir+size_central_dir);
- ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
-
- {
- uLong size_central_dir_to_read = size_central_dir;
- size_t buf_size = SIZEDATA_INDATABLOCK;
- void* buf_read = (void*)ALLOC(buf_size);
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir + byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET) != 0)
- err=ZIP_ERRNO;
-
- while ((size_central_dir_to_read>0) && (err==ZIP_OK))
- {
- uLong read_this = SIZEDATA_INDATABLOCK;
- if (read_this > size_central_dir_to_read)
- read_this = size_central_dir_to_read;
- if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
- err=ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&ziinit.central_dir,buf_read,
- (uLong)read_this);
- size_central_dir_to_read-=read_this;
- }
- TRYFREE(buf_read);
- }
- ziinit.begin_pos = byte_before_the_zipfile;
- ziinit.number_entry = number_entry_CD;
-
- if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
- offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=ZIP_ERRNO;
- }
-
- if (globalcomment)
- {
- *globalcomment = ziinit.globalcomment;
- }
-# endif /* !NO_ADDFILEINEXISTINGZIP*/
-
- if (err != ZIP_OK)
- {
-# ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(ziinit.globalcomment);
-# endif /* !NO_ADDFILEINEXISTINGZIP*/
- TRYFREE(zi);
- return NULL;
- }
- else
- {
- *zi = ziinit;
- return (zipFile)zi;
- }
-}
-
-extern zipFile ZEXPORT zipOpen (file, append)
- voidpf file;
- int append;
-{
- return zipOpen2(file,append,NULL,NULL);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- windowBits, memLevel, strategy,
- password, crcForCrypting)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
- int windowBits;
- int memLevel;
- int strategy;
- const char* password;
- uLong crcForCrypting;
-{
- zip_internal* zi;
- uInt size_filename;
- uInt size_comment;
- uInt i;
- int err = ZIP_OK;
-
-# ifdef NOCRYPT
- if (password != NULL)
- return ZIP_PARAMERROR;
-# endif
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- if ((method!=0) && (method!=Z_DEFLATED))
- return ZIP_PARAMERROR;
-
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- if (err != ZIP_OK)
- return err;
- }
-
-
- if (filename==NULL)
- filename="-";
-
- if (comment==NULL)
- size_comment = 0;
- else
- size_comment = (uInt)strlen(comment);
-
- size_filename = (uInt)strlen(filename);
-
- if (zipfi == NULL)
- zi->ci.dosDate = 0;
- else
- {
- if (zipfi->dosDate != 0)
- zi->ci.dosDate = zipfi->dosDate;
- else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
- }
-
- zi->ci.flag = 0;
- if ((level==8) || (level==9))
- zi->ci.flag |= 2;
- if ((level==2))
- zi->ci.flag |= 4;
- if ((level==1))
- zi->ci.flag |= 6;
- if (password != NULL)
- {
- zi->ci.flag |= 1;
- }
- zi->ci.flag |= 8;
- zi->ci.crc32 = 0;
- zi->ci.method = method;
- zi->ci.encrypt = 0;
- zi->ci.stream_initialised = 0;
- zi->ci.pos_in_buffered_data = 0;
- zi->ci.raw = raw;
- zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
- zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
- size_extrafield_global + size_comment;
- zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
-
- ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
- /* version info */
- ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
- ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
- ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
-
- if (zipfi==NULL)
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
- else
- ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
-
- ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
-
- for (i=0;i<size_filename;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
-
- for (i=0;i<size_extrafield_global;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
- *(((const char*)extrafield_global)+i);
-
- for (i=0;i<size_comment;i++)
- *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
- size_extrafield_global+i) = *(comment+i);
- if (zi->ci.central_header == NULL)
- return ZIP_INTERNALERROR;
-
- /* write the local header */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
-
- if ((err==ZIP_OK) && (size_filename>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
- err = ZIP_ERRNO;
-
- if ((err==ZIP_OK) && (size_extrafield_local>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
- !=size_extrafield_local)
- err = ZIP_ERRNO;
-
- zi->ci.stream.avail_in = (uInt)0;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- zi->ci.stream.total_in = 0;
- zi->ci.stream.total_out = 0;
-
- if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- zi->ci.stream.zalloc = (alloc_func)0;
- zi->ci.stream.zfree = (free_func)0;
- zi->ci.stream.opaque = (voidpf)0;
-
- if (windowBits>0)
- windowBits = -windowBits;
-
- err = deflateInit2(&zi->ci.stream, level,
- Z_DEFLATED, windowBits, memLevel, strategy);
-
- if (err==Z_OK)
- zi->ci.stream_initialised = 1;
- }
-# ifndef NOCRYPT
- zi->ci.crypt_header_size = 0;
- if ((err==Z_OK) && (password != NULL))
- {
- unsigned char bufHead[RAND_HEAD_LEN];
- unsigned int sizeHead;
- zi->ci.encrypt = 1;
- zi->ci.pcrc_32_tab = get_crc_table();
- /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
-
- crcForCrypting = (uLong)zi->ci.dosDate << 16; // ATTANTION! Without this row, you don't unpack your password protected archive in other app.
-
- sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
- zi->ci.crypt_header_size = sizeHead;
-
- if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
- err = ZIP_ERRNO;
- }
-# endif
-
- if (err==Z_OK)
- zi->in_opened_file_inzip = 1;
- return err;
-}
-
-extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
- int raw;
-{
- return zipOpenNewFileInZip3 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, raw,
- -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- NULL, 0);
-}
-
-extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level)
- zipFile file;
- const char* filename;
- const zip_fileinfo* zipfi;
- const void* extrafield_local;
- uInt size_extrafield_local;
- const void* extrafield_global;
- uInt size_extrafield_global;
- const char* comment;
- int method;
- int level;
-{
- return zipOpenNewFileInZip2 (file, filename, zipfi,
- extrafield_local, size_extrafield_local,
- extrafield_global, size_extrafield_global,
- comment, method, level, 0);
-}
-
-local int zipFlushWriteBuffer(zi)
- zip_internal* zi;
-{
- int err=ZIP_OK;
-
- if (zi->ci.encrypt != 0)
- {
-#ifndef NOCRYPT
- uInt i;
- int t;
- for (i=0;i<zi->ci.pos_in_buffered_data;i++)
- zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
- zi->ci.buffered_data[i],t);
-#endif
- }
- if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
- !=zi->ci.pos_in_buffered_data)
- err = ZIP_ERRNO;
- zi->ci.pos_in_buffered_data = 0;
- return err;
-}
-
-extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
- zipFile file;
- const void* buf;
- unsigned len;
-{
- zip_internal* zi;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
-
- zi->ci.stream.next_in = (void*)buf;
- zi->ci.stream.avail_in = len;
- zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
-
- while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
- {
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
-
-
- if(err != ZIP_OK)
- break;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- uLong uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_NO_FLUSH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
-
- }
- else
- {
- uInt copy_this,i;
- if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
- copy_this = zi->ci.stream.avail_in;
- else
- copy_this = zi->ci.stream.avail_out;
- for (i=0;i<copy_this;i++)
- *(((char*)zi->ci.stream.next_out)+i) =
- *(((const char*)zi->ci.stream.next_in)+i);
- {
- zi->ci.stream.avail_in -= copy_this;
- zi->ci.stream.avail_out-= copy_this;
- zi->ci.stream.next_in+= copy_this;
- zi->ci.stream.next_out+= copy_this;
- zi->ci.stream.total_in+= copy_this;
- zi->ci.stream.total_out+= copy_this;
- zi->ci.pos_in_buffered_data += copy_this;
- }
- }
- }
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
- zipFile file;
- uLong uncompressed_size;
- uLong crc32;
-{
- zip_internal* zi;
- uLong compressed_size;
- int err=ZIP_OK;
-
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 0)
- return ZIP_PARAMERROR;
- zi->ci.stream.avail_in = 0;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- while (err==ZIP_OK)
- {
- uLong uTotalOutBefore;
- if (zi->ci.stream.avail_out == 0)
- {
- if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
- err = ZIP_ERRNO;
- zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
- zi->ci.stream.next_out = zi->ci.buffered_data;
- }
- uTotalOutBefore = zi->ci.stream.total_out;
- err=deflate(&zi->ci.stream, Z_FINISH);
- zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
- }
-
- if (err==Z_STREAM_END)
- err=ZIP_OK; /* this is normal */
-
- if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
- if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
- err = ZIP_ERRNO;
-
- if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
- {
- err=deflateEnd(&zi->ci.stream);
- zi->ci.stream_initialised = 0;
- }
-
- if (!zi->ci.raw)
- {
- crc32 = (uLong)zi->ci.crc32;
- uncompressed_size = (uLong)zi->ci.stream.total_in;
- }
- compressed_size = (uLong)zi->ci.stream.total_out;
-# ifndef NOCRYPT
- compressed_size += zi->ci.crypt_header_size;
-# endif
-
- ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
- ziplocal_putValue_inmemory(zi->ci.central_header+20,
- compressed_size,4); /*compr size*/
- if (zi->ci.stream.data_type == Z_ASCII)
- ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
- ziplocal_putValue_inmemory(zi->ci.central_header+24,
- uncompressed_size,4); /*uncompr size*/
-
- if (err==ZIP_OK)
- err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
- (uLong)zi->ci.size_centralheader);
- free(zi->ci.central_header);
-
- if (err==ZIP_OK)
- {
- uLong cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
- if (err==ZIP_OK) /* compressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
- if (err==ZIP_OK) /* uncompressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-
- if (ZSEEK(zi->z_filefunc,zi->filestream,
- cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err = ZIP_ERRNO;
-
- /* Write local Descriptor after file data */
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)DESCRIPTORHEADERMAGIC,4);
-
- if (err==ZIP_OK)
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
-
- if (err==ZIP_OK) /* compressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
-
- if (err==ZIP_OK) /* uncompressed size, unknown */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
-
-
- }
-
- zi->number_entry ++;
- zi->in_opened_file_inzip = 0;
-
- return err;
-}
-
-extern int ZEXPORT zipCloseFileInZip (file)
- zipFile file;
-{
- return zipCloseFileInZipRaw (file,0,0);
-}
-
-extern int ZEXPORT zipClose (file, global_comment)
- zipFile file;
- const char* global_comment;
-{
- zip_internal* zi;
- int err = 0;
- uLong size_centraldir = 0;
- uLong centraldir_pos_inzip;
- uInt size_global_comment;
- if (file == NULL)
- return ZIP_PARAMERROR;
- zi = (zip_internal*)file;
-
- if (zi->in_opened_file_inzip == 1)
- {
- err = zipCloseFileInZip (file);
- }
-
-#ifndef NO_ADDFILEINEXISTINGZIP
- if (global_comment==NULL)
- global_comment = zi->globalcomment;
-#endif
- if (global_comment==NULL)
- size_global_comment = 0;
- else
- size_global_comment = (uInt)strlen(global_comment);
-
- centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
- if (err==ZIP_OK)
- {
- linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
- while (ldi!=NULL)
- {
- if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- ldi->data,ldi->filled_in_this_block)
- !=ldi->filled_in_this_block )
- err = ZIP_ERRNO;
-
- size_centraldir += ldi->filled_in_this_block;
- ldi = ldi->next_datablock;
- }
- }
- free_datablock(zi->central_dir.first_block);
-
- if (err==ZIP_OK) /* Magic End */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
-
- if (err==ZIP_OK) /* number of this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* number of the disk with the start of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* total number of entries in the central dir */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
-
- if (err==ZIP_OK) /* size of the central directory */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
-
- if (err==ZIP_OK) /* offset of start of central directory with respect to the
- starting disk number */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
- (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
-
- if (err==ZIP_OK) /* zipfile comment length */
- err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
-
- if ((err==ZIP_OK) && (size_global_comment>0))
- if (ZWRITE(zi->z_filefunc,zi->filestream,
- global_comment,size_global_comment) != size_global_comment)
- err = ZIP_ERRNO;
-
- if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
- if (err == ZIP_OK)
- err = ZIP_ERRNO;
-
-#ifndef NO_ADDFILEINEXISTINGZIP
- TRYFREE(zi->globalcomment);
-#endif
- TRYFREE(zi);
-
- return err;
-}
diff --git a/misc/quazip/zip.h b/misc/quazip/zip.h
deleted file mode 100644
index 5d9be52..0000000
--- a/misc/quazip/zip.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/* zip.h -- IO for compress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
- WinZip, InfoZip tools and compatible.
- Multi volume ZipFile (span) are not supported.
- Encryption compatible with pkzip 2.04g only supported
- Old compressions used by old PKZip 1.x are not supported
-
- For uncompress .zip file, look at unzip.h
-
-
- I WAIT FEEDBACK at mail info at winimage.com
- Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
-
- Condition of use and distribution are the same than zlib :
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Modified by Sergey A. Tachenov to integrate with Qt.
-
-
-*/
-
-/* for more info about .ZIP format, see
- http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
- http://www.info-zip.org/pub/infozip/doc/
- PkWare has also a specification at :
- ftp://ftp.pkware.com/probdesc.zip
-*/
-
-#ifndef _zip_H
-#define _zip_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
-
-#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
-#endif
-
-#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
-/* like the STRICT of WIN32, we define a pointer that cannot be converted
- from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
-typedef zipFile__ *zipFile;
-#else
-typedef voidp zipFile;
-#endif
-
-#define ZIP_OK (0)
-#define ZIP_EOF (0)
-#define ZIP_ERRNO (Z_ERRNO)
-#define ZIP_PARAMERROR (-102)
-#define ZIP_BADZIPFILE (-103)
-#define ZIP_INTERNALERROR (-104)
-
-#ifndef DEF_MEM_LEVEL
-# if MAX_MEM_LEVEL >= 8
-# define DEF_MEM_LEVEL 8
-# else
-# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-# endif
-#endif
-/* default memLevel */
-
-/* tm_zip contain date/time info */
-typedef struct tm_zip_s
-{
- uInt tm_sec; /* seconds after the minute - [0,59] */
- uInt tm_min; /* minutes after the hour - [0,59] */
- uInt tm_hour; /* hours since midnight - [0,23] */
- uInt tm_mday; /* day of the month - [1,31] */
- uInt tm_mon; /* months since January - [0,11] */
- uInt tm_year; /* years - [1980..2044] */
-} tm_zip;
-
-typedef struct
-{
- tm_zip tmz_date; /* date in understandable format */
- uLong dosDate; /* if dos_date == 0, tmu_date is used */
-/* uLong flag; */ /* general purpose bit flag 2 bytes */
-
- uLong internal_fa; /* internal file attributes 2 bytes */
- uLong external_fa; /* external file attributes 4 bytes */
-} zip_fileinfo;
-
-typedef const char* zipcharpc;
-
-
-#define APPEND_STATUS_CREATE (0)
-#define APPEND_STATUS_CREATEAFTER (1)
-#define APPEND_STATUS_ADDINZIP (2)
-
-extern zipFile ZEXPORT zipOpen OF((voidpf file, int append));
-/*
- Create a zipfile.
- file is whatever the IO API accepts. For Qt IO API it's a pointer to
- QIODevice. For fopen() IO API it's a file name (const char*).
- if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
- will be created at the end of the file.
- (useful if the file contain a self extractor code)
- if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
- add files in existing zip (be sure you don't add file that doesn't exist)
- If the zipfile cannot be opened, the return value is NULL.
- Else, the return value is a zipFile Handle, usable with other function
- of this zip package.
-*/
-
-/* Note : there is no delete function into a zipfile.
- If you want delete file into a zipfile, you must open a zipfile, and create another
- Of couse, you can use RAW reading and writing to copy the file you did not want delte
-*/
-
-extern zipFile ZEXPORT zipOpen2 OF((voidpf file,
- int append,
- zipcharpc* globalcomment,
- zlib_filefunc_def* pzlib_filefunc_def));
-
-extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level));
-/*
- Open a file in the ZIP for writing.
- filename : the filename in zip (if NULL, '-' without quote will be used
- *zipfi contain supplemental information
- if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
- contains the extrafield data the the local header
- if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
- contains the extrafield data the the local header
- if comment != NULL, comment contain the comment string
- method contain the compression method (0 for store, Z_DEFLATED for deflate)
- level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
-*/
-
-
-extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw));
-
-/*
- Same than zipOpenNewFileInZip, except if raw=1, we write raw file
- */
-
-extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
- const char* filename,
- const zip_fileinfo* zipfi,
- const void* extrafield_local,
- uInt size_extrafield_local,
- const void* extrafield_global,
- uInt size_extrafield_global,
- const char* comment,
- int method,
- int level,
- int raw,
- int windowBits,
- int memLevel,
- int strategy,
- const char* password,
- uLong crcForCtypting));
-
-/*
- Same than zipOpenNewFileInZip2, except
- windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
- password : crypting password (NULL for no crypting)
- crcForCtypting : crc of file to compress (needed for crypting)
- */
-
-
-extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
- const void* buf,
- unsigned len));
-/*
- Write data in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
-/*
- Close the current file in the zipfile
-*/
-
-extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
- uLong uncompressed_size,
- uLong crc32));
-/*
- Close the current file in the zipfile, for fiel opened with
- parameter raw=1 in zipOpenNewFileInZip2
- uncompressed_size and crc32 are value for the uncompressed size
-*/
-
-extern int ZEXPORT zipClose OF((zipFile file,
- const char* global_comment));
-/*
- Close the zipfile
-*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _zip_H */
diff --git a/misc/quazip/zlib.h b/misc/quazip/zlib.h
deleted file mode 100644
index 9e5b467..0000000
--- a/misc/quazip/zlib.h
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.2.3, July 18th, 2005
-
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup at gzip.org madler at alumni.caltech.edu
-
-
- The data format used by the zlib library is described by RFCs (Request for
- Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
- (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef ZLIB_H
-#define ZLIB_H
-
-#include "zconf.h"
-#include "qconfig.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
-#if defined(QT_VISIBILITY_AVAILABLE)
-# define Q_ZEXPORT __attribute__((visibility("default")))
-#else
-# ifdef QT_MAKEDLL
-# define Q_ZEXPORT __declspec(dllexport)
-# else
-# define Q_ZEXPORT ZEXPORT
-# endif
-#endif
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms will be added later and will have the same
- stream interface.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-
- The compressed data format used by default by the in-memory functions is
- the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
- around a deflate stream, which is itself documented in RFC 1951.
-
- The library also supports reading and writing files in gzip (.gz) format
- with an interface similar to that of stdio using the functions that start
- with "gz". The gzip format is different from the zlib format. gzip is a
- gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
-
- This library can optionally read and write gzip streams in memory as well.
-
- The zlib format was designed to be compact and fast for use in memory
- and on communications channels. The gzip format was designed for single-
- file compression on file systems, has a larger header than zlib to maintain
- directory information, and uses a different, slower check method than zlib.
-
- The library does not install any signal handler. The decoder checks
- the consistency of the compressed data, so the library should never
- crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidpf opaque; /* private data object passed to zalloc and zfree */
-
- int data_type; /* best guess about the data type: binary or text */
- uLong adler; /* adler32 value of the uncompressed data */
- uLong reserved; /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
- gzip header information passed to and from zlib routines. See RFC 1952
- for more details on the meanings of these fields.
-*/
-typedef struct gz_header_s {
- int text; /* true if compressed data believed to be text */
- uLong time; /* modification time */
- int xflags; /* extra flags (not used when writing a gzip file) */
- int os; /* operating system */
- Bytef *extra; /* pointer to extra field or Z_NULL if none */
- uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
- uInt extra_max; /* space at extra (only when reading header) */
- Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
- uInt name_max; /* space at name (only when reading header) */
- Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
- uInt comm_max; /* space at comment (only when reading header) */
- int hcrc; /* true if there was or will be a header crc */
- int done; /* true when done reading gzip header (not used
- when writing a gzip file) */
-} gz_header;
-
-typedef gz_header FAR *gz_headerp;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- If zlib is used in a multi-threaded application, zalloc and zfree must be
- thread safe.
-
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-#define Z_BLOCK 5
-/* Allowed flush values; see deflate() and inflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_RLE 3
-#define Z_FIXED 4
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_TEXT 1
-#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field (though see inflate()) */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
- /* basic functions */
-
-ZEXTERN Q_ZEXPORT const char * zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- This check is automatically made by deflateInit and inflateInit.
- */
-
-/*
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
- Initializes the internal stream state for compression. The fields
- zalloc, zfree and opaque must be initialized before by the caller.
- If zalloc and zfree are set to Z_NULL, deflateInit updates them to
- use default allocation functions.
-
- The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
- 1 gives best speed, 9 gives best compression, 0 gives no compression at
- all (the input data is simply copied a block at a time).
- Z_DEFAULT_COMPRESSION requests a default compromise between speed and
- compression (currently equivalent to level 6).
-
- deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if level is not a valid compression level,
- Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
- with the version assumed by the caller (ZLIB_VERSION).
- msg is set to null if there is no error message. deflateInit does not
- perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int Q_ZEXPORT deflate OF((z_streamp strm, int flush));
-/*
- deflate compresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce some
- output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. deflate performs one or both of the
- following actions:
-
- - Compress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in and avail_in are updated and
- processing will resume at this point for the next call of deflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. This action is forced if the parameter flush is non zero.
- Forcing flush frequently degrades the compression ratio, so this parameter
- should be set only when necessary (in interactive applications).
- Some output may be provided even if flush is not set.
-
- Before the call of deflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating avail_in or avail_out accordingly; avail_out
- should never be zero before the call. The application can consume the
- compressed output when it wants, for example when the output buffer is full
- (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
- and with zero avail_out, it must be called again after making room in the
- output buffer because there might be more output pending.
-
- Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
- decide how much data to accumualte before producing output, in order to
- maximize compression.
-
- If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
- flushed to the output buffer and the output is aligned on a byte boundary, so
- that the decompressor can get all input data available so far. (In particular
- avail_in is zero after the call if enough output space has been provided
- before the call.) Flushing may degrade compression for some compression
- algorithms and so it should be used only when necessary.
-
- If flush is set to Z_FULL_FLUSH, all output is flushed as with
- Z_SYNC_FLUSH, and the compression state is reset so that decompression can
- restart from this point if previous compressed data has been damaged or if
- random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
- compression.
-
- If deflate returns with avail_out == 0, this function must be called again
- with the same value of the flush parameter and more output space (updated
- avail_out), until the flush is complete (deflate returns with non-zero
- avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
- avail_out is greater than six to avoid repeated flush markers due to
- avail_out == 0 on return.
-
- If the parameter flush is set to Z_FINISH, pending input is processed,
- pending output is flushed and deflate returns with Z_STREAM_END if there
- was enough output space; if deflate returns with Z_OK, this function must be
- called again with Z_FINISH and more output space (updated avail_out) but no
- more input data, until it returns with Z_STREAM_END or an error. After
- deflate has returned Z_STREAM_END, the only possible operations on the
- stream are deflateReset or deflateEnd.
-
- Z_FINISH can be used immediately after deflateInit if all the compression
- is to be done in a single step. In this case, avail_out must be at least
- the value returned by deflateBound (see below). If deflate does not return
- Z_STREAM_END, then it must be called again as described above.
-
- deflate() sets strm->adler to the adler32 checksum of all input read
- so far (that is, total_in bytes).
-
- deflate() may update strm->data_type if it can make a good guess about
- the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
- binary. This field is only for information purposes and does not affect
- the compression algorithm in any manner.
-
- deflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if all input has been
- consumed and all output has been produced (only when flush is set to
- Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
- if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
- (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
- fatal, and deflate() can be called again with more input and more output
- space to continue compressing.
-*/
-
-
-ZEXTERN int Q_ZEXPORT deflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
- stream state was inconsistent, Z_DATA_ERROR if the stream was freed
- prematurely (some input or output was discarded). In the error case,
- msg may be set but then points to a static string (which must not be
- deallocated).
-*/
-
-
-/*
-ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-
- Initializes the internal stream state for decompression. The fields
- next_in, avail_in, zalloc, zfree and opaque must be initialized before by
- the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
- value depends on the compression method), inflateInit determines the
- compression method from the zlib header and allocates all data structures
- accordingly; otherwise the allocation will be deferred to the first call of
- inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
- use default allocation functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
- version assumed by the caller. msg is set to null if there is no error
- message. inflateInit does not perform any decompression apart from reading
- the zlib header if present: this will be done by inflate(). (So next_in and
- avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int Q_ZEXPORT inflate OF((z_streamp strm, int flush));
-/*
- inflate decompresses as much data as possible, and stops when the input
- buffer becomes empty or the output buffer becomes full. It may introduce
- some output latency (reading input without producing any output) except when
- forced to flush.
-
- The detailed semantics are as follows. inflate performs one or both of the
- following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() provides as much output as possible, until there
- is no more input data or no more space in the output buffer (see below
- about the flush parameter).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate(). If inflate returns Z_OK and with zero avail_out, it
- must be called again after making room in the output buffer because there
- might be more output pending.
-
- The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
- Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
- output as possible to the output buffer. Z_BLOCK requests that inflate() stop
- if and when it gets to the next deflate block boundary. When decoding the
- zlib or gzip format, this will cause inflate() to return immediately after
- the header and before the first block. When doing a raw inflate, inflate()
- will go ahead and process the first block, and will return when it gets to
- the end of that block, or when it runs out of data.
-
- The Z_BLOCK option assists in appending to or combining deflate streams.
- Also to assist in this, on return inflate() will set strm->data_type to the
- number of unused bits in the last byte taken from strm->next_in, plus 64
- if inflate() is currently decoding the last block in the deflate stream,
- plus 128 if inflate() returned immediately after decoding an end-of-block
- code or decoding the complete header up to just before the first byte of the
- deflate stream. The end-of-block will not be indicated until all of the
- uncompressed data from that block has been written to strm->next_out. The
- number of unused bits may in general be greater than seven, except when
- bit 7 of data_type is set, in which case the number of unused bits will be
- less than eight.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster approach
- may be used for the single inflate() call.
-
- In this implementation, inflate() always flushes as much output as
- possible to the output buffer, and always uses the faster approach on the
- first call. So the only effect of the flush parameter in this implementation
- is on the return value of inflate(), as noted below, or when it returns early
- because Z_BLOCK is used.
-
- If a preset dictionary is needed after this call (see inflateSetDictionary
- below), inflate sets strm->adler to the adler32 checksum of the dictionary
- chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
- strm->adler to the adler32 checksum of all output produced so far (that is,
- total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
- below. At the end of the stream, inflate() checks that its computed adler32
- checksum is equal to that saved by the compressor and returns Z_STREAM_END
- only if the checksum is correct.
-
- inflate() will decompress and check either zlib-wrapped or gzip-wrapped
- deflate data. The header type is detected automatically. Any information
- contained in the gzip header is not retained, so applications that need that
- information should instead use raw inflate, see inflateInit2() below, or
- inflateBack() and perform their own processing of the gzip header and
- trailer.
-
- inflate() returns Z_OK if some progress has been made (more input processed
- or more output produced), Z_STREAM_END if the end of the compressed data has
- been reached and all uncompressed output has been produced, Z_NEED_DICT if a
- preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
- corrupted (input stream not conforming to the zlib format or incorrect check
- value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
- if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
- Z_BUF_ERROR if no progress is possible or if there was not enough room in the
- output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
- inflate() can be called again with more input and more output space to
- continue decompressing. If Z_DATA_ERROR is returned, the application may then
- call inflateSync() to look for a good compression block if a partial recovery
- of the data is desired.
-*/
-
-
-ZEXTERN int Q_ZEXPORT inflateEnd OF((z_streamp strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* Advanced functions */
-
-/*
- The following functions are needed only in some special applications.
-*/
-
-/*
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
- This is another version of deflateInit with more compression options. The
- fields next_in, zalloc, zfree and opaque must be initialized before by
- the caller.
-
- The method parameter is the compression method. It must be Z_DEFLATED in
- this version of the library.
-
- The windowBits parameter is the base two logarithm of the window size
- (the size of the history buffer). It should be in the range 8..15 for this
- version of the library. Larger values of this parameter result in better
- compression at the expense of memory usage. The default value is 15 if
- deflateInit is used instead.
-
- windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
- determines the window size. deflate() will then generate raw deflate data
- with no zlib header or trailer, and will not compute an adler32 check value.
-
- windowBits can also be greater than 15 for optional gzip encoding. Add
- 16 to windowBits to write a simple gzip header and trailer around the
- compressed data instead of a zlib wrapper. The gzip header will have no
- file name, no extra data, no comment, no modification time (set to zero),
- no header crc, and the operating system will be set to 255 (unknown). If a
- gzip stream is being written, strm->adler is a crc32 instead of an adler32.
-
- The memLevel parameter specifies how much memory should be allocated
- for the internal compression state. memLevel=1 uses minimum memory but
- is slow and reduces compression ratio; memLevel=9 uses maximum memory
- for optimal speed. The default value is 8. See zconf.h for total memory
- usage as a function of windowBits and memLevel.
-
- The strategy parameter is used to tune the compression algorithm. Use the
- value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
- filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
- string match), or Z_RLE to limit match distances to one (run-length
- encoding). Filtered data consists mostly of small values with a somewhat
- random distribution. In this case, the compression algorithm is tuned to
- compress them better. The effect of Z_FILTERED is to force more Huffman
- coding and less string matching; it is somewhat intermediate between
- Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
- Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
- parameter only affects the compression ratio but not the correctness of the
- compressed output even if it is not set appropriately. Z_FIXED prevents the
- use of dynamic Huffman codes, allowing for a simpler decoder for special
- applications.
-
- deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
- method). msg is set to null if there is no error message. deflateInit2 does
- not perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int Q_ZEXPORT deflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the compression dictionary from the given byte sequence
- without producing any compressed output. This function must be called
- immediately after deflateInit, deflateInit2 or deflateReset, before any
- call of deflate. The compressor and decompressor must use exactly the same
- dictionary (see inflateSetDictionary).
-
- The dictionary should consist of strings (byte sequences) that are likely
- to be encountered later in the data to be compressed, with the most commonly
- used strings preferably put towards the end of the dictionary. Using a
- dictionary is most useful when the data to be compressed is short and can be
- predicted with good accuracy; the data can then be compressed better than
- with the default empty dictionary.
-
- Depending on the size of the compression data structures selected by
- deflateInit or deflateInit2, a part of the dictionary may in effect be
- discarded, for example if the dictionary is larger than the window size in
- deflate or deflate2. Thus the strings most likely to be useful should be
- put at the end of the dictionary, not at the front. In addition, the
- current implementation of deflate will use at most the window size minus
- 262 bytes of the provided dictionary.
-
- Upon return of this function, strm->adler is set to the adler32 value
- of the dictionary; the decompressor may later use this value to determine
- which dictionary has been used by the compressor. (The adler32 value
- applies to the whole dictionary even if only a subset of the dictionary is
- actually used by the compressor.) If a raw deflate was requested, then the
- adler32 value is not computed and strm->adler is not set.
-
- deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent (for example if deflate has already been called for this stream
- or if the compression method is bsort). deflateSetDictionary does not
- perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int Q_ZEXPORT deflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when several compression strategies will be
- tried, for example when there are several ways of pre-processing the input
- data with a filter. The streams that will be discarded should then be freed
- by calling deflateEnd. Note that deflateCopy duplicates the internal
- compression state which can be quite large, so this strategy is slow and
- can consume lots of memory.
-
- deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int Q_ZEXPORT deflateReset OF((z_streamp strm));
-/*
- This function is equivalent to deflateEnd followed by deflateInit,
- but does not free and reallocate all the internal compression state.
- The stream will keep the same compression level and any other attributes
- that may have been set by deflateInit2.
-
- deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int Q_ZEXPORT deflateParams OF((z_streamp strm,
- int level,
- int strategy));
-/*
- Dynamically update the compression level and compression strategy. The
- interpretation of level and strategy is as in deflateInit2. This can be
- used to switch between compression and straight copy of the input data, or
- to switch to a different kind of input data requiring a different
- strategy. If the compression level is changed, the input available so far
- is compressed with the old level (and may be flushed); the new level will
- take effect only at the next call of deflate().
-
- Before the call of deflateParams, the stream state must be set as for
- a call of deflate(), since the currently available input may have to
- be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
- deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
- stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
- if strm->avail_out was zero.
-*/
-
-ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
- int good_length,
- int max_lazy,
- int nice_length,
- int max_chain));
-/*
- Fine tune deflate's internal compression parameters. This should only be
- used by someone who understands the algorithm used by zlib's deflate for
- searching for the best matching string, and even then only by the most
- fanatic optimizer trying to squeeze out the last compressed bit for their
- specific input data. Read the deflate.c source code for the meaning of the
- max_lazy, good_length, nice_length, and max_chain parameters.
-
- deflateTune() can be called after deflateInit() or deflateInit2(), and
- returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
- */
-
-ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
- uLong sourceLen));
-/*
- deflateBound() returns an upper bound on the compressed size after
- deflation of sourceLen bytes. It must be called after deflateInit()
- or deflateInit2(). This would be used to allocate an output buffer
- for deflation in a single pass, and so would be called before deflate().
-*/
-
-ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- deflatePrime() inserts bits in the deflate output stream. The intent
- is that this function is used to start off the deflate output with the
- bits leftover from a previous deflate stream when appending to it. As such,
- this function can only be used for raw deflate, and must be used before the
- first deflate() call after a deflateInit2() or deflateReset(). bits must be
- less than or equal to 16, and that many of the least significant bits of
- value will be inserted in the output.
-
- deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- deflateSetHeader() provides gzip header information for when a gzip
- stream is requested by deflateInit2(). deflateSetHeader() may be called
- after deflateInit2() or deflateReset() and before the first call of
- deflate(). The text, time, os, extra field, name, and comment information
- in the provided gz_header structure are written to the gzip header (xflag is
- ignored -- the extra flags are set according to the compression level). The
- caller must assure that, if not Z_NULL, name and comment are terminated with
- a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
- available there. If hcrc is true, a gzip header crc is included. Note that
- the current versions of the command-line version of gzip (up through version
- 1.3.x) do not support header crc's, and will report that it is a "multi-part
- gzip file" and give up.
-
- If deflateSetHeader is not used, the default gzip header has text false,
- the time set to zero, and os set to 255, with no extra, name, or comment
- fields. The gzip header is returned to the default state by deflateReset().
-
- deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
- int windowBits));
-
- This is another version of inflateInit with an extra parameter. The
- fields next_in, avail_in, zalloc, zfree and opaque must be initialized
- before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library. The default value is 15 if inflateInit is used
- instead. windowBits must be greater than or equal to the windowBits value
- provided to deflateInit2() while compressing, or it must be equal to 15 if
- deflateInit2() was not used. If a compressed stream with a larger window
- size is given as input, inflate() will return with the error code
- Z_DATA_ERROR instead of trying to allocate a larger window.
-
- windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
- determines the window size. inflate() will then process raw deflate data,
- not looking for a zlib or gzip header, not generating a check value, and not
- looking for any check values for comparison at the end of the stream. This
- is for use with other formats that use the deflate compressed data format
- such as zip. Those formats provide their own check values. If a custom
- format is developed using the raw deflate format for compressed data, it is
- recommended that a check value such as an adler32 or a crc32 be applied to
- the uncompressed data as is done in the zlib, gzip, and zip formats. For
- most applications, the zlib format should be used as is. Note that comments
- above on the use in deflateInit2() applies to the magnitude of windowBits.
-
- windowBits can also be greater than 15 for optional gzip decoding. Add
- 32 to windowBits to enable zlib and gzip decoding with automatic header
- detection, or add 16 to decode only the gzip format (the zlib format will
- return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
- a crc32 instead of an adler32.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
- is set to null if there is no error message. inflateInit2 does not perform
- any decompression apart from reading the zlib header if present: this will
- be done by inflate(). (So next_in and avail_in may be modified, but next_out
- and avail_out are unchanged.)
-*/
-
-ZEXTERN int Q_ZEXPORT inflateSetDictionary OF((z_streamp strm,
- const Bytef *dictionary,
- uInt dictLength));
-/*
- Initializes the decompression dictionary from the given uncompressed byte
- sequence. This function must be called immediately after a call of inflate,
- if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
- can be determined from the adler32 value returned by that call of inflate.
- The compressor and decompressor must use exactly the same dictionary (see
- deflateSetDictionary). For raw inflate, this function can be called
- immediately after inflateInit2() or inflateReset() and before any call of
- inflate() to set the dictionary. The application must insure that the
- dictionary that was used for compression is provided.
-
- inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
- parameter is invalid (such as NULL dictionary) or the stream state is
- inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
- expected one (incorrect adler32 value). inflateSetDictionary does not
- perform any decompression: this will be done by subsequent calls of
- inflate().
-*/
-
-ZEXTERN int Q_ZEXPORT inflateSync OF((z_streamp strm));
-/*
- Skips invalid compressed data until a full flush point (see above the
- description of deflate with Z_FULL_FLUSH) can be found, or until all
- available input is skipped. No output is provided.
-
- inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no flush point has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
- z_streamp source));
-/*
- Sets the destination stream as a complete copy of the source stream.
-
- This function can be useful when randomly accessing a large stream. The
- first pass through the stream can periodically record the inflate state,
- allowing restarting inflate at those points when randomly accessing the
- stream.
-
- inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
- (such as zalloc being NULL). msg is left unchanged in both source and
- destination.
-*/
-
-ZEXTERN int Q_ZEXPORT inflateReset OF((z_streamp strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
- int bits,
- int value));
-/*
- This function inserts bits in the inflate input stream. The intent is
- that this function is used to start inflating at a bit position in the
- middle of a byte. The provided bits will be used before any bytes are used
- from next_in. This function should only be used with raw inflate, and
- should be used before the first inflate() call after inflateInit2() or
- inflateReset(). bits must be less than or equal to 16, and that many of the
- least significant bits of value will be inserted in the input.
-
- inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
- gz_headerp head));
-/*
- inflateGetHeader() requests that gzip header information be stored in the
- provided gz_header structure. inflateGetHeader() may be called after
- inflateInit2() or inflateReset(), and before the first call of inflate().
- As inflate() processes the gzip stream, head->done is zero until the header
- is completed, at which time head->done is set to one. If a zlib stream is
- being decoded, then head->done is set to -1 to indicate that there will be
- no gzip header information forthcoming. Note that Z_BLOCK can be used to
- force inflate() to return immediately after header processing is complete
- and before any actual data is decompressed.
-
- The text, time, xflags, and os fields are filled in with the gzip header
- contents. hcrc is set to true if there is a header CRC. (The header CRC
- was valid if done is set to one.) If extra is not Z_NULL, then extra_max
- contains the maximum number of bytes to write to extra. Once done is true,
- extra_len contains the actual extra field length, and extra contains the
- extra field, or that field truncated if extra_max is less than extra_len.
- If name is not Z_NULL, then up to name_max characters are written there,
- terminated with a zero unless the length is greater than name_max. If
- comment is not Z_NULL, then up to comm_max characters are written there,
- terminated with a zero unless the length is greater than comm_max. When
- any of extra, name, or comment are not Z_NULL and the respective field is
- not present in the header, then that field is set to Z_NULL to signal its
- absence. This allows the use of deflateSetHeader() with the returned
- structure to duplicate the header. However if those fields are set to
- allocated memory, then the application will need to save those pointers
- elsewhere so that they can be eventually freed.
-
- If inflateGetHeader is not used, then the header information is simply
- discarded. The header is always checked for validity, including the header
- CRC if present. inflateReset() will reset the process to discard the header
- information. The application would need to call inflateGetHeader() again to
- retrieve the header from the next gzip stream.
-
- inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent.
-*/
-
-/*
-ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
- unsigned char FAR *window));
-
- Initialize the internal stream state for decompression using inflateBack()
- calls. The fields zalloc, zfree and opaque in strm must be initialized
- before the call. If zalloc and zfree are Z_NULL, then the default library-
- derived memory allocation routines are used. windowBits is the base two
- logarithm of the window size, in the range 8..15. window is a caller
- supplied buffer of that size. Except for special applications where it is
- assured that deflate was used with small window sizes, windowBits must be 15
- and a 32K byte window must be supplied to be able to decompress general
- deflate streams.
-
- See inflateBack() for the usage of these routines.
-
- inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
- the paramaters are invalid, Z_MEM_ERROR if the internal state could not
- be allocated, or Z_VERSION_ERROR if the version of the library does not
- match the version of the header file.
-*/
-
-typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
-typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
-
-ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
- in_func in, void FAR *in_desc,
- out_func out, void FAR *out_desc));
-/*
- inflateBack() does a raw inflate with a single call using a call-back
- interface for input and output. This is more efficient than inflate() for
- file i/o applications in that it avoids copying between the output and the
- sliding window by simply making the window itself the output buffer. This
- function trusts the application to not change the output buffer passed by
- the output function, at least until inflateBack() returns.
-
- inflateBackInit() must be called first to allocate the internal state
- and to initialize the state with the user-provided window buffer.
- inflateBack() may then be used multiple times to inflate a complete, raw
- deflate stream with each call. inflateBackEnd() is then called to free
- the allocated state.
-
- A raw deflate stream is one with no zlib or gzip header or trailer.
- This routine would normally be used in a utility that reads zip or gzip
- files and writes out uncompressed files. The utility would decode the
- header and process the trailer on its own, hence this routine expects
- only the raw deflate stream to decompress. This is different from the
- normal behavior of inflate(), which expects either a zlib or gzip header and
- trailer around the deflate stream.
-
- inflateBack() uses two subroutines supplied by the caller that are then
- called by inflateBack() for input and output. inflateBack() calls those
- routines until it reads a complete deflate stream and writes out all of the
- uncompressed data, or until it encounters an error. The function's
- parameters and return types are defined above in the in_func and out_func
- typedefs. inflateBack() will call in(in_desc, &buf) which should return the
- number of bytes of provided input, and a pointer to that input in buf. If
- there is no input available, in() must return zero--buf is ignored in that
- case--and inflateBack() will return a buffer error. inflateBack() will call
- out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
- should return zero on success, or non-zero on failure. If out() returns
- non-zero, inflateBack() will return with an error. Neither in() nor out()
- are permitted to change the contents of the window provided to
- inflateBackInit(), which is also the buffer that out() uses to write from.
- The length written by out() will be at most the window size. Any non-zero
- amount of input may be provided by in().
-
- For convenience, inflateBack() can be provided input on the first call by
- setting strm->next_in and strm->avail_in. If that input is exhausted, then
- in() will be called. Therefore strm->next_in must be initialized before
- calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
- immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
- must also be initialized, and then if strm->avail_in is not zero, input will
- initially be taken from strm->next_in[0 .. strm->avail_in - 1].
-
- The in_desc and out_desc parameters of inflateBack() is passed as the
- first parameter of in() and out() respectively when they are called. These
- descriptors can be optionally used to pass any information that the caller-
- supplied in() and out() functions need to do their job.
-
- On return, inflateBack() will set strm->next_in and strm->avail_in to
- pass back any unused input that was provided by the last in() call. The
- return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
- if in() or out() returned an error, Z_DATA_ERROR if there was a format
- error in the deflate stream (in which case strm->msg is set to indicate the
- nature of the error), or Z_STREAM_ERROR if the stream was not properly
- initialized. In the case of Z_BUF_ERROR, an input or output error can be
- distinguished using strm->next_in which will be Z_NULL only if in() returned
- an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
- out() returning non-zero. (in() will always be called before out(), so
- strm->next_in is assured to be defined if out() returns non-zero.) Note
- that inflateBack() cannot return Z_OK.
-*/
-
-ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
-/*
- All memory allocated by inflateBackInit() is freed.
-
- inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
- state was inconsistent.
-*/
-
-ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
-/* Return flags indicating compile-time options.
-
- Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
- 1.0: size of uInt
- 3.2: size of uLong
- 5.4: size of voidpf (pointer)
- 7.6: size of z_off_t
-
- Compiler, assembler, and debug options:
- 8: DEBUG
- 9: ASMV or ASMINF -- use ASM code
- 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
- 11: 0 (reserved)
-
- One-time table building (smaller code, but not thread-safe if true):
- 12: BUILDFIXED -- build static block decoding tables when needed
- 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
- 14,15: 0 (reserved)
-
- Library content (indicates missing functionality):
- 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
- deflate code when not needed)
- 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
- and decode gzip streams (to avoid linking crc code)
- 18-19: 0 (reserved)
-
- Operation variations (changes in library functionality):
- 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
- 21: FASTEST -- deflate algorithm with only one, lowest compression level
- 22,23: 0 (reserved)
-
- The sprintf variant used by gzprintf (zero is best):
- 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
- 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
- 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
-
- Remainder:
- 27-31: 0 (reserved)
- */
-
-
- /* utility functions */
-
-/*
- The following utility functions are implemented on top of the
- basic stream-oriented functions. To simplify the interface, some
- default options are assumed (compression level and memory usage,
- standard memory allocation functions). The source code of these
- utility functions can easily be modified if you need special options.
-*/
-
-ZEXTERN int Q_ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least the value returned
- by compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
- This function can be used to compress a whole file at once if the
- input file is mmap'ed.
- compress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer.
-*/
-
-ZEXTERN int Q_ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen,
- int level));
-/*
- Compresses the source buffer into the destination buffer. The level
- parameter has the same meaning as in deflateInit. sourceLen is the byte
- length of the source buffer. Upon entry, destLen is the total size of the
- destination buffer, which must be at least the value returned by
- compressBound(sourceLen). Upon exit, destLen is the actual size of the
- compressed buffer.
-
- compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
- memory, Z_BUF_ERROR if there was not enough room in the output buffer,
- Z_STREAM_ERROR if the level parameter is invalid.
-*/
-
-ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
-/*
- compressBound() returns an upper bound on the compressed size after
- compress() or compress2() on sourceLen bytes. It would be used before
- a compress() or compress2() call to allocate the destination buffer.
-*/
-
-ZEXTERN int Q_ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
- const Bytef *source, uLong sourceLen));
-/*
- Decompresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be large enough to hold the
- entire uncompressed data. (The size of the uncompressed data must have
- been saved previously by the compressor and transmitted to the decompressor
- by some mechanism outside the scope of this compression library.)
- Upon exit, destLen is the actual size of the compressed buffer.
- This function can be used to decompress a whole file at once if the
- input file is mmap'ed.
-
- uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory, Z_BUF_ERROR if there was not enough room in the output
- buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
-*/
-
-
-typedef voidp gzFile;
-
-ZEXTERN gzFile Q_ZEXPORT gzopen OF((const char *path, const char *mode));
-/*
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb") but can also include a compression level
- ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
- Huffman only compression as in "wb1h", or 'R' for run-length encoding
- as in "wb1R". (See the description of deflateInit2 for more information
- about the strategy parameter.)
-
- gzopen can be used to read a file which is not in gzip format; in this
- case gzread will directly read from the file without decompression.
-
- gzopen returns NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR). */
-
-ZEXTERN gzFile Q_ZEXPORT gzdopen OF((int fd, const char *mode));
-/*
- gzdopen() associates a gzFile with the file descriptor fd. File
- descriptors are obtained from calls like open, dup, creat, pipe or
- fileno (in the file has been previously opened with fopen).
- The mode parameter is as in gzopen.
- The next call of gzclose on the returned gzFile will also close the
- file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
- descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
- gzdopen returns NULL if there was insufficient memory to allocate
- the (de)compression state.
-*/
-
-ZEXTERN int Q_ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-/*
- Dynamically update the compression level or strategy. See the description
- of deflateInit2 for the meaning of these parameters.
- gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
- opened for writing.
-*/
-
-ZEXTERN int Q_ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-/*
- Reads the given number of uncompressed bytes from the compressed file.
- If the input file was not in gzip format, gzread copies the given number
- of bytes into the buffer.
- gzread returns the number of uncompressed bytes actually read (0 for
- end of file, -1 for error). */
-
-ZEXTERN int Q_ZEXPORT gzwrite OF((gzFile file,
- voidpc buf, unsigned len));
-/*
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of uncompressed bytes actually written
- (0 in case of error).
-*/
-
-ZEXTERN int Q_ZEXPORT gzprintf OF((gzFile file, const char *format, ...));
-/*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error). The number of
- uncompressed bytes written is limited to 4095. The caller should assure that
- this limit is not exceeded. If it is exceeded, then gzprintf() will return
- return an error (0) with nothing written. In this case, there may also be a
- buffer overflow with unpredictable consequences, which is possible only if
- zlib was compiled with the insecure functions sprintf() or vsprintf()
- because the secure snprintf() or vsnprintf() functions were not available.
-*/
-
-ZEXTERN int Q_ZEXPORT gzputs OF((gzFile file, const char *s));
-/*
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-
-ZEXTERN Q_ZEXPORT char * gzgets OF((gzFile file, char *buf, int len));
-/*
- Reads bytes from the compressed file until len-1 characters are read, or
- a newline character is read and transferred to buf, or an end-of-file
- condition is encountered. The string is then terminated with a null
- character.
- gzgets returns buf, or Z_NULL in case of error.
-*/
-
-ZEXTERN int Q_ZEXPORT gzputc OF((gzFile file, int c));
-/*
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-
-ZEXTERN int Q_ZEXPORT gzgetc OF((gzFile file));
-/*
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-
-ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
-/*
- Push one character back onto the stream to be read again later.
- Only one character of push-back is allowed. gzungetc() returns the
- character pushed, or -1 on failure. gzungetc() will fail if a
- character has been pushed but not read yet, or if c is -1. The pushed
- character will be discarded if the stream is repositioned with gzseek()
- or gzrewind().
-*/
-
-ZEXTERN int Q_ZEXPORT gzflush OF((gzFile file, int flush));
-/*
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function. The return value is the zlib
- error number (see function gzerror below). gzflush returns Z_OK if
- the flush parameter is Z_FINISH and all output could be flushed.
- gzflush should be called only when strictly necessary because it can
- degrade compression.
-*/
-
-ZEXTERN z_off_t Q_ZEXPORT gzseek OF((gzFile file,
- z_off_t offset, int whence));
-/*
- Sets the starting position for the next gzread or gzwrite on the
- given compressed file. The offset represents a number of bytes in the
- uncompressed data stream. The whence parameter is defined as in lseek(2);
- the value SEEK_END is not supported.
- If the file is opened for reading, this function is emulated but can be
- extremely slow. If the file is opened for writing, only forward seeks are
- supported; gzseek then compresses a sequence of zeroes up to the new
- starting position.
-
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error, in
- particular if the file is opened for writing and the new starting position
- would be before the current position.
-*/
-
-ZEXTERN int Q_ZEXPORT gzrewind OF((gzFile file));
-/*
- Rewinds the given file. This function is supported only for reading.
-
- gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-*/
-
-ZEXTERN z_off_t Q_ZEXPORT gztell OF((gzFile file));
-/*
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-
- gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-*/
-
-ZEXTERN int Q_ZEXPORT gzeof OF((gzFile file));
-/*
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-
-ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
-/*
- Returns 1 if file is being read directly without decompression, otherwise
- zero.
-*/
-
-ZEXTERN int Q_ZEXPORT gzclose OF((gzFile file));
-/*
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state. The return value is the zlib
- error number (see function gzerror below).
-*/
-
-ZEXTERN Q_ZEXPORT const char * gzerror OF((gzFile file, int *errnum));
-/*
- Returns the error message for the last error which occurred on the
- given compressed file. errnum is set to zlib error number. If an
- error occurred in the file system and not in the compression library,
- errnum is set to Z_ERRNO and the application may consult errno
- to get the exact error code.
-*/
-
-ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
-/*
- Clears the error and end-of-file flags for file. This is analogous to the
- clearerr() function in stdio. This is useful for continuing to read a gzip
- file that is being written concurrently.
-*/
-
- /* checksum functions */
-
-/*
- These functions are not related to compression but are exported
- anyway because they might be useful in applications using the
- compression library.
-*/
-
-ZEXTERN uLong Q_ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
- z_off_t len2));
-/*
- Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
- and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
- each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
- seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
-*/
-
-ZEXTERN uLong Q_ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-/*
- Update a running CRC-32 with the bytes buf[0..len-1] and return the
- updated CRC-32. If buf is NULL, this function returns the required initial
- value for the for the crc. Pre- and post-conditioning (one's complement) is
- performed within this function so it shouldn't be done by the application.
- Usage example:
-
- uLong crc = crc32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- crc = crc32(crc, buffer, length);
- }
- if (crc != original_crc) error();
-*/
-
-ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
-
-/*
- Combine two CRC-32 check values into one. For two sequences of bytes,
- seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
- calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
- check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
- len2.
-*/
-
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int Q_ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-ZEXTERN int Q_ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
-ZEXTERN int Q_ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-ZEXTERN int Q_ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
-ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
- unsigned char FAR *window,
- const char *version,
- int stream_size));
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
- deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
- (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-#define inflateBackInit(strm, windowBits, window) \
- inflateBackInit_((strm), (windowBits), (window), \
- ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN Q_ZEXPORT const char * zError OF((int));
-ZEXTERN int Q_ZEXPORT inflateSyncPoint OF((z_streamp z));
-ZEXTERN Q_ZEXPORT const uLongf * get_crc_table OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZLIB_H */
diff --git a/misc/winutils/Hedgewars.lnk b/misc/winutils/Hedgewars.lnk
index 4f85073..b7763d8 100644
Binary files a/misc/winutils/Hedgewars.lnk and b/misc/winutils/Hedgewars.lnk differ
diff --git a/misc/winutils/include/GL/glut.h b/misc/winutils/include/GL/glut.h
new file mode 100644
index 0000000..aa7428f
--- /dev/null
+++ b/misc/winutils/include/GL/glut.h
@@ -0,0 +1,716 @@
+#ifndef __glut_h__
+#define __glut_h__
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */
+
+/* This program is freely distributable without licensing fees and is
+ provided without guarantee or warrantee expressed or implied. This
+ program is -not- in the public domain. */
+
+#if defined(_WIN32)
+
+/* GLUT 3.7 now tries to avoid including <windows.h>
+ to avoid name space pollution, but Win32's <GL/gl.h>
+ needs APIENTRY and WINGDIAPI defined properly. */
+# if 0
+ /* This would put tons of macros and crap in our clean name space. */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# else
+ /* XXX This is from Win32's <windef.h> */
+# ifndef APIENTRY
+# define GLUT_APIENTRY_DEFINED
+# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__)
+# define APIENTRY __stdcall
+# else
+# define APIENTRY
+# endif
+# endif
+ /* XXX This is from Win32's <winnt.h> */
+# ifndef CALLBACK
+# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__)
+# define CALLBACK __stdcall
+# else
+# define CALLBACK
+# endif
+# endif
+ /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */
+# if defined( __LCC__ )
+# undef WINGDIAPI
+# define WINGDIAPI __stdcall
+# else
+ /* XXX This is from Win32's <wingdi.h> and <winnt.h> */
+# ifndef WINGDIAPI
+# define GLUT_WINGDIAPI_DEFINED
+# define WINGDIAPI __declspec(dllimport)
+# endif
+# endif
+ /* XXX This is from Win32's <ctype.h> */
+# ifndef _WCHAR_T_DEFINED
+typedef unsigned short wchar_t;
+# define _WCHAR_T_DEFINED
+# endif
+# endif
+
+/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
+ in your compile preprocessor options. */
+# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA)
+# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */
+/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
+ define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */
+# ifdef GLUT_USE_SGI_OPENGL
+# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */
+# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */
+# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */
+# else
+# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */
+# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */
+# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */
+# endif
+# endif
+
+/* To disable supression of annoying warnings about floats being promoted
+ to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
+ options. */
+# ifndef GLUT_NO_WARNING_DISABLE
+# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */
+# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */
+# endif
+
+/* Win32 has an annoying issue where there are multiple C run-time
+ libraries (CRTs). If the executable is linked with a different CRT
+ from the GLUT DLL, the GLUT DLL will not share the same CRT static
+ data seen by the executable. In particular, atexit callbacks registered
+ in the executable will not be called if GLUT calls its (different)
+ exit routine). GLUT is typically built with the
+ "/MD" option (the CRT with multithreading DLL support), but the Visual
+ C++ linker default is "/ML" (the single threaded CRT).
+
+ One workaround to this issue is requiring users to always link with
+ the same CRT as GLUT is compiled with. That requires users supply a
+ non-standard option. GLUT 3.7 has its own built-in workaround where
+ the executable's "exit" function pointer is covertly passed to GLUT.
+ GLUT then calls the executable's exit function pointer to ensure that
+ any "atexit" calls registered by the application are called if GLUT
+ needs to exit.
+
+ Note that the __glut*WithExit routines should NEVER be called directly.
+ To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
+
+/* XXX This is from Win32's <process.h> */
+# if !defined(_MSC_VER) && !defined(__cdecl)
+ /* Define __cdecl for non-Microsoft compilers. */
+# define __cdecl
+# define GLUT_DEFINED___CDECL
+# endif
+# ifndef _CRTIMP
+# ifdef _NTSDK
+ /* Definition compatible with NT SDK */
+# define _CRTIMP
+# else
+ /* Current definition */
+# ifdef _DLL
+# define _CRTIMP __declspec(dllimport)
+# else
+# define _CRTIMP
+# endif
+# endif
+# define GLUT_DEFINED__CRTIMP
+# endif
+
+/* GLUT API entry point declarations for Win32. */
+# ifdef GLUT_BUILDING_LIB
+# define GLUTAPI __declspec(dllexport)
+# else
+# ifdef _DLL
+# define GLUTAPI __declspec(dllimport)
+# else
+# define GLUTAPI extern
+# endif
+# endif
+
+/* GLUT callback calling convention for Win32. */
+# define GLUTCALLBACK __cdecl
+
+#endif /* _WIN32 */
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_WIN32)
+# ifndef GLUT_BUILDING_LIB
+extern _CRTIMP void __cdecl exit(int);
+# endif
+#else
+/* non-Win32 case. */
+/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */
+# define APIENTRY
+# define GLUT_APIENTRY_DEFINED
+# define CALLBACK
+/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */
+# define GLUTAPI extern
+# define GLUTCALLBACK
+/* Prototype exit for the non-Win32 case (see above). */
+extern void exit(int);
+#endif
+
+/**
+ GLUT API revision history:
+
+ GLUT_API_VERSION is updated to reflect incompatible GLUT
+ API changes (interface changes, semantic changes, deletions,
+ or additions).
+
+ GLUT_API_VERSION=1 First public release of GLUT. 11/29/94
+
+ GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling,
+ extension. Supports new input devices like tablet, dial and button
+ box, and Spaceball. Easy to query OpenGL extensions.
+
+ GLUT_API_VERSION=3 glutMenuStatus added.
+
+ GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer,
+ glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
+ video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
+ glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
+ glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
+**/
+#ifndef GLUT_API_VERSION /* allow this to be overriden */
+#define GLUT_API_VERSION 3
+#endif
+
+/**
+ GLUT implementation revision history:
+
+ GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
+ API revisions and implementation revisions (ie, bug fixes).
+
+ GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of
+ GLUT Xlib-based implementation. 11/29/94
+
+ GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of
+ GLUT Xlib-based implementation providing GLUT version 2
+ interfaces.
+
+ GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95
+
+ GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95
+
+ GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95
+
+ GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96
+
+ GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner
+ and video resize. 1/3/97
+
+ GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
+
+ GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
+
+ GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
+
+ GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
+
+ GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
+
+ GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
+**/
+#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
+#define GLUT_XLIB_IMPLEMENTATION 15
+#endif
+
+/* Display mode bit masks. */
+#define GLUT_RGB 0
+#define GLUT_RGBA GLUT_RGB
+#define GLUT_INDEX 1
+#define GLUT_SINGLE 0
+#define GLUT_DOUBLE 2
+#define GLUT_ACCUM 4
+#define GLUT_ALPHA 8
+#define GLUT_DEPTH 16
+#define GLUT_STENCIL 32
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_MULTISAMPLE 128
+#define GLUT_STEREO 256
+#endif
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_LUMINANCE 512
+#endif
+
+/* Mouse buttons. */
+#define GLUT_LEFT_BUTTON 0
+#define GLUT_MIDDLE_BUTTON 1
+#define GLUT_RIGHT_BUTTON 2
+
+/* Mouse button state. */
+#define GLUT_DOWN 0
+#define GLUT_UP 1
+
+#if (GLUT_API_VERSION >= 2)
+/* function keys */
+#define GLUT_KEY_F1 1
+#define GLUT_KEY_F2 2
+#define GLUT_KEY_F3 3
+#define GLUT_KEY_F4 4
+#define GLUT_KEY_F5 5
+#define GLUT_KEY_F6 6
+#define GLUT_KEY_F7 7
+#define GLUT_KEY_F8 8
+#define GLUT_KEY_F9 9
+#define GLUT_KEY_F10 10
+#define GLUT_KEY_F11 11
+#define GLUT_KEY_F12 12
+/* directional keys */
+#define GLUT_KEY_LEFT 100
+#define GLUT_KEY_UP 101
+#define GLUT_KEY_RIGHT 102
+#define GLUT_KEY_DOWN 103
+#define GLUT_KEY_PAGE_UP 104
+#define GLUT_KEY_PAGE_DOWN 105
+#define GLUT_KEY_HOME 106
+#define GLUT_KEY_END 107
+#define GLUT_KEY_INSERT 108
+#endif
+
+/* Entry/exit state. */
+#define GLUT_LEFT 0
+#define GLUT_ENTERED 1
+
+/* Menu usage state. */
+#define GLUT_MENU_NOT_IN_USE 0
+#define GLUT_MENU_IN_USE 1
+
+/* Visibility state. */
+#define GLUT_NOT_VISIBLE 0
+#define GLUT_VISIBLE 1
+
+/* Window status state. */
+#define GLUT_HIDDEN 0
+#define GLUT_FULLY_RETAINED 1
+#define GLUT_PARTIALLY_RETAINED 2
+#define GLUT_FULLY_COVERED 3
+
+/* Color index component selection values. */
+#define GLUT_RED 0
+#define GLUT_GREEN 1
+#define GLUT_BLUE 2
+
+#if defined(_WIN32)
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN ((void*)0)
+#define GLUT_STROKE_MONO_ROMAN ((void*)1)
+
+/* Bitmap font constants (use these in GLUT program). */
+#define GLUT_BITMAP_9_BY_15 ((void*)2)
+#define GLUT_BITMAP_8_BY_13 ((void*)3)
+#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
+#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_BITMAP_HELVETICA_10 ((void*)6)
+#define GLUT_BITMAP_HELVETICA_12 ((void*)7)
+#define GLUT_BITMAP_HELVETICA_18 ((void*)8)
+#endif
+#else
+/* Stroke font opaque addresses (use constants instead in source code). */
+GLUTAPI void *glutStrokeRoman;
+GLUTAPI void *glutStrokeMonoRoman;
+
+/* Stroke font constants (use these in GLUT program). */
+#define GLUT_STROKE_ROMAN (&glutStrokeRoman)
+#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman)
+
+/* Bitmap font opaque addresses (use constants instead in source code). */
+GLUTAPI void *glutBitmap9By15;
+GLUTAPI void *glutBitmap8By13;
+GLUTAPI void *glutBitmapTimesRoman10;
+GLUTAPI void *glutBitmapTimesRoman24;
+GLUTAPI void *glutBitmapHelvetica10;
+GLUTAPI void *glutBitmapHelvetica12;
+GLUTAPI void *glutBitmapHelvetica18;
+
+/* Bitmap font constants (use these in GLUT program). */
+#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15)
+#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13)
+#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10)
+#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24)
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10)
+#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12)
+#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18)
+#endif
+#endif
+
+/* glutGet parameters. */
+#define GLUT_WINDOW_X ((GLenum) 100)
+#define GLUT_WINDOW_Y ((GLenum) 101)
+#define GLUT_WINDOW_WIDTH ((GLenum) 102)
+#define GLUT_WINDOW_HEIGHT ((GLenum) 103)
+#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104)
+#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105)
+#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106)
+#define GLUT_WINDOW_RED_SIZE ((GLenum) 107)
+#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108)
+#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109)
+#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110)
+#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111)
+#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112)
+#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113)
+#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114)
+#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115)
+#define GLUT_WINDOW_RGBA ((GLenum) 116)
+#define GLUT_WINDOW_PARENT ((GLenum) 117)
+#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118)
+#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119)
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120)
+#define GLUT_WINDOW_STEREO ((GLenum) 121)
+#endif
+#if (GLUT_API_VERSION >= 3)
+#define GLUT_WINDOW_CURSOR ((GLenum) 122)
+#endif
+#define GLUT_SCREEN_WIDTH ((GLenum) 200)
+#define GLUT_SCREEN_HEIGHT ((GLenum) 201)
+#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202)
+#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203)
+#define GLUT_MENU_NUM_ITEMS ((GLenum) 300)
+#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400)
+#define GLUT_INIT_WINDOW_X ((GLenum) 500)
+#define GLUT_INIT_WINDOW_Y ((GLenum) 501)
+#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502)
+#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503)
+#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504)
+#if (GLUT_API_VERSION >= 2)
+#define GLUT_ELAPSED_TIME ((GLenum) 700)
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123)
+#endif
+
+#if (GLUT_API_VERSION >= 2)
+/* glutDeviceGet parameters. */
+#define GLUT_HAS_KEYBOARD ((GLenum) 600)
+#define GLUT_HAS_MOUSE ((GLenum) 601)
+#define GLUT_HAS_SPACEBALL ((GLenum) 602)
+#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603)
+#define GLUT_HAS_TABLET ((GLenum) 604)
+#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605)
+#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606)
+#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607)
+#define GLUT_NUM_DIALS ((GLenum) 608)
+#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609)
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610)
+#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611)
+#define GLUT_HAS_JOYSTICK ((GLenum) 612)
+#define GLUT_OWNS_JOYSTICK ((GLenum) 613)
+#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614)
+#define GLUT_JOYSTICK_AXES ((GLenum) 615)
+#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616)
+#endif
+
+#if (GLUT_API_VERSION >= 3)
+/* glutLayerGet parameters. */
+#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800)
+#define GLUT_LAYER_IN_USE ((GLenum) 801)
+#define GLUT_HAS_OVERLAY ((GLenum) 802)
+#define GLUT_TRANSPARENT_INDEX ((GLenum) 803)
+#define GLUT_NORMAL_DAMAGED ((GLenum) 804)
+#define GLUT_OVERLAY_DAMAGED ((GLenum) 805)
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+/* glutVideoResizeGet parameters. */
+#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900)
+#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901)
+#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902)
+#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903)
+#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904)
+#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905)
+#define GLUT_VIDEO_RESIZE_X ((GLenum) 906)
+#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907)
+#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908)
+#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909)
+#endif
+
+/* glutUseLayer parameters. */
+#define GLUT_NORMAL ((GLenum) 0)
+#define GLUT_OVERLAY ((GLenum) 1)
+
+/* glutGetModifiers return mask. */
+#define GLUT_ACTIVE_SHIFT 1
+#define GLUT_ACTIVE_CTRL 2
+#define GLUT_ACTIVE_ALT 4
+
+/* glutSetCursor parameters. */
+/* Basic arrows. */
+#define GLUT_CURSOR_RIGHT_ARROW 0
+#define GLUT_CURSOR_LEFT_ARROW 1
+/* Symbolic cursor shapes. */
+#define GLUT_CURSOR_INFO 2
+#define GLUT_CURSOR_DESTROY 3
+#define GLUT_CURSOR_HELP 4
+#define GLUT_CURSOR_CYCLE 5
+#define GLUT_CURSOR_SPRAY 6
+#define GLUT_CURSOR_WAIT 7
+#define GLUT_CURSOR_TEXT 8
+#define GLUT_CURSOR_CROSSHAIR 9
+/* Directional cursors. */
+#define GLUT_CURSOR_UP_DOWN 10
+#define GLUT_CURSOR_LEFT_RIGHT 11
+/* Sizing cursors. */
+#define GLUT_CURSOR_TOP_SIDE 12
+#define GLUT_CURSOR_BOTTOM_SIDE 13
+#define GLUT_CURSOR_LEFT_SIDE 14
+#define GLUT_CURSOR_RIGHT_SIDE 15
+#define GLUT_CURSOR_TOP_LEFT_CORNER 16
+#define GLUT_CURSOR_TOP_RIGHT_CORNER 17
+#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18
+#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
+/* Inherit from parent window. */
+#define GLUT_CURSOR_INHERIT 100
+/* Blank cursor. */
+#define GLUT_CURSOR_NONE 101
+/* Fullscreen crosshair (if available). */
+#define GLUT_CURSOR_FULL_CROSSHAIR 102
+#endif
+
+/* GLUT initialization sub-API. */
+GLUTAPI void APIENTRY glutInit(int *argcp, char **argv);
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
+#define glutInit glutInit_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void APIENTRY glutInitDisplayString(const char *string);
+#endif
+GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y);
+GLUTAPI void APIENTRY glutInitWindowSize(int width, int height);
+GLUTAPI void APIENTRY glutMainLoop(void);
+
+/* GLUT window sub-API. */
+GLUTAPI int APIENTRY glutCreateWindow(const char *title);
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
+#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
+GLUTAPI void APIENTRY glutDestroyWindow(int win);
+GLUTAPI void APIENTRY glutPostRedisplay(void);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
+GLUTAPI void APIENTRY glutPostWindowRedisplay(int win);
+#endif
+GLUTAPI void APIENTRY glutSwapBuffers(void);
+GLUTAPI int APIENTRY glutGetWindow(void);
+GLUTAPI void APIENTRY glutSetWindow(int win);
+GLUTAPI void APIENTRY glutSetWindowTitle(const char *title);
+GLUTAPI void APIENTRY glutSetIconTitle(const char *title);
+GLUTAPI void APIENTRY glutPositionWindow(int x, int y);
+GLUTAPI void APIENTRY glutReshapeWindow(int width, int height);
+GLUTAPI void APIENTRY glutPopWindow(void);
+GLUTAPI void APIENTRY glutPushWindow(void);
+GLUTAPI void APIENTRY glutIconifyWindow(void);
+GLUTAPI void APIENTRY glutShowWindow(void);
+GLUTAPI void APIENTRY glutHideWindow(void);
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI void APIENTRY glutFullScreen(void);
+GLUTAPI void APIENTRY glutSetCursor(int cursor);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void APIENTRY glutWarpPointer(int x, int y);
+#endif
+
+/* GLUT overlay sub-API. */
+GLUTAPI void APIENTRY glutEstablishOverlay(void);
+GLUTAPI void APIENTRY glutRemoveOverlay(void);
+GLUTAPI void APIENTRY glutUseLayer(GLenum layer);
+GLUTAPI void APIENTRY glutPostOverlayRedisplay(void);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
+GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win);
+#endif
+GLUTAPI void APIENTRY glutShowOverlay(void);
+GLUTAPI void APIENTRY glutHideOverlay(void);
+#endif
+
+/* GLUT menu sub-API. */
+GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
+#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
+GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
+#ifndef GLUT_BUILDING_LIB
+static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
+#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
+#endif
+#endif
+GLUTAPI void APIENTRY glutDestroyMenu(int menu);
+GLUTAPI int APIENTRY glutGetMenu(void);
+GLUTAPI void APIENTRY glutSetMenu(int menu);
+GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value);
+GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu);
+GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
+GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
+GLUTAPI void APIENTRY glutRemoveMenuItem(int item);
+GLUTAPI void APIENTRY glutAttachMenu(int button);
+GLUTAPI void APIENTRY glutDetachMenu(int button);
+
+/* GLUT window callback sub-API. */
+GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
+GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
+GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
+GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
+GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
+GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
+GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
+GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
+GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
+#if (GLUT_API_VERSION >= 2)
+GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
+GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
+GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
+GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
+GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
+GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
+GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
+GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
+GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
+#endif
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
+GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
+GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
+#endif
+#endif
+#endif
+
+/* GLUT color index sub-API. */
+GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
+GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component);
+GLUTAPI void APIENTRY glutCopyColormap(int win);
+
+/* GLUT state retrieval sub-API. */
+GLUTAPI int APIENTRY glutGet(GLenum type);
+GLUTAPI int APIENTRY glutDeviceGet(GLenum type);
+#if (GLUT_API_VERSION >= 2)
+/* GLUT extension support sub-API */
+GLUTAPI int APIENTRY glutExtensionSupported(const char *name);
+#endif
+#if (GLUT_API_VERSION >= 3)
+GLUTAPI int APIENTRY glutGetModifiers(void);
+GLUTAPI int APIENTRY glutLayerGet(GLenum type);
+#endif
+
+/* GLUT font sub-API */
+GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character);
+GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character);
+GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character);
+GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character);
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string);
+GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string);
+#endif
+
+/* GLUT pre-built models sub-API */
+GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
+GLUTAPI void APIENTRY glutWireCube(GLdouble size);
+GLUTAPI void APIENTRY glutSolidCube(GLdouble size);
+GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
+GLUTAPI void APIENTRY glutWireDodecahedron(void);
+GLUTAPI void APIENTRY glutSolidDodecahedron(void);
+GLUTAPI void APIENTRY glutWireTeapot(GLdouble size);
+GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size);
+GLUTAPI void APIENTRY glutWireOctahedron(void);
+GLUTAPI void APIENTRY glutSolidOctahedron(void);
+GLUTAPI void APIENTRY glutWireTetrahedron(void);
+GLUTAPI void APIENTRY glutSolidTetrahedron(void);
+GLUTAPI void APIENTRY glutWireIcosahedron(void);
+GLUTAPI void APIENTRY glutSolidIcosahedron(void);
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
+/* GLUT video resize sub-API. */
+GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param);
+GLUTAPI void APIENTRY glutSetupVideoResizing(void);
+GLUTAPI void APIENTRY glutStopVideoResizing(void);
+GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height);
+GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height);
+
+/* GLUT debugging sub-API. */
+GLUTAPI void APIENTRY glutReportErrors(void);
+#endif
+
+#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
+/* GLUT device control sub-API. */
+/* glutSetKeyRepeat modes. */
+#define GLUT_KEY_REPEAT_OFF 0
+#define GLUT_KEY_REPEAT_ON 1
+#define GLUT_KEY_REPEAT_DEFAULT 2
+
+/* Joystick button masks. */
+#define GLUT_JOYSTICK_BUTTON_A 1
+#define GLUT_JOYSTICK_BUTTON_B 2
+#define GLUT_JOYSTICK_BUTTON_C 4
+#define GLUT_JOYSTICK_BUTTON_D 8
+
+GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore);
+GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode);
+GLUTAPI void APIENTRY glutForceJoystickFunc(void);
+
+/* GLUT game mode sub-API. */
+/* glutGameModeGet. */
+#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0)
+#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1)
+#define GLUT_GAME_MODE_WIDTH ((GLenum) 2)
+#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3)
+#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4)
+#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5)
+#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6)
+
+GLUTAPI void APIENTRY glutGameModeString(const char *string);
+GLUTAPI int APIENTRY glutEnterGameMode(void);
+GLUTAPI void APIENTRY glutLeaveGameMode(void);
+GLUTAPI int APIENTRY glutGameModeGet(GLenum mode);
+#endif
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#ifdef GLUT_APIENTRY_DEFINED
+# undef GLUT_APIENTRY_DEFINED
+# undef APIENTRY
+#endif
+
+#ifdef GLUT_WINGDIAPI_DEFINED
+# undef GLUT_WINGDIAPI_DEFINED
+# undef WINGDIAPI
+#endif
+
+#ifdef GLUT_DEFINED___CDECL
+# undef GLUT_DEFINED___CDECL
+# undef __cdecl
+#endif
+
+#ifdef GLUT_DEFINED__CRTIMP
+# undef GLUT_DEFINED__CRTIMP
+# undef _CRTIMP
+#endif
+
+#endif /* __glut_h__ */
diff --git a/misc/winutils/include/SDL_net.h b/misc/winutils/include/SDL_net.h
new file mode 100644
index 0000000..8bc3eda
--- /dev/null
+++ b/misc/winutils/include/SDL_net.h
@@ -0,0 +1,449 @@
+/*
+ SDL_net: An example cross-platform network library for use with SDL
+ Copyright (C) 1997-2012 Sam Lantinga <slouken at libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* $Id$ */
+
+#ifndef _SDL_NET_H
+#define _SDL_NET_H
+
+#include "SDL.h"
+#include "SDL_endian.h"
+#include "SDL_version.h"
+#include "begin_code.h"
+
+
+
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
+*/
+#define SDL_NET_MAJOR_VERSION 1
+#define SDL_NET_MINOR_VERSION 2
+#define SDL_NET_PATCHLEVEL 8
+
+/* This macro can be used to fill a version structure with the compile-time
+ * version of the SDL_net library.
+ */
+#define SDL_NET_VERSION(X) \
+{ \
+ (X)->major = SDL_NET_MAJOR_VERSION; \
+ (X)->minor = SDL_NET_MINOR_VERSION; \
+ (X)->patch = SDL_NET_PATCHLEVEL; \
+}
+
+/* This function gets the version of the dynamically linked SDL_net library.
+ it should NOT be used to fill a version structure, instead you should
+ use the SDL_NET_VERSION() macro.
+ */
+extern DECLSPEC const SDL_version * SDLCALL SDLNet_Linked_Version(void);
+
+/* Initialize/Cleanup the network API
+ SDL must be initialized before calls to functions in this library,
+ because this library uses utility functions from the SDL library.
+*/
+extern DECLSPEC int SDLCALL SDLNet_Init(void);
+extern DECLSPEC void SDLCALL SDLNet_Quit(void);
+
+/***********************************************************************/
+/* IPv4 hostname resolution API */
+/***********************************************************************/
+
+typedef struct {
+ Uint32 host; /* 32-bit IPv4 host address */
+ Uint16 port; /* 16-bit protocol port */
+} IPaddress;
+
+/* Resolve a host name and port to an IP address in network form.
+ If the function succeeds, it will return 0.
+ If the host couldn't be resolved, the host portion of the returned
+ address will be INADDR_NONE, and the function will return -1.
+ If 'host' is NULL, the resolved host will be set to INADDR_ANY.
+ */
+#ifndef INADDR_ANY
+#define INADDR_ANY 0x00000000
+#endif
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xFFFFFFFF
+#endif
+#ifndef INADDR_BROADCAST
+#define INADDR_BROADCAST 0xFFFFFFFF
+#endif
+extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port);
+
+/* Resolve an ip address to a host name in canonical form.
+ If the ip couldn't be resolved, this function returns NULL,
+ otherwise a pointer to a static buffer containing the hostname
+ is returned. Note that this function is not thread-safe.
+*/
+extern DECLSPEC const char * SDLCALL SDLNet_ResolveIP(const IPaddress *ip);
+
+/* Get the addresses of network interfaces on this system.
+ This returns the number of addresses saved in 'addresses'
+ */
+extern DECLSPEC int SDLCALL SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount);
+
+/***********************************************************************/
+/* TCP network API */
+/***********************************************************************/
+
+typedef struct _TCPsocket *TCPsocket;
+
+/* Open a TCP network socket
+ If ip.host is INADDR_NONE or INADDR_ANY, this creates a local server
+ socket on the given port, otherwise a TCP connection to the remote
+ host and port is attempted. The address passed in should already be
+ swapped to network byte order (addresses returned from
+ SDLNet_ResolveHost() are already in the correct form).
+ The newly created socket is returned, or NULL if there was an error.
+*/
+extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Open(IPaddress *ip);
+
+/* Accept an incoming connection on the given server socket.
+ The newly created socket is returned, or NULL if there was an error.
+*/
+extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Accept(TCPsocket server);
+
+/* Get the IP address of the remote system associated with the socket.
+ If the socket is a server socket, this function returns NULL.
+*/
+extern DECLSPEC IPaddress * SDLCALL SDLNet_TCP_GetPeerAddress(TCPsocket sock);
+
+/* Send 'len' bytes of 'data' over the non-server socket 'sock'
+ This function returns the actual amount of data sent. If the return value
+ is less than the amount of data sent, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*/
+extern DECLSPEC int SDLCALL SDLNet_TCP_Send(TCPsocket sock, const void *data,
+ int len);
+
+/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
+ and store them in the buffer pointed to by 'data'.
+ This function returns the actual amount of data received. If the return
+ value is less than or equal to zero, then either the remote connection was
+ closed, or an unknown socket error occurred.
+*/
+extern DECLSPEC int SDLCALL SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen);
+
+/* Close a TCP network socket */
+extern DECLSPEC void SDLCALL SDLNet_TCP_Close(TCPsocket sock);
+
+
+/***********************************************************************/
+/* UDP network API */
+/***********************************************************************/
+
+/* The maximum channels on a a UDP socket */
+#define SDLNET_MAX_UDPCHANNELS 32
+/* The maximum addresses bound to a single UDP socket channel */
+#define SDLNET_MAX_UDPADDRESSES 4
+
+typedef struct _UDPsocket *UDPsocket;
+typedef struct {
+ int channel; /* The src/dst channel of the packet */
+ Uint8 *data; /* The packet data */
+ int len; /* The length of the packet data */
+ int maxlen; /* The size of the data buffer */
+ int status; /* packet status after sending */
+ IPaddress address; /* The source/dest address of an incoming/outgoing packet */
+} UDPpacket;
+
+/* Allocate/resize/free a single UDP packet 'size' bytes long.
+ The new packet is returned, or NULL if the function ran out of memory.
+ */
+extern DECLSPEC UDPpacket * SDLCALL SDLNet_AllocPacket(int size);
+extern DECLSPEC int SDLCALL SDLNet_ResizePacket(UDPpacket *packet, int newsize);
+extern DECLSPEC void SDLCALL SDLNet_FreePacket(UDPpacket *packet);
+
+/* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
+ each 'size' bytes long.
+ A pointer to the first packet in the array is returned, or NULL if the
+ function ran out of memory.
+ */
+extern DECLSPEC UDPpacket ** SDLCALL SDLNet_AllocPacketV(int howmany, int size);
+extern DECLSPEC void SDLCALL SDLNet_FreePacketV(UDPpacket **packetV);
+
+
+/* Open a UDP network socket
+ If 'port' is non-zero, the UDP socket is bound to a local port.
+ The 'port' should be given in native byte order, but is used
+ internally in network (big endian) byte order, in addresses, etc.
+ This allows other systems to send to this socket via a known port.
+*/
+extern DECLSPEC UDPsocket SDLCALL SDLNet_UDP_Open(Uint16 port);
+
+/* Set the percentage of simulated packet loss for packets sent on the socket.
+*/
+extern DECLSPEC void SDLCALL SDLNet_UDP_SetPacketLoss(UDPsocket sock, int percent);
+
+/* Bind the address 'address' to the requested channel on the UDP socket.
+ If the channel is -1, then the first unbound channel will be bound with
+ the given address as it's primary address.
+ If the channel is already bound, this new address will be added to the
+ list of valid source addresses for packets arriving on the channel.
+ If the channel is not already bound, then the address becomes the primary
+ address, to which all outbound packets on the channel are sent.
+ This function returns the channel which was bound, or -1 on error.
+*/
+extern DECLSPEC int SDLCALL SDLNet_UDP_Bind(UDPsocket sock, int channel, const IPaddress *address);
+
+/* Unbind all addresses from the given channel */
+extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel);
+
+/* Get the primary IP address of the remote system associated with the
+ socket and channel. If the channel is -1, then the primary IP port
+ of the UDP socket is returned -- this is only meaningful for sockets
+ opened with a specific port.
+ If the channel is not bound and not -1, this function returns NULL.
+ */
+extern DECLSPEC IPaddress * SDLCALL SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel);
+
+/* Send a vector of packets to the the channels specified within the packet.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ Each packet will be updated with the status of the packet after it has
+ been sent, -1 if the packet send failed.
+ This function returns the number of packets sent.
+*/
+extern DECLSPEC int SDLCALL SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets);
+
+/* Send a single packet to the specified channel.
+ If the channel specified in the packet is -1, the packet will be sent to
+ the address in the 'src' member of the packet.
+ The packet will be updated with the status of the packet after it has
+ been sent.
+ This function returns 1 if the packet was sent, or 0 on error.
+
+ NOTE:
+ The maximum size of the packet is limited by the MTU (Maximum Transfer Unit)
+ of the transport medium. It can be as low as 250 bytes for some PPP links,
+ and as high as 1500 bytes for ethernet.
+*/
+extern DECLSPEC int SDLCALL SDLNet_UDP_Send(UDPsocket sock, int channel, UDPpacket *packet);
+
+/* Receive a vector of pending packets from the UDP socket.
+ The returned packets contain the source address and the channel they arrived
+ on. If they did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*/
+extern DECLSPEC int SDLCALL SDLNet_UDP_RecvV(UDPsocket sock, UDPpacket **packets);
+
+/* Receive a single packet from the UDP socket.
+ The returned packet contains the source address and the channel it arrived
+ on. If it did not arrive on a bound channel, the the channel will be set
+ to -1.
+ The channels are checked in highest to lowest order, so if an address is
+ bound to multiple channels, the highest channel with the source address
+ bound will be returned.
+ This function returns the number of packets read from the network, or -1
+ on error. This function does not block, so can return 0 packets pending.
+*/
+extern DECLSPEC int SDLCALL SDLNet_UDP_Recv(UDPsocket sock, UDPpacket *packet);
+
+/* Close a UDP network socket */
+extern DECLSPEC void SDLCALL SDLNet_UDP_Close(UDPsocket sock);
+
+
+/***********************************************************************/
+/* Hooks for checking sockets for available data */
+/***********************************************************************/
+
+typedef struct _SDLNet_SocketSet *SDLNet_SocketSet;
+
+/* Any network socket can be safely cast to this socket type */
+typedef struct _SDLNet_GenericSocket {
+ int ready;
+} *SDLNet_GenericSocket;
+
+/* Allocate a socket set for use with SDLNet_CheckSockets()
+ This returns a socket set for up to 'maxsockets' sockets, or NULL if
+ the function ran out of memory.
+ */
+extern DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets);
+
+/* Add a socket to a set of sockets to be checked for available data */
+#define SDLNet_TCP_AddSocket(set, sock) \
+ SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
+#define SDLNet_UDP_AddSocket(set, sock) \
+ SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
+extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
+
+/* Remove a socket from a set of sockets to be checked for available data */
+#define SDLNet_TCP_DelSocket(set, sock) \
+ SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
+#define SDLNet_UDP_DelSocket(set, sock) \
+ SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock))
+extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
+
+/* This function checks to see if data is available for reading on the
+ given set of sockets. If 'timeout' is 0, it performs a quick poll,
+ otherwise the function returns when either data is available for
+ reading, or the timeout in milliseconds has elapsed, which ever occurs
+ first. This function returns the number of sockets ready for reading,
+ or -1 if there was an error with the select() system call.
+*/
+extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout);
+
+/* After calling SDLNet_CheckSockets(), you can use this function on a
+ socket that was in the socket set, to find out if data is available
+ for reading.
+*/
+#define SDLNet_SocketReady(sock) \
+ ((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready)
+
+/* Free a set of sockets allocated by SDL_NetAllocSocketSet() */
+extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set);
+
+
+/***********************************************************************/
+/* Platform-independent data conversion functions */
+/***********************************************************************/
+
+/* Write a 16/32 bit value to network packet buffer */
+extern DECLSPEC void SDLCALL SDLNet_Write16(Uint16 value, void *area);
+extern DECLSPEC void SDLCALL SDLNet_Write32(Uint32 value, void *area);
+
+/* Read a 16/32 bit value from network packet buffer */
+extern DECLSPEC Uint16 SDLCALL SDLNet_Read16(void *area);
+extern DECLSPEC Uint32 SDLCALL SDLNet_Read32(void *area);
+
+/***********************************************************************/
+/* Error reporting functions */
+/***********************************************************************/
+
+/* We'll use SDL's functions for error reporting */
+#define SDLNet_SetError SDL_SetError
+#define SDLNet_GetError SDL_GetError
+
+/* I'm eventually going to try to disentangle SDL_net from SDL, thus making
+ SDL_net an independent X-platform networking toolkit. Not today though....
+
+extern no_parse_DECLSPEC void SDLCALL SDLNet_SetError(const char *fmt, ...);
+extern no_parse_DECLSPEC char * SDLCALL SDLNet_GetError(void);
+*/
+
+
+/* Inline macro functions to read/write network data */
+
+/* Warning, some systems have data access alignment restrictions */
+#if defined(sparc) || defined(mips)
+#define SDL_DATA_ALIGNED 1
+#endif
+#ifndef SDL_DATA_ALIGNED
+#define SDL_DATA_ALIGNED 0
+#endif
+
+/* Write a 16 bit value to network packet buffer */
+#if !SDL_DATA_ALIGNED
+#define SDLNet_Write16(value, areap) \
+ (*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value))
+#else
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define SDLNet_Write16(value, areap) \
+do \
+{ \
+ Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
+ area[0] = (value >> 8) & 0xFF; \
+ area[1] = value & 0xFF; \
+} while ( 0 )
+#else
+#define SDLNet_Write16(value, areap) \
+do \
+{ \
+ Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
+ area[1] = (value >> 8) & 0xFF; \
+ area[0] = value & 0xFF; \
+} while ( 0 )
+#endif
+#endif /* !SDL_DATA_ALIGNED */
+
+/* Write a 32 bit value to network packet buffer */
+#if !SDL_DATA_ALIGNED
+#define SDLNet_Write32(value, areap) \
+ *SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value);
+#else
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define SDLNet_Write32(value, areap) \
+do \
+{ \
+ Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
+ area[0] = (value >> 24) & 0xFF; \
+ area[1] = (value >> 16) & 0xFF; \
+ area[2] = (value >> 8) & 0xFF; \
+ area[3] = value & 0xFF; \
+} while ( 0 )
+#else
+#define SDLNet_Write32(value, areap) \
+do \
+{ \
+ Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \
+ area[3] = (value >> 24) & 0xFF; \
+ area[2] = (value >> 16) & 0xFF; \
+ area[1] = (value >> 8) & 0xFF; \
+ area[0] = value & 0xFF; \
+} while ( 0 )
+#endif
+#endif /* !SDL_DATA_ALIGNED */
+
+/* Read a 16 bit value from network packet buffer */
+#if !SDL_DATA_ALIGNED
+#define SDLNet_Read16(areap) \
+ (SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap)))
+#else
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define SDLNet_Read16(areap) \
+ (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0)
+#else
+#define SDLNet_Read16(areap) \
+ (((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0)
+#endif
+#endif /* !SDL_DATA_ALIGNED */
+
+/* Read a 32 bit value from network packet buffer */
+#if !SDL_DATA_ALIGNED
+#define SDLNet_Read32(areap) \
+ (SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap)))
+#else
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+#define SDLNet_Read32(areap) \
+ (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \
+ ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0)
+#else
+#define SDLNet_Read32(areap) \
+ (((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \
+ ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0)
+#endif
+#endif /* !SDL_DATA_ALIGNED */
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+}
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_NET_H */
diff --git a/misc/winutils/lib/libSDL.la b/misc/winutils/lib/libSDL.la
deleted file mode 100644
index 4f0519f..0000000
--- a/misc/winutils/lib/libSDL.la
+++ /dev/null
@@ -1,41 +0,0 @@
-# libSDL.la - a libtool library file
-# Generated by ltmain.sh (GNU libtool) 2.2.6
-#
-# Please DO NOT delete this file!
-# It is necessary for linking the library.
-
-# The name that we can dlopen(3).
-dlname='../bin/SDL.dll'
-
-# Names of this library.
-library_names='libSDL.dll.a'
-
-# The name of the static archive.
-old_library='libSDL.a'
-
-# Linker flags that can not go in dependency_libs.
-inherited_linker_flags=''
-
-# Libraries that this one depends upon.
-dependency_libs=' -luser32 -lgdi32 -lwinmm -ldxguid'
-
-# Names of additional weak libraries provided by this library
-weak_library_names=''
-
-# Version information for libSDL.
-current=11
-age=11
-revision=3
-
-# Is this an already installed library?
-installed=yes
-
-# Should we warn about portability when linking against -modules?
-shouldnotlink=no
-
-# Files to dlopen/dlpreopen
-dlopen=''
-dlpreopen=''
-
-# Directory that this library needs to be installed in:
-libdir='/usr/local/lib'
diff --git a/misc/xfire/license.txt b/misc/xfire/license.txt
deleted file mode 100644
index 2d61efd..0000000
--- a/misc/xfire/license.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-Terms and Conditions
-AGREEMENT BETWEEN USER AND XFIRE INC.
-This is a legal agreement between you and Xfire Inc. ("Xfire") with respect to your access and use of the Xfire Service, which may also include Xfire software, content and related documentation and information (collectively, the "Service"). You must accept without modification all of the terms, conditions, and notices contained in these Terms of Use in order to access and/or use the Service (collectively, the "Terms of Use" or "Agreement"). If you do not accept these Terms of Use in their entirety, you may not access or use the Service.
-
-Portions of the Service may be governed by posted guidelines, rules, or other terms and conditions. All such guidelines, rules, terms and conditions are hereby incorporated by reference into these Terms of Use. In the event of a conflict between such other guidelines, rules, terms and conditions and these Terms of Use, the Terms of Use shall control, except that the Xfire Service Privacy Policy, referenced below, supersedes any conflicting language in these Terms of Use and/or any other guidelines, rules, terms and conditions published in connection with the Service with respect to the subject matter covered by such privacy policy.
-
-MODIFICATION OF THESE TERMS OF USE; UPDATES
-Xfire may change the Terms of Use at any time and such changes shall be effective immediately. You are responsible for regularly reviewing the Terms of Use. The most recent version of the Terms of Use can be found at http://www.xfire.com/xf/terms.php. Your continued use of the Service affirms your agreement to the Terms of Use and any changes.
-
-Xfire is not obligated to provide updates or improvements to the Service. However, if Xfire, in its sole discretion, updates or improves the Service, these Terms of Use shall apply to such updates and improvements unless expressly noted otherwise.
-
-CLIENT SOFTWARE USE LIMITATION
-YOU MAY ONLY USE XFIRE CLIENT SOFTWARE OR AUTHORIZED THIRD-PARTY SOFTWARE TO ACCESS AND/OR USE THE SERVICE. You may not use any software or services in conjunction with the Xfire software or authorized third-party software which modifies or reroutes, or attempts to modify or reroute, the Service. You may not authorize any third party to access and/or use the Service on your behalf using any automated process such as a BOT, a spider or periodic caching of information stored by the Xfire Service on your behalf without a separate written agreement with Xfire. You may not use any software or hardware that reduces the number of users directly accessing or using the Service (sometimes called 'multiplexing' or 'pooling' software or hardware).
-
-You may not modify, copy, distribute, transmit, display, perform, reproduce, publish, license, create derivative works from, transfer, or sell any information, software, products or services that are part of the Service except as expressly provided in these Terms of Use.
-
-NO UNLAWFUL OR PROHIBITED USE; RESPONSIBILITY FOR YOUR ACCOUNT
-As a condition of your use of the Service, you will not use the Service for any purpose that is unlawful or prohibited by these Terms of Use. You may not use the Service in any manner that could damage, disable, overburden, or impair the Service or interfere with any other party's use and enjoyment of it. You may not attempt to gain unauthorized access to any account, computer systems or networks associated with the Service or to otherwise interfere with or disrupt any accounts, computer systems or networks connected to the Service. You may not obtain or attempt to obtain any materials or information through any means not intentionally made available or provided for through the Service. You may not use access to the Service to obtain information necessary for you to design, develop or update unauthorized software that you use or provide to others to use to access the Service. You may not charge others to use the Service either directly or indirectly without the express written agreement of Xfire.
-Subject to these Terms of Use, you may use the Service within your commercial organization, but you may not use the Service to advertise or offer to buy or sell any goods or services, or to run a business or commercial entity without the express written agreement of Xfire.
-You agree to use the Service only to send, receive, and transfer appropriate messages and material. By way of example, and not as a limitation, you agree that when using the Service, you will not:
-
-
- Use the Service in connection with surveys, contests, pyramid schemes, chain letters, junk email, spamming or any duplicative, bulk or unsolicited messages (commercial or otherwise).
-
- Defame, abuse, harass, stalk, threaten or otherwise violate the legal rights (such as rights of privacy and publicity) of others.
-
- Create a false identity for the purpose of misleading others.
-
- Publish, transfer, distribute or disseminate any inappropriate, profane, defamatory, obscene, indecent or unlawful topic, name, material or information.
-
- Transfer, stream, or otherwise make available, files or other material that contain images, photographs, software or other material protected by intellectual property laws, including, by way of example, and not as limitation, copyright or trademark laws (or by rights of privacy or publicity) unless you own or control the rights thereto or have received all necessary consents to do the same.
-
- Use any material or information, including images or photographs, which is made available through the Service in any manner that infringes any copyright, trademark, patent, trade secret, or other proprietary right of any party.
-
- Transfer, stream or otherwise make available, files or other material that contain viruses, Trojan horses, worms, time bombs, cancelbots, corrupted files, or any other similar software or programs that may damage the operation of another's computer or property of another.
-
- Download any file or other material transferred by another user of the Service that you know, or reasonably should know, cannot be legally distributed in such manner.
-
- Use, download or otherwise copy, or provide (whether or not for a fee) to a person or entity any directory of users of the Service or other user or usage information or any portion thereof.
-
- Falsify or delete any author attributions, legal or other proper notices or proprietary designations or labels of the origin or source of software or other material contained in a file that is transferred.
-
- Violate any code of conduct or other guidelines which may be applicable to the Service.
-
- Use any portion of the Service to harvest or otherwise collect information about others, including e-mail addresses.
-
-Xfire reserves the right at all times to monitor communications on the Service and disclose any information Xfire deems necessary to (i) ensure your compliance with this Agreement; (ii) satisfy any applicable law, regulation or legal process; or (iii) protect the rights, property, and interests of Xfire, its employees or the public. Xfire also reserves the right to edit, refuse to transfer or to remove any information or materials, in whole or in part, in Xfire's sole discretion.
-
-Always use caution when giving out any personally identifiable information about yourself or your children in the Service. Xfire does not control or endorse the content, messages or information exchanged by means of the Service and, therefore, Xfire specifically disclaims any liability with regard to the Service and any actions resulting from your participation in the Service.
-
-You are responsible for all activities that occur in your Service account. You agree to notify Xfire immediately of any unauthorized use of your account or breach in security known to you related to the Service.
-
-
-PRIVACY
-See the Xfire Service Privacy Statement at http://www.xfire.com/xf/privacy.php for disclosures relating to the collection and use of your information.
-
-
-INTERACTION WITH THIRD PARTY SITES AND SERVICES
-The Service may allow you to interact with third-party Web sites and Web services ("Link(s)"). The Links are not under the control of Xfire and Xfire is not responsible for the contents of any Links, including without limitation any link contained in a Link, or any changes or updates to a Link. Xfire is not responsible for any form of transmission received from any Link, nor is Xfire responsible if the Link is not working appropriately. Xfire is providing these Links to you only as a convenience, and the inclusion of any Link does not imply endorsement by Xfire of the Link or any association with its operators. You are responsible for viewing and abiding by any privacy statements and terms of use posted in connection with the Links.
-
-You are solely responsible for any dealings with third parties (including advertisers) who support the Service, including the delivery of and payment for goods and services.
-
-TERMS OF USE FOR SERVICE-ENABLED PROPERTIES
-For the terms and conditions governing your use of any Xfire or authorized third party Web site or service that enables you to use the Service other than the Service itself ("Service-Enabled Properties"), please refer to the applicable Terms of Use for such Service-Enabled Properties.
-
-SOFTWARE AND CONTENT AVAILABLE ON THE SERVICE
-All Xfire content and software (if any) that is made available to view and/or download in connection with the Service ("Software") is owned by and is the copyrighted work of Xfire and/or its suppliers and is licensed, not sold. Your use of the Software is governed by the terms of the license agreement, if any, which accompanies or is included with the Software ("License Agreement"). You may not install or use any Software that is accompanied by or includes a License Agreement unless you first agree to the License Agreement terms. For any Software not accompanied by a license agreement, Xfire hereby grants to you, the user, a non-exclusive, revocable, personal, non-transferable license to use the Software solely in connection with the Service in accordance with these Terms of Use. You may not lend, lease, rent or sublicense the Software or any aspect of the Service.
-
-You will not disassemble, decompile, or reverse engineer the Software. All Software is protected by copyright laws and international treaty provisions. Any unauthorized reproduction or redistribution of the Software is expressly prohibited by law, and may result in severe civil and criminal penalties. WITHOUT LIMITING THE FOREGOING, COPYING OR REPRODUCTION OF THE SOFTWARE TO ANY OTHER SERVER OR LOCATION FOR FURTHER REPRODUCTION OR REDISTRIBUTION IS EXPRESSLY PROHIBITED. THE SOFTWARE IS WARRANTED, IF AT ALL, ONLY ACCORDING TO THE TERMS OF THE LICENSE AGREEMENT. You acknowledge that the Software, and any accompanying documentation and/or technical information, is subject to applicable export control laws and regulations of the U.S.A. You agree not to export or re-export the Software, directly or indirectly, to any countries that are subject to U.S.A. export restrictions.
-
-Your license to use the Software with the Service terminates when you terminate your use of the Service. Your license to use the Software with the Service may also terminate if Xfire, in its sole discretion, modifies the Service to no longer support such Software.
-
-NO WARRANTIES; LIABILITY DISCLAIMER; EXCLUSIVE REMEDY
-XFIRE PROVIDES THE SERVICE AND THE SOFTWARE "AS IS," "WITH ALL FAULTS" AND "AS AVAILABLE," AND THE ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH YOU. XFIRE, ITS AFFILIATES, ITS RESELLERS, DISTRIBUTORS, SERVICE PROVIDERS AND/OR SUPPLIERS (COLLECTIVELY, THE "XFIRE PARTIES") MAKE NO WARRANTIES. THE XFIRE PARTIES DISCLAIM ANY AND ALL WARRANTIES, EXPRESS, STATUTORY AND IMPLIED, INCLUDING WITHOUT LIMITATION (1) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, WORKMANLIKE EFFORT, ACCURACY, TITLE, QUIET ENJOYMENT, NO ENCUMBRANCES, NO LIENS AND NON-INFRINGEMENT, (2) WARRANTIES ARISING THROUGH COURSE OF DEALING OR USAGE OF TRADE, AND (3) WARRANTIES THAT ACCESS TO OR USE OF THE SERVICE WILL BE UNINTERRUPTED OR ERROR-FREE. THERE ARE NO WARRANTIES THAT EXTEND BEYOND THE FACE OF THIS AGREEMENT. XFIRE MAY CHANGE THE SERVICE OR THE FEATURES IN ANY WAY, AND AT ANY TIME AND FOR ANY REASON.
-
-IN NO EVENT SHALL ANY OF THE XFIRE PARTIES BE LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, SPECIAL, INCIDENTAL, OR PUNITIVE DAMAGES ARISING OUT OF, BASED ON, OR RESULTING FROM THIS AGREEMENT OR YOUR USE OF THE SERVICE, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, WITH THE DELAY OR INABILITY TO USE THE SERVICE, THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, OR FOR ANY INFORMATION, SOFTWARE, PRODUCTS, OR SERVICES OBTAINED THROUGH THE SERVICE, OR OTHERWISE ARISING OUT OF THE USE OF THE SERVICE, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF XFIREOR ANY OF ITS SUPPLIERS HAS BEEN ADVISED OF THE POSSIBILITY OF DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
-
-IF YOU ARE DISSATISFIED WITH ANY PORTION OF THE SERVICE, OR WITH ANY OF THESE TERMS OF USE, YOUR SOLE AND EXCLUSIVE REMEDY IS TO DISCONTINUE USING THE SERVICE.
-
-INDEMNITY
-You agree to indemnify and hold Xfire, its officers, and employees, harmless from any claim or demand, including reasonable attorneys' fees, made by any third party due to or arising out of your use of the Services, the violation of these Terms of Use by you, or the infringement by you, or other user of the Services using your computer or identity, of any intellectual property or other right of any person or entity.
-
-CUSTOMER SUPPORT
-Xfire may, but is not required to, provide you with customer support ("Support"). Unless you have entered into a separate written support agreement with Xfire with respect to the Service, Xfire may terminate any Support it provides at any time in its sole discretion.
-
-Authorized third-party software that uses the Service is not supported by Xfire and you should contact the provider of such software for support, if any.
-
-TERMINATION/ACCESS RESTRICTION
-Unless you, or a third party on your behalf, have entered into a separate written agreement with Xfire that modifies these Terms of Use, Xfire reserves the right, in its sole discretion, to terminate your access to and use of the Service or any portion thereof at any time, without notice. Also, unless you or a third party on your behalf have entered into a separate agreement with Xfire, Xfire may terminate or suspend your access to the Service for inactivity, which is defined as failing to log onto the Service for an extended period of time, as determined by Xfire.
-ELECTRONIC NOTICES
-You consent to Xfire providing you any information regarding the Service in electronic form. Xfire may provide such information to you via e-mail at the e-mail address you specified when you registered for the Service, by instant message to your account, or by access to a Xfire web site. As long as you access and use the Service, you will have the necessary software and hardware to receive such notices. If you do not consent to receive any notices electronically, you must discontinue your use of the Service.
-
-GENERAL
-If you reside in the United States, claims for enforcement, breach or violation of duties or rights under these Terms of Use are governed by the laws of the State of California, without reference to conflict of laws principles. All other claims, including, without limitation, claims under or for violation of state consumer protection laws, unfair competition laws, and in tort, are governed by the laws of your state of residence in the United States. If you reside outside of the United States, these Terms of Use are governed by the laws of the State of California, without reference to conflict of laws principles. You hereby irrevocably consent to the exclusive jurisdiction and venue of courts in San Mateo County, California, U.S.A. in all disputes arising out of or relating to the use of the Service.
-
-YOU AND XFIRE AGREE THAT ANY CAUSE OF ACTION ARISING OUT OF OR RELATED TO THE SERVICE MUST COMMENCE WITHIN ONE (1) YEAR AFTER THE CAUSE OF ACTION ACCRUES. OTHERWISE, SUCH CAUSE OF ACTION IS PERMANENTLY BARRED.
-
-Xfire may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in any Web pages that are part of the Service. Except as expressly provided in these Terms of Use, the furnishing of such Web pages to you does not give you any license to these patents, trademarks, copyrights, or other intellectual property. Any rights not expressly granted herein are reserved.
-
-June 2004
-
-
-
diff --git a/misc/xfire/xfiregameclient.cpp b/misc/xfire/xfiregameclient.cpp
deleted file mode 100644
index 9d43d76..0000000
--- a/misc/xfire/xfiregameclient.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* This file is NOT open source. See "license.txt" to read the full license provided with the Xfire SDK. */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <tlhelp32.h>
-
-#include "xfiregameclient.h"
-
-static HMODULE g_toucan_dll = NULL;
-static void HelperInit();
-static HMODULE HelperGetToucanDLL();
-
-typedef int (*XfireSetCustomGameDataAFunction)(int , const char **, const char **);
-typedef int (*XfireSetCustomGameDataWFunction)(int , const wchar_t **, const wchar_t **);
-typedef int (*XfireSetCustomGameDataUTF8Function)(int , const char **, const char **);
-
-static XfireSetCustomGameDataAFunction ptr_XfireSetCustomGameDataA = NULL;
-static XfireSetCustomGameDataWFunction ptr_XfireSetCustomGameDataW = NULL;
-static XfireSetCustomGameDataUTF8Function ptr_XfireSetCustomGameDataUTF8 = NULL;
-
-/* make sure we are going to call the ANSI version */
-#ifdef MODULEENTRY32
-#undef MODULEENTRY32
-#endif
-
-#ifdef Module32First
-#undef Module32First
-#endif
-
-#ifdef Module32Next
-#undef Module32Next
-#endif
-
-
-int XfireIsLoaded()
-{
- HelperInit();
- if (ptr_XfireSetCustomGameDataA &&
- ptr_XfireSetCustomGameDataW &&
- ptr_XfireSetCustomGameDataUTF8)
- return 1;
- return 0;
-}
-
-int XfireSetCustomGameDataA(int num_keys, const char **keys, const char **values)
-{
- HelperInit();
- if (ptr_XfireSetCustomGameDataA)
- return ptr_XfireSetCustomGameDataA(num_keys, keys, values);
- return 1;
-}
-
-int XfireSetCustomGameDataW(int num_keys, const wchar_t **keys, const wchar_t **values)
-{
- HelperInit();
- if (ptr_XfireSetCustomGameDataW)
- return ptr_XfireSetCustomGameDataW(num_keys, keys, values);
- return 1;
-}
-
-int XfireSetCustomGameDataUTF8(int num_keys, const char **keys, const char **values)
-{
- HelperInit();
- if (ptr_XfireSetCustomGameDataUTF8)
- return ptr_XfireSetCustomGameDataUTF8(num_keys, keys, values);
- return 1;
-}
-
-/* ------------------------------------------------------------------------- */
-static void HelperInit()
-{
- if (!ptr_XfireSetCustomGameDataA ||
- !ptr_XfireSetCustomGameDataW ||
- !ptr_XfireSetCustomGameDataUTF8)
- {
- HMODULE toucan_dll = HelperGetToucanDLL();
- if (toucan_dll)
- {
- ptr_XfireSetCustomGameDataA = (XfireSetCustomGameDataAFunction)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataA_V1");
- ptr_XfireSetCustomGameDataW = (XfireSetCustomGameDataWFunction)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataW_V1");
- ptr_XfireSetCustomGameDataUTF8 = (XfireSetCustomGameDataUTF8Function)::GetProcAddress(toucan_dll, "ToucanSendGameClientDataUTF8_V1");
- }
- }
-}
-
-
-static HMODULE HelperGetToucanDLL()
-{
- if (g_toucan_dll)
- return g_toucan_dll;
-
- /*
- ** We need to enumerate the DLLs loaded to find toucan dll.
- ** This is done because the toucan dll changes with each update.
- ** The toucan dll has the following format. "xfire_toucan_{BUILD_NUMBER}.dll"
- ** We simply try to find a dll w/ the prefix "xfire_toucan"
- */
- HANDLE snapshot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
- if (snapshot_handle != INVALID_HANDLE_VALUE)
- {
- MODULEENTRY32 module_entry;
- module_entry.dwSize = sizeof(MODULEENTRY32);
-
- BOOL result = Module32First(snapshot_handle, &module_entry);
- char module_name[] = "xfire_toucan";
- DWORD module_name_len = sizeof(module_name)-1;
- while (result)
- {
- if (CompareStringA(LOCALE_USER_DEFAULT, NORM_IGNORECASE, module_entry.szModule, module_name_len, module_name, module_name_len) == CSTR_EQUAL)
- {
- g_toucan_dll = module_entry.hModule;
- break;
- }
- result = Module32Next(snapshot_handle, &module_entry);
- }
-
- CloseHandle(snapshot_handle);
- }
-
- return g_toucan_dll;
-}
diff --git a/project_files/Android-build/CMakeLists.txt b/project_files/Android-build/CMakeLists.txt
index 778ec20..15f9e3c 100644
--- a/project_files/Android-build/CMakeLists.txt
+++ b/project_files/Android-build/CMakeLists.txt
@@ -18,7 +18,7 @@
find_program(ANT ant DOC "Path to the java package creator: ant")
if(NOT EXISTS ${ANT})
- MESSAGE(FATAL_ERROR "Couldn't detect the Ant build tool")
+ message(FATAL_ERROR "Couldn't detect the Ant build tool")
endif()
if(NOT ANDROID_NDK)
@@ -26,22 +26,22 @@ if(NOT ANDROID_NDK)
endif()
if(IS_DIRECTORY "${ANDROID_NDK}")
- MESSAGE(STATUS "Detected the android NDK directory at: " ${ANDROID_NDK})
+ message(STATUS "Detected the android NDK directory at: " ${ANDROID_NDK})
else ()
- MESSAGE(FATAL_ERROR "Couldn't detect the Android NDK directory")
+ message(FATAL_ERROR "Couldn't detect the Android NDK directory")
endif()
if(NOT ANDROID_NDK_TOOLCHAINDIR)
- set(toolchainbase "${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.4.3/prebuilt")
+ set(toolchainbase "${ANDROID_NDK}/toolchains/arm-linux-androideabi-4.6/prebuilt")
find_path(ANDROID_NDK_TOOLCHAINDIR arm-linux-androideabi
"${toolchainbase}/linux-x86"
"${toolchainbase}/windows")
endif()
if(IS_DIRECTORY "${ANDROID_NDK_TOOLCHAINDIR}")
- MESSAGE(STATUS "Detected the Android NDK toolchain at: ${ANDROID_NDK_TOOLCHAINDIR}")
+ message(STATUS "Detected the Android NDK toolchain at: ${ANDROID_NDK_TOOLCHAINDIR}")
else ()
- MESSAGE(FATAL_ERROR "Couldn't detect the Android NDK toolchain directory: ${ANDROID_NDK_TOOLCHAINDIR}")
+ message(FATAL_ERROR "Couldn't detect the Android NDK toolchain directory: ${ANDROID_NDK_TOOLCHAINDIR}")
endif()
if(NOT ANDROID_SDK)#Check if its defined at the cmdline
@@ -52,9 +52,9 @@ if(NOT ANDROID_SDK)#Check if its defined at the cmdline
endif()
if( IS_DIRECTORY "${ANDROID_SDK}")
- MESSAGE(STATUS "Detected the android SDK directory at: " ${ANDROID_SDK})
+ message(STATUS "Detected the android SDK directory at: " ${ANDROID_SDK})
else ()
- MESSAGE(FATAL_ERROR "Couldn't detect the Android SDK directory")
+ message(FATAL_ERROR "Couldn't detect the Android SDK directory")
endif()
if( NOT FPC_DIR)
@@ -66,18 +66,18 @@ if( NOT FPC_DIR)
endif()
if( IS_DIRECTORY "${FPC_DIR}")
- MESSAGE(STATUS "Detected the FreePascal directory at: " "${FPC_DIR}")
+ message(STATUS "Detected the FreePascal directory at: " "${FPC_DIR}")
else ()
- MESSAGE(FATAL_ERROR "Couldn't detect the FreePascal directory")
+ message(FATAL_ERROR "Couldn't detect the FreePascal directory")
endif()
set(SDL_DIR /home/richard/Downloads/android-project)
-set(ANDROID_SDK_API_LVL 14)
+set(ANDROID_SDK_API_LVL 16)
set(ANDROID_NDK_API_LVL 5)
-MESSAGE(STATUS "Creating Makefile.android...")
+message(STATUS "Creating Makefile.android...")
configure_file(Templates/Makefile.android .)
@@ -89,9 +89,9 @@ if(ANDROID_EXEC)
"--target android-${ANDROID_SDK_API_LVL}"
OUTPUT_VARIABLE androidoutput
)
- MESSAGE(STATUS "Updating android project config...\n" ${androidoutput})
+ message(STATUS "Updating android project config...\n" ${androidoutput})
else()
- MESSAGE(FATAL_ERROR "Couldn't find the android executable in ${ANDROID_SDK}/platform-tools or ${ANDROID_SDK}/tools.")
+ message(FATAL_ERROR "Couldn't find the android executable in ${ANDROID_SDK}/platform-tools or ${ANDROID_SDK}/tools.")
endif()
exec_program(${HGCOMMAND}
diff --git a/project_files/Android-build/Licenses/Android Support library/NOTICE.txt b/project_files/Android-build/Licenses/Android Support library/NOTICE.txt
new file mode 100644
index 0000000..1fdb31d
--- /dev/null
+++ b/project_files/Android-build/Licenses/Android Support library/NOTICE.txt
@@ -0,0 +1,195 @@
+Notice for all the files in this folder.
+------------------------------------------------------------
+
+
+
+ Copyright (c) 2005-2008, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+
diff --git a/project_files/Android-build/Licenses/ini4j/LICENSE.txt b/project_files/Android-build/Licenses/ini4j/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/project_files/Android-build/Licenses/ini4j/LICENSE.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/project_files/Android-build/Licenses/ini4j/NOTICE.txt b/project_files/Android-build/Licenses/ini4j/NOTICE.txt
new file mode 100644
index 0000000..5013504
--- /dev/null
+++ b/project_files/Android-build/Licenses/ini4j/NOTICE.txt
@@ -0,0 +1,13 @@
+Copyright 2005,2009 Ivan SZKIBA
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/AndroidManifest.xml b/project_files/Android-build/SDL-android-project/AndroidManifest.xml
index 3c62ac5..526c15d 100644
--- a/project_files/Android-build/SDL-android-project/AndroidManifest.xml
+++ b/project_files/Android-build/SDL-android-project/AndroidManifest.xml
@@ -1,54 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.hedgewars.hedgeroid"
- android:versionCode="8"
- android:installLocation="preferExternal" android:versionName="0.2">
- <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="7"></uses-sdk>
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
- <application android:label="@string/app_name" android:icon="@drawable/icon">
- <activity android:name=".MainActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+ package="org.hedgewars.hedgeroid"
+ android:installLocation="preferExternal"
+ android:versionCode="8"
+ android:versionName="0.2" >
+
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="14" >
+ </uses-sdk>
+
+ <uses-permission android:name="android.permission.INTERNET" >
+ </uses-permission>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
+ </uses-permission>
+
+ <application
+ android:icon="@drawable/icon"
+ android:label="@string/app_name" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <activity android:name=".SDLActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation='landscape'>
- </activity>
-
- <activity android:name=".Downloader.DownloadFragment"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.Dialog">
- </activity>
-
- <activity android:name=".Downloader.DownloadListActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation='landscape'
- android:launchMode="singleTop"/>
-
- <service android:name=".Downloader.DownloadService"/>
-
- <activity android:name="StartGameActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation='landscape'>
- </activity>
- <activity android:name="TeamSelectionActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation='landscape'>
- </activity>
- <activity android:name="TeamCreatorActivity"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
- android:screenOrientation='landscape'
- android:windowSoftInputMode="stateUnchanged">
+ <activity
+ android:name=".SDLActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
+ </activity>
+ <activity
+ android:name=".Downloader.DownloadFragment"
+ android:label="@string/app_name"
+ android:theme="@android:style/Theme.Dialog" >
+ </activity>
+ <activity
+ android:name=".Downloader.DownloadListActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTop"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
+
+ <service android:name=".Downloader.DownloadService" />
+
+ <activity
+ android:name=".LocalRoomActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape" >
+ </activity>
+ <activity
+ android:name=".TeamListActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
+ </activity>
+ <activity
+ android:name="TeamCreatorActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:windowSoftInputMode="stateUnchanged" >
+ </activity>
+ <activity
+ android:name=".LobbyActivity"
+ android:label="@string/title_activity_lobby"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
+ </activity>
+ <activity
+ android:name=".NetRoomActivity"
+ android:label="@string/title_activity_room"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
+ </activity>
+ <activity
+ android:name=".WeaponsetListActivity"
+ android:label="@string/title_activity_weaponset_list"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
+ </activity>
+ <activity
+ android:name=".WeaponsetCreatorActivity"
+ android:label="@string/title_activity_weaponset_creator"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
+ </activity>
+ <activity
+ android:name=".SchemeListActivity"
+ android:label="@string/title_activity_scheme_list"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
+ </activity>
+ <activity
+ android:name=".SchemeCreatorActivity"
+ android:label="@string/title_activity_scheme_creator"
+ android:screenOrientation="landscape"
+ android:windowSoftInputMode="adjustPan" >
</activity>
</application>
-</manifest>
+</manifest>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Airplane.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Airplane.png
index b574bf2..353de3a 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Airplane.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Airplane.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos.png
index b3042c0..47419ef 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos_bw.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos_bw.png
index 49f099c..fe27811 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos_bw.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/AmmoMenu/Ammos_bw.png differ
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_42.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_42.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_42.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_42.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_anarchy.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_anarchy.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_anarchy.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_anarchy.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_balrog.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_balrog.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_balrog.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_balrog.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_bars.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bars.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_bars.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bars.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_birdy.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_birdy.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_birdy.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_birdy.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_bloodyblade.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bloodyblade.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_bloodyblade.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bloodyblade.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_brittany.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_brittany.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_brittany.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_brittany.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_bustamove.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bustamove.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_bustamove.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_bustamove.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_cog.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_cog.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_cog.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_cog.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_crossedswords.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_crossedswords.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_crossedswords.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_crossedswords.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_dragonrb.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_dragonrb.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_dragonrb.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_dragonrb.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_earth.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_earth.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_earth.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_earth.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_earth2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_earth2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_earth2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_earth2.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_eyeofhorus.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_eyeofhorus.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_eyeofhorus.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_eyeofhorus.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_face.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_face.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_face.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_face.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_fcw.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_fcw.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_fcw.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_fcw.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_female.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_female.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_female.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_female.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_galaxy.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_galaxy.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_galaxy.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_galaxy.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_hax0r.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_hax0r.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_hax0r.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_hax0r.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_hurrah.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_hurrah.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_hurrah.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_hurrah.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_iluvu.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_iluvu.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_iluvu.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_iluvu.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_lips.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_lips.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_lips.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_lips.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_magicskull.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_magicskull.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_magicskull.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_magicskull.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_male.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_male.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_male.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_male.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_mog.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_mog.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_mog.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_mog.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_music.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_music.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_music.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_music.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_pacman.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pacman.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_pacman.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pacman.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_pacman2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pacman2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_pacman2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pacman2.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_pentagram.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pentagram.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_pentagram.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pentagram.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_pirate.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pirate.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_pirate.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pirate.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_pokemon.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pokemon.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_pokemon.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_pokemon.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_scout.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_scout.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_scout.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_scout.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_shoppa.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_shoppa.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_shoppa.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_shoppa.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_sonic.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_sonic.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_sonic.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_sonic.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_spider.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_spider.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_spider.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_spider.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_star.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_star.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_star.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_star.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_swordshield.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_swordshield.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_swordshield.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_swordshield.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_swordshield2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_swordshield2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_swordshield2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_swordshield2.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_vampire.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_vampire.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_vampire.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_vampire.png
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_yinyang.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_yinyang.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Flags/cm_yinyang.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Flags/cm_yinyang.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Badger.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Badger.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Badger.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Badger.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Cherry.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Cherry.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Cherry.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Cherry.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Duck2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Duck2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Duck2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Duck2.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Earth.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Earth.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Earth.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Earth.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Egg.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Egg.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Egg.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Egg.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Flower.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Flower.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Flower.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Flower.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Ghost.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Ghost.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Ghost.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Ghost.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Grave.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Grave.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Grave.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Grave.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Plinko.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Plinko.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Plinko.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Plinko.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Rip.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Rip.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Rip.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Rip.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Rubberduck.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Rubberduck.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Rubberduck.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Rubberduck.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Simple.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Simple.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Simple.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Simple.png
diff --git a/share/hedgewars/Data/Graphics/Graves/Statue.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Statue.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/Statue.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/Statue.png
diff --git a/share/hedgewars/Data/Graphics/Graves/bp2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/bp2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/bp2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/bp2.png
diff --git a/share/hedgewars/Data/Graphics/Graves/bubble.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/bubble.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/bubble.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/bubble.png
diff --git a/share/hedgewars/Data/Graphics/Graves/chest.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/chest.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/chest.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/chest.png
diff --git a/share/hedgewars/Data/Graphics/Graves/coffin.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/coffin.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/coffin.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/coffin.png
diff --git a/share/hedgewars/Data/Graphics/Graves/deadhog.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/deadhog.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/deadhog.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/deadhog.png
diff --git a/share/hedgewars/Data/Graphics/Graves/eyecross.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/eyecross.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/eyecross.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/eyecross.png
diff --git a/share/hedgewars/Data/Graphics/Graves/heart.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/heart.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/heart.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/heart.png
diff --git a/share/hedgewars/Data/Graphics/Graves/money.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/money.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/money.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/money.png
diff --git a/share/hedgewars/Data/Graphics/Graves/mouton1.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/mouton1.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/mouton1.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/mouton1.png
diff --git a/share/hedgewars/Data/Graphics/Graves/octopus.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/octopus.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/octopus.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/octopus.png
diff --git a/share/hedgewars/Data/Graphics/Graves/plant2.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/plant2.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/plant2.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/plant2.png
diff --git a/share/hedgewars/Data/Graphics/Graves/plant3.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/plant3.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/plant3.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/plant3.png
diff --git a/share/hedgewars/Data/Graphics/Graves/pokeball.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/pokeball.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/pokeball.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/pokeball.png
diff --git a/share/hedgewars/Data/Graphics/Graves/pyramid.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/pyramid.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/pyramid.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/pyramid.png
diff --git a/share/hedgewars/Data/Graphics/Graves/ring.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/ring.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/ring.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/ring.png
diff --git a/share/hedgewars/Data/Graphics/Graves/skull.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/skull.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/skull.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/skull.png
diff --git a/share/hedgewars/Data/Graphics/Graves/star.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/star.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Graves/star.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Graves/star.png
diff --git a/share/hedgewars/Data/Graphics/Hats/android.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hats/android.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/Hats/android.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hats/android.png
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amKamikaze.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amKamikaze.png
index 80dc737..04a90f9 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amKamikaze.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amKamikaze.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amSineGun.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amSineGun.png
index 8135f68..c13d750 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amSineGun.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Hedgehog/amSineGun.png differ
diff --git a/share/hedgewars/Data/Graphics/LandIce.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/LandIce.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/LandIce.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/LandIce.png
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Molotov.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Molotov.png
index 3abaa1f..c1ef4b2 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Molotov.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Molotov.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Progress.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Progress.png
index b24e1bc..d0f7ee4 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Progress.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Progress.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/RCPlane.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/RCPlane.png
index 80622d5..7f24093 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/RCPlane.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/RCPlane.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Snow.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Snow.png
index 80c4ede..7156c8a 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Snow.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Snow.png differ
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/SuddenDeath/SDFlake.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/SuddenDeath/SDFlake.png
index fecf14e..0f627e9 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Graphics/SuddenDeath/SDFlake.png and b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/SuddenDeath/SDFlake.png differ
diff --git a/share/hedgewars/Data/Graphics/botlevels.png b/project_files/Android-build/SDL-android-project/assets/Data/Graphics/botlevels.png
similarity index 100%
copy from share/hedgewars/Data/Graphics/botlevels.png
copy to project_files/Android-build/SDL-android-project/assets/Data/Graphics/botlevels.png
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Locale/en.txt b/project_files/Android-build/SDL-android-project/assets/Data/Locale/en.txt
index efc37a2..6419001 100644
--- a/project_files/Android-build/SDL-android-project/assets/Data/Locale/en.txt
+++ b/project_files/Android-build/SDL-android-project/assets/Data/Locale/en.txt
@@ -79,6 +79,7 @@
01:18=High
01:19=Extreme
01:20=%1 Bounce
+01:21=Audio Muted
; Event messages
; Hog (%1) died
@@ -491,7 +492,7 @@
04:36=Well, sometimes you're just too bad in aiming. Get|some assistance using modern day technology.|Attack: Activate
04:37=Don't fear the daylight. It will just last one turn|but will enable you to absorb the damage you do to|other hogs.|Attack: Activate
04:38=The sniper rifle can be the most devastating weapon|in your whole arsenal, however it's very ineffective|at close quarters. The damage dealt increases with|the distance to its target.|Attack: Shoot (twice)
-04:39=Fly to other parts of the map using the flying|saucer. This hard to master utility is able to|take you to almost any position on the battlefield.|Attack: Activate|Up/Left/Right: Apply force in one direction|Long Jump: Drop grenades or similar weapons
+04:39=Fly to other parts of the map using the flying|saucer. This hard to master utility can|take you to almost any position on the battlefield.|Attack: Activate|Up/Left/Right: Apply force in one direction|Long Jump: Drop grenades or similar weapons
04:40=Set some ground on fire using this bottle filled|with (soon to be) burning liquid.|Attack: Hold to shoot with more power
04:41=The evidence nature might even top the flying|saucer. Birdy can carry your hog around and|drop eggs on your enemies!|Be quick, as using Birdy eats into your turn|time!|Attack: Activate and drop eggs|Up/Left/Right: Flap in one direction
04:42=This portable portal device is capable|of instantly transporting you, your enemies,|or your weaponry between two points on the|terrain.|Use it wisely and your campaign will be a...|HUGE SUCCESS!|Attack: Shoot a portal|Switch: Cycle portal colours
@@ -505,7 +506,7 @@
04:50=Is someone hiding underground?|Dig them out with a drill strike!|Timer controls how far it will dig.
04:51=Get in a free shot by hurling a ball of mud.|Stings a bit, and knocks hogs back.
04:52=UNUSED
-04:53=Go on an adventure through time and space,|while leaving your comrades to fight on alone.|Be prepared to return at any time,|or for Sudden Death or if they are all defeated.|Disclaimer. Does not function in Sudden Death,|if you are alone, or if you are a King.
+04:53=Take a trip through time and space,|while leaving your comrades to fight on alone.|Be prepared to return at any time,|or for Sudden Death or if they are all defeated.|Disclaimer. Does not function in Sudden Death,|if you are alone, or if you are a King.
04:54=INCOMPLETE
04:55=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm b/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm
index e364859..977fe60 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm and b/project_files/Android-build/SDL-android-project/assets/Data/Locale/hedgewars_en.qm differ
diff --git a/share/hedgewars/Data/Scripts/Locale.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Locale.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Locale.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Locale.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Capture_the_Flag.cfg
old mode 100755
new mode 100644
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Capture_the_Flag.cfg
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Capture_the_Flag.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Capture_the_Flag.lua
new file mode 100644
index 0000000..025ab84
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Capture_the_Flag.lua
@@ -0,0 +1,630 @@
+---------------------------------------
+-- CAPTURE_THE_FLAG GAMEPLAY MODE 0.5
+-- by mikade
+---------------------------------------
+
+-- Version History
+---------
+-- 0.1
+---------
+
+-- [conversion from map-dependant CTF_Blizzard to map independant Capture the Flag]
+-- added an intial starting stage where flagspawn is decided by the players (weapon set will require a jetpack unless I set)
+-- changed the flag from a crate to a visual gear, and all associated methods and checks relating to flags (five hours later, lol)
+-- changed starting/respawning positioning to accommodate different map sizes
+-- added another circle to mark flag spawn
+-- added gameFlag filter
+-- changed scoring feedback
+-- cleaned up some code
+
+-- removing own flag from spawning point no longer possible
+-- destroying flags no longer possible.
+-- added basic glowing circle effect to spawn area
+-- added expanding circle to fgear itself
+
+-- removed teleporters
+-- removed random crate drops (this should be decided by scheme)
+-- removed set map criteria like minesNum, turnTime, explosives etc. except for sudden death
+-- removed weapon defintions
+-- removed placement and respawning methods, hopefully divideTeams will have this covered
+
+---------
+-- 0.2
+---------
+
+-- [now with user friendliness]
+-- flag is now placed wherever you end up at the end of your first turn, this ensures that it is always placed by turn 3
+-- removed a bunch of backup code and no-longer needed variables / methods from CTF_Blizzard days
+-- removed an aura that was still mistakenly hanging about
+-- added an in-game note about placements
+-- added an in-game note about the rules of the game
+-- added translation support and loc()'ed everything
+-- changed things so the seed is no longer always the same...
+
+-- In this version:
+---------
+-- 0.3
+---------
+-- [fufufufu kamikaze fix]
+-- added nill checks to make sure the player doesn't generate errors by producing a nil value in hhs[] when he uses kamikaze
+-- added a check to make sure the player doesn't kamikaze straight down and make the flag's starting point underwater
+-- added a check to make sure the player drops the flag if he has it and he uses kamikaze
+
+--------
+-- 0.4
+--------
+
+-- remove user-branding and version numbers
+-- removed some stuff that wasn't needed
+-- fix piano strike exploit
+-- changed delay to allow for better portals
+-- changed starting feedback a little
+-- increased the radius around the circle indicating the flag thief so that it doesn't obscure his health
+
+--------
+-- 0.5
+--------
+
+-- add support for more players
+-- allow limited sudden death
+-- stop TimeBox ruining my life
+-- profit???
+
+-----------------
+--SCRIPT BEGINS
+-----------------
+
+-- enable awesome translaction support so we can use loc() wherever we want
+loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+
+---------------------------------------------------------------
+----------lots of bad variables and things
+----------because someone is too lazy
+----------to read about tables properly
+------------------ "Oh well, they probably have the memory"
+
+local gameStarted = false
+local gameTurns = 0
+
+--------------------------
+-- hog and team tracking variales
+--------------------------
+
+local numhhs = 0 -- store number of hedgehogs
+local hhs = {} -- store hedgehog gears
+
+local numTeams -- store the number of teams in the game
+local teamNameArr = {} -- store the list of teams
+local teamSize = {} -- store how many hogs per team
+local teamIndex = {} -- at what point in the hhs{} does each team begin
+
+-------------------
+-- flag variables
+-------------------
+
+local fPlaced = {} -- has the flag been placed TRUE/FALSE
+
+local fGear = {} -- pointer to the visual gears that represent the flag
+local fGearX = {}
+local fGearY = {}
+
+local fThief = {} -- pointer to the hogs who stole the flags
+local fIsMissing = {} -- have the flags been destroyed or captured
+local fNeedsRespawn = {} -- do the flags need to be respawned
+local fCaptures = {} -- the team "scores" how many captures
+local fSpawnX = {} -- spawn X for flags
+local fSpawnY = {} -- spawn Y for flags
+
+local fThiefX = {}
+local fThiefY = {}
+local FTTC = 0 -- flag thief tracker counter
+
+local fSpawnC = {} -- spawn circle marker
+local fCirc = {} -- flag/carrier marker circles
+local fCol = {} -- colour of the clans
+
+local fGearRad = 0
+local fGearRadMin = 5
+local fGearRadMax = 33
+local fGearTimer = 0
+
+------------------------
+--flag methods
+------------------------
+
+function CheckScore(teamID)
+
+ if teamID == 0 then
+ alt = 1
+ elseif teamID == 1 then
+ alt = 0
+ end
+
+ if fCaptures[teamID] == 3 then
+ for i = 0, (numhhs-1) do
+ if hhs[i] ~= nil then
+ if GetHogClan(hhs[i]) == alt then
+ SetEffect(hhs[i], heResurrectable, false)
+ SetHealth(hhs[i],0)
+ end
+ end
+ end
+ if CurrentHedgehog ~= nil then
+ ShowMission(loc("GAME OVER!"), loc("Victory for the ") .. GetHogTeamName(CurrentHedgehog), loc("Hooray!"), 0, 0)
+ end
+ end
+
+end
+
+function DoFlagStuff(gear)
+
+ if (gear == fGear[0]) then
+ wtf = 0
+ bbq = 1
+ elseif (gear == fGear[1]) then
+ wtf = 1
+ bbq = 0
+ end
+
+ -- player has successfully captured the enemy flag
+ if (GetHogClan(CurrentHedgehog) == wtf) and (CurrentHedgehog == fThief[bbq]) and (fIsMissing[wtf] == false) then
+
+ DeleteVisualGear(fGear[wtf])
+ fGear[wtf] = nil -- the flag has now disappeared
+
+ fIsMissing[wtf] = false
+ fNeedsRespawn[wtf] = true
+ fIsMissing[bbq] = false
+ fNeedsRespawn[bbq] = true
+ fCaptures[wtf] = fCaptures[wtf] +1
+ ShowMission(loc("You have SCORED!!"), GetHogTeamName(CurrentHedgehog) .. ": " .. fCaptures[wtf], loc("Opposing Team: ") .. fCaptures[bbq], 0, 0)
+ PlaySound(sndVictory)
+ fThief[bbq] = nil -- player no longer has the enemy flag
+ CheckScore(wtf)
+
+ --if the player is returning the flag
+ elseif (GetHogClan(CurrentHedgehog) == wtf) and (fIsMissing[wtf] == true) then
+
+ DeleteVisualGear(fGear[wtf])
+ fGear[wtf] = nil -- the flag has now disappeared
+
+ fNeedsRespawn[wtf] = true
+ HandleRespawns() -- this will set fIsMissing[wtf] to false :)
+ AddCaption(loc("Flag returned!"))
+
+ --if the player is taking the enemy flag
+ elseif GetHogClan(CurrentHedgehog) == bbq then
+
+ DeleteVisualGear(fGear[wtf])
+ fGear[wtf] = nil -- the flag has now disappeared
+
+ fIsMissing[wtf] = true
+ for i = 0,numhhs-1 do
+ if CurrentHedgehog ~= nil then
+ if CurrentHedgehog == hhs[i] then
+ fThief[wtf] = hhs[i]
+ end
+ end
+ end
+ AddCaption(loc("Flag captured!"))
+
+ end
+
+end
+
+function CheckFlagProximity()
+
+ for i = 0, 1 do
+ if fGear[i] ~= nil then
+
+ g1X = fGearX[i]
+ g1Y = fGearY[i]
+
+ g2X, g2Y = GetGearPosition(CurrentHedgehog)
+
+ q = g1X - g2X
+ w = g1Y - g2Y
+ dist = (q*q) + (w*w)
+
+ if dist < 500 then --1600
+ DoFlagStuff(fGear[i])
+ end
+ end
+ end
+
+end
+
+
+function HandleRespawns()
+
+ for i = 0, 1 do
+
+ if fNeedsRespawn[i] == true then
+ fGear[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true)
+ fGearX[i] = fSpawnX[i]
+ fGearY[i] = fSpawnY[i]
+
+ fNeedsRespawn[i] = false
+ fIsMissing[i] = false -- new, this should solve problems of a respawned flag being "returned" when a player tries to score
+ AddCaption(loc("Flag respawned!"))
+ end
+
+ end
+
+end
+
+
+function FlagThiefDead(gear)
+
+ if (gear == fThief[0]) then
+ wtf = 0
+ bbq = 1
+ elseif (gear == fThief[1]) then
+ wtf = 1
+ bbq = 0
+ end
+
+ if fThief[wtf] ~= nil then
+ -- falls into water
+ --ShowMission(LAND_HEIGHT, fThiefY[wtf], (LAND_HEIGHT - fThiefY[wtf]), 0, 0)
+ if (LAND_HEIGHT - fThiefY[wtf]) < 15 then
+ fIsMissing[wtf] = true
+ fNeedsRespawn[wtf] = true
+ HandleRespawns()
+ else --normally
+ fGearX[wtf] = fThiefX[wtf]
+ fGearY[wtf] = fThiefY[wtf]
+ fGear[wtf] = AddVisualGear(fGearX[wtf],fGearY[wtf],vgtCircle,0,true)
+ end
+
+ AddVisualGear(fThiefX[wtf], fThiefY[wtf], vgtBigExplosion, 0, false)
+ fThief[wtf] = nil
+ end
+
+end
+
+function HandleCircles()
+
+ fGearTimer = fGearTimer + 1
+ if fGearTimer == 50 then
+ fGearTimer = 0
+ fGearRad = fGearRad + 1
+ if fGearRad > fGearRadMax then
+ fGearRad = fGearRadMin
+ end
+ end
+
+ for i = 0, 1 do
+
+ --SetVisualGearValues(fSpawnC[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, 50, 3, fCol[i]) -- draw a circ for spawning area
+
+ if fIsMissing[i] == false then -- draw a flag marker at the flag's spawning place
+ SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 20, 0, 10, 0, 33, 3, fCol[i])
+ if fGear[i] ~= nil then -- draw the flag gear itself
+ SetVisualGearValues(fGear[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, fGearRad, 2, fCol[i])
+ end
+ elseif (fIsMissing[i] == true) and (fNeedsRespawn[i] == false) then
+ if fThief[i] ~= nil then -- draw circle round flag carrier -- 33
+ SetVisualGearValues(fCirc[i], fThiefX[i], fThiefY[i], 20, 200, 0, 0, 100, 50, 3, fCol[i])
+ --AddCaption("circle marking carrier")
+ elseif fThief[i] == nil then -- draw cirle round dropped flag
+ --g1X,g1Y,g4,g5,g6,g7,g8,g9,g10,g11 = GetVisualGearValues(fGear[i])
+ --SetVisualGearValues(fCirc[i], g1X, g1Y, 20, 200, 0, 0, 100, 33, 2, fCol[i])
+ SetVisualGearValues(fCirc[i], fGearX[i], fGearY[i], 20, 200, 0, 0, 100, 33, 3, fCol[i])
+ --AddCaption('dropped circle marker')
+ if fGear[i] ~= nil then -- flag gear itself
+ --SetVisualGearValues(fGear[i], g1X, g1Y, 20, 200, 0, 0, 100, 10, 4, fCol[i])
+ SetVisualGearValues(fGear[i], fGearX[i], fGearY[i], 20, 200, 0, 0, 100, fGearRad, 2, fCol[i])
+ --AddCaption('dropped flag itself')
+ end
+ end
+ end
+
+ if fNeedsRespawn[i] == true then -- if the flag has been destroyed, no need for a circle
+ SetVisualGearValues(fCirc[i], fSpawnX[i],fSpawnY[i], 20, 200, 0, 0, 100, 0, 0, fCol[i])
+ --AddCaption("needs respawn = true. flag 'destroyed'?")
+ end
+ end
+
+end
+
+------------------------
+-- general methods
+------------------------
+
+function CheckDistance(gear1, gear2)
+
+ g1X, g1Y = GetGearPosition(gear1)
+ g2X, g2Y = GetGearPosition(gear2)
+
+ g1X = g1X - g2X
+ g1Y = g1Y - g2Y
+ z = (g1X*g1X) + (g1Y*g1Y)
+
+ dist = z
+
+ return dist
+
+end
+
+function RebuildTeamInfo()
+
+
+ -- make a list of individual team names
+ for i = 0, (TeamsCount-1) do
+ teamNameArr[i] = i
+ teamSize[i] = 0
+ teamIndex[i] = 0
+ end
+ numTeams = 0
+
+ for i = 0, (numhhs-1) do
+
+ z = 0
+ unfinished = true
+ while(unfinished == true) do
+
+ newTeam = true
+ tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
+
+ if tempHogTeamName == teamNameArr[z] then
+ newTeam = false
+ unfinished = false
+ end
+
+ z = z + 1
+
+ if z == TeamsCount then
+ unfinished = false
+ if newTeam == true then
+ teamNameArr[numTeams] = tempHogTeamName
+ numTeams = numTeams + 1
+ end
+ end
+
+ end
+
+ end
+
+ -- find out how many hogs per team, and the index of the first hog in hhs
+ for i = 0, numTeams-1 do
+
+ for z = 0, numhhs-1 do
+ if GetHogTeamName(hhs[z]) == teamNameArr[i] then
+ if teamSize[i] == 0 then
+ teamIndex[i] = z -- should give starting index
+ end
+ teamSize[i] = teamSize[i] + 1
+ --add a pointer so this hog appears at i in hhs
+ end
+ end
+
+ end
+
+end
+
+function StartTheGame()
+
+ gameStarted = true
+ AddCaption(loc("Game Started!"))
+
+ for i = 0, 1 do
+
+ -- if someone uses kamikaze downwards, this can happen as the hog won't respawn
+ if (LAND_HEIGHT - fSpawnY[i]) < 0 then
+ tempG = AddGear(0, 0, gtTarget, 0, 0, 0, 0)
+ FindPlace(tempG, true, 0, LAND_WIDTH, true)
+ fSpawnX[i], fSpawnY[i] = GetGearPosition(tempG)
+ DeleteGear(tempG)
+ end
+
+ fGear[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true)
+ fCirc[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true)
+ fSpawnC[i] = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true)
+
+ fGearX[i] = fSpawnX[i]
+ fGearY[i] = fSpawnY[i]
+
+ fCol[i] = GetClanColor(i)
+ fIsMissing[i] = false
+ fNeedsRespawn[i] = false
+ fCaptures[i] = 0
+
+ --SetVisualGearValues(zxc, 1000,1000, 20, 100, 0, 10, 1, 100, 5, GetClanColor(0))
+
+ SetVisualGearValues(fSpawnC[i], fSpawnX[i],fSpawnY[i], 20, 100, 0, 10, 0, 75, 5, fCol[i])
+
+ end
+
+end
+
+------------------------
+-- game methods
+------------------------
+
+function onGameInit()
+
+ GameFlags = band(bor(GameFlags, gfDivideTeams), bnot(gfKing + gfForts))
+ --SuddenDeathTurns = 999 -- suddendeath is off, effectively
+ WaterRise = 0
+ Delay = 10
+
+end
+
+
+function onGameStart()
+
+ --ShowMission(loc(caption), loc(subcaption), loc(goal), 0, 0)
+ ShowMission(loc("CAPTURE THE FLAG"), loc("Flags, and their home base will be placed where each team ends their first turn."), "", 0, 0)
+
+ RebuildTeamInfo()
+
+ -- should gfDivideTeams do this automatically?
+ --[[for i = 0, (TeamsCount-1) do
+ for g = teamIndex[i], (teamIndex[i]+teamSize[i]-1) do
+ if GetHogClan(hhs[g]) == 0 then
+ FindPlace(hhs[g], false, 0, LAND_WIDTH/2)
+ elseif GetHogClan(hhs[g]) == 1 then
+ FindPlace(hhs[g], false, LAND_WIDTH/2, LAND_WIDTH)
+ end
+ end
+ end]]
+
+ fPlaced[0] = false
+ fPlaced[1] = false
+
+ --zxc = AddVisualGear(fSpawnX[i],fSpawnY[i],vgtCircle,0,true)
+
+
+ --SetVisualGearValues(zxc, 1000,1000, 20, 255, 1, 10, 0, 200, 1, GetClanColor(0))
+ --minO,max0 -glowyornot --pulsate timer -- fuckall -- radius -- width -- colour
+end
+
+
+function onNewTurn()
+
+ gameTurns = gameTurns + 1
+
+ if lastTeam ~= GetHogTeamName(CurrentHedgehog) then
+ lastTeam = GetHogTeamName(CurrentHedgehog)
+ end
+
+ --AddCaption("Handling respawns")
+ if gameStarted == true then
+ HandleRespawns()
+ --new method of placing starting flags
+ elseif gameTurns == 1 then
+ ShowMission(loc("CAPTURE THE FLAG"), loc("Flags, and their home base will be placed where each team ends their first turn."), "", 0, 0)
+ elseif gameTurns == 2 then
+ fPlaced[0] = true
+ ShowMission(loc("CAPTURE THE FLAG"), loc("RULES OF THE GAME [Press ESC to view]"), loc(" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"), 0, 0)
+ elseif gameTurns == 3 then
+ fPlaced[1] = true
+ StartTheGame()
+ end
+
+end
+
+function onGameTick()
+
+ -- onRessurect calls AFTER you have resurrected,
+ -- so keeping track of x,y a few milliseconds before
+ -- is useful
+ --FTTC = FTTC + 1
+ --if FTTC == 100 then
+ -- FTTC = 0
+ for i = 0,1 do
+ if fThief[i] ~= nil then
+ fThiefX[i] = GetX(fThief[i])
+ fThiefY[i] = GetY(fThief[i])
+ end
+ end
+ --end
+
+ -- things we wanna check often
+ if (CurrentHedgehog ~= nil) then
+ --AddCaption(LAND_HEIGHT - GetY(CurrentHedgehog))
+ --AddCaption(GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog))
+ --CheckTeleporters()
+
+ end
+
+ if gameStarted == true then
+ HandleCircles()
+ if CurrentHedgehog ~= nil then
+ CheckFlagProximity()
+ end
+ elseif CurrentHedgehog ~= nil then -- if the game hasn't started yet, keep track of where we are gonna put the flags on turn end
+
+ if GetHogClan(CurrentHedgehog) == 0 then
+ i = 0
+ elseif GetHogClan(CurrentHedgehog) == 1 then
+ i = 1
+ end
+
+ fSpawnX[i] = GetX(CurrentHedgehog)
+ fSpawnY[i] = GetY(CurrentHedgehog)
+
+ end
+
+end
+
+function onGearResurrect(gear)
+
+ --AddCaption("A gear has been resurrected!")
+
+ -- mark the flag thief as dead if he needed a respawn
+ for i = 0,1 do
+ if gear == fThief[i] then
+ FlagThiefDead(gear)
+ end
+ end
+
+ -- should be covered by gfDivideTeams, actually
+ -- place hogs belonging to each clan either left or right side of map
+ --if GetHogClan(gear) == 0 then
+ -- FindPlace(gear, false, 0, LAND_WIDTH/2)
+ --elseif GetHogClan(gear) == 1 then
+ -- FindPlace(gear, false, LAND_WIDTH/2, LAND_WIDTH)
+ --end
+
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+
+end
+
+function InABetterPlaceNow(gear)
+ for i = 0, (numhhs-1) do
+ if gear == hhs[i] then
+
+ for i = 0,1 do
+ if gear == fThief[i] then
+ FlagThiefDead(gear)
+ end
+ end
+ hhs[i] = nil
+ end
+ end
+end
+
+function onHogHide(gear)
+ InABetterPlaceNow(gear)
+end
+
+function onHogRestore(gear)
+ match = false
+ for i = 0, (numhhs-1) do
+ if (hhs[i] == nil) and (match == false) then
+ hhs[i] = gear
+ --AddCaption(GetHogName(gear) .. " has reappeared it seems!")
+ match = true
+ end
+ end
+end
+
+
+function onGearAdd(gear)
+
+ if GetGearType(gear) == gtHedgehog then
+ hhs[numhhs] = gear
+ numhhs = numhhs + 1
+ SetEffect(gear, heResurrectable, true)
+
+ elseif GetGearType(gear) == gtPiano then
+
+ for i = 0, 1 do
+ if CurrentHedgehog == fThief[i] then
+ FlagThiefDead(gear)
+ end
+ end
+
+ end
+
+end
+
+function onGearDelete(gear)
+
+ if GetGearType(gear) == gtHedgehog then
+ InABetterPlaceNow(gear)
+ end
+
+end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Highlander.cfg
old mode 100755
new mode 100644
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Highlander.cfg
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Highlander.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Highlander.lua
new file mode 100644
index 0000000..94905fa
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Highlander.lua
@@ -0,0 +1,233 @@
+--------------------------------
+-- HIGHLANDER / HOGS OF WAR
+-- version 0.3c
+-- by mikade
+--------------------------------
+
+-----------
+--0.1
+-----------
+
+-- concept test
+
+-----------
+--0.2
+-----------
+
+-- remove tardis till Henek fixes his tracker
+-- change wep crates to health crates
+-- reset arb turntimevalue
+-- include randomOrder
+-- Until fixed .17 methods come out, remove switches and resurrector
+-- on request, removed kamikaze and piano weapons
+-- provisional fixing of bugs that can't actually be fixed yet
+
+-----------
+--0.3
+-----------
+
+-- meh, update incorrect display
+-- may change this in the future to have switches
+-- but for now people are used to it without, so~
+
+-- mudball is now counted as a utility
+
+-----------
+--0.3b
+-----------
+
+-- cleaned up code and got rid of unneccessary vars
+-- mudball is a weapon again
+-- landgun is now a utility
+-- extra time, vampirism utility removed
+-- hammer wep removed
+-- all hogs have kamikaze
+
+-----------
+--0.3c
+-----------
+
+-- restructured some code
+-- added napalm (whoops) to list of possible weapons you can get
+-- hogs no longer recieve airstrike-related weps on border maps
+
+loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+
+local airWeapons = {amAirAttack, amMineStrike, amNapalm, amDrillStrike --[[,amPiano]]}
+
+local atkArray = {
+ amBazooka, amBee, amMortar, amDrill, --[[amSnowball,]]
+ amGrenade, amClusterBomb, amMolotov, amWatermelon, amHellishBomb, amGasBomb,
+ amShotgun, amDEagle, amFlamethrower, amSniperRifle, amSineGun,
+ amFirePunch, amWhip, amBaseballBat, --[[amKamikaze,]] amSeduction, --[[amHammer,]]
+ amMine, amDynamite, amCake, amBallgun, amRCPlane, amSMine,
+ amRCPlane, amSMine,
+ amBirdy
+ }
+
+local utilArray = {
+ amBlowTorch, amPickHammer, amGirder, amPortalGun,
+ amRope, amParachute, amTeleport, amJetpack,
+ amInvulnerable, amLaserSight, --[[amVampiric,]]
+ amLowGravity, amExtraDamage, --[[amExtraTime,]]
+ amLandGun
+ --[[,amTardis, amResurrector, amSwitch]]
+ }
+
+local wepArray = {}
+
+local currName
+local lastName
+local started = false
+local switchStage = 0
+
+function StartingSetUp(gear)
+
+ for i = 1, #wepArray do
+ setGearValue(gear,wepArray[i],0)
+ end
+
+ setGearValue(gear,amKamikaze,1)
+
+ i = 1 + GetRandom(#atkArray)
+ setGearValue(gear,atkArray[i],1)
+
+ i = 1 + GetRandom(#utilArray)
+ setGearValue(gear,utilArray[i],1)
+
+ SetHealth(gear, 100)
+
+end
+
+--[[function SaveWeapons(gear)
+
+ -
+ for i = 1, (#wepArray) do
+ setGearValue(gear, wepArray[i], GetAmmoCount(gear, wepArray[i]) )
+ --AddAmmo(gear, wepArray[i], getGearValue(gear,wepArray[i]) )
+ end
+
+end]]
+
+function ConvertValues(gear)
+
+ for i = 1, #wepArray do
+ AddAmmo(gear, wepArray[i], getGearValue(gear,wepArray[i]) )
+ end
+
+
+end
+
+
+function TransferWeps(gear)
+
+ if CurrentHedgehog ~= nil then
+
+ for i = 1, #wepArray do
+ val = getGearValue(gear,wepArray[i])
+ if val ~= 0 then
+ setGearValue(CurrentHedgehog, wepArray[i], val)
+ AddAmmo(CurrentHedgehog, wepArray[i], val)
+ end
+ end
+
+ end
+
+end
+
+function onGameInit()
+ GameFlags = gfInfAttack + gfRandomOrder
+ HealthCaseProb = 100
+end
+
+function onGameStart()
+
+
+ ShowMission (
+ loc("HIGHLANDER"),
+ loc("Not all hogs are born equal."),
+
+ "- " .. loc("Eliminate enemy hogs and take their weapons.") .. "|" ..
+ "- " .. loc("Per-Hog Ammo") .. "|" ..
+ "- " .. loc("Weapons reset.") .. "|" ..
+ "- " .. loc("Unlimited Attacks") .. "|" ..
+ "", 4, 4000
+ )
+
+ if MapHasBorder() == false then
+ for i, w in pairs(airWeapons) do
+ table.insert(atkArray, w)
+ end
+ end
+
+ for i, w in pairs(atkArray) do
+ table.insert(wepArray, w)
+ end
+
+ for i, w in pairs(utilArray) do
+ table.insert(wepArray, w)
+ end
+
+ runOnGears(StartingSetUp)
+ runOnGears(ConvertValues)
+
+
+end
+
+function onNewTurn()
+--
+end
+
+
+function onGameTick20()
+
+ if (CurrentHedgehog ~= nil) then
+
+ currName = GetHogName(CurrentHedgehog)
+
+ if (currName ~= lastName) then
+ AddCaption(loc("Switched to ") .. currName .. "!")
+ ConvertValues(CurrentHedgehog)
+ end
+
+ lastName = currName
+ end
+
+end
+
+--[[function onHogHide(gear)
+ -- waiting for Henek
+end
+
+function onHogRestore(gear)
+ -- waiting for Henek
+end]]
+
+function onGearAdd(gear)
+
+ --if GetGearType(gear) == gtSwitcher then
+ -- SaveWeapons(CurrentHedgehog)
+ --end
+
+ if (GetGearType(gear) == gtHedgehog) then
+ trackGear(gear)
+ end
+
+end
+
+function onGearDelete(gear)
+
+ if (GetGearType(gear) == gtHedgehog) then --or (GetGearType(gear) == gtResurrector) then
+ TransferWeps(gear)
+ trackDeletion(gear)
+ end
+
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amKamikaze, 9, 0, 0, 0)
+ --SetAmmo(amSwitch, 9, 0, 0, 0) -------1
+end
+
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/No_Jumping.cfg
old mode 100755
new mode 100644
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/No_Jumping.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/No_Jumping.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/No_Jumping.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Racer.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Racer.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Racer.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Racer.cfg
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Racer.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Racer.lua
new file mode 100644
index 0000000..4e3ba32
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Racer.lua
@@ -0,0 +1,700 @@
+
+------------------------------------------
+-- RACER 0.5
+-- map-independant racing script
+-- by mikade
+-----------------------------------------
+
+-----------------------------------
+--0.1: took all the code from crazy racer and scrapped most of it
+-----------------------------------
+
+-- Removed tumbler system
+-- Removed extra adds like boosters etc
+-- Added experimental waypoint placement system
+-- More user feedback
+-- Reduced race complexity limit to 5 waypoints
+-- stop placement at complexity limit reached and end turn
+-- guys dont keep racing after dying
+-- invulnerable feasibility
+-- reverted time keeping method
+-- reduced feedback display time
+-- colour-coded addcaptions
+-- cleaned up code
+-- support for more players properly added
+-- tardis fix
+-- remove airstrikes
+
+-- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn
+
+-- update feedback
+
+-------
+-- 0.2
+-------
+
+-- allow gameflags
+-- extend time to 90s
+-- remove other air-attack based weps
+-- turn off water rise for sd
+
+-------
+-- 0.3
+-------
+
+-- prevent WP being placed in land
+-- prevent waypoints being placed outside border
+
+-------
+-- 0.4
+-------
+
+-- update user feedback
+-- add more sounds
+
+-------
+-- 0.5
+-------
+
+-- fix ghost disappearing if hog falls in water or somehow dies
+-- lengthen ghost tracking interval to improve performance on slower machines
+-- increase waypoint limit to 8
+-- allow for persistent showmission information
+
+-----------------------------
+-- SCRIPT BEGINS
+-----------------------------
+
+loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+
+------------------
+-- Got Variables?
+------------------
+
+local fMod = 1000000 -- 1
+local roundLimit = 3
+local roundNumber = 0
+local firstClan = 10
+
+local fastX = {}
+local fastY = {}
+local fastCount = 0
+local fastIndex = 0
+local fastColour
+
+local currX = {}
+local currY = {}
+local currCount = 0
+
+--------------------------
+-- hog and team tracking variales
+--------------------------
+
+local numhhs = 0 -- store number of hedgehogs
+local hhs = {} -- store hedgehog gears
+
+local numTeams -- store the number of teams in the game
+local teamNameArr = {} -- store the list of teams
+local teamClan = {}
+local teamSize = {} -- store how many hogs per team
+local teamIndex = {} -- at what point in the hhs{} does each team begin
+
+local teamComment = {}
+local teamScore = {}
+
+-------
+-- racer vars
+--------
+
+local cGear = nil
+
+local bestClan = nil
+local bestTime = nil
+
+local gameBegun = false
+local gameOver = false
+local racerActive = false
+local trackTime = 0
+
+local wpCirc = {}
+local wpX = {}
+local wpY = {}
+local wpCol = {}
+local wpActive = {}
+local wpRad = 450 --75
+local wpCount = 0
+local wpLimit = 8
+
+local roundN
+local lastRound
+local RoundHasChanged
+
+-------------------
+-- general methods
+-------------------
+
+function RebuildTeamInfo()
+
+
+ -- make a list of individual team names
+ for i = 0, (TeamsCount-1) do
+ teamNameArr[i] = " " -- = i
+ teamSize[i] = 0
+ teamIndex[i] = 0
+ teamScore[i] = 100000
+ end
+ numTeams = 0
+
+ for i = 0, (numhhs-1) do
+
+ z = 0
+ unfinished = true
+ while(unfinished == true) do
+
+ newTeam = true
+ tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
+
+ if tempHogTeamName == teamNameArr[z] then
+ newTeam = false
+ unfinished = false
+ end
+
+ z = z + 1
+
+ if z == TeamsCount then
+ unfinished = false
+ if newTeam == true then
+ teamNameArr[numTeams] = tempHogTeamName
+ numTeams = numTeams + 1
+ end
+ end
+
+ end
+
+ end
+
+ -- find out how many hogs per team, and the index of the first hog in hhs
+ for i = 0, (numTeams-1) do
+ for z = 0, (numhhs-1) do
+ if GetHogTeamName(hhs[z]) == teamNameArr[i] then
+ teamClan[i] = GetHogClan(hhs[z])
+ if teamSize[i] == 0 then
+ teamIndex[i] = z -- should give starting index
+ end
+ teamSize[i] = teamSize[i] + 1
+ --add a pointer so this hog appears at i in hhs
+ end
+ end
+
+ end
+
+end
+
+
+-----------------
+-- RACER METHODS
+-----------------
+
+function CheckWaypoints()
+
+ trackFinished = true
+
+ for i = 0, (wpCount-1) do
+
+ g1X, g1Y = GetGearPosition(CurrentHedgehog)
+ g2X, g2Y = wpX[i], wpY[i]
+
+ g1X = g1X - g2X
+ g1Y = g1Y - g2Y
+ dist = (g1X*g1X) + (g1Y*g1Y)
+
+ --if i == 0 then
+ -- AddCaption(dist .. "/" .. (wpRad*wpRad) )
+ --end
+
+ NR = (48/100*wpRad)/2
+
+ if dist < (NR*NR) then
+ --if dist < (wpRad*wpRad) then
+ --AddCaption("howdy")
+ wpActive[i] = true
+ wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new --GetClanColor(1)
+ SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+
+ wpRem = 0
+ for k = 0, (wpCount-1) do
+ if wpActive[k] == false then
+ wpRem = wpRem + 1
+ end
+ end
+
+ AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo)
+
+ end
+
+ if wpActive[i] == false then
+ trackFinished = false
+ end
+
+ end
+
+ return(trackFinished)
+
+end
+
+function AdjustScores()
+
+ if bestTime == nil then
+ bestTime = 100000
+ bestClan = 10
+ bestTimeComment = "N/A"
+ end
+
+ newScore = false
+
+ -- update this clan's time if the new track is better
+ for i = 0, (numTeams-1) do
+ if teamClan[i] == GetHogClan(CurrentHedgehog) then
+ if trackTime < teamScore[i] then
+ teamScore[i] = trackTime
+ newScore = true
+ else
+ newScore = false
+ end
+ end
+ end
+
+ --bestTime = 100000
+ --bestClan = 10
+
+ -- find the best time out of those so far
+ for i = 0, (numTeams-1) do
+ if teamScore[i] < bestTime then
+ bestTime = teamScore[i]
+ bestClan = teamClan[i]
+ end
+ end
+
+ if bestTime ~= 100000 then
+ bestTimeComment = (bestTime/1000) ..loc("s")
+ end
+
+ if newScore == true then
+ if trackTime == bestTime then -- best time of the race
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, 0, 4000)
+ PlaySound(sndHomerun)
+ else -- best time for the clan
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, 4, 4000)
+ end
+ else -- not any kind of new score
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
+ PlaySound(sndHellish)
+ end
+
+
+ --------
+ --new
+ --------
+
+ if bestTime == trackTime then
+ --AddCaption("wooooooooooooooooooooooooooooo")
+
+ fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
+
+ for i = 0, (currCount-1) do
+ fastX[i] = currX[i]
+ fastY[i] = currY[i]
+ end
+
+ fastCount = currCount
+ fastIndex = 0
+
+ --currCount = 0 -- is this needed?
+
+ else
+ currCount = 0
+ fastIndex = 0
+ end
+
+
+end
+
+function onNewRound()
+
+ roundNumber = roundNumber + 1
+
+ totalComment = ""
+ for i = 0, (TeamsCount-1) do
+ if teamNameArr[i] ~= " " then -- teamScore[teamClan[i]]
+ teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|")
+ totalComment = totalComment .. teamComment[i]
+ elseif teamNameArr[i] == " " then
+ teamComment[i] = "|"
+ end
+ end
+
+ ShowMission( loc("RACER"),
+ loc("STATUS UPDATE"),
+ loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" ..
+ loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000)
+
+ -- end game if its at round limit
+ if roundNumber == roundLimit then
+ for i = 0, (numhhs-1) do
+ if GetHogClan(hhs[i]) ~= bestClan then
+ SetEffect(hhs[i], heResurrectable, false)
+ SetHealth(hhs[i],0)
+ end
+ end
+ gameOver = true
+ TurnTimeLeft = 1
+ end
+
+end
+
+function CheckForNewRound()
+
+ -------------
+ ------ new
+ -------------
+
+ --[[turnN = turnN + 1
+ if gameBegun == false then
+ if turnN == 2 then
+ for i = 0, (numhhs-1) do
+ if hhs[i] ~= nil then
+ SetEffect(hhs[i], heResurrectable, false)
+ SetHealth(hhs[i],0)
+ end
+ end
+ gameOver = true
+ TurnTimeLeft = 1
+ end
+ else
+
+
+ end]]
+
+ --[[if roundBegun == true then
+
+ if RoundHasChanged == true then
+ roundN = roundN + 1
+ RoundHasChanged = false
+ onNewRound()
+ end
+
+ if lastRound ~= TotalRounds then -- new round, but not really
+
+ if RoundHasChanged == false then
+ RoundHasChanged = true
+ end
+
+ end
+
+ AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds)
+
+ lastRound = TotalRounds
+
+ end]]
+
+ ------------
+ ----- old
+ ------------
+
+ if GetHogClan(CurrentHedgehog) == firstClan then
+ onNewRound()
+ end
+
+end
+
+function DisableTumbler()
+ currCount = 0
+ fastIndex = 0
+ TurnTimeLeft = 0
+ racerActive = false -- newadd
+end
+
+function HandleGhost()
+
+ -- get the current xy of the racer at this point
+ currX[currCount] = GetX(CurrentHedgehog)
+ currY[currCount] = GetY(CurrentHedgehog)
+ currCount = currCount + 1
+
+ -- draw a ping of smoke where the fastest player was at this point
+ if (fastCount ~= 0) and (fastIndex < fastCount) then
+
+ fastIndex = fastIndex + 1
+
+ tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+ SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
+
+ --AddCaption("fC: " .. fastIndex .. " / " .. fastCount)
+
+ else
+
+ --AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount)
+
+ end
+
+
+
+end
+
+----------------------------------
+-- GAME METHODS / EVENT HANDLERS
+----------------------------------
+
+function onGameInit()
+ GameFlags = GameFlags + gfInfAttack + gfInvulnerable
+ CaseFreq = 0
+ TurnTime = 90000
+ WaterRise = 0
+end
+
+
+function onGameStart()
+
+ roundN = 0
+ lastRound = TotalRounds
+ RoundHasChanged = false -- true
+
+ RebuildTeamInfo()
+
+ ShowMission (
+ loc("RACER"),
+ loc("a Hedgewars mini-game"),
+
+ loc("Build a track and race.") .. "|" ..
+ loc("Round Limit:") .. " " .. roundLimit .. "|" ..
+
+ "", 4, 4000
+ )
+end
+
+function PlaceWayPoint(x,y)
+
+ if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek
+
+ wpX[wpCount] = x
+ wpY[wpCount] = y
+ wpCol[wpCount] = 0xffffffff
+ wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
+ --100
+ SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount])
+
+ wpCount = wpCount + 1
+
+ AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount))
+
+ end
+
+end
+
+function onNewTurn()
+
+ CheckForNewRound()
+
+ racerActive = false
+
+ trackTime = 0
+
+ currCount = 0 -- hopefully this solves problem
+ AddAmmo(CurrentHedgehog, amAirAttack, 0)
+ gTimer = 0
+
+ -- Set the waypoints to unactive on new round
+ for i = 0,(wpCount-1) do
+ wpActive[i] = false
+ wpCol[i] = 0xffffffff
+ SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+ end
+
+ -- Handle Starting Stage of Game
+ if (gameOver == false) and (gameBegun == false) then
+ if wpCount >= 3 then
+ gameBegun = true
+ roundNumber = 0
+ firstClan = GetHogClan(CurrentHedgehog)
+ ShowMission(loc("RACER"),
+ loc("GAME BEGUN!!!"),
+ loc("Complete the track as fast as you can!"), 2, 4000)
+ else
+ ShowMission(loc("RACER"),
+ loc("NOT ENOUGH WAYPOINTS"),
+ loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000)
+ AddAmmo(CurrentHedgehog, amAirAttack, 4000)
+ ParseCommand("setweap " .. string.char(amAirAttack))
+ end
+ end
+
+ if gameOver == true then
+ gameBegun = false
+ racerActive = false -- newadd
+ end
+
+ AddAmmo(CurrentHedgehog, amTardis, 0)
+ AddAmmo(CurrentHedgehog, amDrillStrike, 0)
+ AddAmmo(CurrentHedgehog, amMineStrike, 0)
+ AddAmmo(CurrentHedgehog, amNapalm, 0)
+ AddAmmo(CurrentHedgehog, amPiano, 0)
+
+end
+
+function onGameTick20()
+
+ -- airstrike detected, convert this into a potential waypoint spot
+ if cGear ~= nil then
+ x,y = GetGearPosition(cGear)
+ if x > -9000 then
+ x,y = GetGearTarget(cGear)
+
+
+ if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
+ AddCaption(loc("Please place the way-point in the open, within the map boundaries."))
+ PlaySound(sndDenied)
+ elseif (y > WaterLine-50) then
+ AddCaption(loc("Please place the way-point further from the waterline."))
+ PlaySound(sndDenied)
+ else
+ PlaceWayPoint(x, y)
+ if wpCount == wpLimit then
+ AddCaption(loc("Race complexity limit reached."))
+ DisableTumbler()
+ end
+ end
+ else
+ DeleteGear(cGear)
+ end
+ SetGearPosition(cGear, -10000, 0)
+ end
+
+
+ -- start the player tumbling with a boom once their turn has actually begun
+ if racerActive == false then
+
+ if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
+
+ -- if the gamehas started put the player in the middle of the first
+ --waypoint that was placed
+ if gameBegun == true then
+ AddCaption(loc("Good to go!"))
+ racerActive = true
+ trackTime = 0
+
+ SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
+ AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
+ FollowGear(CurrentHedgehog)
+
+ HideMission()
+
+ else
+ -- still in placement mode
+ end
+
+ end
+ end
+
+
+
+ -- has the player started his tumbling spree?
+ if (CurrentHedgehog ~= nil) then
+
+ --airstrike conversion used to be here
+
+ -- if the RACE has started, show tracktimes and keep tabs on waypoints
+ if (racerActive == true) and (gameBegun == true) then
+
+ --ghost
+ if GameTime%40 == 0 then
+ HandleGhost()
+ end
+
+ trackTime = trackTime + 20
+
+ if GameTime%100 == 0 then
+
+ if trackTime%1000 == 0 then
+ AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+ else
+ AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+ end
+
+ if (CheckWaypoints() == true) then
+ AdjustScores()
+ racerActive = false
+ DisableTumbler()
+ end
+
+ end
+
+ end
+
+
+
+ -- if the player has expended his tunbling time, stop him tumbling
+ if TurnTimeLeft <= 20 then
+ DisableTumbler()
+ end
+
+ end
+
+end
+
+function onGearResurrect(gear)
+
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+
+ if gear == CurrentHedgehog then
+ DisableTumbler()
+ end
+
+ -- if the player stops and "dies" or flies into water, stop him racing
+ --[[if gear == CurrentHedgehog then
+ DisableTumbler()
+ ShowMission(loc("RACER"),
+ loc("TRACK FAILED!"),
+ loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
+ end]]
+
+end
+
+function onGearAdd(gear)
+
+ if GetGearType(gear) == gtHedgehog then
+ hhs[numhhs] = gear
+ numhhs = numhhs + 1
+ SetEffect(gear, heResurrectable, true)
+ end
+
+ if GetGearType(gear) == gtAirAttack then
+ cGear = gear
+ end
+
+end
+
+function onGearDelete(gear)
+
+ if GetGearType(gear) == gtAirAttack then
+ cGear = nil
+ end
+
+end
+
+--[[function onAmmoStoreInit()
+ SetAmmo(amRope, 9, 0, 0, 0)
+ SetAmmo(amJetpack, 9, 0, 0, 0)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+end]]
+
+
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Random_Weapon.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Random_Weapon.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Random_Weapon.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Random_Weapon.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Space_Invasion.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Space_Invasion.cfg
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Space_Invasion.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Space_Invasion.lua
new file mode 100644
index 0000000..a6f349a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Space_Invasion.lua
@@ -0,0 +1,2435 @@
+
+loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+
+---------------------------------------------------
+---------------------------------------------------
+---------------------------------------------------
+--- Space Invasion Code Follows (1.1)
+---------------------------------------------------
+---------------------------------------------------
+-- VERSION HISTORY
+----------------
+-- version 0.1
+----------------
+-- conversion of tumbler into space invasion
+-- a million and one changes
+-- bells and whistles
+
+----------------
+-- version 0.2
+----------------
+-- code slowly getting cleaner, it still looks like a spaghetti monster tho
+-- lots of console tracking :/
+-- all visual gears are now compulsary (will probably revert this)
+-- implemented fMod to try combat desyncs and bring this in line with dev
+
+----------------
+-- version 0.3
+----------------
+-- values of scoring changed to 3:10, and now based on vCircScore
+-- time gained from killing a red circ increased from 3 to 4
+-- circles now spawn at a distance of at least 800 or until sanity limit
+-- roundsLimit now based off MinesTime (kinda, its an experiment)
+
+-----------------
+--0.4
+-----------------
+-- commented out a lot of WriteLnToConsoles (dont need them at this point)
+-- added some different WriteLnToConsoles
+-- changed some of the collision detect for explosives in checkvarious()
+
+-----------------
+--0.5
+-----------------
+-- added implementation for a projectile shield
+-- added a "bonus" orange invader that partially recharges player shield
+-- added a tough "blueboss" blue invader
+-- expanded user feedback
+-- circles now have health and are capable of being merely "damaged"
+-- redid a lot of the collision code and added CircleDamaged
+-- added more sounds to events
+-- added more visual gears
+
+-----------------
+--0.6
+-----------------
+-- removed a few WriteLns
+-- added randomized grunts on circ damage
+-- added (mostly) graceful fading out of circles :D:
+-- changed odds for circles
+-- changed user feedback
+-- fixed the location of the explosion where player bashes into circ
+
+-----------------
+--0.7
+-----------------
+-- added PlaySound(sndSuddenDeath) when ammo gets depleted
+-- added an extra "Ammo Depleted" note if user presses fire while empty
+-- specified how much shield power is gained on shield powerup collection
+-- changed odds for circles AGAIN, ammo is now sliiightly more common
+-- switched most of the explosions/smoke effects back to non-critical vgears (with a few exceptions)
+-- tumbletime is now based off turntime and is variable
+-- delete explosives in DeleteFarFlungBarrel rather than explode them on map boundaries to save on performance
+-- utilized the improved AddCaption to tint / prevent overrides
+-- temporarily disabled bugged sort that displays teams according to their score
+-- reluctantly changed the colour of the bonus circ to purple
+-- standarized point notation
+-- added some missing locs
+-- commented out remaining WriteLnToConsoles for the meanwhile with the prefix "nw"
+
+-- ACHIEIVEMENTS added
+-- (during one turn) aka repeatable
+-- Ammo Manic (Destroy 3 green circles for + 5 points)
+-- Drone Hunter (Destroy 5 red circles for + 10 points)
+-- Shield Seeker (Destroy 3 purple circles for +10 points)
+-- Boss Slayer (Destroy 2 blue circles for +25 points)
+
+-- Shield Master (disolve 5 shells for +10 points)
+-- Shield Miser (don't use your shield at all (3.5*roundkills)+2 points)
+
+-- Depleted Kamikaze! (kamikaze into a blue/red circ when you are out of ammo) 5pts
+-- Timed Kamikaze! (kamikaze into a blue/red circ when you only have 5s left) 10pts
+-- Kamikaze Expert (combination of the above two) 15pts
+
+-- Multi-shot (destroy more than 1 invader with a single bullet) 15pts
+-- X-Hit Combo (destroy another invader in less than 3 seconds) chainLength*2 points
+
+-- Accuracy Bonus (80% accuracy at the end of your turn with more than 5 shots fired) 15pts
+
+--(during the length of the game) aka non-repeatable
+-- 10/25/50 kills (+25/+50/+100 points)
+
+-----------------
+--0.8
+-----------------
+-- added a HUD for turntimeleft, ammo, shield
+-- shieldhealth hits 0 properly
+
+------------------------
+-- version 0.8.1
+------------------------
+
+-- stop hiding non-existant 4th Tag
+-- redraw HUD on screen resolution change
+
+------------------------
+-- version 0.9
+------------------------
+-- time for more 'EXPERIMENTS' mwahahahahahaha D:
+-- (hopefully) balanced Shield Miser
+-- bosses are no longer a redunkulous 50 points, but toned down to 30
+-- experimental radar (it's INTERACTIVE and math-heavy :D) (visual gears are safe... right? D:)
+-- bugfix and balance for multishot
+
+------------------------
+-- version 1.0
+------------------------
+-- if only version numbers actually worked like this, wouldn't that be awful :D
+-- added surfer achievement
+-- increased value of shield miser by 1 point per kill (OP?)
+
+------------------------
+-- version 1.1
+------------------------
+-- fixed radar so that blips dont go past circs when you get very close
+-- added a missing loc for shield depletion
+-- increased delay to 1000 to try stop noobies missing their turn
+-- added sniper achievement for hits from over a 1000000 away
+-- added achievement for 3 "sniper" shots in a round
+-- added achievement for 3 "point blank" shots in a round
+-- added "fierce Competition" achievement for shooting an enemy hog (once per round)
+-- some support for more weapons later
+
+--------------------------
+--notes for later
+--------------------------
+-- maybe add a check for a tie, IMPOSSIBRU THERE ARE NO TIES
+-- more achievements? (3 kamikazes in a row, supreme shield expert/miser etc?)
+
+-- if more weps are added, replace primshotsfired all over the place
+
+-- look for derp and let invaders shoot again
+
+-- more weps? flamer/machineballgun,
+-- some kind of bomb that just drops straight down
+-- "fire and forget" missile
+-- shockwave
+
+-- some kind of ability-meter that lets you do something awesome when you are
+-- doing really well in a given round.
+-- probably new kind of shield that pops any invaders who come near
+
+-- fix game never ending bug
+-- fix radar
+-- new invader: golden snitch, doesn't show up on your radar
+
+-- maybe replace (48/100*vCircRadius[i])/2 with something better
+
+
+--[[CAPTION CATEGORIES
+-----------------
+capgrpGameState
+-----------------
+AddCaption(LOC_NOT("Sniper!") .. " +10 " .. LOC_NOT("points") .. "!",0xffba00ff,capgrpAmmostate)
+--they call me bullsye
+--point blank combo
+--fierce Competition
+-----------------
+capgrpAmmostate
+-----------------
+AddCaption( chainLength .. LOC_NOT("-chain! +") .. chainLength*2 .. LOC_NOT(" points!"),0xffba00ff,capgrpAmmostate)
+AddCaption(LOC_NOT("Multi-shot! +15 points!"),0xffba00ff,capgrpAmmostate)
+
+-----------------
+capgrpAmmoinfo
+-----------------
+AddCaption(LOC_NOT("Shield Miser! +20 points!"),0xffba00ff,capgrpAmmoinfo)
+AddCaption(LOC_NOT("Shield Master! +10 points!"),0xffba00ff,capgrpAmmoinfo)
+
+-----------------
+capgrpVolume
+-----------------
+AddCaption(LOC_NOT("Boom! +25 points!"),0xffba00ff,capgrpVolume)
+AddCaption(LOC_NOT("BOOM! +50 points!"),0xffba00ff,capgrpVolume)
+AddCaption(LOC_NOT("BOOM! BOOM! BOOM! +100 points!"),0xffba00ff,capgrpVolume)
+AddCaption(LOC_NOT("Accuracy Bonus! +15 points!"),0xffba00ff,capgrpVolume)
+AddCaption(LOC_NOT("Surfer! +15 points!"),0xffba00ff,capgrpVolume)
+
+-----------------
+capgrpMessage
+-----------------
+AddCaption(LOC_NOT("Ammo Depleted!"),0xff0000ff,capgrpMessage)
+AddCaption(LOC_NOT("Ammo: ") .. primShotsLeft)
+AddCaption(LOC_NOT("Shield Depleted"),0xff0000ff,capgrpMessage)
+AddCaption( LOC_NOT("Shield ON:") .. " " .. shieldHealth - 80 .. " " .. LOC_NOT("Power Remaining") )
+AddCaption(LOC_NOT("Shield OFF:") .. " " .. shieldHealth - 80 .. " " .. LOC_NOT("Power Remaining") )
+
+AddCaption(LOC_NOT("Time Extended!") .. "+" .. 4 .. LOC_NOT("s"), 0xff0000ff,capgrpMessage )
+AddCaption("+" .. 3 .. " " .. LOC_NOT("Ammo"), 0x00ff00ff,capgrpMessage)
+AddCaption(LOC_NOT("Shield boosted! +30 power"), 0xff00ffff,capgrpMessage)
+AddCaption(LOC_NOT("Shield is fully recharged!"), 0xffae00ff,capgrpMessage)
+AddCaption(LOC_NOT("Boss defeated! +50 points!"), 0x0050ffff,capgrpMessage)
+
+AddCaption(LOC_NOT("GOTCHA!"))
+AddCaption(LOC_NOT("Kamikaze Expert! +15 points!"),0xffba00ff,capgrpMessage)
+AddCaption(LOC_NOT("Depleted Kamikaze! +5 points!"),0xffba00ff,capgrpMessage)
+AddCaption(LOC_NOT("Timed Kamikaze! +10 points!"),0xffba00ff,capgrpMessage)
+
+-----------------
+capgrpMessage2
+-----------------
+AddCaption(LOC_NOT("Drone Hunter! +10 points!"),0xffba00ff,capgrpMessage2)
+AddCaption(LOC_NOT("Ammo Maniac! +5 points!"),0xffba00ff,capgrpMessage2)
+AddCaption(LOC_NOT("Shield Seeker! +10 points!"),0xffba00ff,capgrpMessage2)
+AddCaption(LOC_NOT("Boss Slayer! +25 points!"),0xffba00ff,capgrpMessage2)
+]]
+
+----------------------------------
+-- so I herd u liek wariables
+----------------------------------
+
+--local fMod = 1 -- for use in .15 single player only, otherwise desync
+local fMod = 1000000 -- use this for dev and .16+ games
+
+-- some console stuff
+local shellID = 0
+local explosivesID = 0
+
+-- gaudyRacer
+local boosterOn = false
+local roundLimit = 3 -- no longer set here (see version history)
+local roundNumber = 0
+local firstClan = 10
+local gameOver = false
+local gameBegun = false
+
+local bestClan = 10
+local bestScore = 0
+local sdScore = {}
+local sdName = {}
+local sdKills = {}
+
+local roundN = 0
+local lastRound
+local RoundHasChanged = true
+
+--------------------------
+-- hog and team tracking variales
+--------------------------
+
+local numhhs = 0
+local hhs = {}
+
+local numTeams
+local teamNameArr = {}
+local teamClan = {}
+local teamSize = {}
+local teamIndex = {}
+
+local teamComment = {}
+local teamScore = {}
+local teamCircsKilled = {}
+local teamSurfer = {}
+
+-- stats variables
+--local teamRed = {}
+--local teamBlue = {}
+--local teamOrange = {}
+--local teamGreen = {}
+local roundKills = 0
+local RK = 0
+local GK = 0
+local BK = 0
+local OK = 0
+local SK = 0
+local shieldMiser = true
+local fierceComp = false
+local chainCounter = 0
+local chainLength = 0
+local shotsFired = 0
+local shotsHit = 0
+local SurfTime = 0
+local sniperHits = 0
+local pointBlankHits = 0
+---------------------
+-- tumbler goods
+---------------------
+
+local leftOn = false
+local rightOn = false
+local upOn = false
+local downOn = false
+
+----------------
+-- TUMBLER
+local wep = {}
+local wepAmmo = {}
+local wepCol = {}
+local wepIndex = 0
+local wepCount = 0
+local fireTimer = 0
+----------------
+
+
+
+local primShotsMax = 5
+local primShotsLeft = 0
+
+local TimeLeft = 0
+local stopMovement = false
+local tumbleStarted = false
+
+local beam = false
+local pShield
+local shieldHealth
+
+local shockwave
+local shockwaveHealth = 0
+local shockwaveRad = 300
+
+local vTag = {}
+
+-----------------------------------------------
+-- CIRCLY GOODIES
+-----------------------------------------------
+
+local CirclesAreGo = false
+local playerIsFine = true
+local targetHit = false
+
+local FadeAlpha = 0 -- used to fade the circles out gracefully when player dies
+local pTimer = 0 -- tracking projectiles following player
+
+--local m2Count = 0 -- handle speed of circs
+
+local vCirc = {}
+local vCCount = 0
+
+local rCirc = {}
+local rCircX = {}
+local rCircY = {}
+local rAlpha = 255
+local radShotsLeft = 0
+
+local vCircActive = {}
+local vCircHealth = {}
+local vType = {}
+local vCounter = {} -- how often this circ gets to "fire" etc
+local vCounterLim = {} -- when vCounter == vCounterLim circle performs its special
+local vCircScore = {} -- how many points killing this invader gives
+
+local vCircRadMax = {}
+local vCircRadMin = {}
+local vCircRadDir = {}
+local vCircRadCounter = {}
+
+local vCircDX = {}
+local vCircDY = {}
+
+local vCircX = {}
+local vCircY = {}
+local vCircMinA = {}
+local vCircMaxA = {}
+local vCircType = {}
+local vCircPulse = {}
+local vCircFuckAll = {}
+local vCircRadius = {}
+local vCircWidth = {}
+local vCircCol = {}
+
+-------------------------------------------
+-- some lazy copypasta/modified methods
+-------------------------------------------
+
+
+
+function HideTags()
+
+ for i = 0, 2 do
+ SetVisualGearValues(vTag[i],0,0,0,0,0,1,0, 0, 240000, 0xffffff00)
+ end
+
+end
+
+function DrawTag(i)
+
+ zoomL = 1.3
+
+ xOffset = 40
+
+ if i == 0 then
+ yOffset = 40
+ tCol = 0xffba00ff
+ tValue = TimeLeft
+ elseif i == 1 then
+ zoomL = 1.1
+ yOffset = 70
+ tCol = 0x00ff00ff
+ tValue = wepAmmo[wepIndex] --primShotsLeft
+ elseif i == 2 then
+ zoomL = 1.1
+ xOffset = 40 + 35
+ yOffset = 70
+ tCol = 0xa800ffff
+ tValue = shieldHealth - 80
+ end
+
+ DeleteVisualGear(vTag[i])
+ vTag[i] = AddVisualGear(0, 0, vgtHealthTag, 0, false)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vTag[i])
+ SetVisualGearValues (
+ vTag[i], --id
+ -(ScreenWidth/2) + xOffset, --xoffset
+ ScreenHeight - yOffset, --yoffset
+ 0, --dx
+ 0, --dy
+ zoomL, --zoom
+ 1, --~= 0 means align to screen
+ g7, --frameticks
+ tValue, --value
+ 240000, --timer
+ tCol --GetClanColor( GetHogClan(CurrentHedgehog) )
+ )
+
+end
+
+function RebuildTeamInfo()
+
+ -- make a list of individual team names
+ for i = 0, (TeamsCount-1) do
+ teamNameArr[i] = " " -- = i
+ teamSize[i] = 0
+ teamIndex[i] = 0
+ teamScore[i] = 0
+ teamCircsKilled[i] = 0
+ teamSurfer[i] = false
+ end
+ numTeams = 0
+
+ for i = 0, (numhhs-1) do
+
+ z = 0
+ unfinished = true
+ while(unfinished == true) do
+
+ newTeam = true
+ tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
+
+ if tempHogTeamName == teamNameArr[z] then
+ newTeam = false
+ unfinished = false
+ end
+
+ z = z + 1
+
+ if z == (TeamsCount-1) then
+ unfinished = false
+ if newTeam == true then
+ teamNameArr[numTeams] = tempHogTeamName
+ numTeams = numTeams + 1
+ end
+ end
+
+ end
+
+ end
+
+ -- find out how many hogs per team, and the index of the first hog in hhs
+ for i = 0, (TeamsCount-1) do
+
+ for z = 0, (numhhs-1) do
+ if GetHogTeamName(hhs[z]) == teamNameArr[i] then
+ teamClan[i] = GetHogClan(hhs[z])
+ if teamSize[i] == 0 then
+ teamIndex[i] = z -- should give starting index
+ end
+ teamSize[i] = teamSize[i] + 1
+ --add a pointer so this hog appears at i in hhs
+ end
+ end
+
+ end
+
+end
+
+-- control
+function AwardPoints(p)
+
+ for i = 0,(TeamsCount-1) do
+ if teamClan[i] == GetHogClan(CurrentHedgehog) then
+ teamScore[i] = teamScore[i] + p
+ end
+ end
+
+end
+
+function AwardKills(t)
+
+ roundKills = roundKills + 1
+
+ for i = 0,(TeamsCount-1) do
+ if teamClan[i] == GetHogClan(CurrentHedgehog) then
+ teamCircsKilled[i] = teamCircsKilled[i] + 1
+
+ if teamCircsKilled[i] == 10 then
+ AddCaption(loc("Boom!") .. " +25 " .. loc("points").."!",0xffba00ff,capgrpVolume)
+ AwardPoints(25)
+ elseif teamCircsKilled[i] == 25 then
+ AddCaption(loc("BOOM!") .. " +50 " .. loc("points") .. "!",0xffba00ff,capgrpVolume)
+ AwardPoints(50)
+ elseif teamCircsKilled[i] == 50 then
+ AddCaption(loc("BOOM!") .. loc("BOOM!") .. loc("BOOM!") .. " +100 " .. loc("points") .. "!",0xffba00ff,capgrpVolume)
+ AwardPoints(100)
+ end
+
+ --[[
+ if t == "R" then
+ redCircsKilled[i] = redCircsKilled[i] + 1
+ end
+ --etc
+ --etc
+ ]]
+ end
+ end
+
+end
+
+-----------------
+
+function bubbleSort(table)
+
+ for i = 1, #table do
+ for j = 2, #table do
+ if table[j] < table[j-1] then
+
+ temp = table[j-1]
+ t2 = sdName[j-1]
+ t3 = sdKills[j-1]
+
+ table[j-1] = table[j]
+ sdName[j-1] = sdName[j]
+ sdKills[j-1] = sdKills[j]
+
+ table[j] = temp
+ sdName[j] = t2
+ sdKills[j] = t3
+
+ end
+ end
+ end
+
+ return
+
+end
+
+-----------------
+
+function CommentOnScore()
+
+ for i = 0,(TeamsCount-1) do
+ sdScore[i] = teamScore[i]
+ sdKills[i] = teamCircsKilled[i]
+ sdName[i] = teamNameArr[i]
+ end
+
+ --bubbleSort(sdScore)
+
+ for i = 0,(TeamsCount-1) do
+ if sdName[i] ~= " " then
+ teamComment[i] = sdName[i] .. " |" ..
+ loc("SCORE") .. ": " .. sdScore[i] .. " " .. loc("points") .. "|" ..
+ loc("KILLS") .. ": " .. sdKills[i] .. " " .. loc("invaders destroyed") .. "|" ..
+ " " .. "|"
+ elseif sdName[i] == " " then
+ teamComment[i] = "|"
+ end
+ end
+
+ entireC = ""
+ for i = (TeamsCount-1),0,-1 do
+ entireC = entireC .. teamComment[i]
+ end
+
+ ShowMission("SPACE INVASION", loc("STATUS UPDATE"), loc("Rounds Complete") .. ": " .. roundNumber .. "/" .. roundLimit .. "| " .. "|" .. loc("Team Scores") .. ": |" ..entireC, 4, 1)
+
+end
+
+function onNewRound()
+ roundNumber = roundNumber + 1
+
+ CommentOnScore()
+
+ -- end game if its at round limit
+ if roundNumber == roundLimit then
+
+ for i = 0, (TeamsCount-1) do
+ if teamScore[i] > bestScore then
+ bestScore = teamScore[i]
+ bestClan = teamClan[i]
+ end
+ end
+
+ for i = 0, (numhhs-1) do
+ if GetHogClan(hhs[i]) ~= bestClan then
+ SetEffect(hhs[i], heResurrectable, false)
+ SetHealth(hhs[i],0)
+ end
+ end
+ gameOver = true
+ TurnTimeLeft = 0 --1
+ TimeLeft = 0
+ end
+end
+
+-- gaudy racer
+function CheckForNewRound()
+
+ ----------
+ -- new
+ ----------
+
+ --[[if gameBegun == true then
+
+ if RoundHasChanged == true then
+ roundN = roundN + 1
+ RoundHasChanged = false
+ onNewRound()
+ end
+
+ if lastRound ~= TotalRounds then -- new round, but not really
+
+ if RoundHasChanged == false then
+ RoundHasChanged = true
+ end
+
+ end
+
+ --AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds)
+ lastRound = TotalRounds
+
+ end]]
+
+ ----------
+ -- old
+ ----------
+ if GetHogClan(CurrentHedgehog) == firstClan then
+ onNewRound()
+ end
+
+end
+
+
+----------------------------------------
+-- some tumbler/space invaders methods
+----------------------------------------
+
+function isATrackedGear(gear)
+ if (GetGearType(gear) == gtExplosives) or
+ (GetGearType(gear) == gtShell) or
+ (GetGearType(gear) == gtFlame) or-- new -- gtBall
+ (GetGearType(gear) == gtBall)
+ then
+ return(true)
+ else
+ return(false)
+ end
+end
+
+function setNewGearValues(gear)
+
+ if GetGearType(gear) == gtShell then
+ lfs = 50 -- roughly 5 seconds
+ shellID = shellID + 1
+ setGearValue(gear,"ID",shellID)
+ --nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this shell")
+ elseif GetGearType(gear) == gtBall then
+ lfs = 5 --70 -- 7s
+ elseif GetGearType(gear) == gtExplosives then
+ lfs = 15 -- 1.5s
+ explosivesID = explosivesID + 1
+ setGearValue(gear,"ID",explosivesID)
+ setGearValue(gear,"XP", GetX(gear))
+ setGearValue(gear,"YP", GetY(gear))
+ --nw WriteLnToConsole("Just assigned ID " .. getGearValue(gear,"ID") .. " to this explosives")
+ elseif GetGearType(gear) == gtFlame then
+ lfs = 5 -- 0.5s
+ else
+ lfs = 100
+ end
+
+ setGearValue(gear,"lifespan",lfs)
+ --WriteLnToConsole("I also set its lifespan to " .. lfs)
+
+
+end
+
+function HandleLifeSpan(gear)
+
+ decreaseGearValue(gear,"lifespan")
+
+ --WriteLnToConsole("Just decreased the lifespan of a gear to " .. getGearValue(gear,"lifespan"))
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+
+ if getGearValue(gear,"lifespan") == 0 then
+
+ if GetGearType(gear) == gtShell then
+ AddVisualGear(GetX(gear), GetY(gear), vgtExplosion, 0, false)
+ WriteLnToConsole("about to delete a shell due to lifespan == 0")
+ --elseif GetGearType(gear) == gtBall then
+ -- AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, true)
+ elseif GetGearType(gear) == gtExplosives then
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+ --nw WriteLnToConsole("about to delete a explosive due to lifespan == 0")
+ elseif GetGearType(gear) == gtFlame then
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, false)
+ --WriteLnToConsole("about to delete flame due to lifespan == 0")
+ end
+
+ DeleteGear(gear)
+
+ end
+
+end
+
+-- this prevents ugly barrel clipping sounds when a barrel flies off map limits
+function DeleteFarFlungBarrel(gear)
+
+ if GetGearType(gear) == gtExplosives then
+ if (GetX(gear) < -1900) or
+ (GetX(gear) > 6200) or
+ (GetY(gear) < -3400)
+ then
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+ DeleteGear(gear)
+ --SetHealth(gear, 0)
+ --WriteLnToConsole("I'm setting barrel ID " .. getGearValue(gear,"ID") .. " to 0 health because it's been flung too close to the map edges. at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+ end
+
+ end
+
+end
+
+-----------------------
+--EVENT HANDLERS
+-- action keys
+-----------------------
+
+function HandleFlameThrower()
+
+ --
+ --flamer
+
+ fireTimer = fireTimer + 1
+ if fireTimer == 6 then -- 6
+ fireTimer = 0
+
+ if (wep[wepIndex] == loc("Flamer") ) and (preciseOn == true) and (wepAmmo[wepIndex] > 0) and (stopMovement == false) and (tumbleStarted == true) then
+
+ wepAmmo[wepIndex] = wepAmmo[wepIndex] - 1
+ AddCaption(
+ loc("Flamer") .. ": " ..
+ (wepAmmo[wepIndex]/800*100) - (wepAmmo[wepIndex]/800*100)%2 .. "%",
+ wepCol[2],
+ capgrpMessage2
+ )
+ DrawTag(3)
+
+ dx, dy = GetGearVelocity(CurrentHedgehog) --gtFlame -- gtSnowball -- gtAirBomb
+ shell = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtFlame, 0, 0, 0, 0)
+
+ xdev = 1 + GetRandom(35) --25
+ xdev = xdev / 100
+
+ r = GetRandom(2)
+ if r == 1 then
+ xdev = xdev*-1
+ end
+
+ ydev = 1 + GetRandom(35) --25
+ ydev = ydev / 100
+
+ r = GetRandom(2)
+ if r == 1 then
+ ydev = ydev*-1
+ end
+
+ --4.5 or 2.5 nonflames --4.5
+ SetGearVelocity(shell, (dx*4.5)+(xdev*fMod), (dy*4.5)+(ydev*fMod)) --10
+
+ end
+
+ end
+
+
+end
+
+function ChangeWeapon()
+
+ wepIndex = wepIndex + 1
+ if wepIndex == wepCount then
+ wepIndex = 0
+ end
+
+ AddCaption(wep[wepIndex] .. " " .. loc("selected!"), wepCol[wepIndex],capgrpAmmoinfo )
+ AddCaption(wepAmmo[wepIndex] .. " " .. loc("shots remaining."), wepCol[wepIndex],capgrpMessage2)
+
+end
+
+--function onTimer()
+
+ -- experimental wep
+ --[[SetVisualGearValues(shockwave, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 40, 255, 1, 10, 0, 300, 1, 0xff33ffff)
+ AddCaption("boom")
+ PlaySound(sndWarp)
+ shockwaveHealth = 100
+ shockwaveRad = 100]]
+
+
+ --change wep
+ --ChangeWeapon()
+
+ -- booster
+ --[[if boosterOn == false then
+ boosterOn = true
+ else
+ boosterOn = false
+ end]]
+
+--end
+
+-- o rite dis wan iz liek synched n stuff hope full lee
+-- old method
+--[[function onPrecise()
+
+
+ -- Fire Barrel
+ if (primShotsLeft > 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then
+
+ shotsFired = shotsFired +1
+
+ morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtExplosives, 0, 0, 0, 1)
+
+ primShotsLeft = primShotsLeft - 1
+
+ if primShotsLeft == 0 then
+ PlaySound(sndSuddenDeath)
+ AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage)
+ else
+ AddCaption(loc("Ammo") .. ": " .. primShotsLeft)
+ end
+ DrawTag(1)
+
+ CopyPV(CurrentHedgehog, morte) -- new addition
+ x,y = GetGearVelocity(morte)
+
+ x = x*2
+ y = y*2
+ SetGearVelocity(morte, x, y)
+
+
+ elseif (primShotsLeft == 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then
+ AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage)
+ end
+
+
+end]]
+
+-- derp tumbler
+function onPrecise()
+
+ if (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) and (wepAmmo[wepIndex] > 0) then
+
+ wepAmmo[wepIndex] = wepAmmo[wepIndex] - 1
+ --AddCaption(wepAmmo[wepIndex] .. " " .. loc("shots remaining."), wepCol[wepIndex],capgrpMessage2)
+
+ if wep[wepIndex] == loc("Barrel Launcher") then
+ shotsFired = shotsFired +1
+
+ morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtExplosives, 0, 0, 0, 1)
+ CopyPV(CurrentHedgehog, morte) -- new addition
+ x,y = GetGearVelocity(morte)
+ x = x*2
+ y = y*2
+ SetGearVelocity(morte, x, y)
+
+ if wepAmmo[wepIndex] == 0 then
+ PlaySound(sndSuddenDeath)
+ AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage)
+ else
+ --AddCaption(loc("Ammo") .. ": " .. wepAmmo[wepIndex])
+ end
+ DrawTag(1)
+
+ elseif wep[wepIndex] == loc("Mine Deployer") then
+ morte = AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtAirBomb, 0, 0, 0, 0)
+ SetTimer(morte, 1000)
+ DrawTag(1)
+ end
+
+ elseif (wepAmmo[wepIndex] == 0) and (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then
+ AddCaption(loc("Ammo Depleted!"),0xff0000ff,capgrpMessage)
+ end
+
+ preciseOn = true
+
+end
+
+function onPreciseUp()
+ preciseOn = false
+end
+
+function onLJump()
+
+ if (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) then
+ shieldMiser = false
+ if shieldHealth == 80 then
+ AddCaption(loc("Shield Depleted"),0xff0000ff,capgrpMessage)
+ PlaySound(sndMineTick)
+ PlaySound(sndSwitchHog)
+ elseif (beam == false) and (shieldHealth > 80) then
+ beam = true
+ SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 40, 255, 1, 10, 0, 300, 1, 0xa800ffff)
+ AddCaption( loc("Shield ON:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") )
+ PlaySound(sndWarp)
+ else
+ beam = false
+ SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 0, 0, 1, 10, 0, 0, 0, 0xa800ffff)
+ AddCaption(loc("Shield OFF:") .. " " .. shieldHealth - 80 .. " " .. loc("Power Remaining") )
+ end
+ end
+end
+
+function onHJump()
+
+ if (CurrentHedgehog ~= nil) and (stopMovement == false) and (tumbleStarted == true) and
+ (rAlpha == 255) and (radShotsLeft > 0) then
+ rPingTimer = 0
+ rAlpha = 0
+ radShotsLeft = radShotsLeft -1
+ AddCaption(loc("Pings left:") .. " " .. radShotsLeft,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage)
+ end
+
+end
+
+-----------------
+-- movement keys
+-----------------
+
+function onLeft()
+ leftOn = true
+end
+
+function onRight()
+ rightOn = true
+end
+
+function onUp()
+ upOn = true
+end
+
+function onDown()
+ downOn = true
+end
+
+function onDownUp()
+ downOn = false
+end
+
+function onUpUp()
+ upOn = false
+end
+
+function onLeftUp()
+ leftOn = false
+end
+
+function onRightUp()
+ rightOn = false
+end
+
+--------------------------
+-- other event handlers
+--------------------------
+
+function onGameInit()
+ GameFlags = 0 + gfRandomOrder
+ Theme = "EarthRise"
+ CaseFreq = 0
+ HealthCaseProb = 0
+ MinesNum = 0
+ Explosives = 0
+ Delay = 1000
+
+ for i = 0, 3 do
+ vTag[0] = AddVisualGear(0, 0, vgtHealthTag, 0, false)
+ end
+
+ HideTags()
+
+ wep[0] = loc("Barrel Launcher")
+ wep[1] = loc("Mine Deployer")
+ wep[2] = loc("Flamer")
+
+ wepCol[0] = 0x78818eff
+ wepCol[1] = 0xa12a77ff
+ wepCol[2] = 0xf49318ff
+
+ wepCount = 3
+
+end
+
+function onGameStart()
+
+ if (MinesTime == -1000) or (MinesTime == 0) then
+ roundLimit = 3
+ else
+ roundLimit = (MinesTime / 1000)
+ end
+
+ ShowMission (
+ "SPACE INVASION",
+ loc("a Hedgewars mini-game"),
+
+ loc("Destroy invaders to score points.") .. "|" ..
+ " " .. "|" ..
+
+ loc("Round Limit") .. ": " .. roundLimit .. "|" ..
+ loc("Turn Time") .. ": " .. (TurnTime/1000) .. loc("sec") .. "|" ..
+ " " .. "|" ..
+
+ loc("Movement: [Up], [Down], [Left], [Right]") .. "|" ..
+ loc("Fire") .. ": " .. loc("[Left Shift]") .. "|" ..
+ loc("Toggle Shield") .. ": " .. loc("[Enter]") .. "|" ..
+ loc("Radar Ping") .. ": " .. loc("[Backspace]") .. "|" ..
+
+ --" " .. "|" ..
+ --LOC_NOT("Invaders List: ") .. "|" ..
+ --LOC_NOT("Blue Jabberwock: (50 points)") .. "|" ..
+ --LOC_NOT("Red Warbler: (10 points)") .. "|" ..
+ --LOC_NOT("Orange Gob: (5 points)") .. "|" ..
+ --LOC_NOT("Green Wrangler: (3 points)") .. "|" ..
+
+
+ "", 4, 4000
+ )
+
+ CreateMeSomeCircles()
+ RebuildTeamInfo() -- control
+ lastRound = TotalRounds
+
+end
+
+function onScreenResize()
+
+ -- redraw Tags so that their screen locations are updated
+ if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then
+ DrawTag(0)
+ DrawTag(1)
+ DrawTag(2)
+ end
+
+end
+
+function onNewTurn()
+
+ --primShotsLeft = primShotsMax
+ radShotsLeft = 2
+ stopMovement = false
+ tumbleStarted = false
+ boosterOn = false
+ beam = false
+ shieldHealth = 30 + 80 -- 50 = 5 secs, roughly
+ shockwaveHealth = 0
+
+ RK = 0
+ GK = 0
+ BK = 0
+ OK = 0
+ SK = 0
+ roundKills = 0
+ shieldMiser = true
+ fierceComp = false
+ shotsFired = 0
+ shotsHit = 0
+ sniperHits = 0
+ pointBlankHits = 0
+ chainLength = 0
+ chainCounter = 0
+ SurfTime = 12
+
+ -------------------------
+ -- gaudy racer
+ -------------------------
+ CheckForNewRound()
+
+ -- Handle Starting Stage of Game
+ if (gameOver == false) and (gameBegun == false) then
+ gameBegun = true
+ roundNumber = 0 -- 0
+ firstClan = GetHogClan(CurrentHedgehog)
+ end
+
+ if gameOver == true then
+ gameBegun = false
+ stopMovement = true
+ tumbleStarted = false
+ SetMyCircles(false)
+ end
+
+
+ -------
+ -- tumbler
+ ----
+
+ wepAmmo[0] = 5
+ wepAmmo[1] = 2
+ wepAmmo[2] = 5000
+ wepIndex = 2
+ ChangeWeapon()
+
+
+ HideTags()
+
+ ---------------
+ ---------------
+ --AddCaption("num g: " .. numGears() )
+ --WriteLnToConsole("onNewTurn, I just set a bunch of variables to their necessary states. This was done at:")
+ --WriteLnToConsole("The above occured at Game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+end
+
+function ThingsToBeRunOnGears(gear)
+
+ HandleLifeSpan(gear)
+ DeleteFarFlungBarrel(gear)
+
+ if CirclesAreGo == true then
+ CheckVarious(gear)
+ ProjectileTrack(gear)
+ end
+
+end
+
+
+function onGameTick20()
+
+
+ --WriteLnToConsole("Start of GameTick")
+
+ HandleCircles()
+
+ -- derp
+ --if shockwaveHealth > 0 then
+ -- shockwaveHealth = shockwaveHealth - 1
+ -- shockwaveRad = shockwaveRad + 5
+ --end
+
+
+ if GameTime%100 == 0 then
+
+ if beam == true then
+ shieldHealth = shieldHealth - 1
+ if shieldHealth < 80 then -- <= 80
+ shieldHealth = 80
+ beam = false
+ AddCaption(loc("Shield Depleted"),0xff0000ff,capgrpMessage)
+ PlaySound(sndMineTick)
+ PlaySound(sndSwitchHog)
+ end
+ end
+
+
+
+ --nw WriteLnToConsole("Starting ThingsToBeRunOnGears()")
+
+ runOnGears(ThingsToBeRunOnGears)
+
+ --nw WriteLnToConsole("Finished ThingsToBeRunOnGears()")
+
+ --runOnGears(HandleLifeSpan)
+ --runOnGears(DeleteFarFlungBarrel)
+
+ if CirclesAreGo == true and CurrentHedgehog ~= nil then
+ CheckDistances()
+ --runOnGears(CheckVarious) -- used to be in handletracking for some bizarre reason
+ --runOnGears(ProjectileTrack)
+ end
+
+ -- white smoke trail as player falls from the sky
+ if (TimeLeft <= 0) and (stopMovement == true) and (CurrentHedgehog ~= nil) then
+ j,k = GetGearVelocity(CurrentHedgehog)
+ if (j ~= 0) and (k ~= 0) then
+ AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true)
+ end
+ end
+
+ --nw WriteLnToConsole("Finished 100Timer")
+
+ end
+
+
+ -- start the player tumbling with a boom once their turn has actually begun
+ if (tumbleStarted == false) and (gameOver == false) then
+ if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
+ --AddCaption(LOC_NOT("Good to go!"))
+ tumbleStarted = true
+ TimeLeft = div(TurnTime, 1000) --45
+ FadeAlpha = 0
+ rAlpha = 255
+ AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
+ DrawTag(0)
+ DrawTag(1)
+ DrawTag(2)
+ SetMyCircles(true)
+ end
+ end
+
+ --WriteLnToConsole("Finished initial check")
+
+ if (CurrentHedgehog ~= nil) and (tumbleStarted == true) then
+
+ --AddCaption(GetX(CurrentHedgehog) .. ";" .. GetY(CurrentHedgehog) )
+
+ -- Calculate and display turn time
+ if GameTime%1000 == 0 then
+ TimeLeft = TimeLeft - 1
+
+ if TimeLeft >= 0 then
+ --AddCaption(LOC_NOT("Time Left: ") .. TimeLeft)
+ DrawTag(0)
+ end
+
+ end
+
+ --WriteLnToConsole("Finished timeleft calculations")
+
+ -------------------------------
+ -- Player has run out of luck (out of time or hit by gtShell)
+ -------------------------------
+ -- checks in FloatyThings
+ if PlayerIsFine() == false then
+ TimeLeft = 0
+ end
+
+ --WriteLnToConsole("successfully checked playerIsFine")
+
+ if (TimeLeft == 0) then
+ if (stopMovement == false) then --time to stop the player
+ stopMovement = true
+ boosterOn = false
+ beam = false
+ upOn = false
+ down = false
+ leftOn = false
+ rightOn = false
+ SetMyCircles(false)
+ HideTags()
+ rAlpha = 255
+ --nw WriteLnToConsole("Player is out of luck")
+
+ if shieldMiser == true then
+
+ p = (roundKills*3.5) - ((roundKills*3.5)%1) + 2
+
+ AddCaption(loc("Shield Miser!") .." +" .. p .." ".. loc("points") .. "!",0xffba00ff,capgrpAmmoinfo)
+ AwardPoints(p)
+ end
+
+ if ((shotsHit / shotsFired * 100) >= 80) and (shotsFired > 4) then
+ AddCaption(loc("Accuracy Bonus!") .. " +15 " .. loc("points") .. "!",0xffba00ff,capgrpVolume)
+ AwardPoints(15)
+ end
+
+ end
+ else -- remove this if you want tumbler to fall slowly on death
+ -------------------------------
+ -- Player is still in luck
+ -------------------------------
+
+
+ --WriteLnToConsole("about to do chainCounter checks")
+ if chainCounter > 0 then
+ chainCounter = chainCounter -1
+ if chainCounter == 0 then
+ chainLength = 0
+ end
+ end
+
+ -- handle movement based on IO
+ if GameTime%100 == 0 then -- 100
+ --nw WriteLnToConsole("Start of Player MoveTimer")
+
+ ---------------
+ -- new trail code
+ ---------------
+ -- the trail lets you know you have 5s left to pilot, akin to birdy feathers
+ if (TimeLeft <= 5) and (TimeLeft > 0) then --vgtSmoke
+ tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmoke, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+ SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, GetClanColor(GetHogClan(CurrentHedgehog)) )
+ end
+ --------------
+ --------------
+
+ ------------------------
+ -- surfer achievement
+ ------------------------
+
+ if (WaterLine - GetY(CurrentHedgehog)) < 15 then
+ SurfTime = SurfTime -1
+ end
+
+ if SurfTime ~= 12 then
+
+ SurfTime = SurfTime - 1
+ if SurfTime <= 0 then
+ for i = 0,(TeamsCount-1) do
+ if teamClan[i] == GetHogClan(CurrentHedgehog) and (teamSurfer[i] == false) then
+ teamSurfer[i] = true
+ SurfTime = 12
+ AddCaption(loc("Surfer! +15 points!"),0xffba00ff,capgrpVolume)
+ AwardPoints(15)
+ end
+ end
+ end
+ end
+
+
+ dx, dy = GetGearVelocity(CurrentHedgehog)
+
+ --WriteLnToConsole("I just got the velocity of currenthedgehog. It is dx: " .. dx .. "; dy: " .. dy)
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+ if boosterOn == true then
+ tempE = AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtDust, 0, false)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+ SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, 1, g9, GetClanColor(GetHogClan(CurrentHedgehog)) )
+ dxlimit = 0.8*fMod
+ dylimit = 0.8*fMod
+ else
+ dxlimit = 0.4*fMod
+ dylimit = 0.4*fMod
+ end
+
+ if dx > dxlimit then
+ dx = dxlimit
+ end
+ if dy > dylimit then
+ dy = dylimit
+ end
+ if dx < -dxlimit then
+ dx = -dxlimit
+ end
+ if dy < -dylimit then
+ dy = -dylimit
+ end
+
+
+ if leftOn == true then
+ dx = dx - 0.1*fMod
+ end
+ if rightOn == true then
+ dx = dx + 0.1*fMod
+ end
+
+ if upOn == true then
+ dy = dy - 0.1*fMod
+ end
+ if downOn == true then
+ dy = dy + 0.1*fMod
+ end
+
+ SetGearVelocity(CurrentHedgehog, dx, dy)
+
+ --WriteLnToConsole("I just SET the velocity of currenthedgehog. It is now dx: " .. dx .. "; dy: " .. dy)
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+ --nw WriteLnToConsole("End of Player MoveTimer")
+
+ end
+
+
+ HandleFlameThrower()
+
+
+ end -- new end I put here to check if he's still alive or not
+
+ end
+
+ --WriteLnToConsole("End of GameTick")
+
+end
+
+function onGearDamage(gear, damage)
+ if GetGearType(gear) == gtHedgehog then
+ if (fierceComp == false) and (damage >= 60) and (GetHogClan(gear) ~= GetHogClan(CurrentHedgehog)) then
+ fierceComp = true
+ AddCaption(loc("Fierce Competition!") .. " +8 " .. loc("points") .. "!",0xffba00ff,capgrpGameState)
+ AwardPoints(8)
+ end
+ end
+end
+
+function onGearResurrect(gear)
+
+ -- did I fall into the water? well, that was a stupid thing to do
+ if gear == CurrentHedgehog then
+ TimeLeft = 0
+ --WriteLnToConsole("Current hedgehog just drowned himself")
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+ end
+
+end
+
+function onGearAdd(gear)
+
+ if isATrackedGear(gear) then
+ trackGear(gear)
+ setNewGearValues(gear)
+ end
+
+ --if GetGearType(gear) == gtBall then
+ -- SetTimer(gear, 5000)
+ --end
+
+ if GetGearType(gear) == gtHedgehog then
+ SetEffect(gear, heResurrectable, true)
+
+ -----------
+ -- control
+ hhs[numhhs] = gear
+ numhhs = numhhs + 1
+ -----------
+ end
+
+end
+
+function onGearDelete(gear)
+
+
+ --[[if GetGearType(gear) == gtShell then
+ --nw WriteLnToConsole("on GearDelete call. Shell ID: " .. getGearValue(gear,"ID"))
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+ --if CurrentHedgehog ~= nil then
+ -- WriteLnToConsole("As it happens, player is at: " .. GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog))
+ --end
+ elseif GetGearType(gear) == gtExplosives then
+ --nw WriteLnToConsole("on GearDelete call. Explosives ID: " .. getGearValue(gear,"ID"))
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+ --if CurrentHedgehog ~= nil then
+ -- WriteLnToConsole("As it happens, player is at: " .. GetX(CurrentHedgehog) .. "; " .. GetY(CurrentHedgehog))
+ --end
+ elseif GetGearType(gear) == gtFlame then
+ --WriteLnToConsole("on GearDelete flame")
+ end]]
+
+ if isATrackedGear(gear) then
+ trackDeletion(gear)
+ end
+
+ if CurrentHedgehog ~= nil then
+ FollowGear(CurrentHedgehog)
+ end
+
+end
+
+
+
+------------------------------------------------------------
+------------------------------------------------------------
+------------------------------------------------------------
+------------------------------------------------------------
+-- FLOATY THINGS
+-- "I'll make this into a generic library and code properly
+-- when I have more time and feel less lazy"
+------------------------------------------------------------
+------------------------------------------------------------
+------------------------------------------------------------
+------------------------------------------------------------
+
+function DoHorribleThings(cUID)
+
+ -- work out the distance to the target
+ g1X, g1Y = GetGearPosition(CurrentHedgehog)
+ g2X, g2Y = vCircX[cUID], vCircY[cUID]
+ q = g1X - g2X
+ w = g1Y - g2Y
+ r = math.sqrt( (q*q) + (w*w) ) --alternate
+
+ opp = w
+ if opp < 0 then
+ opp = opp*-1
+ end
+
+ -- work out the angle (theta) to the target
+ t = math.deg ( math.asin(opp / r) )
+
+ -- based on the radius of the radar, calculate what x/y displacement should be
+ NR = 150 -- radius at which to draw circs
+ NX = math.cos( math.rad(t) ) * NR
+ NY = math.sin( math.rad(t) ) * NR
+
+ -- displace xy based on where this thing actually is
+
+ if r < NR then
+ rCircX[cUID] = g2X
+ elseif q > 0 then
+ rCircX[cUID] = g1X - NX
+ else
+ rCircX[cUID] = g1X + NX
+ end
+
+ if r < NR then
+ rCircY[cUID] = g2Y
+ elseif w > 0 then
+ rCircY[cUID] = g1Y - NY
+ else
+ rCircY[cUID] = g1Y + NY
+ end
+
+end
+
+function PlayerIsFine()
+ return (playerIsFine)
+end
+
+function GetDistFromXYtoXY(a, b, c, d)
+ q = a - c
+ w = b - d
+ return ( (q*q) + (w*w) )
+end
+
+function GetDistFromGearToGear(gear, gear2)
+
+ g1X, g1Y = GetGearPosition(gear)
+ g2X, g2Y = GetGearPosition(gear2)
+ q = g1X - g2X
+ w = g1Y - g2Y
+
+
+ --[[
+ WriteLnToConsole("I just got the position of two gears and calculated the distance betwen them")
+ if gear == CurrentHedgehog then
+ WriteLnToConsole("Gear 1 is CurrentHedgehog.")
+ end
+ if gear2 == CurrentHedgehog then
+ WriteLnToConsole("Gear 2 is CurrentHedgehog.")
+ end
+ WriteLnToConsole("G1X: " .. g1X .. "; G1Y: " .. g1Y)
+ WriteLnToConsole("G2X: " .. g2X .. "; G2Y: " .. g2Y)
+ WriteLnToConsole("Their distance is " .. (q*q) + (w*w) )
+ WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+]]
+
+
+ return ( (q*q) + (w*w) )
+
+end
+
+function GetDistFromGearToXY(gear, g2X, g2Y)
+
+ g1X, g1Y = GetGearPosition(gear)
+ q = g1X - g2X
+ w = g1Y - g2Y
+
+
+ --[[WriteLnToConsole("I just got the position of a gear and calculated the distance betwen it and another xy")
+ if gear == CurrentHedgehog then
+ WriteLnToConsole("Gear 1 is CurrentHedgehog.")
+ end
+
+ WriteLnToConsole("G1X: " .. g1X .. "; G1Y: " .. g1Y)
+ WriteLnToConsole("Other X: " .. g2X .. "; Other Y: " .. g2Y)
+ WriteLnToConsole("Their distance is " .. (q*q) + (w*w) )
+ WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+]]
+
+
+ return ( (q*q) + (w*w) )
+
+
+end
+
+function CreateMeSomeCircles()
+
+ for i = 0, 7 do
+ vCCount = vCCount +1
+ vCirc[i] = AddVisualGear(0,0,vgtCircle,0,true)
+
+ rCirc[i] = AddVisualGear(0,0,vgtCircle,0,true)
+ rCircX[i] = 0
+ rCircY[i] = 0
+
+ vCircDX[i] = 0
+ vCircDY[i] = 0
+
+ vType[i] = "generic"
+ vCounter[i] = 0
+ vCounterLim[i] = 150
+ vCircScore[i] = 0
+ vCircHealth[i] = 1
+
+ vCircMinA[i] = 80 --80 --20
+ vCircMaxA[i] = 255
+ vCircType[i] = 1 --1
+ vCircPulse[i] = 10
+ vCircFuckAll[i] = 0
+ vCircRadius[i] = 0
+ vCircWidth[i] = 3 --5
+
+ vCircRadMax[i] = 0
+ vCircRadMin[i] = 0
+ vCircRadDir[i] = -1
+ vCircRadCounter[i] = 0
+
+ vCircX[i], vCircY[i] = 0,0
+
+ vCircCol[i] = 0xff00ffff
+
+ SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], vCircMinA[i], vCircMaxA[i], vCircType[i], vCircPulse[i], vCircFuckAll[i], vCircRadius[i], vCircWidth[i], vCircCol[i])
+
+ SetVisualGearValues(rCirc[i], 0, 0, 100, 255, 1, 10, 0, 40, 3, vCircCol[i])
+
+ end
+
+ pShield = AddVisualGear(0,0,vgtCircle,0,true)
+ --SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), 80, 200, 1, 10, 0, 200, 5, 0xff00ffff)
+
+
+ shockwave = AddVisualGear(0,0,vgtCircle,0,true)
+
+end
+
+function IGotMeASafeXYValue(i)
+
+ acceptibleDistance = 800
+
+ -- put this in here to thwart attempts at repositioning and test sanity limit
+ --vCircX[i] = GetX(CurrentHedgehog)+250
+ --vCircY[i] = GetY(CurrentHedgehog)+250
+
+ vCircX[i] = GetRandom(5000)
+ vCircY[i] = GetRandom(2000)
+ dist = GetDistFromGearToXY(CurrentHedgehog, vCircX[i], vCircY[i])
+ if dist > acceptibleDistance*acceptibleDistance then
+ return(true)
+ else
+ return(false)
+ end
+
+end
+
+function CircleDamaged(i)
+
+ res = ""
+ vCircHealth[i] = vCircHealth[i] -1
+
+ if vCircHealth[i] <= 0 then
+ -- circle is dead, do death effects/consequences
+
+ vCircActive[i] = false
+
+ if (vType[i] == "drone") then
+ PlaySound(sndHellishImpact4)
+ TimeLeft = TimeLeft + 4
+ AddCaption(loc("Time Extended!") .. "+" .. 4 .. loc("sec"), 0xff0000ff,capgrpMessage )
+ DrawTag(0)
+
+ morte = AddGear(vCircX[i], vCircY[i], gtExplosives, 0, 0, 0, 1)
+ SetHealth(morte, 0)
+
+ RK = RK + 1
+ if RK == 5 then
+ RK = 0
+ AddCaption(loc("Drone Hunter!") .. " +10 " .. loc("points") .. "!",0xffba00ff,capgrpMessage2)
+ AwardPoints(10)
+ end
+
+ elseif (vType[i] == "ammo") then
+ AddVisualGear(vCircX[i], vCircY[i], vgtExplosion, 0, false)
+ PlaySound(sndExplosion)
+ PlaySound(sndShotgunReload)
+ wepAmmo[0] = wepAmmo[0] +3
+ --primShotsLeft = primShotsLeft + 3
+ AddCaption("+" .. 3 .. " " .. loc("Ammo"), 0x00ff00ff,capgrpMessage)
+ DrawTag(1)
+
+ GK = GK + 1
+ if GK == 3 then
+ GK = 0
+ AddCaption(loc("Ammo Maniac!") .. " +5 " .. loc("points") .. "!",0xffba00ff,capgrpMessage2)
+ AwardPoints(5)
+ end
+
+ elseif (vType[i] == "bonus") then
+
+ AddVisualGear(vCircX[i], vCircY[i], vgtExplosion, 0, false)
+ PlaySound(sndExplosion)
+
+ AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false)
+ AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false)
+ AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false)
+ AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false)
+ AddVisualGear(vCircX[i], vCircY[i], vgtFire, 0, false)
+ AddVisualGear(vCircX[i], vCircY[i], vgtSmoke, 0, false)
+
+ PlaySound(sndVaporize)
+ --sndWarp sndMineTick --sndSwitchHog --sndSuddenDeath
+
+ shieldHealth = shieldHealth + 30
+ AddCaption(loc("Shield boosted! +30 power"), 0xa800ffff,capgrpMessage)
+ if shieldHealth >= 250 then
+ shieldHealth = 250
+ AddCaption(loc("Shield is fully recharged!"),0xa800ffff,capgrpMessage)
+ end
+ DrawTag(2)
+
+ OK = OK + 1
+ if OK == 3 then
+ OK = 0
+ AddCaption(loc("Shield Seeker!") .. " + 10 " .. loc("points") .. "!",0xffba00ff,capgrpMessage2)
+ AwardPoints(10)
+ end
+
+ elseif (vType[i] == "blueboss") then
+ PlaySound(sndHellishImpact3)
+ AddCaption(loc("Boss defeated!") .. " +30 " .. loc("points") .. "!", 0x0050ffff,capgrpMessage)
+
+ morte = AddGear(vCircX[i], vCircY[i], gtExplosives, 0, 0, 0, 1)
+ SetHealth(morte, 0)
+
+ BK = BK + 1
+ if BK == 2 then
+ BK = 0
+ AddCaption(loc("Boss Slayer!") .. " +25 " .. loc("points") .. "!",0xffba00ff,capgrpMessage2)
+ AwardPoints(25)
+ end
+
+ end
+
+ AwardPoints(vCircScore[i])
+ AwardKills()
+ SetUpCircle(i)
+ res = "fatal"
+
+ chainCounter = 3000
+ chainLength = chainLength + 1
+ if chainLength > 1 then
+ AddCaption( chainLength .. "-" .. loc("Hit Combo!") .. " +" .. chainLength*2 .. " " .. loc("points") .. "!",0xffba00ff,capgrpAmmostate)
+ AwardPoints(chainLength*2)
+ end
+
+ else
+ -- circle is merely damaged
+ -- do damage effects/sounds
+ AddVisualGear(vCircX[i], vCircY[i], vgtSteam, 0, false)
+ r = GetRandom(4)
+ if r == 0 then
+ PlaySound(sndHellishImpact1)
+ elseif r == 1 then
+ PlaySound(sndHellishImpact2)
+ elseif r == 2 then
+ PlaySound(sndHellishImpact3)
+ elseif r == 3 then
+ PlaySound(sndHellishImpact4)
+ end
+ res = "non-fatal"
+
+ end
+
+ return(res)
+
+end
+
+function SetUpCircle(i)
+
+
+ r = GetRandom(10)
+ --r = 8
+ -- 80% of spawning either red/green
+ if r <= 7 then
+
+ --r = GetRandom(5)
+ r = GetRandom(2)
+ --r = 1
+ if r == 0 then
+ --if r <= 2 then
+ vCircCol[i] = 0xff0000ff -- red
+ vType[i] = "drone"
+ vCircRadMin[i] = 50 *5
+ vCircRadMax[i] = 90 *5
+ vCounterLim[i] = 150
+ vCircScore[i] = 10
+ vCircHealth[i] = 1
+ --else
+ elseif r == 1 then
+ vCircCol[i] = 0x00ff00ff -- green
+ vType[i] = "ammo"
+ vCircRadMin[i] = 25 *7
+ vCircRadMax[i] = 30 *7
+ vCircScore[i] = 3
+ vCircHealth[i] = 1
+ end
+
+ -- 20% chance of spawning boss or bonus
+ else
+ r = GetRandom(5)
+ --r = GetRandom(2)
+ --r = 0
+ if r <= 1 then
+ --if r == 0 then
+ vCircCol[i] = 0x0050ffff -- sexy blue
+ vType[i] = "blueboss"
+ vCircRadMin[i] = 100*5
+ vCircRadMax[i] = 180*5
+ vCircWidth[i] = 1
+ vCounterLim[i] = 100
+ vCircScore[i] = 30
+ vCircHealth[i] = 3
+ else
+ --elseif r == 1 then
+ --vCircCol[i] = 0xffae00ff -- orange
+ vCircCol[i] = 0xa800ffff -- purp
+ vType[i] = "bonus"
+ vCircRadMin[i] = 20 *7
+ vCircRadMax[i] = 40 *7
+ vCircScore[i] = 5
+ vCircHealth[i] = 1
+ end
+
+ end
+
+ -- regenerate circle xy if too close to player or until sanity limit kicks in
+ reN = 0
+ --zzz = 0
+ while (reN < 10) do
+ if IGotMeASafeXYValue(i) == false then
+ reN = reN + 1
+ --zzz = zzz + 1
+ else
+ reN = 15
+ end
+ end
+ --AddCaption("Took me this many retries: " .. zzz) -- number of times it took to work
+
+ vCircRadius[i] = vCircRadMax[i] - GetRandom(vCircRadMin[i])
+
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i])
+ SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], vCircWidth[i], vCircCol[i]-0x000000ff)
+ -- - -0x000000ff
+
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(rCirc[i])
+ SetVisualGearValues(rCirc[i], 0, 0, g3, g4, g5, g6, g7, g8, g9, vCircCol[i]-0x000000ff)
+
+
+ vCircActive[i] = true -- new
+
+ --nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i])
+ --nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i])
+ --nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i])
+
+end
+
+function SetMyCircles(s)
+
+ CirclesAreGo = s
+ playerIsFine = s
+
+ if s == true then
+ --nw WriteLnToConsole("About to set up all circles, old values are here:")
+ for i = 0,(vCCount-1) do
+ --nw WriteLnToConsole("CIRC " .. i .. ": X: " .. vCircX[i] .. "; Y: " .. vCircY[i])
+ --nw WriteLnToConsole("CIRC " .. i .. ": dX: " .. vCircDX[i] .. "; dY: " .. vCircDY[i])
+ --nw WriteLnToConsole("CIRC " .. i .. ": RAD:" .. vCircRadius[i])
+ end
+ --nw WriteLnToConsole("Old values given, new values to follow...")
+ end
+
+ for i = 0,(vCCount-1) do
+
+ if s == false then
+ --vCircCol[i] = 0xffffffff
+ vCircActive[i] = false
+ elseif s == true then
+ SetUpCircle(i)
+ end
+
+ end
+
+end
+
+function WellHeAintGonnaJumpNoMore(x,y)
+
+ AddVisualGear(x, y, vgtBigExplosion, 0, false)
+ playerIsFine = false
+ AddCaption(loc("GOTCHA!"))
+ PlaySound(sndExplosion)
+ PlaySound(sndHellish)
+
+ targetHit = true
+
+end
+
+--- collision detection for weapons fire
+function CheckVarious(gear)
+
+ --if (GetGearType(gear) == gtExplosives) then
+ --nw WriteLnToConsole("Start of CheckVarious(): Exp ID: " .. getGearValue(gear,"ID"))
+ --elseif (GetGearType(gear) == gtShell) then
+ --nw WriteLnToConsole("Start of CheckVarious(): Shell ID: " .. getGearValue(gear,"ID"))
+ --end
+
+ targetHit = false
+
+ -- if circle is hit by player fire
+ if (GetGearType(gear) == gtExplosives) then
+ circsHit = 0
+
+ for i = 0,(vCCount-1) do
+
+ --nw WriteLnToConsole("Is it neccessary to check for collision with circ " .. i)
+
+ --if (vCircActive[i] == true) and ( (vType[i] == "drone") ) then
+
+ --nw WriteLnToConsole("YES. about to calc distance between gtExplosives and circ " .. i)
+
+ dist = GetDistFromGearToXY(gear, vCircX[i], vCircY[i])
+
+ -- calculate my real radius if I am an aura
+ if vCircType[i] == 0 then
+ NR = vCircRadius[i]
+ else
+ NR = (48/100*vCircRadius[i])/2
+ end
+
+ if dist <= NR*NR then
+
+
+ --nw WriteLnToConsole("Collision confirmed. The gtExplosives is within the circ radius!")
+
+ dist = (GetDistFromXYtoXY(vCircX[i], vCircY[i], getGearValue(gear,"XP"), getGearValue(gear,"YP")) - (NR*NR))
+ --AddCaption(loc("Dist: ") .. dist .. "!",0xffba00ff,capgrpGameState)
+ if dist >= 1000000 then
+ sniperHits = sniperHits +1
+ AddCaption(loc("Sniper!") .. " +8 " .. loc("points") .. "!",0xffba00ff,capgrpGameState)
+ AwardPoints(8)
+ if sniperHits == 3 then
+ sniperHits = 0
+ AddCaption(loc("They Call Me Bullseye!") .. " +16 " .. loc("points") .. "!",0xffba00ff,capgrpGameState)
+ AwardPoints(15)
+ end
+ elseif dist <= 6000 then
+ pointBlankHits = pointBlankHits +1
+ if pointBlankHits == 3 then
+ pointBlankHits = 0
+ AddCaption(loc("Point Blank Combo!") .. " +5 " .. loc("points") .. "!",0xffba00ff,capgrpGameState)
+ AwardPoints(5)
+ end
+ end
+
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+
+ targetHit = true
+ --DeleteGear(gear)
+ --SetHealth(gear,0)
+ --WriteLnToConsole("set " .. "Exp ID: " .. getGearValue(gear,"ID") .. " health to 0")
+ --WriteLnToConsole("targetHit set to true, explosive is at distance " .. dist .. "(within range " .. NR*NR.. ") of circ" )
+
+ CircleDamaged(i)
+
+ circsHit = circsHit + 1
+ if circsHit > 1 then
+ AddCaption(loc("Multi-shot!") .. " +15 " .. loc("points") .. "!",0xffba00ff,capgrpAmmostate)
+ AwardPoints(15)
+ circsHit = 0
+ end
+
+ shotsHit = shotsHit + 1
+
+
+
+ end
+
+ --end
+
+ end
+
+ -- if player is hit by circle bazooka
+ elseif (GetGearType(gear) == gtShell) and (CurrentHedgehog ~= nil) then --or (GetGearType(gear) == gtBall) then
+
+ dist = GetDistFromGearToGear(gear, CurrentHedgehog)
+
+ if beam == true then
+
+ if dist < 3000 then
+ tempE = AddVisualGear(GetX(gear), GetY(gear), vgtSmoke, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+ SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, 0xff00ffff )
+ PlaySound(sndVaporize)
+ DeleteGear(gear)
+
+ SK = SK + 1
+ if SK == 5 then
+ SK = 0
+ AddCaption(loc("Shield Master!") .. " +10 " .. loc("points") .. "!",0xffba00ff,capgrpAmmoinfo)
+ AwardPoints(10)
+ end
+ end
+
+ elseif dist < 1600 then
+ WellHeAintGonnaJumpNoMore(GetX(gear), GetY(gear))
+ end
+
+ --[[if targetHit == true then
+ WriteLnToConsole("about to delete shell due to targetHit being set to true earlier")
+ DeleteGear(gear)
+ WriteLnToConsole("there, I deleted it")
+ end]]
+
+
+ end
+
+ if targetHit == true then
+ --nw WriteLnToConsole("about to delete something due to targetHit being set to true earlier")
+ DeleteGear(gear)
+ --nw WriteLnToConsole("there, I deleted it")
+ end
+
+ --nw WriteLnToConsole("End of CheckVarious()")
+
+end
+
+-- collision detection for player entering a circle
+function CheckDistances()
+
+ --nw WriteLnToConsole("Start of CheckDistances()")
+
+ for i = 0,(vCCount-1) do
+
+
+ --nw WriteLnToConsole("Attempting to calculate dist of circ " .. i)
+
+ g1X, g1Y = GetGearPosition(CurrentHedgehog)
+ g2X, g2Y = vCircX[i], vCircY[i]
+
+ g1X = g1X - g2X
+ g1Y = g1Y - g2Y
+ dist = (g1X*g1X) + (g1Y*g1Y)
+
+ --DoHorribleThings(i, g1X, g1Y, g2X, g2Y, dist)
+
+ --nw WriteLnToConsole("Calcs done. Dist to CurrentHedgehog is " .. dist)
+
+ -- calculate my real radius if I am an aura
+ if vCircType[i] == 0 then
+ NR = vCircRadius[i]
+ else
+ NR = (48/100*vCircRadius[i])/2
+ end
+
+ if dist <= NR*NR then
+
+ if (vCircActive[i] == true) and
+ ((vType[i] == "ammo") or (vType[i] == "bonus") )
+ then
+
+ CircleDamaged(i)
+
+ elseif (vCircActive[i] == true) and
+ ( (vType[i] == "drone") or (vType[i] == "blueboss") )
+ then
+
+ ss = CircleDamaged(i)
+ WellHeAintGonnaJumpNoMore(GetX(CurrentHedgehog),GetY(CurrentHedgehog))
+
+ if ss == "fatal" then
+
+ if (wepAmmo[0] == 0) and (TimeLeft <= 9) then
+ --if (primShotsLeft == 0) and (TimeLeft <= 9) then
+ AddCaption(loc("Kamikaze Expert!") .. " +15 " .. loc("points") .. "!",0xffba00ff,capgrpMessage)
+ AwardPoints(15)
+ elseif (wepAmmo[0] == 0) then
+ AddCaption(loc("Depleted Kamikaze!") .. " +5 " .. loc("points") .. "!",0xffba00ff,capgrpMessage)
+ AwardPoints(5)
+ elseif TimeLeft <= 9 then
+ AddCaption(loc("Timed Kamikaze!") .. " +10 " .. loc("points") .. "!",0xffba00ff,capgrpMessage)
+ AwardPoints(10)
+ end
+ end
+
+ end
+
+
+ end
+
+ end
+
+ --nw WriteLnToConsole("End of CheckDistances()")
+
+end
+
+function HandleCircles()
+
+ --[[if CirclesAreGo == true then
+
+ --CheckDistances()
+ --runOnGears(CheckVarious) -- used to be in handletracking for some bizarre reason
+
+ --pTimer = pTimer + 1
+ --if pTimer == 100 then
+ -- pTimer = 0
+ -- runOnGears(ProjectileTrack)
+ --end
+
+ end]]
+
+
+ if rAlpha ~= 255 then
+
+ if GameTime%100 == 0 then
+
+ rAlpha = rAlpha + 5
+ if rAlpha >= 255 then
+ rAlpha = 255
+ end
+ end
+
+ end
+
+ for i = 0,(vCCount-1) do
+
+ --if (vCircActive[i] == true) then
+ SetVisualGearValues(rCirc[i], rCircX[i], rCircY[i], 100, 255, 1, 10, 0, 40, 3, vCircCol[i]-rAlpha)
+ --end
+
+
+
+ vCounter[i] = vCounter[i] + 1
+ if vCounter[i] >= vCounterLim[i] then
+
+ vCounter[i] = 0
+
+ if ((vType[i] == "drone") or (vType[i] == "blueboss") ) and
+ (vCircActive[i] == true) then
+ AddGear(vCircX[i], vCircY[i], gtShell, 0, 0, 0, 1)
+
+ --WriteLnToConsole("Circle " .. i .. " just fired/added a gtShell")
+ --WriteLnToConsole("The above event occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+
+ --elseif (vType[i] == "bluebottle") and (vCircActive[i] == true) then
+ -- AddGear(vCircX[i], vCircY[i]-vCircRadius[i], gtBall, 0, 0, 0, 1)
+ -- AddGear(vCircX[i], vCircY[i]+vCircRadius[i], gtBall, 0, 0, 0, 1)
+ -- AddGear(vCircX[i]-vCircRadius[i], vCircY[i], gtBall, 0, 0, 0, 1)
+ -- AddGear(vCircX[i]+vCircRadius[i], vCircY[i], gtBall, 0, 0, 0, 1)
+ end
+
+ end
+
+ if (vCircActive[i] == true) then
+
+ vCircRadCounter[i] = vCircRadCounter[i] + 1
+ if vCircRadCounter[i] == 100 then
+
+ vCircRadCounter[i] = 0
+
+ -- make my radius increase/decrease faster if I am an aura
+ if vCircType[i] == 0 then
+ M = 1
+ else
+ M = 10
+ end
+
+ vCircRadius[i] = vCircRadius[i] + vCircRadDir[i]
+ if vCircRadius[i] > vCircRadMax[i] then
+ vCircRadDir[i] = -M
+ elseif vCircRadius[i] < vCircRadMin[i] then
+ vCircRadDir[i] = M
+ end
+
+
+ -- random effect test
+ -- maybe use this to tell the difference between circs
+ -- you can kill by shooting or not
+ --vgtSmoke vgtSmokeWhite
+ --vgtSteam -- nice long trail
+ --vgtDust -- short trail on earthrise
+ --vgtSmokeTrace
+ if vType[i] == "ammo" then
+
+ tempE = AddVisualGear(vCircX[i], vCircY[i], vgtSmoke, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff
+ SetVisualGearValues(tempE, vCircX[i], vCircY[i], g3, g4, g5, g6, g7, g8, g9, vCircCol[i] )
+
+ --AddVisualGear(vCircX[i], vCircY[i], vgtDust, 0, true)
+
+ elseif vType[i] == "bonus" then
+
+ tempE = AddVisualGear(vCircX[i], vCircY[i], vgtDust, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff --vCircCol[i]
+ SetVisualGearValues(tempE, vCircX[i], vCircY[i], g3, g4, g5, g6, g7, 1, g9, 0xff00ffff )
+
+
+ elseif vType[i] == "blueboss" then
+
+ k = 25
+ g = vgtSteam
+ trailColour = 0xae00ffff
+
+ -- 0xffae00ff -- orange
+ -- 0xae00ffff -- purp
+
+ tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff
+ SetVisualGearValues(tempE, vCircX[i], vCircY[i]+k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 )
+
+ tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff
+ SetVisualGearValues(tempE, vCircX[i]+k, vCircY[i]-k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 )
+
+ tempE = AddVisualGear(vCircX[i], vCircY[i], g, 0, true)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE) --0xff00ffff --0x00ff00ff
+ SetVisualGearValues(tempE, vCircX[i]-k, vCircY[i]-k, g3, g4, g5, g6, g7, g8, g9, trailColour-75 )
+
+
+ end
+
+
+ end
+
+ end
+
+
+ end
+
+ -- alter the circles velocities
+ if GameTime%2000 == 0 then
+
+ for i = 0,(vCCount-1) do
+
+ -- bounce the circles off the edges if they go too far
+ -- or make them move in random directions
+
+ if vCircX[i] > 5500 then
+ vCircDX[i] = -4 --5 circmovchange
+ elseif vCircX[i] < -1500 then
+ vCircDX[i] = 4 --5 circmovchange
+ else
+
+ z = GetRandom(2)
+ if z == 1 then
+ z = 1
+ else
+ z = -1
+ end
+ vCircDX[i] = vCircDX[i] + GetRandom(3)*z --3 circmovchange
+ end
+
+ if vCircY[i] > 1500 then
+ vCircDY[i] = -4 --5 circmovchange
+ elseif vCircY[i] < -2900 then
+ vCircDY[i] = 4 --5 circmovchange
+ else
+ z = GetRandom(2)
+ if z == 1 then
+ z = 1
+ else
+ z = -1
+ end
+ vCircDY[i] = vCircDY[i] + GetRandom(3)*z --3 circmovchange
+ end
+
+ end
+
+ end
+
+ -- move the circles according to their current velocities
+ --m2Count = m2Count + 1
+ --if m2Count == 25 then --25 circmovchange
+
+ -- m2Count = 0
+ for i = 0,(vCCount-1) do
+ vCircX[i] = vCircX[i] + vCircDX[i]
+ vCircY[i] = vCircY[i] + vCircDY[i]
+
+ if (CurrentHedgehog ~= nil) and (rAlpha ~= 255) then
+ DoHorribleThings(i)--(i, g1X, g1Y, g2X, g2Y, dist)
+ end
+
+ end
+
+ if (TimeLeft == 0) and (tumbleStarted == true) then
+
+ FadeAlpha = FadeAlpha + 1
+ if FadeAlpha >= 255 then
+ FadeAlpha = 255
+ end
+
+ --new
+ --if FadeAlpha == 1 then
+ -- AddCaption("GOT IT")
+ -- for i = 0,(vCCount-1) do
+ -- g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i])
+ -- vCircCol[i] = g10
+ -- end
+ --end
+
+ end
+
+
+ -- derp
+ if shockwaveHealth > 0 then
+ shockwaveHealth = shockwaveHealth - 1
+ shockwaveRad = shockwaveRad + 80
+
+ --mrm = ((48/100*shockwaveRad)/2)
+ --AddVisualGear(GetX(CurrentHedgehog)-mrm+GetRandom(mrm*2),GetY(CurrentHedgehog)-mrm+GetRandom(mrm*2), vgtSmoke, 0, false)
+ end
+
+
+
+ --end
+
+ for i = 0,(vCCount-1) do
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) -- vCircCol[i] g10
+ SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], g9, g10)
+ end
+
+ if (TimeLeft == 0) or
+ ((tumbleStarted == false)) then
+ for i = 0,(vCCount-1) do
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(vCirc[i]) -- vCircCol[i] g10
+ SetVisualGearValues(vCirc[i], vCircX[i], vCircY[i], g3, g4, g5, g6, g7, vCircRadius[i], g9, (vCircCol[i]-FadeAlpha))
+ end
+ end
+
+
+ if (CurrentHedgehog ~= nil) then
+ if beam == true then
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(pShield)
+ --SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 200, g9, g10 )
+ SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 200, g9, 0xa800ffff-0x000000ff - -shieldHealth )
+ DrawTag(2)
+ else
+ SetVisualGearValues(pShield, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 0, g9, g10 )
+ end
+
+ if shockwaveHealth > 0 then
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(shockwave)
+ SetVisualGearValues(shockwave, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, shockwaveRad, g9, 0xff3300ff-0x000000ff - -shockwaveHealth )
+ else
+ SetVisualGearValues(shockwave, GetX(CurrentHedgehog), GetY(CurrentHedgehog), g3, g4, g5, g6, g7, 0, g9, g10 )
+ end
+
+ end
+
+
+end
+
+function ProjectileTrack(gear)
+
+ if (GetGearType(gear) == gtShell) then
+
+ --nw WriteLnToConsole("ProjectileTrack() for Shell ID: " .. getGearValue(gear,"ID"))
+
+ -- newnew
+ if (GetGearType(gear) == gtShell) then
+ turningSpeed = 0.1*fMod
+ --elseif (GetGearType(gear) == gtBall) then
+ -- turningSpeed = 0.2*fMod
+ end
+
+ dx, dy = GetGearVelocity(gear)
+
+ --WriteLnToConsole("I'm trying to track currenthedge with shell ID: " .. getGearValue(gear,"ID"))
+ --WriteLnToConsole("I just got the velocity of the shell. It is dx: " .. dx .. "; dy: " .. dy)
+ --WriteLnToConsole("CurrentHedgehog is at X: " .. GetX(CurrentHedgehog) .. "; Y: " .. GetY(CurrentHedgehog) )
+
+ if CurrentHedgehog ~= nil then
+ if GetX(gear) > GetX(CurrentHedgehog) then
+ dx = dx - turningSpeed--0.1
+ else
+ dx = dx + turningSpeed--0.1
+ end
+
+ if GetY(gear) > GetY(CurrentHedgehog) then
+ dy = dy - turningSpeed--0.1
+ else
+ dy = dy + turningSpeed--0.1
+ end
+ end
+
+
+ if (GetGearType(gear) == gtShell) then
+ dxlimit = 0.4*fMod
+ dylimit = 0.4*fMod
+ --elseif (GetGearType(gear) == gtBall) then
+ -- dxlimit = 0.5 -- 0.5 is about the same
+ -- dylimit = 0.5 -- 0.6 is faster than player
+ end
+
+ if dx > dxlimit then
+ dx = dxlimit
+ end
+ if dy > dylimit then
+ dy = dylimit
+ end
+ if dx < -dxlimit then
+ dx = -dxlimit
+ end
+ if dy < -dylimit then
+ dy = -dylimit
+ end
+
+ SetGearVelocity(gear, dx, dy)
+
+ --WriteLnToConsole("I just SET the velocity of shell towards currenthegdge. It is now dx: " .. dx .. "; dy: " .. dy)
+ --WriteLnToConsole("The above events occured game Time: " .. GameTime .. "; luaTicks: " .. luaGameTicks)
+ --nw WriteLnToConsole("ProjectileTrack() finished successfully")
+
+ end
+
+end
+
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/The_Specialists.cfg
old mode 100755
new mode 100644
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/The_Specialists.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/The_Specialists.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/The_Specialists.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Tumbler.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Tumbler.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Tumbler.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Tumbler.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/Tumbler.lua
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/WxW.cfg b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/WxW.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/WxW.cfg
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/WxW.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/WxW.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/WxW.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Multiplayer/WxW.lua
diff --git a/share/hedgewars/Data/Scripts/Tracker.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Tracker.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Tracker.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Tracker.lua
diff --git a/share/hedgewars/Data/Scripts/Utils.lua b/project_files/Android-build/SDL-android-project/assets/Data/Scripts/Utils.lua
similarity index 100%
copy from share/hedgewars/Data/Scripts/Utils.lua
copy to project_files/Android-build/SDL-android-project/assets/Data/Scripts/Utils.lua
diff --git a/share/hedgewars/Data/Sounds/TARDIS.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/TARDIS.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/TARDIS.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/TARDIS.ogg
diff --git a/share/hedgewars/Data/Sounds/beep.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/beep.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/beep.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/beep.ogg
diff --git a/project_files/Android-build/SDL-android-project/assets/Data/Sounds/beewater.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/beewater.ogg
index 0661862..ac6863b 100644
Binary files a/project_files/Android-build/SDL-android-project/assets/Data/Sounds/beewater.ogg and b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/beewater.ogg differ
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Amazing.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Amazing.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Amazing.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Amazing.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Brilliant.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Brilliant.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Brilliant.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Brilliant.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Bugger.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Bugger.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Bugger.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Bugger.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Bungee.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Bungee.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Bungee.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Bungee.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Cutitout.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Cutitout.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Cutitout.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Cutitout.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Drat.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Drat.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Drat.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Drat.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Excellent.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Excellent.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Excellent.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Excellent.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Fire.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Fire.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Fire.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Fire.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Gonnagetyou.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Gonnagetyou.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Gonnagetyou.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Gonnagetyou.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Grenade.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Grenade.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Grenade.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Grenade.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Hmm.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Hmm.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Hmm.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Hmm.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Justyouwait.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Justyouwait.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Justyouwait.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Justyouwait.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Leavemealone.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Leavemealone.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Leavemealone.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Leavemealone.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Ohdear.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Ohdear.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Ohdear.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Ohdear.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Ouch.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Ouch.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Ouch.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Ouch.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Perfect.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Perfect.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Perfect.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Perfect.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Revenge.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Revenge.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Revenge.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Revenge.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Runaway.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Runaway.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Runaway.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Runaway.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Solong.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Solong.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Solong.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Solong.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Thisoneismine.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Thisoneismine.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Thisoneismine.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Thisoneismine.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Watchthis.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Watchthis.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Watchthis.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Watchthis.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Whatthe.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Whatthe.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Whatthe.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Whatthe.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/Whoopsee.ogg b/project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Whoopsee.ogg
similarity index 100%
copy from share/hedgewars/Data/Sounds/voices/Classic/Whoopsee.ogg
copy to project_files/Android-build/SDL-android-project/assets/Data/Sounds/voices/Classic/Whoopsee.ogg
diff --git a/project_files/Android-build/SDL-android-project/assets/assetsversion.txt b/project_files/Android-build/SDL-android-project/assets/assetsversion.txt
new file mode 100644
index 0000000..f11c82a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/assets/assetsversion.txt
@@ -0,0 +1 @@
+9
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/jni/Android.mk b/project_files/Android-build/SDL-android-project/jni/Android.mk
index ff2c49c..a58e7ab 100644
--- a/project_files/Android-build/SDL-android-project/jni/Android.mk
+++ b/project_files/Android-build/SDL-android-project/jni/Android.mk
@@ -6,5 +6,6 @@ include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
include $(JNI_DIR)/../../../../misc/Android.mk
+include $(JNI_DIR)/../../../frontlib/Android.mk
diff --git a/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp b/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp
index abc5662..4e1b918 100644
--- a/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp
+++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/main/android/SDL_android_main.cpp
@@ -27,23 +27,20 @@ extern "C" void Java_org_hedgewars_hedgeroid_SDLActivity_nativeInit(JNIEnv* env,
char *argv[argc];
jstring jstringArgv[argc];
for(int i = 0; i < argc; i++){
- jstringArgv[i] = (jstring)env->GetObjectArrayElement(strArray, i); //get the element
- argv[i] = (char*)malloc(sizeof(char) * env->GetStringLength(jstringArgv[i]));
- strcpy(argv[i], env->GetStringUTFChars(jstringArgv[i], JNI_FALSE)); //copy it to a mutable location
- //Don't release memory the JAVA GC will take care of it
- //env->ReleaseStringChars(jstringArgv[i], (jchar*)argv[i]);
+ jstringArgv[i] = (jstring)env->GetObjectArrayElement(strArray, i); //get the element
+ argv[i] = (char*)malloc(env->GetStringUTFLength(jstringArgv[i]) + 1);
+ const char *str = env->GetStringUTFChars(jstringArgv[i], NULL);
+ strcpy(argv[i], str); //copy it to a mutable location
+ env->ReleaseStringUTFChars(jstringArgv[i], str);
}
/* Run the application code! */
- int status;
- status = SDL_main(argc, argv);
+ int status = SDL_main(argc, argv);
//Clean up argv
for(int i = 0; i < argc; i++){
+ free(argv[i]);
}
-
- /* We exit here for consistency with other platforms. */
- //exit(status); Xeli: Or lets not crash the entire app.....
}
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk b/project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk
new file mode 100644
index 0000000..ecf61e5
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/jni/jnidispatch/Android.mk
@@ -0,0 +1,6 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libjnidispatch
+LOCAL_SRC_FILES := libjnidispatch.so
+include $(PREBUILT_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/jni/jnidispatch/README b/project_files/Android-build/SDL-android-project/jni/jnidispatch/README
new file mode 100644
index 0000000..c314777
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/jni/jnidispatch/README
@@ -0,0 +1 @@
+This library is part of JNA and just needs to be copied into the libs/armeabi folder. However, putting it there directly will get it cleaned away on build.
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c b/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c
index 976184b..2660cd0 100644
--- a/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c
+++ b/project_files/Android-build/SDL-android-project/jni/src/hedgewars_main.c
@@ -1,3 +1,4 @@
+#include<stdint.h>
#include "android/log.h"
#include "SDL.h"
@@ -6,7 +7,7 @@
#define TAG "HWEngine Loader"
-typedef (*HWEngine_Game)(char**);
+typedef (*HWEngine_Game)(int32_t argc, char** argv);
main(int argc, char *argv[]){
void *handle;
@@ -33,7 +34,7 @@ main(int argc, char *argv[]){
exit(EXIT_FAILURE);
}
__android_log_print(ANDROID_LOG_INFO, TAG, "dlsym succeeded");
- Game(argv);
+ Game(argc, argv);
__android_log_print(ANDROID_LOG_INFO, TAG, "Game() ended");
dlclose(handle);
diff --git a/project_files/Android-build/SDL-android-project/libs/android-support-v13.jar b/project_files/Android-build/SDL-android-project/libs/android-support-v13.jar
index 3d7f841..008f3ce 100644
Binary files a/project_files/Android-build/SDL-android-project/libs/android-support-v13.jar and b/project_files/Android-build/SDL-android-project/libs/android-support-v13.jar differ
diff --git a/project_files/Android-build/SDL-android-project/libs/jna-3.5.1.jar b/project_files/Android-build/SDL-android-project/libs/jna-3.5.1.jar
new file mode 100644
index 0000000..1ebbba9
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/libs/jna-3.5.1.jar differ
diff --git a/QTfrontend/res/LocalPlay.png b/project_files/Android-build/SDL-android-project/res/drawable-hdpi/button_local_play.png
similarity index 100%
copy from QTfrontend/res/LocalPlay.png
copy to project_files/Android-build/SDL-android-project/res/drawable-hdpi/button_local_play.png
diff --git a/QTfrontend/res/NetworkPlay.png b/project_files/Android-build/SDL-android-project/res/drawable-hdpi/button_network_play.png
similarity index 100%
copy from QTfrontend/res/NetworkPlay.png
copy to project_files/Android-build/SDL-android-project/res/drawable-hdpi/button_network_play.png
diff --git a/QTfrontend/res/LocalPlay.png b/project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/button_local_play.png
similarity index 100%
copy from QTfrontend/res/LocalPlay.png
copy to project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/button_local_play.png
diff --git a/QTfrontend/res/NetworkPlay.png b/project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/button_network_play.png
similarity index 100%
copy from QTfrontend/res/NetworkPlay.png
copy to project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/button_network_play.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/backbutton.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/backbutton.png
deleted file mode 100644
index 1aa3a3d..0000000
Binary files a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/backbutton.png and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button.xml
new file mode 100644
index 0000000..e36b0d9
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/button_focused" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/button_focused_disabled" />
+ <item android:state_focused="false" android:state_enabled="true" android:drawable="@drawable/button_normal" />
+ <item android:state_focused="false" android:state_enabled="false" android:drawable="@drawable/button_disabled" />
+</selector>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_disabled.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_disabled.9.png
new file mode 100644
index 0000000..90b8d88
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_disabled.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused.9.png
new file mode 100644
index 0000000..9c0ae98
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused_disabled.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused_disabled.9.png
new file mode 100644
index 0000000..4f4f490
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_focused_disabled.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_normal.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_normal.9.png
new file mode 100644
index 0000000..bc53591
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/button_normal.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.9.png
deleted file mode 100644
index 18bcc29..0000000
Binary files a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.9.png and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.xml
new file mode 100644
index 0000000..058960a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/dropdown_focused" />
+ <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/dropdown_focused_disabled" />
+ <item android:state_focused="false" android:state_enabled="true" android:drawable="@drawable/dropdown_normal" />
+ <item android:state_focused="false" android:state_enabled="false" android:drawable="@drawable/dropdown_disabled" />
+</selector>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_disabled.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_disabled.9.png
new file mode 100644
index 0000000..4775683
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_disabled.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused.9.png
new file mode 100644
index 0000000..ca59d4e
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused_disabled.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused_disabled.9.png
new file mode 100644
index 0000000..519d17a
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_focused_disabled.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_normal.9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_normal.9.png
new file mode 100644
index 0000000..bfb2e08
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/dropdown_normal.9.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount.xml
new file mode 100644
index 0000000..2b86953
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount.xml
@@ -0,0 +1,10 @@
+ <level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="1" android:drawable="@drawable/hogcount1" />
+ <item android:maxLevel="2" android:drawable="@drawable/hogcount2" />
+ <item android:maxLevel="3" android:drawable="@drawable/hogcount3" />
+ <item android:maxLevel="4" android:drawable="@drawable/hogcount4" />
+ <item android:maxLevel="5" android:drawable="@drawable/hogcount5" />
+ <item android:maxLevel="6" android:drawable="@drawable/hogcount6" />
+ <item android:maxLevel="7" android:drawable="@drawable/hogcount7" />
+ <item android:maxLevel="8" android:drawable="@drawable/hogcount8" />
+ </level-list>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount1.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount1.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount1.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount1.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount2.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount2.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount2.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount2.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount3.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount3.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount3.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount3.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount4.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount4.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount4.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount4.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount5.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount5.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount5.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount5.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount6.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount6.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount6.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount6.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount7.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount7.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount7.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount7.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount8.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount8.png
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount8.png
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/hogcount8.png
diff --git a/QTfrontend/res/lightbulb_off.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_off.png
similarity index 100%
copy from QTfrontend/res/lightbulb_off.png
copy to project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_off.png
diff --git a/QTfrontend/res/lightbulb_on.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_on.png
similarity index 100%
copy from QTfrontend/res/lightbulb_on.png
copy to project_files/Android-build/SDL-android-project/res/drawable-mdpi/lightbulb_on.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/playerlist_player.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/playerlist_player.png
new file mode 100644
index 0000000..c743412
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/playerlist_player.png differ
diff --git a/QTfrontend/res/iconDamage.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/roomlist_ingame.png
similarity index 100%
copy from QTfrontend/res/iconDamage.png
copy to project_files/Android-build/SDL-android-project/res/drawable-mdpi/roomlist_ingame.png
diff --git a/QTfrontend/res/iconTime.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/roomlist_preparing.png
similarity index 100%
copy from QTfrontend/res/iconTime.png
copy to project_files/Android-build/SDL-android-project/res/drawable-mdpi/roomlist_preparing.png
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/savebutton.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/savebutton.png
deleted file mode 100644
index 8d5f871..0000000
Binary files a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/savebutton.png and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_local_by_level.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_local_by_level.xml
new file mode 100644
index 0000000..44e10d0
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_local_by_level.xml
@@ -0,0 +1,8 @@
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="0" android:drawable="@drawable/human" />
+ <item android:maxLevel="1" android:drawable="@drawable/bot5" />
+ <item android:maxLevel="2" android:drawable="@drawable/bot4" />
+ <item android:maxLevel="3" android:drawable="@drawable/bot3" />
+ <item android:maxLevel="4" android:drawable="@drawable/bot2" />
+ <item android:maxLevel="5" android:drawable="@drawable/bot1" />
+</level-list>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot1.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot1.png
new file mode 100644
index 0000000..2b3c8d7
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot1.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot2.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot2.png
new file mode 100644
index 0000000..f365c01
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot2.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot3.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot3.png
new file mode 100644
index 0000000..2a30a61
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot3.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot4.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot4.png
new file mode 100644
index 0000000..8a6c2c3
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot4.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot5.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot5.png
new file mode 100644
index 0000000..3de07ae
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_bot5.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_by_level.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_by_level.xml
new file mode 100644
index 0000000..02f198a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_by_level.xml
@@ -0,0 +1,8 @@
+<level-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:maxLevel="0" android:drawable="@drawable/team_net_human" />
+ <item android:maxLevel="1" android:drawable="@drawable/team_net_bot5" />
+ <item android:maxLevel="2" android:drawable="@drawable/team_net_bot4" />
+ <item android:maxLevel="3" android:drawable="@drawable/team_net_bot3" />
+ <item android:maxLevel="4" android:drawable="@drawable/team_net_bot2" />
+ <item android:maxLevel="5" android:drawable="@drawable/team_net_bot1" />
+</level-list>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_human.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_human.png
new file mode 100644
index 0000000..abb69cd
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/team_net_human.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount0.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount0.png
deleted file mode 100644
index f71d34a..0000000
Binary files a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount0.png and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount9.png b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount9.png
deleted file mode 100644
index 49ef836..0000000
Binary files a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount9.png and /dev/null differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount.xml b/project_files/Android-build/SDL-android-project/res/drawable-mdpi/teams_number.xml
similarity index 100%
rename from project_files/Android-build/SDL-android-project/res/drawable-mdpi/teamcount.xml
rename to project_files/Android-build/SDL-android-project/res/drawable-mdpi/teams_number.xml
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_local_play.png b/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_local_play.png
new file mode 100644
index 0000000..382732b
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_local_play.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_network_play.png b/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_network_play.png
new file mode 100644
index 0000000..12199da
Binary files /dev/null and b/project_files/Android-build/SDL-android-project/res/drawable-small-hdpi/button_network_play.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml b/project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml
new file mode 100644
index 0000000..5cc0efb
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-large/activity_lobby.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <include layout="@layout/background"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="5dp" >
+
+ <FrameLayout
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_marginBottom="10dp"
+ android:layout_weight="0.4"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/roomListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.RoomlistFragment"
+ tools:layout="@layout/fragment_roomlist" />
+ </FrameLayout>
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.6"
+ android:baselineAligned="false"
+ android:orientation="horizontal" >
+
+ <FrameLayout
+ android:id="@+id/playerFrame"
+ android:layout_width="250dp"
+ android:layout_height="fill_parent"
+ android:layout_alignParentRight="true"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/playerListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.LobbyPlayerlistFragment"
+ tools:layout="@layout/fragment_playerlist" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@id/playerFrame"
+ android:layout_marginRight="10dp"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/chatFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.ChatFragment"
+ tools:layout="@layout/fragment_chat" />
+ </FrameLayout>
+ </RelativeLayout>
+
+ </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout-large/activity_localroom.xml b/project_files/Android-build/SDL-android-project/res/layout-large/activity_localroom.xml
new file mode 100644
index 0000000..85460f7
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-large/activity_localroom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="2dp" >
+
+ <LinearLayout
+ android:id="@+id/upperFrame"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginBottom="4dp"
+ android:layout_above="@+id/startGame"
+ android:baselineAligned="false"
+ android:minHeight="200dp" >
+
+ <FrameLayout
+ android:id="@+id/mapFrame"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_marginRight="4dp"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/mapFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.MapFragment"
+ tools:layout="@layout/fragment_map" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/settingsFrame"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_marginRight="4dp"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.SettingsFragment"
+ tools:layout="@layout/fragment_settings" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/teamsFrame"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/teamsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.TeamlistFragment"
+ tools:layout="@layout/fragment_teamlist" />
+ </FrameLayout>
+ </LinearLayout>
+
+ <Button
+ android:id="@id/startGame"
+ android:layout_width="200dp"
+ android:layout_height="67dp"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:background="@drawable/startgamebutton" />
+ </RelativeLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout-large/activity_netroom.xml b/project_files/Android-build/SDL-android-project/res/layout-large/activity_netroom.xml
new file mode 100644
index 0000000..c8182fc
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-large/activity_netroom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="2dp" >
+
+ <LinearLayout
+ android:id="@+id/upperFrame"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginBottom="4dp"
+ android:baselineAligned="false"
+ android:minHeight="200dp" >
+
+ <FrameLayout
+ android:id="@+id/mapFrame"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="4dp"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/mapFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.MapFragment"
+ tools:layout="@layout/fragment_map" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/settingsFrame"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="4dp"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.SettingsFragment"
+ tools:layout="@layout/fragment_settings" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/teamsFrame"
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/teamsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.TeamlistFragment"
+ tools:layout="@layout/fragment_teamlist" />
+ </FrameLayout>
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/playerFrame"
+ android:layout_width="200dp"
+ android:layout_height="fill_parent"
+ android:layout_above="@+id/startGame"
+ android:layout_alignParentRight="true"
+ android:layout_below="@id/upperFrame"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/playerListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.RoomPlayerlistFragment"
+ tools:layout="@layout/fragment_playerlist" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="0dp"
+ android:layout_height="fill_parent"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@id/upperFrame"
+ android:layout_marginRight="4dp"
+ android:layout_toLeftOf="@id/playerFrame"
+ android:background="@drawable/box" >
+
+ <fragment
+ android:id="@+id/chatFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.ChatFragment"
+ tools:layout="@layout/fragment_chat" />
+ </FrameLayout>
+
+ <Button
+ android:id="@id/startGame"
+ android:layout_width="200dp"
+ android:layout_height="67dp"
+ android:layout_marginTop="4dp"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:background="@drawable/startgamebutton" />
+
+ </RelativeLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout-large/fragment_roomlist.xml b/project_files/Android-build/SDL-android-project/res/layout-large/fragment_roomlist.xml
new file mode 100644
index 0000000..69bdd0e
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-large/fragment_roomlist.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <FrameLayout
+ android:id="@+id/listHeader"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+ <include layout="@layout/listview_room_header" />
+ </FrameLayout>
+
+ <ListView
+ android:id="@id/android:list"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_alignParentBottom="true"
+ android:layout_below="@+id/listHeader"
+ android:cacheColorHint="@android:color/transparent"
+ android:drawSelectorOnTop="false"
+ tools:listitem="@layout/listview_room" />
+
+ <TextView
+ android:id="@id/android:empty"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true"
+ android:text="@string/no_rooms_in_list" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout-large/listview_room.xml b/project_files/Android-build/SDL-android-project/res/layout-large/listview_room.xml
new file mode 100644
index 0000000..2e1dd2c
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-large/listview_room.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+
+<TextView
+ android:id="@+id/roomname"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1.5"
+ android:padding="3dp"
+ android:drawablePadding="5dp"
+ android:gravity="left|center_vertical"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+<include layout="@layout/roomlist_player_team_count" />
+
+<TextView
+ android:id="@+id/owner"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="left"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+
+<TextView
+ android:id="@+id/map"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="left"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+
+<TextView
+ android:id="@+id/scheme"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="left"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+
+<TextView
+ android:id="@+id/weapons"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="left"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+
+</LinearLayout>
+
+
diff --git a/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count.xml b/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count.xml
new file mode 100644
index 0000000..0027144
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <TextView
+ android:id="@+id/playercount"
+ android:layout_width="20dp"
+ android:layout_height="wrap_content"
+ android:padding="3dp"
+ android:gravity="center"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+
+ <TextView
+ android:id="@+id/teamcount"
+ android:layout_width="20dp"
+ android:layout_height="wrap_content"
+ android:padding="3dp"
+ android:gravity="center"
+ android:layout_gravity="center_vertical"
+ android:singleLine="true"/>
+</merge>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count_header.xml b/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count_header.xml
new file mode 100644
index 0000000..b243468
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout-xlarge/roomlist_player_team_count_header.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
+
+ <TextView
+ android:id="@+id/playercount"
+ android:layout_width="20dp"
+ android:layout_height="wrap_content"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_clients"/>
+
+ <TextView
+ android:id="@+id/teamcount"
+ android:layout_width="20dp"
+ android:layout_height="wrap_content"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_teams" />
+</merge>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_lobby.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_lobby.xml
new file mode 100644
index 0000000..2dcbad5
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_lobby.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <TabHost
+ android:id="@android:id/tabhost"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="0" />
+
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" >
+
+ <fragment
+ android:id="@+id/roomListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.RoomlistFragment"
+ tools:layout="@layout/fragment_roomlist" />
+
+ <fragment
+ android:id="@+id/chatFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.ChatFragment"
+ tools:layout="@layout/fragment_chat" />
+
+ <fragment
+ android:id="@+id/playerListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.LobbyPlayerlistFragment"
+ tools:layout="@layout/fragment_playerlist" />
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_localroom.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_localroom.xml
new file mode 100644
index 0000000..dabcb12
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_localroom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <TabHost
+ android:id="@android:id/tabhost"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="0" />
+
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" >
+
+ <fragment
+ android:id="@+id/mapFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.MapFragment"
+ tools:layout="@layout/fragment_map" />
+
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.SettingsFragment"
+ tools:layout="@layout/fragment_settings" />
+
+
+ <LinearLayout
+ android:id="@+id/teamlistContainer"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+ <fragment
+ android:id="@+id/teamlistFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ class="org.hedgewars.hedgeroid.TeamlistFragment"
+ tools:layout="@layout/fragment_teamlist" />
+
+ <Button
+ android:id="@+id/startGame"
+ android:layout_width="120dp"
+ android:layout_height="40dp"
+ android:layout_gravity="right"
+ android:layout_marginTop="4dp"
+ android:background="@drawable/startgamebutton" />
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_main.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_main.xml
new file mode 100644
index 0000000..5660c56
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_main.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <View
+ android:id="@+id/placeholder"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_centerInParent="true" />
+
+ <FrameLayout
+ android:id="@+id/frameLayout1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@id/placeholder" >
+
+ <Button
+ android:id="@+id/startGame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:drawableTop="@drawable/button_local_play"
+ android:text="@string/main_button_localplay" />
+ </FrameLayout>
+
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@id/placeholder" >
+
+ <Button
+ android:id="@+id/joinLobby"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:drawableTop="@drawable/button_network_play"
+ android:text="@string/main_button_netplay" />
+ </FrameLayout>
+ </RelativeLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml
new file mode 100644
index 0000000..89943d6
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_netroom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <include layout="@layout/background" />
+
+ <TabHost
+ android:id="@android:id/tabhost"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <TabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="0" />
+
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" >
+
+ <fragment
+ android:id="@+id/mapFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.MapFragment"
+ tools:layout="@layout/fragment_map" />
+
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.SettingsFragment"
+ tools:layout="@layout/fragment_settings" />
+
+ <fragment
+ android:id="@+id/teamlistFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.TeamlistFragment"
+ tools:layout="@layout/fragment_teamlist" />
+
+ <fragment
+ android:id="@+id/chatFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ class="org.hedgewars.hedgeroid.ChatFragment"
+ tools:layout="@layout/fragment_chat" />
+
+ <LinearLayout
+ android:id="@+id/playerListContainer"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <fragment
+ android:id="@+id/playerListFragment"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ class="org.hedgewars.hedgeroid.RoomPlayerlistFragment"
+ tools:layout="@layout/fragment_playerlist" />
+
+ <Button
+ android:id="@+id/startGame"
+ android:layout_width="120dp"
+ android:layout_height="40dp"
+ android:layout_gravity="right"
+ android:layout_marginTop="4dp"
+ android:background="@drawable/startgamebutton" />
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+ </TabHost>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_schemelist.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_schemelist.xml
new file mode 100644
index 0000000..9ab9175
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_schemelist.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:cacheColorHint="@android:color/transparent" />
+
+ <Button
+ android:id="@+id/addButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/schemelist_add_button_text"
+ android:background="@drawable/button" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_teamlist.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_teamlist.xml
new file mode 100644
index 0000000..04c4a6a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_teamlist.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <include layout="@layout/background"/>
+
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="@string/teamlist_empty" />
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_height="fill_parent"
+ android:layout_width="wrap_content"
+ android:layout_margin="3dp"
+ android:background="@drawable/box" />
+
+ <ImageButton
+ android:id="@+id/btnAdd"
+ android:layout_width="wrap_content"
+ android:layout_height="50dip"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:adjustViewBounds="true"
+ android:scaleType="centerInside"
+ android:background="@android:color/transparent"
+ android:src="@drawable/settings"
+ android:contentDescription="@string/teamlist_add_content_description"/>
+
+</RelativeLayout>
diff --git a/project_files/Android-build/SDL-android-project/res/layout/activity_weaponsetlist.xml b/project_files/Android-build/SDL-android-project/res/layout/activity_weaponsetlist.xml
new file mode 100644
index 0000000..6e302c1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/activity_weaponsetlist.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="@string/weaponsetlist_empty" />
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:cacheColorHint="@android:color/transparent" />
+
+ <Button
+ android:id="@+id/addButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/button"
+ android:text="@string/weaponsetlist_add_button_text" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/backbutton.xml b/project_files/Android-build/SDL-android-project/res/layout/backbutton.xml
deleted file mode 100644
index bca25f5..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/backbutton.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <ImageButton
- android:id="@+id/btnBack"
- android:layout_width="120dip"
- android:layout_height="40dip"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/backbutton"/>
-</merge>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/config.xml b/project_files/Android-build/SDL-android-project/res/layout/config.xml
deleted file mode 100644
index 0dcb864..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/config.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <ListView
- android:id="@+id/listView"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"/>
-
-</RelativeLayout>
-
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_chat.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_chat.xml
new file mode 100644
index 0000000..05842fb
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_chat.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@+id/chatConsole"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:clickable="false"
+ android:cacheColorHint="@android:color/transparent"
+ android:transcriptMode="normal"
+ android:focusableInTouchMode="false"
+ android:focusable="false"
+ android:longClickable="false"
+ android:stackFromBottom="true"
+ />
+
+ <EditText
+ android:id="@+id/chatInput"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="@string/chat_hint"
+ android:imeOptions="actionSend"
+ android:inputType="text" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_map.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_map.xml
new file mode 100644
index 0000000..314f986
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_map.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="3dp"
+ android:paddingLeft="5dp"
+ android:paddingRight="3dp"
+ android:paddingTop="3dp" >
+
+ <ImageView
+ android:id="@+id/mapPreview"
+ android:layout_width="256dip"
+ android:layout_height="128dip"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:background="@drawable/box"
+ android:scaleType="fitCenter"
+ android:src="@drawable/roomlist_preparing" />
+
+ <TableLayout
+ android:id="@+id/gameOptions"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/mapPreview"
+ android:stretchColumns="1" >
+
+ <TableRow android:layout_marginTop="5dip" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/map_gen" />
+
+ <Spinner
+ android:id="@+id/spinMapType"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft = "5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/rowMapName"
+ android:layout_marginTop="5dip" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/map_name" />
+
+ <Spinner
+ android:id="@+id/spinMapName"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft = "5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/rowTemplateFilter"
+ android:layout_marginTop="5dip"
+ android:visibility="gone" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/map_template" />
+
+ <Spinner
+ android:id="@+id/spinTemplateFilter"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft = "5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <TableRow
+ android:id="@+id/rowMazeSize"
+ android:layout_marginTop="5dip"
+ android:visibility="gone" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/map_maze_size" />
+
+ <Spinner
+ android:id="@+id/spinMazeSize"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft = "5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <Button
+ android:id="@+id/btnEditDrawnMap"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dip"
+ android:background="@drawable/button"
+ android:enabled="false"
+ android:text="@string/map_button_editdrawnmap"
+ android:visibility="gone" />
+ </TableLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_playerlist.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_playerlist.xml
new file mode 100644
index 0000000..4857356
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_playerlist.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@id/android:list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:drawSelectorOnTop="false"
+ android:cacheColorHint="@android:color/transparent"
+ tools:listitem="@layout/listview_player" />
+
+ <TextView
+ android:id="@id/android:empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="@string/no_players_in_list" />
+</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_roomlist.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_roomlist.xml
new file mode 100644
index 0000000..16c4989
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_roomlist.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp" >
+
+ <ListView
+ android:id="@id/android:list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:drawSelectorOnTop="false"
+ android:cacheColorHint="@android:color/transparent"
+ tools:listitem="@layout/listview_room" />
+
+ <TextView
+ android:id="@id/android:empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/no_rooms_in_list" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_settings.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_settings.xml
new file mode 100644
index 0000000..691ccc9
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_settings.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="3dp"
+ android:paddingLeft="5dp"
+ android:paddingRight="3dp"
+ android:paddingTop="3dp" >
+
+ <TableLayout
+ android:id="@+id/gameOptions"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:stretchColumns="1" >
+
+ <TableRow>
+
+ <TextView
+ android:id="@+id/txtGameplay"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start_gameplay" />
+
+ <Spinner
+ android:id="@+id/spinGameplay"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <TableRow android:layout_marginTop="5dip" >
+
+ <TextView
+ android:id="@+id/txtGamescheme"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start_gamescheme" />
+
+ <Spinner
+ android:id="@+id/spinGamescheme"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+
+ <TableRow android:layout_marginTop="5dip" >
+
+ <TextView
+ android:id="@+id/txtweapons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/start_weapons" />
+
+ <Spinner
+ android:id="@+id/spinweapons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dip"
+ android:background="@drawable/dropdown" />
+ </TableRow>
+ </TableLayout>
+
+ <ImageView
+ android:id="@+id/imgTheme"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@+id/spinTheme"
+ android:layout_alignLeft="@id/gameOptions"
+ android:layout_alignTop="@id/spinTheme"
+ android:adjustViewBounds="true" />
+
+ <Spinner
+ android:id="@id/spinTheme"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@id/gameOptions"
+ android:layout_marginTop="5dip"
+ android:layout_toRightOf="@+id/imgTheme"
+ android:background="@drawable/dropdown" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml b/project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml
new file mode 100644
index 0000000..04c70ba
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/fragment_teamlist.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:paddingBottom="3dp"
+ android:paddingLeft="5dp"
+ android:paddingRight="3dp"
+ android:paddingTop="3dp" >
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:cacheColorHint="@android:color/transparent" />
+
+ <TextView
+ android:id="@id/android:empty"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:text="@string/no_teams_in_list" />
+
+ <Button
+ android:id="@+id/addTeamButton"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/button"
+ android:text="@string/teamlist_addteam" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/listview_item.xml b/project_files/Android-build/SDL-android-project/res/layout/listview_item.xml
index 5950cec..9dd662a 100644
--- a/project_files/Android-build/SDL-android-project/res/layout/listview_item.xml
+++ b/project_files/Android-build/SDL-android-project/res/layout/listview_item.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="10dip"
diff --git a/project_files/Android-build/SDL-android-project/res/layout/listview_player.xml b/project_files/Android-build/SDL-android-project/res/layout/listview_player.xml
new file mode 100644
index 0000000..497f8c7
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/listview_player.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/text1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
+ android:drawablePadding="5dp"
+ android:drawableLeft="@drawable/playerlist_player"
+ android:gravity="center_vertical|left"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/listview_room.xml b/project_files/Android-build/SDL-android-project/res/layout/listview_room.xml
new file mode 100644
index 0000000..b3f13e4
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/listview_room.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:mode="twoLine"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:drawablePadding="5dp"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@android:id/text2"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@android:id/text1"
+ android:layout_below="@android:id/text1"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+
+</TwoLineListItem>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/listview_room_header.xml b/project_files/Android-build/SDL-android-project/res/layout/listview_room_header.xml
new file mode 100644
index 0000000..1ce54e1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/listview_room_header.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+<TextView
+ android:id="@+id/roomname"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_weight="1.5"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_roomname" />
+
+<include layout="@layout/roomlist_player_team_count_header" />
+
+<TextView
+ android:id="@+id/owner"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_owner" />
+
+<TextView
+ android:id="@+id/map"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_map" />
+
+<TextView
+ android:id="@+id/scheme"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_scheme" />
+
+<TextView
+ android:id="@+id/weapons"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.5"
+ android:padding="3dp"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/roomlist_header_weapons" />
+
+</LinearLayout>
+
+
diff --git a/project_files/Android-build/SDL-android-project/res/layout/listview_team.xml b/project_files/Android-build/SDL-android-project/res/layout/listview_team.xml
new file mode 100644
index 0000000..f5a55b1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/listview_team.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp" >
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical|left"
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+ android:drawablePadding="5dp"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageButton
+ android:id="@+id/colorButton"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center_vertical|right"
+ android:src="#fff"
+ android:padding="8dp"
+ android:contentDescription="@string/teamlist_color_button_description" />
+
+ <ImageButton
+ android:id="@+id/hogCountButton"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center_vertical|right"
+ android:src="@drawable/hogcount"
+ android:scaleType="centerCrop"
+ android:padding="0dp"
+ android:contentDescription="@string/teamlist_hogcount_button_description" />
+</LinearLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/main.xml b/project_files/Android-build/SDL-android-project/res/layout/main.xml
deleted file mode 100644
index 0a0bb32..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/main.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <include layout="@layout/background"/>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <Button
- android:id="@+id/downloader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="downloader"/>
-
- <Button
- android:id="@+id/startGame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="startgame"/>
-
-</LinearLayout>
-</FrameLayout>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/savebutton.xml b/project_files/Android-build/SDL-android-project/res/layout/savebutton.xml
deleted file mode 100644
index 3a6ea60..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/savebutton.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <ImageButton
- android:id="@+id/btnSave"
- android:layout_width="120dip"
- android:layout_height="40dip"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/savebutton"/>
-</merge>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/layout/starting_game.xml b/project_files/Android-build/SDL-android-project/res/layout/starting_game.xml
deleted file mode 100644
index 393508b..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/starting_game.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <include
- layout="@layout/background"/>
-
- <ImageView
- android:id="@+id/mapPreview"
- android:layout_width="256dip"
- android:layout_height="128dip"
- android:layout_margin="5dip"
- android:scaleType="fitXY"
- android:background="@drawable/box"
- android:src="@drawable/backbutton"/>
-
- <Spinner
- android:id="@+id/spinMaps"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_below="@id/mapPreview"
- android:layout_alignRight="@id/mapPreview"
- android:layout_toRightOf="@+id/txtMap"
- android:background="@drawable/dropdown"/>
- <TextView
- android:id="@id/txtMap"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/start_map"
- android:layout_alignTop="@id/spinMaps"
- android:layout_alignBottom="@id/spinMaps"
- android:layout_alignLeft="@id/mapPreview"
- android:gravity="center"/>
-
- <TableLayout
- android:id="@+id/gameOptions"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_toRightOf="@id/mapPreview"
- android:layout_alignParentRight="true"
- android:padding="3dip"
- android:layout_margin="5dip"
- android:background="@drawable/box"
- android:stretchColumns="0,2"
- android:shrinkColumns="1">
-
- <TableRow>
- <TextView
- android:id="@+id/txtGameplay"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/start_gameplay"/>
- <Spinner
- android:id="@+id/spinGameplay"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/dropdown"
- />
- </TableRow>
- <TableRow>
- <TextView
- android:id="@+id/txtGamescheme"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/start_gamescheme"/>
- <Spinner
- android:id="@+id/spinGamescheme"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/dropdown"/>
- <ImageButton
- android:id="@+id/btnGamescheme"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/edit"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:layout_gravity="center"
- android:padding="3dip"/>
- </TableRow>
- <TableRow>
- <TextView
- android:id="@+id/txtweapons"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_below="@id/txtGamescheme"
- android:layout_marginTop="5dip"
- android:text="@string/start_weapons"/>
-
- <Spinner
- android:id="@+id/spinweapons"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/dropdown"/>
-
- <ImageButton
- android:id="@+id/btnweapons"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:background="@drawable/edit"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:layout_gravity="center"
- android:padding="3dip"/>
- </TableRow>
- </TableLayout>
-
- <ImageView
- android:id="@+id/imgTheme"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignTop="@+id/spinTheme"
- android:layout_alignBottom="@id/spinTheme"
- android:layout_alignLeft="@id/gameOptions"
- android:adjustViewBounds="true"/>
-
- <Spinner
- android:id="@id/spinTheme"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toRightOf="@+id/imgTheme"
- android:layout_alignParentRight="true"
- android:layout_below="@id/gameOptions"
- android:background="@drawable/dropdown"/>
-
- <include layout="@layout/backbutton"/>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true"
- android:orientation="horizontal">
- <ImageButton
- android:id="@+id/btnTeams"
- android:layout_width="120dip"
- android:layout_height="40dip"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/teams"/>
- <ImageView
- android:id="@+id/imgTeamsCount"
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/teamcount"/>
-
- </LinearLayout>
-
- <ImageButton
- android:id="@+id/btnStart"
- android:layout_width="120dip"
- android:layout_height="40dip"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/startgamebutton"/>
-
-</RelativeLayout>
-
diff --git a/project_files/Android-build/SDL-android-project/res/layout/tab_indicator_vertical.xml b/project_files/Android-build/SDL-android-project/res/layout/tab_indicator_vertical.xml
new file mode 100644
index 0000000..9d40be2
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/layout/tab_indicator_vertical.xml
@@ -0,0 +1,23 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:background="@drawable/box">
+
+ <ImageView android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ />
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scrollHorizontally="false"
+ android:padding="4dp"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ style="?android:attr/tabWidgetStyle"
+ />
+</RelativeLayout>
diff --git a/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml b/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml
index 495570b..b8c21c2 100644
--- a/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml
+++ b/project_files/Android-build/SDL-android-project/res/layout/team_creation.xml
@@ -15,8 +15,6 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
- <include layout="@layout/backbutton"/>
- <include layout="@layout/savebutton"/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
diff --git a/project_files/Android-build/SDL-android-project/res/layout/team_selection_dialog.xml b/project_files/Android-build/SDL-android-project/res/layout/team_selection_dialog.xml
deleted file mode 100644
index fe98717..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/team_selection_dialog.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <TextView
- android:id="@+id/team_selection_dialog_select"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/select"/>
- <TextView
- android:id="@+id/team_selection_dialog_edit"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/edit"/>
- <TextView
- android:id="@+id/team_selection_dialog_delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/delete"/>
-</LinearLayout>
diff --git a/project_files/Android-build/SDL-android-project/res/layout/team_selection_entry.xml b/project_files/Android-build/SDL-android-project/res/layout/team_selection_entry.xml
index b86263a..0bdcb76 100644
--- a/project_files/Android-build/SDL-android-project/res/layout/team_selection_entry.xml
+++ b/project_files/Android-build/SDL-android-project/res/layout/team_selection_entry.xml
@@ -31,7 +31,7 @@
android:layout_alignBottom="@id/imgDifficulty"
android:adjustViewBounds="true"
android:scaleType="centerInside"
- android:src="@drawable/teamcount7"/>
+ android:src="@drawable/hogcount"/>
<TextView
android:id="@+id/txtName"
android:layout_height="fill_parent"
diff --git a/project_files/Android-build/SDL-android-project/res/layout/team_selector.xml b/project_files/Android-build/SDL-android-project/res/layout/team_selector.xml
deleted file mode 100644
index 3c7ea3e..0000000
--- a/project_files/Android-build/SDL-android-project/res/layout/team_selector.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <include layout="@layout/background"/>
-
- <include layout="@layout/backbutton"/>
-
- <ImageButton
- android:id="@+id/btnAdd"
- android:layout_width="wrap_content"
- android:layout_height="50dip"
- android:layout_alignParentBottom="true"
- android:layout_alignParentRight="true"
- android:adjustViewBounds="true"
- android:scaleType="centerInside"
- android:background="@android:color/transparent"
- android:src="@drawable/settings"/>
- <TextView
- android:id="@+id/txtInfo"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_alignParentBottom="true"
- android:layout_toRightOf="@id/btnBack"
- android:layout_toLeftOf="@id/btnAdd"
- android:layout_alignTop="@id/btnBack"
- android:layout_margin="3dp"
- android:gravity="center"
- android:background="@drawable/box"/>
-
-
-
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_above="@id/txtInfo"
- android:layout_margin="3dp">
-
- <ListView
- android:id="@+id/selectedTeams"
- android:layout_height="fill_parent"
- android:layout_width="wrap_content"
- android:layout_margin="3dp"
- android:background="@drawable/box"
- android:layout_weight="1"/>
-
- <ListView
- android:id="@+id/availableTeams"
- android:layout_height="fill_parent"
- android:layout_width="wrap_content"
- android:layout_margin="3dp"
- android:background="@drawable/box"
- android:layout_weight="1"/>
- </LinearLayout>
-</RelativeLayout>
diff --git a/project_files/Android-build/SDL-android-project/res/menu/lobby_options.xml b/project_files/Android-build/SDL-android-project/res/menu/lobby_options.xml
new file mode 100644
index 0000000..8c0af1e
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/menu/lobby_options.xml
@@ -0,0 +1,10 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/room_create"
+ android:title="@string/lobby_roomlistmenu_create"
+ android:showAsAction="ifRoom" />
+ <item
+ android:id="@+id/disconnect"
+ android:title="@string/lobby_menu_disconnect"
+ android:showAsAction="ifRoom" />
+</menu>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/menu/lobby_playerlist_context.xml b/project_files/Android-build/SDL-android-project/res/menu/lobby_playerlist_context.xml
new file mode 100644
index 0000000..9d762a6
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/menu/lobby_playerlist_context.xml
@@ -0,0 +1,10 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/player_info"
+ android:title="@string/lobby_playerlist_contextmenu_info">
+ </item>
+ <item
+ android:id="@+id/player_follow"
+ android:title="@string/lobby_playerlist_contextmenu_follow">
+ </item>
+</menu>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/menu/main_options.xml b/project_files/Android-build/SDL-android-project/res/menu/main_options.xml
new file mode 100644
index 0000000..4b743be
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/menu/main_options.xml
@@ -0,0 +1,20 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/download"
+ android:title="@string/main_menu_downloader"
+ android:icon="@android:drawable/ic_menu_save"
+ android:showAsAction="ifRoom|withText" />
+ <item
+ android:id="@+id/preferences"
+ android:title="@string/main_menu_preferences"
+ android:icon="@android:drawable/ic_menu_preferences"
+ android:showAsAction="ifRoom|withText" />
+ <item
+ android:id="@+id/edit_teams"
+ android:title="@string/edit_teams_menu"
+ android:showAsAction="ifRoom|withText" />
+ <item
+ android:id="@+id/edit_weaponsets"
+ android:title="@string/edit_weaponsets_menu"
+ android:showAsAction="ifRoom|withText" />
+</menu>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_chief_context.xml b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_chief_context.xml
new file mode 100644
index 0000000..5fd9cff
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_chief_context.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/player_kick"
+ android:title="@string/playerlist_contextmenu_kick">
+ </item>
+</menu>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_context.xml b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_context.xml
new file mode 100644
index 0000000..aa717b4
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/menu/room_playerlist_context.xml
@@ -0,0 +1,6 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/player_info"
+ android:title="@string/lobby_playerlist_contextmenu_info">
+ </item>
+</menu>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/basicflags.xml b/project_files/Android-build/SDL-android-project/res/raw/basicflags.xml
deleted file mode 100644
index 9ce626e..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/basicflags.xml
+++ /dev/null
@@ -1,390 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<basicflags>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$damagepct</string>
- </command>
- <default>
- <integer>100</integer>
- </default>
- <image>
- <string>Damage</string>
- </image>
- <max>
- <integer>300</integer>
- </max>
- <min>
- <integer>10</integer>
- </min>
- <title>
- <string>Damage Modifier</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>true</boolean>
- </checkOverMax>
- <times1000>
- <boolean>true</boolean>
- </times1000>
- <command>
- <string>e$turntime</string>
- </command>
- <default>
- <integer>45</integer>
- </default>
- <image>
- <string>Time</string>
- </image>
- <max>
- <integer>100</integer>
- </max>
- <min>
- <integer>1</integer>
- </min>
- <title>
- <string>Turn Time</string>
- </title>
- </flag>
- <flag>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>inithealth</string>
- </command>
- <default>
- <integer>200</integer>
- </default>
- <image>
- <string>Health</string>
- </image>
- <max>
- <integer>200</integer>
- </max>
- <min>
- <integer>50</integer>
- </min>
- <title>
- <string>Initial Health</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>true</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$sd_turns</string>
- </command>
- <default>
- <integer>15</integer>
- </default>
- <image>
- <string>SuddenDeath</string>
- </image>
- <max>
- <integer>50</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Sudden Death Timeout</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$casefreq</string>
- </command>
- <default>
- <integer>5</integer>
- </default>
- <image>
- <string>Box</string>
- </image>
- <max>
- <integer>9</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Crate Drop Turns</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>true</boolean>
- </times1000>
- <command>
- <string>e$minestime</string>
- </command>
- <default>
- <integer>3</integer>
- </default>
- <image>
- <string>Time</string>
- </image>
- <max>
- <integer>5</integer>
- </max>
- <min>
- <integer>-1</integer>
- </min>
- <title>
- <string>Mines Time</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$minesnum</string>
- </command>
- <default>
- <integer>4</integer>
- </default>
- <image>
- <string>Mine</string>
- </image>
- <max>
- <integer>80</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Mines Number</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$minedudpct</string>
- </command>
- <default>
- <integer>0</integer>
- </default>
- <image>
- <string>Dud</string>
- </image>
- <max>
- <integer>100</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Dud Mines Probability (%)</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$explosives</string>
- </command>
- <default>
- <integer>2</integer>
- </default>
- <image>
- <string>Damage</string>
- </image>
- <max>
- <integer>40</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Explosives</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$healthprob</string>
- </command>
- <default>
- <integer>35</integer>
- </default>
- <image>
- <string>Health</string>
- </image>
- <max>
- <integer>100</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Health Kit Probability (%)</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$hcaseamount</string>
- </command>
- <default>
- <integer>25</integer>
- </default>
- <image>
- <string>Health</string>
- </image>
- <max>
- <integer>200</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Health Amount in Kit</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$waterrise</string>
- </command>
- <default>
- <integer>47</integer>
- </default>
- <image>
- <string>SuddenDeath</string>
- </image>
- <max>
- <integer>100</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Water Rise Amount</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$healthdec</string>
- </command>
- <default>
- <integer>5</integer>
- </default>
- <image>
- <string>SuddenDeath</string>
- </image>
- <max>
- <integer>100</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Health Decrease</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$ropepct</string>
- </command>
- <default>
- <integer>100</integer>
- </default>
- <image>
- <string>Rope</string>
- </image>
- <max>
- <integer>999</integer>
- </max>
- <min>
- <integer>25</integer>
- </min>
- <title>
- <string>Rope Length (%)</string>
- </title>
- </flag>
- <flag>
- <checkOverMax>
- <boolean>false</boolean>
- </checkOverMax>
- <times1000>
- <boolean>false</boolean>
- </times1000>
- <command>
- <string>e$getawaytime</string>
- </command>
- <default>
- <integer>100</integer>
- </default>
- <image>
- <string>Time</string>
- </image>
- <max>
- <integer>999</integer>
- </max>
- <min>
- <integer>0</integer>
- </min>
- <title>
- <string>Get Away Time (%)</string>
- </title>
- </flag>
-</basicflags>
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_barrelmayhem.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_barrelmayhem.xml
deleted file mode 100644
index fc7e822..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_barrelmayhem.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Barrel Mayhem</name>
- <basicflags>
- <integer>100</integer>
- <integer>30</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>80</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_cleanslate.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_cleanslate.xml
deleted file mode 100644
index 0fac1f3..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_cleanslate.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Clean Slate</name>
- <basicflags>
- <integer>100</integer>
- <integer>45</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>4</integer>
- <integer>0</integer>
- <integer>2</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_default_scheme.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_default_scheme.xml
deleted file mode 100644
index d91bc38..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_default_scheme.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Default</name>
- <basicflags>
- <integer>100</integer>
- <integer>45</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>4</integer>
- <integer>0</integer>
- <integer>2</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_fortmode.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_fortmode.xml
deleted file mode 100644
index 0172b73..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_fortmode.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Fort Mode</name>
- <basicflags>
- <integer>100</integer>
- <integer>45</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_kingmode.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_kingmode.xml
deleted file mode 100644
index cb28cca..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_kingmode.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>King Mode</name>
- <basicflags>
- <integer>100</integer>
- <integer>45</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>4</integer>
- <integer>0</integer>
- <integer>2</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_minefield.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_minefield.xml
deleted file mode 100644
index f18ca60..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_minefield.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Minefield</name>
- <basicflags>
- <integer>100</integer>
- <integer>30</integer>
- <integer>50</integer>
- <integer>15</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>80</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_promode.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_promode.xml
deleted file mode 100644
index fe1431f..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_promode.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Pro Mode</name>
- <basicflags>
- <integer>100</integer>
- <integer>15</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>0</integer>
- <integer>3</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>2</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_shoppa.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_shoppa.xml
deleted file mode 100644
index 0396f4a..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_shoppa.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Shoppa</name>
- <basicflags>
- <integer>100</integer>
- <integer>30</integer>
- <integer>100</integer>
- <integer>50</integer>
- <integer>1</integer>
- <integer>3</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_thinkingwithportals.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_thinkingwithportals.xml
deleted file mode 100644
index 471f5f2..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_thinkingwithportals.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Thinking with Portals</name>
- <basicflags>
- <integer>100</integer>
- <integer>45</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>2</integer>
- <integer>3</integer>
- <integer>5</integer>
- <integer>0</integer>
- <integer>5</integer>
- <integer>25</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_timeless.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_timeless.xml
deleted file mode 100644
index 5db47b7..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_timeless.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Timeless</name>
- <basicflags>
- <integer>100</integer>
- <integer>9999</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>5</integer>
- <integer>10</integer>
- <integer>2</integer>
- <integer>35</integer>
- <integer>30</integer>
- <integer>0</integer>
- <integer>0</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/scheme_tunnelhogs.xml b/project_files/Android-build/SDL-android-project/res/raw/scheme_tunnelhogs.xml
deleted file mode 100644
index de7d986..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/scheme_tunnelhogs.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scheme>
- <name>Tunnelhogs</name>
- <basicflags>
- <integer>100</integer>
- <integer>30</integer>
- <integer>100</integer>
- <integer>15</integer>
- <integer>5</integer>
- <integer>3</integer>
- <integer>10</integer>
- <integer>10</integer>
- <integer>10</integer>
- <integer>35</integer>
- <integer>25</integer>
- <integer>47</integer>
- <integer>5</integer>
- <integer>100</integer>
- <integer>100</integer>
- </basicflags>
- <gamemod>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <true/>
- <false/>
- <false/>
- <true/>
- <true/>
- <true/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- <false/>
- </gamemod>
-</scheme>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/schemes_builtin.ini b/project_files/Android-build/SDL-android-project/res/raw/schemes_builtin.ini
new file mode 100644
index 0000000..482d933
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/raw/schemes_builtin.ini
@@ -0,0 +1,456 @@
+
+[schemes]
+size = 11
+1\name = Default
+1\fortsmode = false
+1\divteams = false
+1\solidland = false
+1\border = false
+1\lowgrav = false
+1\laser = false
+1\invulnerability = false
+1\resethealth = false
+1\vampiric = false
+1\karma = false
+1\artillery = false
+1\randomorder = false
+1\king = false
+1\placehog = false
+1\sharedammo = false
+1\disablegirders = false
+1\disablelandobjects = false
+1\aisurvival = false
+1\infattack = false
+1\resetweps = false
+1\perhogammo = false
+1\disablewind = false
+1\morewind = false
+1\tagteam = false
+1\bottomborder = false
+1\damagefactor = 100
+1\turntime = 45
+1\health = 100
+1\suddendeath = 15
+1\caseprobability = 5
+1\minestime = 3
+1\minesnum = 4
+1\minedudpct = 0
+1\explosives = 2
+1\healthprobability = 35
+1\healthcaseamount = 25
+1\waterrise = 47
+1\healthdecrease = 5
+1\ropepct = 100
+1\getawaytime = 100
+2\name = Pro Mode
+2\fortsmode = false
+2\divteams = false
+2\solidland = false
+2\border = false
+2\lowgrav = false
+2\laser = false
+2\invulnerability = false
+2\resethealth = false
+2\vampiric = false
+2\karma = false
+2\artillery = false
+2\randomorder = true
+2\king = false
+2\placehog = false
+2\sharedammo = false
+2\disablegirders = false
+2\disablelandobjects = false
+2\aisurvival = false
+2\infattack = false
+2\resetweps = false
+2\perhogammo = false
+2\disablewind = false
+2\morewind = false
+2\tagteam = false
+2\bottomborder = false
+2\damagefactor = 100
+2\turntime = 45
+2\health = 100
+2\suddendeath = 15
+2\caseprobability = 5
+2\minestime = 3
+2\minesnum = 4
+2\minedudpct = 0
+2\explosives = 2
+2\healthprobability = 35
+2\healthcaseamount = 25
+2\waterrise = 47
+2\healthdecrease = 5
+2\ropepct = 100
+2\getawaytime = 100
+3\name = Shoppa
+3\fortsmode = false
+3\divteams = false
+3\solidland = false
+3\border = false
+3\lowgrav = false
+3\laser = false
+3\invulnerability = false
+3\resethealth = false
+3\vampiric = false
+3\karma = false
+3\artillery = false
+3\randomorder = true
+3\king = false
+3\placehog = false
+3\sharedammo = true
+3\disablegirders = false
+3\disablelandobjects = false
+3\aisurvival = false
+3\infattack = false
+3\resetweps = false
+3\perhogammo = false
+3\disablewind = false
+3\morewind = false
+3\tagteam = false
+3\bottomborder = false
+3\damagefactor = 100
+3\turntime = 15
+3\health = 100
+3\suddendeath = 15
+3\caseprobability = 0
+3\minestime = 3
+3\minesnum = 0
+3\minedudpct = 0
+3\explosives = 2
+3\healthprobability = 35
+3\healthcaseamount = 25
+3\waterrise = 47
+3\healthdecrease = 5
+3\ropepct = 100
+3\getawaytime = 100
+4\name = Clean Slate
+4\fortsmode = false
+4\divteams = false
+4\solidland = true
+4\border = true
+4\lowgrav = false
+4\laser = false
+4\invulnerability = false
+4\resethealth = false
+4\vampiric = false
+4\karma = false
+4\artillery = false
+4\randomorder = true
+4\king = false
+4\placehog = false
+4\sharedammo = true
+4\disablegirders = true
+4\disablelandobjects = false
+4\aisurvival = false
+4\infattack = false
+4\resetweps = true
+4\perhogammo = false
+4\disablewind = false
+4\morewind = false
+4\tagteam = false
+4\bottomborder = false
+4\damagefactor = 100
+4\turntime = 30
+4\health = 100
+4\suddendeath = 50
+4\caseprobability = 1
+4\minestime = 3
+4\minesnum = 0
+4\minedudpct = 0
+4\explosives = 0
+4\healthprobability = 0
+4\healthcaseamount = 25
+4\waterrise = 47
+4\healthdecrease = 5
+4\ropepct = 100
+4\getawaytime = 100
+5\name = Minefield
+5\fortsmode = false
+5\divteams = false
+5\solidland = false
+5\border = false
+5\lowgrav = false
+5\laser = false
+5\invulnerability = false
+5\resethealth = true
+5\vampiric = false
+5\karma = false
+5\artillery = false
+5\randomorder = true
+5\king = false
+5\placehog = false
+5\sharedammo = false
+5\disablegirders = false
+5\disablelandobjects = false
+5\aisurvival = false
+5\infattack = true
+5\resetweps = true
+5\perhogammo = false
+5\disablewind = false
+5\morewind = false
+5\tagteam = false
+5\bottomborder = false
+5\damagefactor = 100
+5\turntime = 45
+5\health = 100
+5\suddendeath = 15
+5\caseprobability = 5
+5\minestime = 3
+5\minesnum = 4
+5\minedudpct = 0
+5\explosives = 2
+5\healthprobability = 35
+5\healthcaseamount = 25
+5\waterrise = 47
+5\healthdecrease = 5
+5\ropepct = 100
+5\getawaytime = 100
+6\name = Barrel Mayhem
+6\fortsmode = false
+6\divteams = false
+6\solidland = false
+6\border = false
+6\lowgrav = false
+6\laser = false
+6\invulnerability = false
+6\resethealth = false
+6\vampiric = false
+6\karma = false
+6\artillery = false
+6\randomorder = true
+6\king = false
+6\placehog = false
+6\sharedammo = true
+6\disablegirders = true
+6\disablelandobjects = false
+6\aisurvival = false
+6\infattack = false
+6\resetweps = false
+6\perhogammo = false
+6\disablewind = false
+6\morewind = false
+6\tagteam = false
+6\bottomborder = false
+6\damagefactor = 100
+6\turntime = 30
+6\health = 50
+6\suddendeath = 15
+6\caseprobability = 0
+6\minestime = 0
+6\minesnum = 80
+6\minedudpct = 0
+6\explosives = 0
+6\healthprobability = 35
+6\healthcaseamount = 25
+6\waterrise = 47
+6\healthdecrease = 5
+6\ropepct = 100
+6\getawaytime = 100
+7\name = Tunnel Hogs
+7\fortsmode = false
+7\divteams = false
+7\solidland = false
+7\border = false
+7\lowgrav = false
+7\laser = false
+7\invulnerability = false
+7\resethealth = false
+7\vampiric = false
+7\karma = false
+7\artillery = false
+7\randomorder = true
+7\king = false
+7\placehog = false
+7\sharedammo = true
+7\disablegirders = false
+7\disablelandobjects = false
+7\aisurvival = false
+7\infattack = false
+7\resetweps = false
+7\perhogammo = false
+7\disablewind = false
+7\morewind = false
+7\tagteam = false
+7\bottomborder = false
+7\damagefactor = 100
+7\turntime = 30
+7\health = 100
+7\suddendeath = 15
+7\caseprobability = 0
+7\minestime = 0
+7\minesnum = 0
+7\minedudpct = 0
+7\explosives = 80
+7\healthprobability = 35
+7\healthcaseamount = 25
+7\waterrise = 47
+7\healthdecrease = 5
+7\ropepct = 100
+7\getawaytime = 100
+8\name = Fort Mode
+8\fortsmode = false
+8\divteams = false
+8\solidland = false
+8\border = true
+8\lowgrav = false
+8\laser = false
+8\invulnerability = false
+8\resethealth = false
+8\vampiric = false
+8\karma = false
+8\artillery = false
+8\randomorder = true
+8\king = false
+8\placehog = false
+8\sharedammo = true
+8\disablegirders = true
+8\disablelandobjects = true
+8\aisurvival = false
+8\infattack = false
+8\resetweps = false
+8\perhogammo = false
+8\disablewind = false
+8\morewind = false
+8\tagteam = false
+8\bottomborder = false
+8\damagefactor = 100
+8\turntime = 30
+8\health = 100
+8\suddendeath = 15
+8\caseprobability = 5
+8\minestime = 3
+8\minesnum = 10
+8\minedudpct = 10
+8\explosives = 10
+8\healthprobability = 35
+8\healthcaseamount = 25
+8\waterrise = 47
+8\healthdecrease = 5
+8\ropepct = 100
+8\getawaytime = 100
+9\name = Timeless
+9\fortsmode = true
+9\divteams = true
+9\solidland = false
+9\border = false
+9\lowgrav = true
+9\laser = false
+9\invulnerability = false
+9\resethealth = false
+9\vampiric = false
+9\karma = false
+9\artillery = false
+9\randomorder = true
+9\king = false
+9\placehog = false
+9\sharedammo = false
+9\disablegirders = false
+9\disablelandobjects = false
+9\aisurvival = false
+9\infattack = false
+9\resetweps = false
+9\perhogammo = false
+9\disablewind = false
+9\morewind = false
+9\tagteam = false
+9\bottomborder = false
+9\damagefactor = 100
+9\turntime = 45
+9\health = 100
+9\suddendeath = 15
+9\caseprobability = 5
+9\minestime = 3
+9\minesnum = 0
+9\minedudpct = 0
+9\explosives = 0
+9\healthprobability = 35
+9\healthcaseamount = 25
+9\waterrise = 47
+9\healthdecrease = 5
+9\ropepct = 100
+9\getawaytime = 100
+10\name = Thinking with Portals
+10\fortsmode = false
+10\divteams = false
+10\solidland = false
+10\border = false
+10\lowgrav = false
+10\laser = false
+10\invulnerability = false
+10\resethealth = false
+10\vampiric = false
+10\karma = false
+10\artillery = false
+10\randomorder = true
+10\king = false
+10\placehog = false
+10\sharedammo = false
+10\disablegirders = false
+10\disablelandobjects = false
+10\aisurvival = false
+10\infattack = false
+10\resetweps = false
+10\perhogammo = true
+10\disablewind = false
+10\morewind = false
+10\tagteam = false
+10\bottomborder = false
+10\damagefactor = 100
+10\turntime = 9999
+10\health = 100
+10\suddendeath = 15
+10\caseprobability = 5
+10\minestime = 3
+10\minesnum = 5
+10\minedudpct = 10
+10\explosives = 2
+10\healthprobability = 35
+10\healthcaseamount = 30
+10\waterrise = 0
+10\healthdecrease = 0
+10\ropepct = 100
+10\getawaytime = 100
+11\name = King Mode
+11\fortsmode = false
+11\divteams = false
+11\solidland = false
+11\border = false
+11\lowgrav = false
+11\laser = false
+11\invulnerability = false
+11\resethealth = false
+11\vampiric = false
+11\karma = false
+11\artillery = true
+11\randomorder = true
+11\king = false
+11\placehog = false
+11\sharedammo = false
+11\disablegirders = false
+11\disablelandobjects = false
+11\aisurvival = false
+11\infattack = false
+11\resetweps = false
+11\perhogammo = false
+11\disablewind = false
+11\morewind = false
+11\tagteam = false
+11\bottomborder = false
+11\damagefactor = 100
+11\turntime = 45
+11\health = 100
+11\suddendeath = 15
+11\caseprobability = 2
+11\minestime = 3
+11\minesnum = 5
+11\minedudpct = 0
+11\explosives = 5
+11\healthprobability = 25
+11\healthcaseamount = 25
+11\waterrise = 47
+11\healthdecrease = 5
+11\ropepct = 100
+11\getawaytime = 100
+
+
diff --git a/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt b/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt
new file mode 100644
index 0000000..f9e7d01
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/raw/team_one.hwt
@@ -0,0 +1,74 @@
+[Team]
+Name=Team 1
+Grave=Bone
+Fort=Lego
+Voicepack=Classic
+Flag=hedgewars
+Difficulty=0
+Rounds=0
+Wins=0
+CampaignProgress=0
+
+[Hedgehog0]
+Name=Leonidas
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog1]
+Name=Pipo
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog2]
+Name=Sonic
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog3]
+Name=Xin
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog4]
+Name=Arnold
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog5]
+Name=Jack
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog6]
+Name=Tom
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog7]
+Name=Goldie
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
diff --git a/project_files/Android-build/SDL-android-project/res/raw/team_one.xml b/project_files/Android-build/SDL-android-project/res/raw/team_one.xml
deleted file mode 100644
index a8caa08..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/team_one.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
-<team>
- <name>Team 1</name>
- <flag>hedgewars</flag>
- <fort>Lego</fort>
- <grave>Bone</grave>
- <voice>Classic</voice>
- <hash>0</hash>
- <hog>
- <name>Leonidas</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Pipo</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Sonic</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Xin</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Arnold</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Jack</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Tom</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
- <hog>
- <name>Goldie</name>
- <hat>NoHat</hat>
- <level>0</level>
- </hog>
-</team>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt b/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt
new file mode 100644
index 0000000..f4aa66b
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/raw/team_two.hwt
@@ -0,0 +1,74 @@
+[Team]
+Name=Team 2
+Grave=Bone
+Fort=Lego
+Voicepack=Classic
+Flag=cm_binary
+Difficulty=2
+Rounds=0
+Wins=0
+CampaignProgress=0
+
+[Hedgehog0]
+Name=Paris
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog1]
+Name=Knut
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog2]
+Name=Ash
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog3]
+Name=Woad
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog4]
+Name=Bob
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog5]
+Name=Corky
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog6]
+Name=Bea
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
+
+[Hedgehog7]
+Name=Silvia
+Hat=NoHat
+Rounds=0
+Kills=0
+Deaths=0
+Suicides=0
diff --git a/project_files/Android-build/SDL-android-project/res/raw/team_two.xml b/project_files/Android-build/SDL-android-project/res/raw/team_two.xml
deleted file mode 100644
index 6d187b3..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/team_two.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
-<team>
- <name>Team 2</name>
- <flag>cm_binary</flag>
- <fort>Lego</fort>
- <grave>Bone</grave>
- <voice>Classic</voice>
- <hash>0</hash>
- <hog>
- <name>Paris</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Knut</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Ash</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Woad</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Bob</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Corky</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Bea</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
- <hog>
- <name>Silvia</name>
- <hat>NoHat</hat>
- <level>2</level>
- </hog>
-</team>
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_clean b/project_files/Android-build/SDL-android-project/res/raw/weapon_clean
deleted file mode 100644
index ad08faf..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_clean
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Clean</name>
- <QT>
- 101000900001000001100000000000000000000000000000100000
- </QT>
- <probability>
- 040504054160065554655446477657666666615551010111541111
- </probability>
- <delay>
- 000000000000000000000000000000000000000000000000000000
- </delay>
- <crate>
- 131111031211111112311411111111111111121111110111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_crazy b/project_files/Android-build/SDL-android-project/res/raw/weapon_crazy
deleted file mode 100644
index 64197be..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_crazy
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Crazy</name>
- <QT>
- 999999999999999999299999999999999929999999990999999229
- </QT>
- <probability>
- 111111011111111111111111111111111111111111110111111111
- </probability>
- <delay>
- 000000000000000000000000000000000000000000000000000000
- </delay>
- <crate>
- 131111031211111112311411111111111111121111010111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_default b/project_files/Android-build/SDL-android-project/res/raw/weapon_default
deleted file mode 100644
index bd40785..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_default
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Default</name>
- <QT>
- 939192942219912103223511100120100000021111010101111991
- </QT>
- <probability>
- 040504054160065554655446477657666666615551010111541111
- </probability>
- <delay>
- 000000000000020550000004000700400000000022000000060000
- </delay>
- <crate>
- 131111031211111112311411111111111111121111110111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_mines b/project_files/Android-build/SDL-android-project/res/raw/weapon_mines
deleted file mode 100644
index ca43d99..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_mines
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Mines</name>
- <QT>
- 000000990009000000030000000000000000000000000000000000
- </QT>
- <probability>
- 000000000000000000000000000000000000000000000000000000
- </probability>
- <delay>
- 000000000000020550000004000700400000000020000000060000
- </delay>
- <crate>
- 111111111111111111111111111111111111111111110111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_portals b/project_files/Android-build/SDL-android-project/res/raw/weapon_portals
deleted file mode 100644
index f291588..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_portals
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Portals</name>
- <QT>
- 900000900200000000210000000000000011000009000000000000
- </QT>
- <probability>
- 040504054160065554655446477657666666615551010111541111
- </probability>
- <delay>
- 000000000000020550000004000700400000000020000000060000
- </delay>
- <crate>
- 131111031211111112311411111111111111121111110111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_promode b/project_files/Android-build/SDL-android-project/res/raw/weapon_promode
deleted file mode 100644
index b427f7d..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_promode
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Pro Mode</name>
- <QT>
- 909000900000000000000900000000000000000000000000000000
- </QT>
- <probability>
- 000000000000000000000000000000000000000000000000000000
- </probability>
- <delay>
- 000000000000020550000004000700400000000020000000000000
- </delay>
- <crate>
- 111111111111111111111111111111111111111110010111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapon_shoppa b/project_files/Android-build/SDL-android-project/res/raw/weapon_shoppa
deleted file mode 100644
index 737feb3..0000000
--- a/project_files/Android-build/SDL-android-project/res/raw/weapon_shoppa
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<weapon>
- <name>Shoppa</name>
- <QT>
- 000000990000000000000000000000000000000000000000000000
- </QT>
- <probability>
- 444441004424440221011212122242200000000200040001001111
- </probability>
- <delay>
- 000000000000000000000000000000000000000000000000000000
- </delay>
- <crate>
- 111111111111111111111111111111111111111110110111111111
- </crate>
-</weapon>
-
diff --git a/project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini b/project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini
new file mode 100644
index 0000000..ae2ba55
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/res/raw/weapons_builtin.ini
@@ -0,0 +1,8 @@
+[General]
+%44efault=9391929422199121032235111001201000000211110101011111011040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002200000006000001311110312111111123114111111111111111211111101111111010
+%43razy=9999999999999999992999999999999999299999999909999992099111111011111111111111111111111111111111111110111111101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211110101111111011
+%50ro%20%4dode=9090009000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000000000001111111111111111111111111111111111111111100101111111011
+%53hoppa=0000009900000000000000000000000000000000000000000000000444441004424440221011212122242200000000200040001001100000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111101101111111001
+%43lean%20%53late=1010009000010000011000000000000000000000000000001000000040504054160065554655446477657666666615551010111541101100000000000000000000000000000000000000000000000000000001311110312111111123114111111111111111211111101111111011
+%4dinefield=0000009900090000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002055000000400070040000000002000000006000001111111111111111111111111111111111111111111101111111011
+%54hinking%20with%20%50ortals=9000009002000000002100000000000000110000090000000000000040504054160065554655446477657666666615551010111541101100000000000002055000000400070040000000002000000006000001311110312111111123114111111111111111211111101111111011
diff --git a/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml b/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml
index 1328335..95a3d4f 100644
--- a/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml
+++ b/project_files/Android-build/SDL-android-project/res/values/frontend_data_pointers.xml
@@ -1,34 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
-
-<array name="schemes">
- <item>@raw/basicflags</item>
- <item>@raw/scheme_default_scheme</item>
- <item>@raw/scheme_barrelmayhem</item>
- <item>@raw/scheme_cleanslate</item>
- <item>@raw/scheme_fortmode</item>
- <item>@raw/scheme_kingmode</item>
- <item>@raw/scheme_minefield</item>
- <item>@raw/scheme_promode</item>
- <item>@raw/scheme_shoppa</item>
- <item>@raw/scheme_thinkingwithportals</item>
- <item>@raw/scheme_timeless</item>
- <item>@raw/scheme_tunnelhogs</item>
-</array>
-
-<array name="weapons">
- <item>@raw/weapon_default</item>
- <item>@raw/weapon_clean</item>
- <item>@raw/weapon_crazy</item>
- <item>@raw/weapon_mines</item>
- <item>@raw/weapon_portals</item>
- <item>@raw/weapon_promode</item>
- <item>@raw/weapon_shoppa</item>
-</array>
-
<array name="teams">
<item>@raw/team_one</item>
<item>@raw/team_two</item>
-
+</array>
+<array name="teamFilenames">
+ <item>Team 1.hwt</item>
+ <item>Team 2.hwt</item>
</array>
</resources>
diff --git a/project_files/Android-build/SDL-android-project/res/values/strings.xml b/project_files/Android-build/SDL-android-project/res/values/strings.xml
index 34a8f06..25dd4cb 100644
--- a/project_files/Android-build/SDL-android-project/res/values/strings.xml
+++ b/project_files/Android-build/SDL-android-project/res/values/strings.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
+
<string name="app_name">Hedgewars</string>
-
<string name="select">Select</string>
<string name="edit">Edit</string>
<string name="delete">Delete</string>
<string name="saved">Saved succesfully</string>
-
+
<!-- SDCARD -->
<string name="sdcard_not_mounted_title">Sorry! Could not find the SDCard</string>
<string name="sdcard_not_mounted">There\'s been an error when accessing the SDcard. Please check if there is an SDcard present in the device (internal or external) and if the SDcard is not mounted (via usb to your computer for example). Hedgewars for Android will now quit</string>
-
+
<!-- Notification -->
- <string name="notification_title">Downloading hedgewars files...</string>
+ <string name="notification_title">Downloading hedgewars files…</string>
<string name="notification_done">Successfully downloaded: </string>
-
+
<!-- Download Activity -->
<string name="download_background">Continue in background</string>
<string name="download_cancel">Cancel</string>
@@ -22,28 +22,31 @@
<string name="download_back">Back to main menu</string>
<string name="download_tryagain">Try again</string>
<string name="download_failed">The download has failed because of: </string>
- <string name="download_userexplain">Before starting the game we must download some extra files...</string>
-
+ <string name="download_userexplain">Before starting the game we must download some extra files…</string>
<string name="download_areyousure">Are you sure you want to download this package?</string>
<string name="download_alreadydownloaded">You\'ve already downloaded this package, are you sure you want to download it again?</string>
<string name="download_downloadnow">Download now!</string>
-
<string name="download_queued">This download has been queued</string>
+
+ <!-- main activity -->
+ <string name="main_button_localplay">Local Game</string>
+ <string name="main_button_netplay">Network Game</string>
+ <string name="main_menu_downloader">Downloader</string>
+ <string name="main_menu_preferences">Preferences</string>
<!-- start game -->
-
<string name="start_gameplay">Style</string>
- <string name="start_gamescheme">Game scheme</string>
+ <string name="start_gamescheme">Scheme</string>
<string name="start_weapons">Weapons</string>
<string name="start_map">Map</string>
<string name="start_filter">Filter</string>
- <string name="start_themes">Themes</string>
-
-
-
+
<!-- Teams -->
- <string name="not_enough_teams">Not enough teams</string>
- <string name="teams_info_template">Selected teams = %d</string>
+ <string name="not_enough_teams">You need at least two teams.</string>
+ <string name="not_enough_clans">You need at least two different team colors (clans).</string>
+ <string name="teamlist_empty">No teams</string>
+ <string name="teamlist_add_content_description">New team</string>
+
<!-- Settings -->
<string name="name">Name</string>
<string name="name_default">Unnamed</string>
@@ -52,7 +55,7 @@
<string name="flag">Flag</string>
<string name="voice">Voice</string>
<string name="fort">Fort</string>
-
+
<!-- Difficulty levels -->
<string name="human">Human</string>
<string name="bot5">Level 5</string>
@@ -60,5 +63,131 @@
<string name="bot3">Level 3</string>
<string name="bot2">Level 2</string>
<string name="bot1">Level 1</string>
+
+ <string name="title_activity_lobby">Hedgewars Server Lobby</string>
+ <string name="title_activity_room">Room</string>
+ <string name="title_activity_weaponset_list">User-defined Weaponsets</string>
+ <string name="title_activity_weaponset_creator">Weaponset Editor</string>
+ <string name="title_activity_scheme_list">User-defined Schemes</string>
+ <string name="title_activity_scheme_creator">Scheme Editor</string>
+
+ <string name="chat_hint">Type here to chat</string>
+
+ <!-- Map settings -->
+ <string name="map_gen">Map</string>
+ <string name="map_name">Name</string>
+ <string name="map_template">Type</string>
+ <string name="map_maze_size">Type</string>
+ <string name="map_mission_prefix">Mission: </string>
+ <string name="map_button_editdrawnmap">Edit drawn map</string>
+ <string-array name="map_types">
+ <item>Generated map</item>
+ <item>Generated maze</item>
+ <item>Hand-drawn map</item>
+ <item>Map file</item>
+ </string-array>
+ <string-array name="map_templates">
+ <item>Random</item>
+ <item>Small</item>
+ <item>Medium</item>
+ <item>Large</item>
+ <item>Cavern</item>
+ <item>Wacky</item>
+ </string-array>
+ <string-array name="map_maze_sizes">
+ <item>Small tunnels</item>
+ <item>Medium tunnels</item>
+ <item>Large tunnels</item>
+ <item>Small floating islands</item>
+ <item>Medium floating islands</item>
+ <item>Large floating islands</item>
+ </string-array>
+
+ <!-- Player list -->
+ <string name="no_players_in_list">No players</string>
+
+ <!-- Teamlist -->
+ <string name="teamlist_addteam">Add team</string>
+ <string name="teamlist_color_button_description">Team color</string>
+ <string name="teamlist_hogcount_button_description">Hog count</string>
+ <string name="no_teams_in_list">No teams</string>
+ <string name="edit_teams_menu">Edit Teams</string>
+
+ <!-- Roomlist -->
+ <string name="roomlist_header_roomname">Room Name</string>
+ <string name="roomlist_header_clients">C</string>
+ <string name="roomlist_header_teams">T</string>
+ <string name="roomlist_header_owner">Owner</string>
+ <string name="roomlist_header_map">Map</string>
+ <string name="roomlist_header_scheme">Rules</string>
+ <string name="roomlist_header_weapons">Weapons</string>
+ <string name="no_rooms_in_list">No rooms</string>
+
+ <string name="roomlist_owner">by %1$s</string>
+ <string name="roomlist_map">Map: %1$s</string>
+ <string name="roomlist_scheme">Scheme: %1$s</string>
+ <string name="map_regular">Random map</string>
+ <string name="map_maze">Random maze</string>
+ <string name="map_drawn">Drawn map</string>
+
+ <!-- Chatlog messages -->
+ <string name="log_player_join">%1$s has joined.</string>
+ <string name="log_player_leave">%1$s has left.</string>
+ <string name="log_player_leave_with_msg">%1$s has left (%2$s).</string>
+
+ <!-- Start netgame dialog -->
+ <string name="start_netgame_dialog_title">Connect</string>
+ <string name="start_netgame_dialog_message">Please select a username.</string>
+ <string name="start_netgame_dialog_playername_hint">Username</string>
+
+ <string name="playerlist_contextmenu_kick">Kick</string>
+ <string name="lobby_playerlist_contextmenu_info">Info (shown in chat)</string>
+ <string name="lobby_playerlist_contextmenu_follow">Follow</string>
+ <string name="lobby_roomlistmenu_create">Create room</string>
+ <string name="lobby_roomlistmenu_refresh">Refresh</string>
+ <string name="lobby_menu_disconnect">Disconnect</string>
+ <string name="lobby_tab_rooms">Rooms</string>
+ <string name="lobby_tab_chat">Chat</string>
+ <string name="lobby_tab_players">Users</string>
+
+ <string name="not_implemented_yet">Sorry, not implemented yet. :(</string>
+
+ <!-- Errors -->
+ <string name="error_connection_failed">Unable to connect to the server.</string>
+ <string name="error_unexpected">An unexpected error has occurred: %1$s</string>
+ <string name="error_server_too_old">The server you tried to connect to is using an incompatible protocol.</string>
+ <string name="error_auth_failed">Unable to authenticate for your username.</string>
+ <string name="error_connection_lost">The connection to the server was lost.</string>
+ <string name="error_save_failed">Saving has failed.</string>
+ <string name="error_missing_sdcard_or_files">Error: Either the sdcard is not available, or files are missing from the Data directory.</string>
+ <string name="error_team_attribute_not_found">Error: This team uses assets which we do not have. Try downloading the big data package from the main menu.</string>
+
+ <!-- Dialogs -->
+ <string name="dialog_connecting_title">Please wait</string>
+ <string name="dialog_connecting_message">Connecting to the server…</string>
+ <string name="dialog_password_title">Password required</string>
+ <string name="dialog_password_message">The server has requested a password to connect as "%1$s".</string>
+ <string name="dialog_password_hint">Password</string>
+ <string name="dialog_password_remember">remember password</string>
+ <string name="dialog_create_room_hint">Room name</string>
+ <string name="dialog_create_room_title">Create new room</string>
+ <string name="dialog_addteam_title">Add team</string>
+
+ <string name="toast_disconnected">Disconnected: %1$s</string>
+ <string name="toast_room_abandoned">The room was closed because the owner left.</string>
+ <string name="toast_kicked">You were kicked from the room.</string>
+
+ <!-- Weaponset editor -->
+ <string name="weaponsetlist_add_button_text">New Weaponset</string>
+ <string name="weaponsetlist_empty">No weaponsets</string>
+ <string name="edit_weaponsets_menu">Edit Weaponsets</string>
+
+ <string name="schemelist_add_button_text">New Scheme</string>
+ <!-- Room activity tabs -->
+ <string name="room_tab_map">Map</string>
+ <string name="room_tab_settings">Game</string>
+ <string name="room_tab_teams">Teams</string>
+ <string name="room_tab_chat">Chat</string>
+ <string name="room_tab_players">Users</string>
</resources>
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java
new file mode 100644
index 0000000..092a9c2
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/BasicRoomState.java
@@ -0,0 +1,161 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import static org.hedgewars.hedgeroid.util.ObjectUtils.equal;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.hedgewars.hedgeroid.RoomStateManager;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+
+/**
+ * Common base implementation for a roomstate that will call listeners on every
+ * change. The derived classes have to coordinate how state is changed to
+ * complete the implementation of the RoomStateManager interface.
+ *
+ * See {@link RoomStateManager} for a description of what this is for.
+ */
+public abstract class BasicRoomState implements RoomStateManager {
+ private final List<RoomStateManager.Listener> observers = new LinkedList<RoomStateManager.Listener>();
+
+ private boolean chief;
+ private String gameStyle;
+ private Scheme scheme;
+ private MapRecipe map;
+ private Weaponset weaponset;
+ private Map<String, TeamInGame> teams = Collections.emptyMap();
+
+ public final MapRecipe getMapRecipe() {
+ return map;
+ }
+
+ public final boolean getChiefStatus() {
+ return chief;
+ }
+
+ public final Scheme getScheme() {
+ return scheme;
+ }
+
+ public final String getGameStyle() {
+ return gameStyle;
+ }
+
+ public final Weaponset getWeaponset() {
+ return weaponset;
+ }
+
+ public final Map<String, TeamInGame> getTeams() {
+ return teams;
+ }
+
+ public final void setWeaponset(Weaponset weaponset) {
+ if(!equal(weaponset, this.weaponset)) {
+ this.weaponset = weaponset;
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onWeaponsetChanged(weaponset);
+ }
+ }
+ }
+
+ public final void setMapRecipe(MapRecipe map) {
+ if(!equal(map, this.map)) {
+ this.map = map;
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onMapChanged(map);
+ }
+ }
+ }
+
+ public final void setGameStyle(String gameStyle) {
+ if(!equal(gameStyle, this.gameStyle)) {
+ this.gameStyle = gameStyle;
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onGameStyleChanged(gameStyle);
+ }
+ }
+ }
+
+ public final void setScheme(Scheme scheme) {
+ if(!equal(scheme, this.scheme)) {
+ this.scheme = scheme;
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onSchemeChanged(scheme);
+ }
+ }
+ }
+
+ public final void setChief(boolean chief) {
+ if(chief != this.chief) {
+ this.chief = chief;
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onChiefStatusChanged(chief);
+ }
+ }
+ }
+
+ public final void putTeam(TeamInGame team) {
+ TeamInGame oldEntry = teams.get(team.team.name);
+ if(!equal(team, oldEntry)) {
+ Map<String, TeamInGame> changedMap = new TreeMap<String, TeamInGame>(teams);
+ changedMap.put(team.team.name, team);
+ teams = Collections.unmodifiableMap(changedMap);
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onTeamsChanged(teams);
+ }
+ }
+ }
+
+ public final void removeTeam(String teamname) {
+ if(teams.containsKey(teamname)) {
+ Map<String, TeamInGame> changedMap = new TreeMap<String, TeamInGame>(teams);
+ changedMap.remove(teamname);
+ teams = Collections.unmodifiableMap(changedMap);
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onTeamsChanged(teams);
+ }
+ }
+ }
+
+ public final void setTeams(Map<String, TeamInGame> newTeams) {
+ if(!newTeams.equals(teams)) {
+ teams = Collections.unmodifiableMap(new TreeMap<String, TeamInGame>(newTeams));
+ for(RoomStateManager.Listener observer : observers) {
+ observer.onTeamsChanged(teams);
+ }
+ }
+ }
+
+ public final void addListener(Listener observer) {
+ observers.add(observer);
+ }
+
+ public final void removeListener(Listener observer) {
+ observers.remove(observer);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java
new file mode 100644
index 0000000..1b21400
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatFragment.java
@@ -0,0 +1,99 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.netplay.MessageLog;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * This fragment displays a chatlog and text input field for chatting in either
+ * the lobby or a room.
+ */
+public class ChatFragment extends Fragment {
+ private ChatlogAdapter adapter;
+ private Netplay netplay;
+ private MessageLog messageLog;
+ private boolean inRoom;
+
+ public void setInRoom(boolean inRoom) {
+ this.inRoom = inRoom;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ netplay = Netplay.getAppInstance(getActivity().getApplicationContext());
+ adapter = new ChatlogAdapter(getActivity());
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ messageLog = inRoom ? netplay.roomChatlog : netplay.lobbyChatlog;
+ adapter.setLog(messageLog.getLog());
+ messageLog.addListener(adapter);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ messageLog.removeListener(adapter);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_chat, container, false);
+
+ ListView listView = (ListView) view.findViewById(R.id.chatConsole);
+ listView.setAdapter(adapter);
+ listView.setDivider(null);
+ listView.setDividerHeight(0);
+ listView.setVerticalFadingEdgeEnabled(true);
+
+ EditText editText = (EditText) view.findViewById(R.id.chatInput);
+ editText.setOnEditorActionListener(new ChatSendListener());
+
+ return view;
+ }
+
+ private final class ChatSendListener implements OnEditorActionListener {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ String text = v.getText().toString();
+ if(text.length()>0) {
+ v.setText("");
+ netplay.sendChat(text);
+ }
+ return true;
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java
new file mode 100644
index 0000000..d470983
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ChatlogAdapter.java
@@ -0,0 +1,121 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.netplay.MessageLog;
+
+import android.content.Context;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView.LayoutParams;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+/**
+ * Optimization: ListView is smart enough to try re-using the same view for an item
+ * with the same ID, but it still calls getView for those items when the list changes.
+ * Since lines with a given ID never change in our chatlog, we can avoid the effort
+ * of TextView.setText in many cases by checking if the view is already set up for the
+ * line with the right ID - but to do that, the view needs to remember the ID it's
+ * holding the text for. That's what the LoglineView does.
+ */
+class LoglineView extends TextView {
+ long chatlogId = -1;
+
+ public LoglineView(Context context) {
+ super(context);
+ }
+}
+
+/**
+ * For performance reasons, the chatlog is implemented as ListView instead of a
+ * single TextView (although I later learned that TextView might also have
+ * facilities for efficient appending with limited backlog... oh well, this
+ * works). Every chat line is a line in the ListView, and this adapter prepares
+ * the textviews from a messagelog in an efficient way.
+ */
+public class ChatlogAdapter extends BaseAdapter implements MessageLog.Listener {
+ long idOffset = 0;
+ private List<CharSequence> log = new ArrayList<CharSequence>();
+ private Context context;
+
+ public ChatlogAdapter(Context context) {
+ this.context = context;
+ }
+
+ public int getCount() {
+ return log.size();
+ }
+
+ public Object getItem(int position) {
+ return log.get(position);
+ }
+
+ public long getItemId(int position) {
+ return position+idOffset;
+ }
+
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ public void clear() {
+ idOffset += log.size();
+ log.clear();
+ notifyDataSetChanged();
+ }
+
+ public void lineAdded(CharSequence text) {
+ log.add(text);
+ notifyDataSetChanged();
+ }
+
+ public void lineRemoved() {
+ log.remove(0);
+ idOffset += 1;
+ notifyDataSetChanged();
+ }
+
+ public void setLog(Collection<CharSequence> log) {
+ idOffset += log.size();
+ this.log = new ArrayList<CharSequence>(log);
+ notifyDataSetChanged();
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LoglineView v = (LoglineView)convertView;
+ if (v == null) {
+ v = new LoglineView(context);
+ v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+ v.setMovementMethod(LinkMovementMethod.getInstance());
+ }
+ long id = getItemId(position);
+ if(id != v.chatlogId) {
+ v.setText(log.get(position));
+ v.chatlogId = id;
+ }
+ return v;
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java
new file mode 100644
index 0000000..8da259c
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectingDialog.java
@@ -0,0 +1,94 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.widget.Toast;
+
+/**
+ * Indeterminate progress dialog that is shown in the MainActivity while trying
+ * to connect to the server. If the connection fails (disconnect before we reach
+ * lobby state), an error toast with the disconnect message is shown.
+ *
+ */
+public class ConnectingDialog extends ConnectionDependendDialogFragment {
+ @Override
+ public void onStart() {
+ super.onStart();
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED));
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(disconnectedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED));
+
+ if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() != State.CONNECTING) {
+ dismiss();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(connectedReceiver);
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(disconnectedReceiver);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ ProgressDialog dialog = new ProgressDialog(getActivity());
+ dialog.setIndeterminate(true);
+ dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+ dialog.setTitle(R.string.dialog_connecting_title);
+ dialog.setMessage(getString(R.string.dialog_connecting_message));
+ return dialog;
+ }
+
+ private BroadcastReceiver connectedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Dialog dialog = getDialog();
+ if(dialog != null) {
+ dialog.dismiss();
+ } else {
+ dismiss();
+ }
+ }
+ };
+
+ private BroadcastReceiver disconnectedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Toast.makeText(getActivity(), intent.getExtras().getString(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show();
+ }
+ };
+
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+ Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect();
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java
new file mode 100644
index 0000000..eab6ba9
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/ConnectionDependendDialogFragment.java
@@ -0,0 +1,65 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.content.LocalBroadcastManager;
+
+/**
+ * Helper class for DialogFragments that are supposed to be dismissed when the
+ * network connection is lost. This is used for some dialog fragments that
+ * appear during connecting (e.g. username input)
+ */
+public class ConnectionDependendDialogFragment extends DialogFragment {
+ @Override
+ public void onStart() {
+ super.onStart();
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).registerReceiver(dismissReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED));
+ if(Netplay.getAppInstance(getActivity().getApplicationContext()).getState() == State.NOT_CONNECTED) {
+ dismiss();
+ }
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ LocalBroadcastManager.getInstance(getActivity().getApplicationContext()).unregisterReceiver(dismissReceiver);
+ }
+
+ private BroadcastReceiver dismissReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Dialog dialog = getDialog();
+ if(dialog != null) {
+ dialog.dismiss();
+ } else {
+ dismiss();
+ }
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java
index ab0a3a0..9031375 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/FrontendDataUtils.java
@@ -1,10 +1,12 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,95 +15,89 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid.Datastructures;
import java.io.File;
+import java.io.FileNotFoundException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.hedgewars.hedgeroid.R;
-import org.hedgewars.hedgeroid.Utils;
-import org.hedgewars.hedgeroid.Datastructures.Map.MapType;
+import org.hedgewars.hedgeroid.util.FileUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import java.nio.ByteBuffer;
public class FrontendDataUtils {
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Maps directory doesn't exist
+ */
+ public static List<MapFile> getMaps(Context c) throws FileNotFoundException {
+ File[] files = FileUtils.getFilesFromRelativeDir(c,"Maps");
+ List<MapFile> ret = new ArrayList<MapFile>();
- public static ArrayList<Map> getMaps(Context c){
- File[] files = Utils.getFilesFromRelativeDir(c,"Maps");
- ArrayList<Map> ret = new ArrayList<Map>();
-
- for(File f : files){
- if(Utils.hasFileWithSuffix(f, ".lua")){
- ret.add(new Map(f,MapType.TYPE_MISSION, c));
- }else{
- ret.add(new Map(f, MapType.TYPE_DEFAULT,c));
- }
+ for(File f : files) {
+ boolean isMission = FileUtils.hasFileWithSuffix(f, ".lua");
+ ret.add(new MapFile(f.getName(), isMission));
}
- Collections.sort(ret);
return ret;
}
- public static List<String> getGameplay(Context c){
- String[] files = Utils.getFileNamesFromRelativeDir(c, "Scripts/Multiplayer");
- ArrayList<String> ret = new ArrayList<String>();
-
- for(int i = 0; i < files.length; i++){
- if(files[i].endsWith(".lua")){
- ret.add(files[i].replace('_', ' ').substring(0, files[i].length()-4)); //replace _ by a space and removed the last four characters (.lua)
+ /**
+ * Returns a list of all multiplayer scripts (game styles)
+ * @throws FileNotFoundException if the sdcard isn't available or the Scripts/Multiplayer directory doesn't exist
+ */
+ public static List<String> getGameStyles(Context c) throws FileNotFoundException {
+ File[] files = FileUtils.getFilesFromRelativeDir(c, "Scripts/Multiplayer");
+ List<String> ret = new ArrayList<String>();
+ /*
+ * Caution: It is important that the "empty" style has this exact name, because
+ * it will be interpreted as "don't load a script" by the frontlib, and also by
+ * the QtFrontend in a netgame. This should probably be improved some time
+ * (maybe TODO add a dummy script called "Normal" to the MP scripts?)
+ */
+ ret.add("Normal");
+ for(int i = 0; i < files.length; i++) {
+ String name = files[i].getName();
+ if(name.endsWith(".lua")){
+ //replace _ by a space and removed the last four characters (.lua)
+ ret.add(name.replace('_', ' ').substring(0, name.length()-4));
}
}
- ret.add(0,"None");
- Collections.sort(ret);
- return ret;
- }
-
- public static List<String> getThemes(Context c){
- List<String> list = Utils.getDirsWithFileSuffix(c, "Themes", "icon.png");
- Collections.sort(list);
- return list;
- }
-
- public static List<Scheme> getSchemes(Context c){
- List<Scheme> list = Scheme.getSchemes(c);
- Collections.sort(list);
- return list;
+ return ret;
}
- public static List<Weapon> getWeapons(Context c){
- List<Weapon> list = Weapon.getWeapons(c);
- Collections.sort(list);
- return list;
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Themes directory doesn't exist
+ */
+ public static List<String> getThemes(Context c) throws FileNotFoundException {
+ return FileUtils.getDirsWithFileSuffix(c, "Themes", "icon.png");
}
- public static ArrayList<HashMap<String, ?>> getGraves(Context c){
- String pathPrefix = Utils.getDataPath(c) + "Graphics/Graves/";
- ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c,"Graphics/Graves", ".png", true);
- ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Graphics/Graves directory doesn't exist
+ */
+ public static List<Map<String, ?>> getGraves(Context c) throws FileNotFoundException {
+ File gravePath = FileUtils.getDataPathFile(c, "Graphics", "Graves");
+ List<String> names = FileUtils.getFileNamesFromDirWithSuffix(c,"Graphics/Graves", ".png", true);
+ List<Map<String, ?>> data = new ArrayList<Map<String, ?>>(names.size());
for(String s : names){
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("txt", s);
- Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+ Bitmap b = BitmapFactory.decodeFile(new File(gravePath, s + ".png").getAbsolutePath());
int width = b.getWidth();
- if(b.getHeight() > width){//some pictures contain more 'frames' underneath each other, if so we only use the first frame
- Bitmap tmp = Bitmap.createBitmap(width, width, b.getConfig());
- int[] pixels = new int[width * width];
- b.getPixels(pixels, 0,width,0,0,width,width);
- tmp.setPixels(pixels,0,width,0,0,width,width);
- b.recycle();
- b = tmp;
+ if(b.getHeight() > width){
+ // some pictures contain more 'frames' underneath each other, if so we only use the first frame
+ b = Bitmap.createBitmap(b, 0, 0, width, width);
}
map.put("img", b);
data.add(map);
@@ -109,24 +105,30 @@ public class FrontendDataUtils {
return data;
}
- public static ArrayList<HashMap<String, ?>> getFlags(Context c){
- String pathPrefix = Utils.getDataPath(c) + "Graphics/Flags/";
- ArrayList<String> names = Utils.getFilesFromDirWithSuffix(c, "Graphics/Flags", ".png", true);
- ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(names.size());
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Graphics/Graves directory doesn't exist
+ */
+ public static List<Map<String, ?>> getFlags(Context c) throws FileNotFoundException {
+ File flagsPath = FileUtils.getDataPathFile(c, "Graphics", "Flags");
+ List<String> names = FileUtils.getFileNamesFromDirWithSuffix(c, "Graphics/Flags", ".png", true);
+ List<Map<String, ?>> data = new ArrayList<Map<String, ?>>(names.size());
for(String s : names){
- HashMap<String, Object> map = new HashMap<String, Object>();
+ Map<String, Object> map = new HashMap<String, Object>();
map.put("txt", s);
- Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+ Bitmap b = BitmapFactory.decodeFile(new File(flagsPath, s + ".png").getAbsolutePath());
map.put("img", b);
data.add(map);
}
return data;
}
- public static ArrayList<String> getVoices(Context c){
- File[] files = Utils.getFilesFromRelativeDir(c, "Sounds/voices");
- ArrayList<String> ret = new ArrayList<String>();
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Sounds/voices directory doesn't exist
+ */
+ public static List<String> getVoices(Context c) throws FileNotFoundException {
+ File[] files = FileUtils.getFilesFromRelativeDir(c, "Sounds/voices");
+ List<String> ret = new ArrayList<String>();
for(File f : files){
if(f.isDirectory()) ret.add(f.getName());
@@ -134,35 +136,43 @@ public class FrontendDataUtils {
return ret;
}
- public static ArrayList<String> getForts(Context c){
- return Utils.getFilesFromDirWithSuffix(c,"Forts", "L.png", true);
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Forts directory doesn't exist
+ */
+ public static List<String> getForts(Context c) throws FileNotFoundException {
+ return FileUtils.getFileNamesFromDirWithSuffix(c,"Forts", "L.png", true);
}
- public static ArrayList<HashMap<String, ?>> getTypes(Context c){
- ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(6);
+
+ public static List<Map<String, ?>> getTypes(Context c){
+ List<Map<String, ?>> data = new ArrayList<Map<String, ?>>(6);
String[] levels = {c.getString(R.string.human), c.getString(R.string.bot5), c.getString(R.string.bot4), c.getString(R.string.bot3), c.getString(R.string.bot2), c.getString(R.string.bot1)};
int[] images = {R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1};
for(int i = 0; i < levels.length; i++){
- HashMap<String, Object> map = new HashMap<String, Object>();
+ Map<String, Object> map = new HashMap<String, Object>();
map.put("txt", levels[i]);
map.put("img", images[i]);
+ map.put("level", i);
+
data.add(map);
}
return data;
}
- public static ArrayList<HashMap<String, ?>> getHats(Context c){
- ArrayList<String> files = Utils.getFilesFromDirWithSuffix(c,"Graphics/Hats", ".png", true);
- String pathPrefix = Utils.getDataPath(c) + "Graphics/Hats/";
+ /**
+ * @throws FileNotFoundException if the sdcard isn't available or the Graphics/Hats directory doesn't exist
+ */
+ public static List<Map<String, ?>> getHats(Context c) throws FileNotFoundException {
+ List<String> files = FileUtils.getFileNamesFromDirWithSuffix(c,"Graphics/Hats", ".png", true);
+ File hatsPath = FileUtils.getDataPathFile(c, "Graphics", "Hats");
int size = files.size();
- ArrayList<HashMap<String, ?>> data = new ArrayList<HashMap<String, ?>>(size);
+ List<Map<String, ?>> data = new ArrayList<Map<String, ?>>(size);
- HashMap<String, Object> hashmap;
for(String s : files){
- hashmap = new HashMap<String, Object>();
+ Map<String, Object> hashmap = new HashMap<String, Object>();
hashmap.put("txt", s);
- Bitmap b = BitmapFactory.decodeFile(pathPrefix + s + ".png");//create a full path - decode to to a bitmap
+ Bitmap b = BitmapFactory.decodeFile(new File(hatsPath, s + ".png").getAbsolutePath());
b = Bitmap.createBitmap(b, 0,0,b.getWidth()/2, b.getWidth()/2);
hashmap.put("img", b);
data.add(hashmap);
@@ -171,50 +181,21 @@ public class FrontendDataUtils {
return data;
}
- public static List<HashMap<String, Object>> getTeams(Context c){
- List<HashMap<String, Object>> ret = new ArrayList<HashMap<String, Object>>();
-
- File teamsDir = new File(c.getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS);
+ public static List<Team> getTeams(Context c) {
+ List<Team> ret = new ArrayList<Team>();
+
+ File teamsDir = new File(c.getFilesDir(), Team.DIRECTORY_TEAMS);
File[] teamFileNames = teamsDir.listFiles();
if(teamFileNames != null){
- for(File s : teamFileNames){
- Team t = Team.getTeamFromXml(s.getAbsolutePath());
- if(t != null){
- t.file = s.getName();
- ret.add(teamToMap(t));
+ for(File file : teamFileNames){
+ if(file.getName().endsWith(".hwt")) {
+ Team team = Team.load(file);
+ if(team != null){
+ ret.add(team);
+ }
}
}
}
return ret;
}
-
- public static HashMap<String, Object> teamToMap(Team t){
- HashMap<String, Object> hashmap = new HashMap<String, Object>();
- hashmap.put("team", t);
- hashmap.put("txt", t.name);
- hashmap.put("color", t.color);
- hashmap.put("count", t.hogCount);
- switch(t.levels[0]){
- case 0:
- hashmap.put("img", R.drawable.human);
- break;
- case 1:
- hashmap.put("img", R.drawable.bot5);
- break;
- case 2:
- hashmap.put("img", R.drawable.bot4);
- break;
- case 3:
- hashmap.put("img", R.drawable.bot3);
- break;
- case 4:
- hashmap.put("img", R.drawable.bot2);
- break;
- default:
- case 5:
- hashmap.put("img", R.drawable.bot1);
- break;
- }
- return hashmap;
- }
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameConfig.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameConfig.java
new file mode 100644
index 0000000..6db4f4a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameConfig.java
@@ -0,0 +1,62 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * Game configuration from the point of view of the UI. This differs slightly from the
+ * frontlib view, because the engine allows setting a separate initial health and weapon set
+ * for each hog, while the Android UI currently only supports both attributes on a per-game
+ * basis (initial health is contained in the scheme).
+ *
+ * This difference means that creating a GameConfig object from a frontlib object can, in
+ * theory, lose information. This does not cause problems at the moment because for now
+ * weaponset and initial health are always per-game, but that might change in the future.
+ */
+public final class GameConfig {
+ public static final String DEFAULT_STYLE = "Normal";
+ public static final String DEFAULT_SCHEME = "Default";
+ public static final String DEFAULT_WEAPONSET = "Default";
+ public static final String DEFAULT_THEME = "Bamboo";
+
+ public final String style;
+ public final Scheme scheme;
+ public final MapRecipe map;
+ public final List<TeamInGame> teams;
+ public final Weaponset weaponset;
+
+ public GameConfig(String style, Scheme scheme, MapRecipe map, List<TeamInGame> teams, Weaponset weaponset) {
+ this.style = style;
+ this.scheme = scheme;
+ this.map = map;
+ this.teams = Collections.unmodifiableList(new ArrayList<TeamInGame>(teams));
+ this.weaponset = weaponset;
+ }
+
+ @Override
+ public String toString() {
+ return "GameConfig [style=" + style + ", scheme=" + scheme + ", map="
+ + map + ", teams=" + teams + ", weaponset=" + weaponset + "]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java
deleted file mode 100644
index 733090f..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/GameMode.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid.Datastructures;
-
-public enum GameMode {
- MODE_LOCAL, MODE_DEMO, MODE_NET, MODE_SAVE
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java
deleted file mode 100644
index d8ed13b..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Grave.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid.Datastructures;
-
-public class Grave{
-
- public final String name;
- public final String path;
-
- public Grave(String _name, String _path) {
- name = _name;
- path = _path;
- }
-
- public String toString(){
- return name;
- }
-
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Hog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Hog.java
new file mode 100644
index 0000000..3e9a059
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Hog.java
@@ -0,0 +1,36 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+public final class Hog {
+ public final String name, hat;
+ public final int level;
+
+ public Hog(String name, String hat, int level) {
+ this.name = name;
+ this.hat = hat;
+ this.level = level;
+ }
+
+ @Override
+ public String toString() {
+ return "Hog [name=" + name + ", hat=" + hat + ", level=" + level + "]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java
deleted file mode 100644
index ec14441..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Map.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-package org.hedgewars.hedgeroid.Datastructures;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
-
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class Map implements Comparable<Map>, Parcelable{
-
- private static final String MISSION_PREFIX = "Mission: ";
-
- private String name;
- private String path;
- private String previewPath;
- private MapType type;
-
- public Map(File mapDir, MapType _type, Context c){
- type = _type;
-
- name = mapDir.getName();
- path = mapDir.getAbsolutePath();
- previewPath = path + "/preview.png";
-
- /*switch(type){
- case TYPE_DEFAULT:
-
- break;
- case TYPE_GENERATED:
- //TODO
- break;
- case TYPE_MISSION:
- name = MISSION_PREFIX + mapDir.getName();
- path = mapDir.getAbsolutePath();
- break;
- }*/
-
-
- }
-
- public Map(Parcel in){
- readFromParcel(in);
- }
-
- public String toString(){
- switch(type){
- default:
- case TYPE_DEFAULT:
- return name;
- case TYPE_GENERATED:
- return "bla";
- case TYPE_MISSION:
- return MISSION_PREFIX + name;
- }
- }
-
- public void sendToEngine(EngineProtocolNetwork epn) throws IOException{
- epn.sendToEngine(String.format("emap %s",name));
- }
-
- public MapType getType(){
- return type;
- }
-
- public Drawable getDrawable(){
- switch(type){
- case TYPE_MISSION:
- case TYPE_DEFAULT:
- return Drawable.createFromPath(previewPath);
- case TYPE_GENERATED:
-
- default:
- return null;
- }
- }
-
- public int compareTo(Map another) {
- switch(type){
- case TYPE_GENERATED:
- switch(another.getType()){
- case TYPE_GENERATED:
- return name.compareTo(another.name);
- case TYPE_MISSION:
- return -1;
- case TYPE_DEFAULT:
- return -1;
- }
- case TYPE_MISSION:
- switch(another.getType()){
- case TYPE_GENERATED:
- return 1;
- case TYPE_MISSION:
- return name.compareTo(another.name);
- case TYPE_DEFAULT:
- return -1;
- }
- case TYPE_DEFAULT:
- switch(another.getType()){
- case TYPE_GENERATED:
- return 1;
- case TYPE_MISSION:
- return 1;
- case TYPE_DEFAULT:
- return name.compareTo(another.name);
- }
- }
- return 0;//default case this should never happen
- }
-
- public enum MapType{
- TYPE_DEFAULT, TYPE_MISSION, TYPE_GENERATED
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeString(path);
- dest.writeString(previewPath);
- dest.writeString(type.name());
- }
-
- private void readFromParcel(Parcel src){
- name = src.readString();
- path = src.readString();
- previewPath = src.readString();
- type = MapType.valueOf(src.readString());
- }
- public static final Parcelable.Creator<Map> CREATOR = new Parcelable.Creator<Map>() {
- public Map createFromParcel(Parcel source) {
- return new Map(source);
- }
- public Map[] newArray(int size) {
- return new Map[size];
- }
-
- };
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapFile.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapFile.java
new file mode 100644
index 0000000..e4b8888
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapFile.java
@@ -0,0 +1,86 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.util.FileUtils;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+/**
+ * Represents a map from the data directory
+ */
+public final class MapFile {
+ public static final String MAP_DIRECTORY = "Maps";
+
+ public final String name;
+ public final boolean isMission;
+
+ public MapFile(String name, boolean isMission) {
+ this.name = name;
+ this.isMission = isMission;
+ }
+
+ /**
+ * @throws FileNotFoundException if the sdcard is not available. Does NOT throw if the requested map file does not exist.
+ */
+ public static File getFileForMapname(Context ctx, String mapname) throws FileNotFoundException {
+ return FileUtils.getDataPathFile(ctx, MAP_DIRECTORY, mapname);
+ }
+
+ public static final Comparator<MapFile> MISSIONS_FIRST_NAME_ORDER = new Comparator<MapFile>() {
+ public int compare(MapFile lhs, MapFile rhs) {
+ if(lhs.isMission != rhs.isMission) {
+ return lhs.isMission && !rhs.isMission ? -1 : 1;
+ } else {
+ return lhs.name.compareToIgnoreCase(rhs.name);
+ }
+ }
+ };
+
+ @Override
+ public String toString() {
+ return "MapFile [name=" + name + ", isMission=" + isMission + "]";
+ }
+
+ public File getPreviewFile(Context c) throws FileNotFoundException {
+ return getPreviewFile(c, name);
+ }
+
+ public static File getPreviewFile(Context c, String mapName) throws FileNotFoundException {
+ return FileUtils.getDataPathFile(c, MAP_DIRECTORY, mapName, "preview.png");
+ }
+
+ public static List<String> toDisplayNameList(List<MapFile> mapFiles, Resources res) {
+ String missionPrefix = res.getString(R.string.map_mission_prefix);
+ List<String> result = new ArrayList<String>();
+ for(MapFile mapFile : mapFiles) {
+ result.add((mapFile.isMission ? missionPrefix : "") + mapFile.name);
+ }
+ return result;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapRecipe.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapRecipe.java
new file mode 100644
index 0000000..6fe2b66
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MapRecipe.java
@@ -0,0 +1,203 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+
+import android.content.res.Resources;
+
+public final class MapRecipe {
+ public static final String MAPNAME_REGULAR = "+rnd+";
+ public static final String MAPNAME_MAZE = "+maze+";
+ public static final String MAPNAME_DRAWN = "+drawn+";
+
+ public final int mapgen; // Frontlib.MAPGEN_xxx
+ public final int templateFilter; // Frontlib.TEMPLATEFILTER_xxx, only used when mapgen==MAPGEN_REGULAR
+ public final int mazeSize; // Frontlib.MAZE_SIZE_xxx, only used when mapgen==MAPGEN_MAZE
+ public final String name, seed, theme;
+
+ private final byte[] drawData; // For drawn maps, can be null.
+
+ public MapRecipe(int mapgen, int templateFilter, int mazeSize, String name, String seed, String theme, byte[] drawData) {
+ this.mapgen = mapgen;
+ this.templateFilter = templateFilter;
+ this.mazeSize = mazeSize;
+ this.name = name;
+ this.seed = seed;
+ this.theme = theme;
+ this.drawData = drawData==null ? null : drawData.clone();
+ }
+
+ public static MapRecipe makeMap(String name, String seed, String theme) {
+ return new MapRecipe(Frontlib.MAPGEN_NAMED, 0, 0, name, seed, theme, null);
+ }
+
+ public static MapRecipe makeRandomMap(int templateFilter, String seed, String theme) {
+ return new MapRecipe(Frontlib.MAPGEN_REGULAR, templateFilter, 0, MAPNAME_REGULAR, seed, theme, null);
+ }
+
+ public static MapRecipe makeRandomMaze(int mazeSize, String seed, String theme) {
+ return new MapRecipe(Frontlib.MAPGEN_MAZE, 0, mazeSize, MAPNAME_MAZE, seed, theme, null);
+ }
+
+ public static MapRecipe makeDrawnMap(String seed, String theme, byte[] drawData) {
+ return new MapRecipe(Frontlib.MAPGEN_DRAWN, 0, 0, MAPNAME_DRAWN, seed, theme, drawData);
+ }
+
+ public byte[] getDrawData() {
+ return drawData==null ? null : drawData.clone();
+ }
+
+ public MapRecipe withMapgen(int mapgen) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withTemplateFilter(int templateFilter) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withMazeSize(int mazeSize) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withName(String name) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withSeed(String seed) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withTheme(String theme) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public MapRecipe withDrawData(byte[] drawData) {
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, drawData);
+ }
+
+ public static String formatMapName(Resources res, String map) {
+ if(map.charAt(0)=='+') {
+ if(map.equals(MAPNAME_REGULAR)) {
+ return res.getString(R.string.map_regular);
+ } else if(map.equals(MAPNAME_MAZE)) {
+ return res.getString(R.string.map_maze);
+ } else if(map.equals(MAPNAME_DRAWN)) {
+ return res.getString(R.string.map_drawn);
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Returns the mapname corresponding to the map generator (e.g. "+rnd+" for regular maps)
+ * If the mapgen does not have a unique name (MAPGEN_NAMED) or is not known, the def
+ * value is returned.
+ */
+ public static String mapnameForGenerator(int mapgen, String def) {
+ switch(mapgen) {
+ case Frontlib.MAPGEN_REGULAR: return MAPNAME_REGULAR;
+ case Frontlib.MAPGEN_MAZE: return MAPNAME_MAZE;
+ case Frontlib.MAPGEN_DRAWN: return MAPNAME_DRAWN;
+ default: return def;
+ }
+ }
+
+ /**
+ * In a sense this is the inverse of mapnameForGenerator. Returns the mapgen that uses
+ * mapName as special identifier, or MAPGEN_NAMED if there is none.
+ */
+ public static int generatorForMapname(String mapName) {
+ if(MapRecipe.MAPNAME_REGULAR.equals(mapName)) {
+ return Frontlib.MAPGEN_REGULAR;
+ } else if(MapRecipe.MAPNAME_MAZE.equals(mapName)) {
+ return Frontlib.MAPGEN_MAZE;
+ } else if(MapRecipe.MAPNAME_DRAWN.equals(mapName)) {
+ return Frontlib.MAPGEN_DRAWN;
+ } else {
+ return Frontlib.MAPGEN_NAMED;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "MapRecipe [mapgen=" + mapgen + ", templateFilter="
+ + templateFilter + ", mazeSize=" + mazeSize + ", name=" + name
+ + ", seed=" + seed + ", theme=" + theme + ", drawData="
+ + Arrays.toString(drawData) + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode(drawData);
+ result = prime * result + mapgen;
+ result = prime * result + mazeSize;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((seed == null) ? 0 : seed.hashCode());
+ result = prime * result + templateFilter;
+ result = prime * result + ((theme == null) ? 0 : theme.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ MapRecipe other = (MapRecipe) obj;
+ if (!Arrays.equals(drawData, other.drawData))
+ return false;
+ if (mapgen != other.mapgen)
+ return false;
+ if (mazeSize != other.mazeSize)
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (seed == null) {
+ if (other.seed != null)
+ return false;
+ } else if (!seed.equals(other.seed))
+ return false;
+ if (templateFilter != other.templateFilter)
+ return false;
+ if (theme == null) {
+ if (other.theme != null)
+ return false;
+ } else if (!theme.equals(other.theme))
+ return false;
+ return true;
+ }
+
+ public static String makeRandomSeed() {
+ return "{"+UUID.randomUUID().toString()+"}";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MetaScheme.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MetaScheme.java
new file mode 100644
index 0000000..a0fbec3
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/MetaScheme.java
@@ -0,0 +1,82 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.frontlib.Flib;
+
+public final class MetaScheme {
+ public static final MetaScheme INSTANCE = Flib.INSTANCE.flib_get_metascheme().deref();
+
+ public static final class Mod {
+ public final String name;
+ public final int bitmaskIndex;
+
+ public Mod(String name, int bitmaskIndex) {
+ this.name = name;
+ this.bitmaskIndex = bitmaskIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "MetaScheme$Mod [name=" + name + ", bitmaskIndex=" + bitmaskIndex + "]";
+ }
+ }
+
+ public static final class Setting {
+ public final String name, engineCommand;
+ public final boolean maxMeansInfinity, times1000;
+ public final int min, max, def;
+
+ public Setting(String name, String engineCommand, boolean maxMeansInfinity, boolean times1000, int min, int max, int def) {
+ this.name = name;
+ this.engineCommand = engineCommand;
+ this.maxMeansInfinity = maxMeansInfinity;
+ this.times1000 = times1000;
+ this.min = min;
+ this.max = max;
+ this.def = def;
+ }
+
+ @Override
+ public String toString() {
+ return "MetaScheme$Setting [name=" + name + ", engineCommand=" + engineCommand
+ + ", maxMeansInfinite=" + maxMeansInfinity + ", times1000="
+ + times1000 + ", min=" + min + ", max=" + max + ", def="
+ + def + "]";
+ }
+ }
+
+ public final List<Mod> mods;
+ public final List<Setting> settings;
+
+ public MetaScheme(List<Mod> mods, List<Setting> settings) {
+ this.mods = Collections.unmodifiableList(new ArrayList<Mod>(mods));
+ this.settings = Collections.unmodifiableList(new ArrayList<Setting>(settings));
+ }
+
+ @Override
+ public String toString() {
+ return "MetaScheme [\nmods=" + mods + ", \nsettings=" + settings + "\n]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Player.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Player.java
new file mode 100644
index 0000000..e084978
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Player.java
@@ -0,0 +1,52 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.Comparator;
+
+/**
+ * Basic information about a player on a server.
+ */
+public final class Player {
+ public final String name;
+ public final boolean registered, admin;
+
+ public Player(String name, boolean registered, boolean admin) {
+ this.name = name;
+ this.registered = registered;
+ this.admin = admin;
+ }
+
+ @Override
+ public String toString() {
+ return "Player [name=" + name + ", registered=" + registered
+ + ", admin=" + admin + "]";
+ }
+
+ public static Comparator<Player> ADMIN_NAME_ORDER = new Comparator<Player>() {
+ public int compare(Player lhs, Player rhs) {
+ if(lhs.admin != rhs.admin) {
+ return lhs.admin ? -1 : 1;
+ } else {
+ return lhs.name.compareToIgnoreCase(rhs.name);
+ }
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/PlayerInRoom.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/PlayerInRoom.java
new file mode 100644
index 0000000..a9350e1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/PlayerInRoom.java
@@ -0,0 +1,37 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+public final class PlayerInRoom {
+ public final Player player;
+ public final boolean ready, roomChief;
+
+ public PlayerInRoom(Player player, boolean ready, boolean roomChief) {
+ this.player = player;
+ this.ready = ready;
+ this.roomChief = roomChief;
+ }
+
+ @Override
+ public String toString() {
+ return "PlayerInRoom [player=" + player + ", ready=" + ready
+ + ", roomChief=" + roomChief + "]";
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Room.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Room.java
new file mode 100644
index 0000000..298d173
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Room.java
@@ -0,0 +1,55 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import android.content.res.Resources;
+
+/**
+ * A room as presented in the roomlist in a server lobby.
+ */
+public final class Room {
+ public final String name, map, scheme, weapons, owner;
+ public final int playerCount, teamCount;
+ public final boolean inProgress;
+
+ public Room(String name, String map, String scheme, String weapons,
+ String owner, int playerCount, int teamCount, boolean inProgress) {
+ this.name = name;
+ this.map = map;
+ this.scheme = scheme;
+ this.weapons = weapons;
+ this.owner = owner;
+ this.playerCount = playerCount;
+ this.teamCount = teamCount;
+ this.inProgress = inProgress;
+ }
+
+ public String formatMapName(Resources res) {
+ return MapRecipe.formatMapName(res, map);
+ }
+
+ @Override
+ public String toString() {
+ return "RoomlistRoom [name=" + name + ", map=" + map + ", scheme="
+ + scheme + ", weapons=" + weapons + ", owner=" + owner
+ + ", playerCount=" + playerCount + ", teamCount=" + teamCount
+ + ", inProgress=" + inProgress + "]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/RoomWithId.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/RoomWithId.java
new file mode 100644
index 0000000..1543896
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/RoomWithId.java
@@ -0,0 +1,43 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.Comparator;
+
+public final class RoomWithId {
+ public final Room room;
+ public final long id;
+
+ public RoomWithId(Room room, long id) {
+ this.room = room;
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "RoomWithId [room=" + room + ", id=" + id + "]";
+ }
+
+ public static final Comparator<RoomWithId> NEWEST_FIRST_ORDER = new Comparator<RoomWithId>() {
+ public int compare(RoomWithId lhs, RoomWithId rhs) {
+ return rhs.id<lhs.id ? -1 : rhs.id>lhs.id ? 1 : 0;
+ }
+ };
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java
index 3f2c729..429154a 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Scheme.java
@@ -1,10 +1,11 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,356 +14,93 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.hedgewars.hedgeroid.Datastructures;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
-import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class Scheme implements Parcelable, Comparable<Scheme>{
-
- public static final String DIRECTORY_SCHEME = "schemes";
-
- private String name;
- //private ArrayList<Integer> basic;
- private Integer gamemod;
- private ArrayList<Integer> basic;;
- private static ArrayList<LinkedHashMap<String, ?>> basicflags = new ArrayList<LinkedHashMap<String, ?>>();//TODO why is it static?
- public int health;
-
- public Scheme(String _name, ArrayList<Integer> _basic, int _gamemod){
- name = _name;
- gamemod = _gamemod;
- basic = _basic;
+public final class Scheme {
+ public final String name;
+ public final Map<String, Integer> settings;
+ public final Map<String, Boolean> mods;
+
+ public Scheme(String name, Map<String, Integer> settings, Map<String, Boolean> mods) {
+ this.name = name;
+ this.settings = Collections.unmodifiableMap(new HashMap<String, Integer>(settings));
+ this.mods = Collections.unmodifiableMap(new HashMap<String, Boolean>(mods));
}
- public Scheme(Parcel in){
- readFromParcel(in);
+ public int getHealth() {
+ Integer health = settings.get("health");
+ return health==null ? 100 : health.intValue();
}
- public void sendToEngine(EngineProtocolNetwork epn)throws IOException{
- epn.sendToEngine(String.format("e$gmflags %d", gamemod));
-
- for(int pos = 0; pos < basic.size(); pos++){
- LinkedHashMap<String, ?> basicflag = basicflags.get(pos);
-
- String command = (String)basicflag.get("command");
- Integer value = basic.get(pos);
-
- if(command.equals("inithealth")){//Health is a special case, it doesn't need to be send
- health = value; //to the engine yet, we'll do that with the other HH info
- continue;
- }
-
- Boolean checkOverMax = (Boolean) basicflag.get("checkOverMax");
- Boolean times1000 = (Boolean) basicflag.get("times1000");
- Integer max = (Integer) basicflag.get("max");
-
- if(checkOverMax && value >= max) value = max;
- if(times1000) value *= 1000;
-
- epn.sendToEngine(String.format("%s %d", command, value));
+ public static Scheme createDefaultScheme(MetaScheme meta) {
+ String name = GameConfig.DEFAULT_SCHEME;
+ Map<String, Integer> settings = new TreeMap<String, Integer>();
+ Map<String, Boolean> mods = new TreeMap<String, Boolean>();
+ for(MetaScheme.Setting setting : meta.settings) {
+ settings.put(setting.name, setting.def);
}
- }
- public String toString(){
- return name;
- }
-
-
- public static final int STATE_START = 0;
- public static final int STATE_ROOT = 1;
- public static final int STATE_NAME = 2;
- public static final int STATE_BASICFLAGS = 3;
- public static final int STATE_GAMEMOD = 4;
- public static final int STATE_BASICFLAG_INTEGER = 5;
- public static final int STATE_GAMEMOD_TRUE = 6;
- public static final int STATE_GAMEMOD_FALSE = 7;
-
- public static ArrayList<Scheme> getSchemes(Context c) throws IllegalArgumentException{
- String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_SCHEME + '/';
- String[] files = new File(dir).list(fnf);
- if(files == null) files = new String[]{};
- Arrays.sort(files);
- ArrayList<Scheme> schemes = new ArrayList<Scheme>();
-
- try {
- XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-
- for(String file : files){
- BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
- xmlPuller.setInput(br);
- String name = null;
- ArrayList<Integer> basic = new ArrayList<Integer>();
- Integer gamemod = 0;
- int health = 0;
- int mask = 0x000000004;
-
- int eventType = xmlPuller.getEventType();
- int state = STATE_START;
- while(eventType != XmlPullParser.END_DOCUMENT){
- switch(state){
- case STATE_START:
- if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("scheme")) state = STATE_ROOT;
- else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
- break;
- case STATE_ROOT:
- if(eventType == XmlPullParser.START_TAG){
- if(xmlPuller.getName().equals("basicflags")) state = STATE_BASICFLAGS;
- else if(xmlPuller.getName().toLowerCase().equals("gamemod")) state = STATE_GAMEMOD;
- else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
- else throwException(file, eventType);
- }else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
- else throwException(xmlPuller.getText(), eventType);
- break;
- case STATE_BASICFLAGS:
- if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("integer")) state = STATE_BASICFLAG_INTEGER;
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_GAMEMOD:
- if(eventType == XmlPullParser.START_TAG){
- if(xmlPuller.getName().toLowerCase().equals("true")) state = STATE_GAMEMOD_TRUE;
- else if(xmlPuller.getName().toLowerCase().equals("false")) state = STATE_GAMEMOD_FALSE;
- else throwException(file, eventType);
- }else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_NAME:
- if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_BASICFLAG_INTEGER:
- if(eventType == XmlPullParser.TEXT) basic.add(Integer.parseInt(xmlPuller.getText().trim()));
- else if(eventType == XmlPullParser.END_TAG) state = STATE_BASICFLAGS;
- else throwException(file, eventType);
- break;
- case STATE_GAMEMOD_FALSE:
- if(eventType == XmlPullParser.TEXT) gamemod <<= 1;
- else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
- else throwException(file, eventType);
- break;
- case STATE_GAMEMOD_TRUE:
- if(eventType == XmlPullParser.TEXT){
- gamemod |= mask;
- gamemod <<= 1;
- }else if(eventType == XmlPullParser.END_TAG) state = STATE_GAMEMOD;
- else throwException(file, eventType);
- break;
- }
- eventType = getEventType(xmlPuller);
- }//end while(eventtype != END_DOCUMENT
- schemes.add(new Scheme(name, basic, gamemod));
- }//end for(string file : files
- return schemes;
- } catch (XmlPullParserException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ for(MetaScheme.Mod mod : meta.mods) {
+ mods.put(mod.name, Boolean.FALSE);
}
- return new ArrayList<Scheme>();//TODO handle correctly
+ return new Scheme(name, settings, mods);
}
- private static FilenameFilter fnf = new FilenameFilter(){
- public boolean accept(File dir, String filename) {
- return filename.toLowerCase().startsWith("scheme_");
- }
- };
-
- /**
- * This method will parse the basic flags from a prespecified xml file.
- * I use a raw xml file rather than one parsed by aatp at compile time
- * to keep it generic with other frontends, ie in the future we could
- * use one provided by the Data folder.
- */
- public static void parseBasicFlags(Context c){
- String filename = String.format("%s/%s/basicflags", c.getFilesDir().getAbsolutePath(), DIRECTORY_SCHEME);
-
- XmlPullParser xmlPuller = null;
- BufferedReader br = null;
- try {
- XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
- xmlPuller = xmlPullFactory.newPullParser();
- br = new BufferedReader(new FileReader(filename), 1024);
- xmlPuller.setInput(br);
-
- int eventType = getEventType(xmlPuller);
- boolean continueParsing = true;
- do{
- switch(eventType){
-
- case XmlPullParser.START_TAG:
- if(xmlPuller.getName().toLowerCase().equals("flag")){
- basicflags.add(parseFlag(xmlPuller));
- }else if(xmlPuller.getName().toLowerCase().equals("basicflags")){
- eventType = getEventType(xmlPuller);
- }else{
- skipCurrentTag(xmlPuller);
- eventType = getEventType(xmlPuller);
- }
- break;
- case XmlPullParser.START_DOCUMENT://ignore all tags not being "flag"
- case XmlPullParser.END_TAG:
- case XmlPullParser.TEXT:
- default:
- continueParsing = true;
- case XmlPullParser.END_DOCUMENT:
- continueParsing = false;
- }
- }while(continueParsing);
-
- }catch(IOException e){
- e.printStackTrace();
- }catch (XmlPullParserException e) {
- e.printStackTrace();
- }finally{
- if(br != null)
- try {
- br.close();
- } catch (IOException e) {}
- }
-
+ @Override
+ public String toString() {
+ return "Scheme [name=" + name + ", settings=" + settings + ", mods="
+ + mods + "]";
}
-
- /*
- * * Parses a Tag structure from xml as example we use
- *<flag>
- * <checkOverMax>
- * <boolean>false</boolean>
- * </checkOverMax>
- *</flag>
- *
- * It returns a LinkedHashMap with key/value pairs
- */
- private static LinkedHashMap<String, Object> parseFlag(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
- LinkedHashMap<String, Object> hash = new LinkedHashMap<String, Object>();
-
- int eventType = xmlPuller.getEventType();//Get the event type which triggered this method
- if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().toLowerCase().equals("flag")){//valid start of flag tag
- String lcKey = null;
- String lcType = null;
- String value = null;
-
- eventType = getEventType(xmlPuller);//<checkOverMax>
- while(eventType == XmlPullParser.START_TAG){
- lcKey = xmlPuller.getName();//checkOverMax
- if(getEventType(xmlPuller) == XmlPullParser.START_TAG){//<boolean>
- lcType = xmlPuller.getName().toLowerCase();
- if(getEventType(xmlPuller) == XmlPullParser.TEXT){
- value = xmlPuller.getText();
- if(getEventType(xmlPuller) == XmlPullParser.END_TAG && //</boolean>
- getEventType(xmlPuller) == XmlPullParser.END_TAG){//</checkOverMax>
- if(lcType.equals("boolean")) hash.put(lcKey, new Boolean(value));
- else if(lcType.equals("string"))hash.put(lcKey, value);
- else if(lcType.equals("integer")){
- try{
- hash.put(lcKey, new Integer(value));
- }catch (NumberFormatException e){
- throw new XmlPullParserException("Wrong integer value in xml file");
- }
- }else{
- throwException("basicflags", eventType);
- }
- }//</boolean> / </checkOverMax>
- }//if TEXT
- }//if boolean
- eventType = getEventType(xmlPuller);//start new loop
- }
- eventType = getEventType(xmlPuller);//</flag>
- }
-
- return hash;
- }
-
- private static void skipCurrentTag(XmlPullParser xmlPuller) throws XmlPullParserException, IOException{
- int eventType = xmlPuller.getEventType();
- if(eventType != XmlPullParser.START_TAG)return;
- String tag = xmlPuller.getName().toLowerCase();
-
- while(true){
- eventType = getEventType(xmlPuller);//getNext()
- switch(eventType){
- case XmlPullParser.START_DOCUMENT://we're inside of a start tag so START_ or END_DOCUMENT is just wrong
- case XmlPullParser.END_DOCUMENT:
- throw new XmlPullParserException("invalid xml file");
- case XmlPullParser.START_TAG://if we get a new tag recursively handle it
- skipCurrentTag(xmlPuller);
- break;
- case XmlPullParser.TEXT:
- break;
- case XmlPullParser.END_TAG:
- if(!xmlPuller.getName().toLowerCase().equals(tag)){//if the end tag doesn't match the start tag
- throw new XmlPullParserException("invalid xml file");
- }else{
- return;//skip completed
- }
-
- }
- }
- }
-
- /**
- * Skips whitespaces..
- */
- private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
- int eventType = xmlPuller.next();
- while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
- eventType = xmlPuller.next();
- }
- return eventType;
- }
- private static void throwException(String file, int eventType){
- throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((mods == null) ? 0 : mods.hashCode());
+ result = prime * result
+ + ((settings == null) ? 0 : settings.hashCode());
+ return result;
}
- public int describeContents() {
- return 0;
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Scheme other = (Scheme) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (mods == null) {
+ if (other.mods != null)
+ return false;
+ } else if (!mods.equals(other.mods))
+ return false;
+ if (settings == null) {
+ if (other.settings != null)
+ return false;
+ } else if (!settings.equals(other.settings))
+ return false;
+ return true;
}
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(gamemod);
- dest.writeList(basic);
- }
-
- public void readFromParcel(Parcel src){
- name = src.readString();
- gamemod = src.readInt();
- basic = src.readArrayList(ArrayList.class.getClassLoader());
- }
-
- public static final Parcelable.Creator<Scheme> CREATOR = new Parcelable.Creator<Scheme>() {
- public Scheme createFromParcel(Parcel source) {
- return new Scheme(source);
- }
- public Scheme[] newArray(int size) {
- return new Scheme[size];
+ public static final Comparator<Scheme> NAME_ORDER = new Comparator<Scheme>() {
+ public int compare(Scheme lhs, Scheme rhs) {
+ return String.CASE_INSENSITIVE_ORDER.compare(lhs.name, rhs.name);
}
-
};
-
- public int compareTo(Scheme another) {
- return name.compareTo(another.name);
- }
-}
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Schemes.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Schemes.java
new file mode 100644
index 0000000..fdd1242
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Schemes.java
@@ -0,0 +1,75 @@
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.SchemelistPtr;
+
+import android.content.Context;
+
+/**
+ * Functions for handling the persistent list of schemes.
+ * Schemes in that list are identified by name (case sensitive).
+ */
+public final class Schemes {
+ private Schemes() {
+ throw new AssertionError("This class is not meant to be instantiated");
+ }
+
+ public static File getUserSchemesFile(Context c) {
+ return new File(c.getFilesDir(), "schemes_user.ini");
+ }
+
+ public static File getBuiltinSchemesFile(Context c) {
+ return new File(c.getFilesDir(), "schemes_builtin.ini");
+ }
+
+ public static List<Scheme> loadAllSchemes(Context c) throws IOException {
+ List<Scheme> result = loadBuiltinSchemes(c);
+ result.addAll(loadUserSchemes(c));
+ return result;
+ }
+
+ public static List<Scheme> loadUserSchemes(Context c) throws IOException {
+ return loadSchemes(c, getUserSchemesFile(c));
+ }
+
+ public static List<Scheme> loadBuiltinSchemes(Context c) throws IOException {
+ return loadSchemes(c, getBuiltinSchemesFile(c));
+ }
+
+ public static List<Scheme> loadSchemes(Context c, File schemeFile) throws IOException {
+ if(!schemeFile.isFile()) {
+ // No schemes file == no schemes, no error
+ return new ArrayList<Scheme>();
+ }
+ SchemelistPtr schemeListPtr = null;
+ try {
+ schemeListPtr = Flib.INSTANCE.flib_schemelist_from_ini(schemeFile.getAbsolutePath());
+ if(schemeListPtr == null) {
+ throw new IOException("Unable to read schemelist");
+ }
+ return schemeListPtr.deref();
+ } finally {
+ if(schemeListPtr != null) {
+ Flib.INSTANCE.flib_schemelist_destroy(schemeListPtr);
+ }
+ }
+ }
+
+ public static void saveUserSchemes(Context c, List<Scheme> schemes) throws IOException {
+ SchemelistPtr ptr = SchemelistPtr.createJavaOwned(schemes);
+ Flib.INSTANCE.flib_schemelist_to_ini(getUserSchemesFile(c).getAbsolutePath(), ptr);
+ }
+
+ public static List<String> toNameList(List<Scheme> schemes) {
+ List<String> result = new ArrayList<String>();
+ for(Scheme scheme : schemes) {
+ result.add(scheme.name);
+ }
+ return result;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java
index ec835ce..b7ccfc6 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Team.java
@@ -1,10 +1,12 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,356 +15,77 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid.Datastructures;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.IOException;
-import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
-import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-import org.xmlpull.v1.XmlSerializer;
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamPtr;
+import org.hedgewars.hedgeroid.util.FileUtils;
import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Xml;
-
-public class Team implements Parcelable{
+public final class Team {
public static final String DIRECTORY_TEAMS = "teams";
- private static final Integer[] TEAM_COLORS = {
- 0xd12b42, /* red */
- 0x4980c1, /* blue */
- 0x6ab530, /* green */
- 0xbc64c4, /* purple */
- 0xe76d14, /* orange */
- 0x3fb6e6, /* cyan */
- 0xe3e90c, /* yellow */
- 0x61d4ac, /* mint */
- 0xf1c3e1, /* pink */
- /* add new colors here */
- };
-
-// private static final Integer[] TEAM_COLORS = {
-// 0xff0000, /* red */
-// 0x00ff00, /* blue */
-// 0x0000ff, /* green */
-// };
- private static final int STATE_START = 0;
- private static final int STATE_ROOT = 1;
- private static final int STATE_HOG_ROOT = 2;
-
- public String name, grave, flag, voice, fort, hash;
- public String file = null;
-
- public static int maxNumberOfHogs = 0;
- public static int maxNumberOfTeams = 0;
-
- static{
- maxNumberOfHogs = PascalExports.HWgetMaxNumberOfHogs();
- maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams();
- }
- public String[] hats = new String[maxNumberOfHogs];
- public String[] hogNames = new String[maxNumberOfHogs];
- public int[] levels = new int[maxNumberOfHogs];
+ public static final int HEDGEHOGS_PER_TEAM = Flib.INSTANCE.flib_get_hedgehogs_per_team();
+ public static final int maxNumberOfTeams = PascalExports.HWgetMaxNumberOfTeams();
- public int hogCount = 4;
- public int color = TEAM_COLORS[0];
+ public final String name, grave, flag, voice, fort;
+ public final List<Hog> hogs;
- public Team(){
- }
-
- public Team(Parcel in){
- readFromParcel(in);
- }
-
- public boolean equals(Object o){
- if(super.equals(o)) return true;
- else if(o instanceof Team){
- Team t = (Team)o;
- boolean ret = name.equals(t.name);
- ret &= grave.equals(t.grave);
- ret &= flag.equals(t.flag);
- ret &= voice.equals(t.voice);
- ret &= fort.equals(t.fort);
- ret &= hash.equals(t.hash);
- return ret;
- }else{
- return false;
+ public Team(String name, String grave, String flag, String voice, String fort, List<Hog> hogs) {
+ if(hogs.size() != HEDGEHOGS_PER_TEAM) {
+ throw new IllegalArgumentException("A team must consist of "+HEDGEHOGS_PER_TEAM+" hogs.");
}
- }
-
- public void setRandomColor(int[] illegalcolors){
- Integer[] colorsToPickFrom = TEAM_COLORS;
- if(illegalcolors != null){
- ArrayList<Integer> colors = new ArrayList<Integer>();
- for(int color : TEAM_COLORS){
- boolean validColor = true;
- for(int illegal : illegalcolors){
- if(color == illegal) validColor = false;
- }
- if(validColor) colors.add(color);
- }
- if(colors.size() != 0) colorsToPickFrom = colors.toArray(new Integer[1]);
+ this.name = name;
+ this.grave = grave;
+ this.flag = flag;
+ this.voice = voice;
+ this.fort = fort;
+ this.hogs = Collections.unmodifiableList(new ArrayList<Hog>(hogs));
+ }
+
+ public void save(File f) throws IOException {
+ TeamPtr teamPtr = TeamPtr.createJavaOwned(this);
+ if(Flib.INSTANCE.flib_team_to_ini(f.getAbsolutePath(), teamPtr) != 0) {
+ throw new IOException("Error saving team "+name);
}
- int index = (int)Math.round(Math.random()*(colorsToPickFrom.length-1));
- color = colorsToPickFrom[index];
}
-
- public void sendToEngine(EngineProtocolNetwork epn, int hogCount, int health) throws IOException{
- epn.sendToEngine(String.format("eaddteam %s %d %s", hash, color, name));
- epn.sendToEngine(String.format("egrave %s", grave));
- epn.sendToEngine(String.format("efort %s", fort));
- epn.sendToEngine(String.format("evoicepack %s", voice));
- epn.sendToEngine(String.format("eflag %s", flag));
-
- for(int i = 0; i < hogCount; i++){
- epn.sendToEngine(String.format("eaddhh %d %d %s", levels[i], health, hogNames[i]));
- epn.sendToEngine(String.format("ehat %s", hats[i]));
- }
- }
-
- public void setFileName(Context c){
- if(file == null){
- file = validFileName(c, name);
- }
- }
- private String validFileName(Context c, String fileName){
- String absolutePath = String.format("%s/%s", c.getFilesDir(), fileName);
- File f = new File(absolutePath);
- if(f.exists()){
- String newFileName = fileName + (int)(Math.random()*10);
- return validFileName(c, newFileName);
- }else{
- return fileName;
- }
- }
-
- /*
- * XML METHODS
- */
-
- /**
- * Read the xml file path and convert it to a Team object
- * @param path absolute path to the xml file
- * @return
- */
- public static Team getTeamFromXml(String path){
- try {
- XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-
- BufferedReader br = new BufferedReader(new FileReader(path), 1024);
- xmlPuller.setInput(br);
- Team team = new Team();
- int hogCounter = 0;
-
- int eventType = xmlPuller.getEventType();
- int state = STATE_START;
- while(eventType != XmlPullParser.END_DOCUMENT){
- switch(state){
- case STATE_START:
- if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("team")) state = STATE_ROOT;
- else if(eventType != XmlPullParser.START_DOCUMENT) throwException(path, eventType);
- break;
- case STATE_ROOT:
- if(eventType == XmlPullParser.START_TAG){
- if(xmlPuller.getName().toLowerCase().equals("name")){
- team.name = getXmlText(xmlPuller, "name");
- }else if(xmlPuller.getName().toLowerCase().equals("flag")){
- team.flag= getXmlText(xmlPuller, "flag");
- }else if(xmlPuller.getName().toLowerCase().equals("voice")){
- team.voice = getXmlText(xmlPuller, "voice");
- }else if(xmlPuller.getName().toLowerCase().equals("grave")){
- team.grave = getXmlText(xmlPuller, "grave");
- }else if(xmlPuller.getName().toLowerCase().equals("fort")){
- team.fort = getXmlText(xmlPuller, "fort");
- }else if(xmlPuller.getName().toLowerCase().equals("hash")){
- team.hash = getXmlText(xmlPuller, "hash");
- }else if(xmlPuller.getName().toLowerCase().equals("hog")){
- state = STATE_HOG_ROOT;
- }else throwException(xmlPuller.getName(), eventType);
- }else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
- else throwException(xmlPuller.getText(), eventType);
- break;
- case STATE_HOG_ROOT:
- if(eventType == XmlPullParser.START_TAG){
- if(xmlPuller.getName().toLowerCase().equals("name")){
- team.hogNames[hogCounter] = getXmlText(xmlPuller, "name");
- }else if(xmlPuller.getName().toLowerCase().equals("hat")){
- team.hats[hogCounter] = getXmlText(xmlPuller, "hat");
- }else if(xmlPuller.getName().toLowerCase().equals("level")){
- team.levels[hogCounter] = Integer.parseInt(getXmlText(xmlPuller, "level"));
- }else throwException(xmlPuller.getText(), eventType);
- }else if(eventType == XmlPullParser.END_TAG){
- hogCounter++;
- state = STATE_ROOT;
- }else throwException(xmlPuller.getText(), eventType);
- break;
- }
- eventType = getEventType(xmlPuller);
- }//end while(eventtype != END_DOCUMENT
+ public static Team load(File f) {
+ TeamPtr teamPtr = Flib.INSTANCE.flib_team_from_ini(f.getAbsolutePath());
+ if(teamPtr != null) {
+ Team team = teamPtr.deref().team;
+ Flib.INSTANCE.flib_team_destroy(teamPtr);
return team;
- } catch (NumberFormatException e){
- e.printStackTrace();
- } catch (XmlPullParserException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- private static String getXmlText(XmlPullParser xmlPuller, String parentTag)throws XmlPullParserException, IOException{
- if(getEventType(xmlPuller) == XmlPullParser.TEXT){
- String txt = xmlPuller.getText();
- if(getEventType(xmlPuller) == XmlPullParser.END_TAG && xmlPuller.getName().toLowerCase().equals(parentTag)){
- return txt;
- }
- }
- throw new XmlPullParserException("malformed xml file on string read from tag: " + parentTag);
- }
-
- /**
- * Skips whitespaces..
- */
- private static int getEventType(XmlPullParser xmlPuller)throws XmlPullParserException, IOException{
- int eventType = xmlPuller.next();
- while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){
- eventType = xmlPuller.next();
+ } else {
+ return null;
}
- return eventType;
}
-
- private static void throwException(String file, int eventType){
- throw new IllegalArgumentException(String.format("Xml file: %s malformed with error: %d.", file, eventType));
- }
-
- public void writeToXml(OutputStream os){
- XmlSerializer serializer = Xml.newSerializer();
- try{
- serializer.setOutput(os, "UTF-8");
- serializer.startDocument("UTF-8", true);
- serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
- serializer.startTag(null, "team");
- serializer.startTag(null, "name");
- serializer.text(name);
- serializer.endTag(null, "name");
- serializer.startTag(null, "flag");
- serializer.text(flag);
- serializer.endTag(null, "flag");
- serializer.startTag(null, "fort");
- serializer.text(fort);
- serializer.endTag(null, "fort");
- serializer.startTag(null, "grave");
- serializer.text(grave);
- serializer.endTag(null, "grave");
- serializer.startTag(null, "voice");
- serializer.text(voice);
- serializer.endTag(null, "voice");
- serializer.startTag(null, "hash");
- serializer.text(hash);
- serializer.endTag(null, "hash");
-
- for(int i = 0; i < maxNumberOfHogs; i++){
- serializer.startTag(null, "hog");
- serializer.startTag(null, "name");
- serializer.text(hogNames[i]);
- serializer.endTag(null, "name");
- serializer.startTag(null, "hat");
- serializer.text(hats[i]);
- serializer.endTag(null, "hat");
- serializer.startTag(null, "level");
- serializer.text(String.valueOf(levels[i]));
- serializer.endTag(null, "level");
-
- serializer.endTag(null, "hog");
- }
- serializer.endTag(null, "team");
- serializer.endDocument();
- serializer.flush();
-
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- try {
- os.close();
- } catch (IOException e) {}
- }
- }
- /*
- * END XML METHODS
- */
-
-
-
- /*
- * PARCABLE METHODS
- */
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeString(grave);
- dest.writeString(flag);
- dest.writeString(voice);
- dest.writeString(fort);
- dest.writeString(hash);
- dest.writeStringArray(hats);
- dest.writeStringArray(hogNames);
- dest.writeIntArray(levels);
- dest.writeInt(color);
- dest.writeInt(hogCount);
- dest.writeString(file);
+
+ public static File getTeamfileByName(Context c, String teamName) {
+ return new File(new File(c.getFilesDir(), DIRECTORY_TEAMS), FileUtils.replaceBadChars(teamName)+".hwt");
}
-
-
- public void readFromParcel(Parcel src){
- name = src.readString();
- grave = src.readString();
- flag = src.readString();
- voice = src.readString();
- fort = src.readString();
- hash = src.readString();
- src.readStringArray(hats);
- src.readStringArray(hogNames);
- src.readIntArray(levels);
- color = src.readInt();
- hogCount = src.readInt();
- file = src.readString();
+
+ @Override
+ public String toString() {
+ return "Team [name=" + name + ", grave=" + grave + ", flag=" + flag
+ + ", voice=" + voice + ", fort=" + fort + ", hogs=" + hogs
+ + "]";
}
-
- public static final Parcelable.Creator<Team> CREATOR = new Parcelable.Creator<Team>() {
- public Team createFromParcel(Parcel source) {
- return new Team(source);
- }
- public Team[] newArray(int size) {
- return new Team[size];
+
+ public static Comparator<Team> NAME_ORDER = new Comparator<Team>() {
+ public int compare(Team lhs, Team rhs) {
+ return lhs.name.compareToIgnoreCase(rhs.name);
}
-
};
-
- /*
- * END PARCABLE METHODS
- */
-
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamInGame.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamInGame.java
new file mode 100644
index 0000000..b8b1a81
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamInGame.java
@@ -0,0 +1,58 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+/**
+ * A team with per-game configuration. This is similar to the frontlib "team" structure,
+ * except that it does not include weaponset and initial health, which are handled on a
+ * per-game basis in the UI, but per-hog in the frontlib.
+ */
+public final class TeamInGame {
+ public final Team team;
+ public final TeamIngameAttributes ingameAttribs;
+
+ public TeamInGame(Team team, TeamIngameAttributes ingameAttribs) {
+ this.team = team;
+ this.ingameAttribs = ingameAttribs;
+ }
+
+ public TeamInGame withAttribs(TeamIngameAttributes attribs) {
+ return new TeamInGame(team, attribs);
+ }
+
+ public static int getUnusedOrRandomColorIndex(Collection<TeamInGame> teams) {
+ int[] illegalColors = new int[teams.size()];
+ int i=0;
+ for(TeamInGame team : teams) {
+ illegalColors[i] = team.ingameAttribs.colorIndex;
+ i++;
+ }
+ return TeamIngameAttributes.randomColorIndex(illegalColors);
+ }
+
+ public static Comparator<TeamInGame> NAME_ORDER = new Comparator<TeamInGame>() {
+ public int compare(TeamInGame lhs, TeamInGame rhs) {
+ return Team.NAME_ORDER.compare(lhs.team, rhs.team);
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamIngameAttributes.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamIngameAttributes.java
new file mode 100644
index 0000000..301c400
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/TeamIngameAttributes.java
@@ -0,0 +1,80 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+import org.hedgewars.hedgeroid.frontlib.Flib;
+
+public final class TeamIngameAttributes {
+ public static final int DEFAULT_HOG_COUNT = 4;
+ public static final int[] TEAM_COLORS;
+
+ static {
+ int[] teamColors = new int[Flib.INSTANCE.flib_get_teamcolor_count()];
+ for(int i=0; i<teamColors.length; i++) {
+ teamColors[i] = Flib.INSTANCE.flib_get_teamcolor(i);
+ }
+ TEAM_COLORS = teamColors;
+ }
+
+ public final String ownerName;
+ public final int colorIndex, hogCount;
+ public final boolean remoteDriven;
+
+ public TeamIngameAttributes(String ownerName, int colorIndex, int hogCount, boolean remoteDriven) {
+ this.ownerName = ownerName;
+ this.colorIndex = colorIndex;
+ this.hogCount = hogCount;
+ this.remoteDriven = remoteDriven;
+ }
+
+ public static int randomColorIndex(int[] illegalColors) {
+ Random rnd = new Random();
+ ArrayList<Integer> legalcolors = new ArrayList<Integer>();
+ for(int i=0; i<TEAM_COLORS.length; i++) {
+ legalcolors.add(i);
+ }
+ for(int illegalColor : illegalColors) {
+ legalcolors.remove(Integer.valueOf(illegalColor));
+ }
+ if(legalcolors.isEmpty()) {
+ return rnd.nextInt(TEAM_COLORS.length);
+ } else {
+ return legalcolors.get(rnd.nextInt(legalcolors.size()));
+ }
+ }
+
+ public TeamIngameAttributes withColorIndex(int colorIndex) {
+ return new TeamIngameAttributes(ownerName, colorIndex, hogCount, remoteDriven);
+ }
+
+ public TeamIngameAttributes withHogCount(int hogCount) {
+ return new TeamIngameAttributes(ownerName, colorIndex, hogCount, remoteDriven);
+ }
+
+ @Override
+ public String toString() {
+ return "TeamIngameAttributes [ownerName=" + ownerName + ", colorIndex="
+ + colorIndex + ", hogCount=" + hogCount + ", remoteDriven="
+ + remoteDriven + "]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weapon.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weapon.java
deleted file mode 100644
index 0f0a06e..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weapon.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-package org.hedgewars.hedgeroid.Datastructures;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
-import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class Weapon implements Parcelable, Comparable<Weapon>{
-
- public static final String DIRECTORY_WEAPON = "weapons";
-
- private String name;
- private String QT;
- private String prob;
- private String delay;
- private String crate;
- private static int maxWeapons;
-
- static{
- maxWeapons = PascalExports.HWgetNumberOfWeapons();
- }
-
- public Weapon(String _name, String _QT, String _prob, String _delay, String _crate){
- name = _name;
-
- //Incase there's a newer ammoStore which is bigger we append with zeros
- StringBuffer sb = new StringBuffer();
- while(_QT.length() + sb.length() < maxWeapons){
- sb.append('0');
- }
-
- QT = String.format("e%s %s%s", "ammloadt", _QT, sb);
- prob = String.format("e%s %s%s", "ammprob", _prob, sb);
- delay = String.format("e%s %s%s", "ammdelay", _delay, sb);
- crate = String.format("e%s %s%s", "ammreinf", _crate, sb);
- }
-
- public Weapon(Parcel in){
- readFromParcel(in);
- }
-
- public String toString(){
- return name;
- }
-
- public void sendToEngine(EngineProtocolNetwork epn, int teamsCount) throws IOException{
- epn.sendToEngine(QT);//command prefix is already in string
- epn.sendToEngine(prob);
- epn.sendToEngine(delay);
- epn.sendToEngine(crate);
-
- for(int i = 0; i < teamsCount; i++){
- epn.sendToEngine("eammstore");
- }
- }
-
- public static final int STATE_START = 0;
- public static final int STATE_ROOT = 1;
- public static final int STATE_NAME = 2;
- public static final int STATE_QT = 3;
- public static final int STATE_PROBABILITY = 4;
- public static final int STATE_DELAY = 5;
- public static final int STATE_CRATE = 6;
-
- public static ArrayList<Weapon> getWeapons(Context c) throws IllegalArgumentException{
- String dir = c.getFilesDir().getAbsolutePath() + '/' + DIRECTORY_WEAPON + '/';
- String[] files = new File(dir).list();
- if(files == null) files = new String[]{};
-
- ArrayList<Weapon> weapons = new ArrayList<Weapon>();
-
- try {
- XmlPullParserFactory xmlPullFactory = XmlPullParserFactory.newInstance();
- XmlPullParser xmlPuller = xmlPullFactory.newPullParser();
-
- for(String file : files){
- BufferedReader br = new BufferedReader(new FileReader(dir + file), 1024);
- xmlPuller.setInput(br);
- String name = null;
- String qt = null;
- String prob = null;
- String delay = null;
- String crate = null;
-
- int eventType = xmlPuller.getEventType();
- int state = STATE_START;
- while(eventType != XmlPullParser.END_DOCUMENT){
- switch(state){
- case STATE_START:
- if(eventType == XmlPullParser.START_TAG && xmlPuller.getName().equals("weapon")) state = STATE_ROOT;
- else if(eventType != XmlPullParser.START_DOCUMENT) throwException(file, eventType);
- break;
- case STATE_ROOT:
- if(eventType == XmlPullParser.START_TAG){
- if(xmlPuller.getName().toLowerCase().equals("qt")) state = STATE_QT;
- else if(xmlPuller.getName().toLowerCase().equals("name")) state = STATE_NAME;
- else if(xmlPuller.getName().toLowerCase().equals("probability")) state = STATE_PROBABILITY;
- else if(xmlPuller.getName().toLowerCase().equals("delay")) state = STATE_DELAY;
- else if(xmlPuller.getName().toLowerCase().equals("crate")) state = STATE_CRATE;
- else throwException(file, eventType);
- }else if(eventType == XmlPullParser.END_TAG) state = STATE_START;
- else throwException(xmlPuller.getText(), eventType);
- break;
- case STATE_NAME:
- if(eventType == XmlPullParser.TEXT) name = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_QT:
- if(eventType == XmlPullParser.TEXT) qt = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_PROBABILITY:
- if(eventType == XmlPullParser.TEXT) prob = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_DELAY:
- if(eventType == XmlPullParser.TEXT) delay = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- case STATE_CRATE:
- if(eventType == XmlPullParser.TEXT) crate = xmlPuller.getText().trim();
- else if(eventType == XmlPullParser.END_TAG) state = STATE_ROOT;
- else throwException(file, eventType);
- break;
- }
- eventType = xmlPuller.next();
- while(eventType == XmlPullParser.TEXT && xmlPuller.isWhitespace()){//Skip whitespaces
- eventType = xmlPuller.next();
- }
- }//end while(eventtype != END_DOCUMENT
- weapons.add(new Weapon(name, qt, prob, delay, crate));
- }//end for(string file : files
- return weapons;
-
- } catch (XmlPullParserException e) {
- e.printStackTrace();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return new ArrayList<Weapon>();//TODO handle correctly
- }
-
- private static void throwException(String file, int eventType){
- throw new IllegalArgumentException(String.format("Xml file: %s malformed with eventType: %d.", file, eventType));
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeString(QT);
- dest.writeString(prob);
- dest.writeString(delay);
- dest.writeString(crate);
- }
-
- private void readFromParcel(Parcel src){
- name = src.readString();
- QT = src.readString();
- prob = src.readString();
- delay = src.readString();
- crate = src.readString();
- }
-
- public static final Parcelable.Creator<Weapon> CREATOR = new Parcelable.Creator<Weapon>() {
- public Weapon createFromParcel(Parcel source) {
- return new Weapon(source);
- }
- public Weapon[] newArray(int size) {
- return new Weapon[size];
- }
-
- };
-
- public int compareTo(Weapon another) {
- return name.compareTo(another.name);
- }
-
-
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponset.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponset.java
new file mode 100644
index 0000000..adcb633
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponset.java
@@ -0,0 +1,102 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.util.Comparator;
+
+import org.hedgewars.hedgeroid.frontlib.Flib;
+
+public final class Weaponset {
+ public static final int WEAPONS_COUNT = Flib.INSTANCE.flib_get_weapons_count();
+
+ public final String name, loadout, crateProb, crateAmmo, delay;
+
+ public Weaponset(String name, String loadout, String crateProb, String crateAmmo, String delay) {
+ this.name = name;
+ this.loadout = loadout;
+ this.crateProb = crateProb;
+ this.crateAmmo = crateAmmo;
+ this.delay = delay;
+ }
+
+ @Override
+ public String toString() {
+ return "Weaponset [name=" + name + ", loadout=" + loadout
+ + ", crateProb=" + crateProb + ", crateAmmo=" + crateAmmo
+ + ", delay=" + delay + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((crateAmmo == null) ? 0 : crateAmmo.hashCode());
+ result = prime * result
+ + ((crateProb == null) ? 0 : crateProb.hashCode());
+ result = prime * result + ((delay == null) ? 0 : delay.hashCode());
+ result = prime * result + ((loadout == null) ? 0 : loadout.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Weaponset other = (Weaponset) obj;
+ if (crateAmmo == null) {
+ if (other.crateAmmo != null)
+ return false;
+ } else if (!crateAmmo.equals(other.crateAmmo))
+ return false;
+ if (crateProb == null) {
+ if (other.crateProb != null)
+ return false;
+ } else if (!crateProb.equals(other.crateProb))
+ return false;
+ if (delay == null) {
+ if (other.delay != null)
+ return false;
+ } else if (!delay.equals(other.delay))
+ return false;
+ if (loadout == null) {
+ if (other.loadout != null)
+ return false;
+ } else if (!loadout.equals(other.loadout))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ public static Comparator<Weaponset> NAME_ORDER = new Comparator<Weaponset>() {
+ public int compare(Weaponset lhs, Weaponset rhs) {
+ return String.CASE_INSENSITIVE_ORDER.compare(lhs.name, rhs.name);
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponsets.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponsets.java
new file mode 100644
index 0000000..23a2a93
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Datastructures/Weaponsets.java
@@ -0,0 +1,103 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.Datastructures;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.WeaponsetListPtr;
+
+import android.content.Context;
+
+public final class Weaponsets {
+ private Weaponsets() {
+ throw new AssertionError("This class is not meant to be instantiated");
+ }
+
+ public static File getUserWeaponsetsFile(Context c) {
+ return new File(c.getFilesDir(), "weapons_user.ini");
+ }
+
+ public static File getBuiltinWeaponsetsFile(Context c) {
+ return new File(c.getFilesDir(), "weapons_builtin.ini");
+ }
+
+ public static List<Weaponset> loadAllWeaponsets(Context c) throws IOException {
+ List<Weaponset> result = loadBuiltinWeaponsets(c);
+ result.addAll(loadUserWeaponsets(c));
+ return result;
+ }
+
+ public static List<Weaponset> loadUserWeaponsets(Context c) throws IOException {
+ return loadWeaponsets(c, getUserWeaponsetsFile(c));
+ }
+
+ public static List<Weaponset> loadBuiltinWeaponsets(Context c) throws IOException {
+ return loadWeaponsets(c, getBuiltinWeaponsetsFile(c));
+ }
+
+ public static List<Weaponset> loadWeaponsets(Context c, File weaponsetFile) throws IOException {
+ if(!weaponsetFile.isFile()) {
+ // No file == no weaponsets, no error
+ return new ArrayList<Weaponset>();
+ }
+ WeaponsetListPtr weaponsetListPtr = null;
+ try {
+ weaponsetListPtr = Flib.INSTANCE.flib_weaponsetlist_from_ini(weaponsetFile.getAbsolutePath());
+ if(weaponsetListPtr == null) {
+ throw new IOException("Unable to read weaponsets from "+weaponsetFile);
+ }
+ return weaponsetListPtr.deref();
+ } finally {
+ if(weaponsetListPtr != null) {
+ Flib.INSTANCE.flib_weaponsetlist_destroy(weaponsetListPtr);
+ }
+ }
+ }
+
+ public static void saveUserWeaponsets(Context c, List<Weaponset> weaponsets) throws IOException {
+ WeaponsetListPtr ptr = WeaponsetListPtr.createJavaOwned(weaponsets);
+ Flib.INSTANCE.flib_weaponsetlist_to_ini(getUserWeaponsetsFile(c).getAbsolutePath(), ptr);
+ }
+
+ public static void deleteUserWeaponset(Context c, String setToDelete) throws IOException {
+ List<Weaponset> userWeaponsets = loadUserWeaponsets(c);
+ for(Iterator<Weaponset> iter = userWeaponsets.iterator(); iter.hasNext();) {
+ Weaponset set = iter.next();
+ if(set.name.equals(setToDelete)) {
+ iter.remove();
+ break;
+ }
+ }
+ saveUserWeaponsets(c, userWeaponsets);
+ }
+
+ public static List<String> toNameList(List<Weaponset> weaponsets) {
+ List<String> result = new ArrayList<String>();
+ for(Weaponset weaponset : weaponsets) {
+ result.add(weaponset.name);
+ }
+ return result;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java
index 31f9329..ac38dd6 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAssets.java
@@ -1,100 +1,83 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.hedgewars.hedgeroid.Downloader;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import org.hedgewars.hedgeroid.MainActivity;
import org.hedgewars.hedgeroid.R;
-import org.hedgewars.hedgeroid.Utils;
-import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Schemes;
import org.hedgewars.hedgeroid.Datastructures.Team;
-import org.hedgewars.hedgeroid.Datastructures.Weapon;
+import org.hedgewars.hedgeroid.Datastructures.Weaponsets;
+import org.hedgewars.hedgeroid.util.FileUtils;
-import android.content.Context;
import android.content.res.AssetManager;
import android.os.AsyncTask;
import android.util.Log;
-public class DownloadAssets extends AsyncTask<Object, Long, Long>{
-
- private MainActivity act;
- private static byte[] buffer = null;
+public class DownloadAssets extends AsyncTask<Object, Long, Boolean> {
+ private static final String VERSION_FILENAME = "assetsversion.txt";
+ private final MainActivity act;
- public DownloadAssets(MainActivity _act){
- act = _act;
+ public DownloadAssets(MainActivity act){
+ this.act = act;
}
- public static Long copyFileOrDir(Context c, String path) {
- AssetManager assetManager = c.getAssets();
- String assets[] = null;
- try {
- assets = assetManager.list(path);
- if (assets.length == 0) {
- return DownloadAssets.copyFile(c, path);
- } else {
- String fullPath = Utils.getCachePath(c) + path;
- File dir = new File(fullPath);
- if (!dir.exists())
- dir.mkdir();
- for (int i = 0; i < assets.length; ++i) {
- Long result = DownloadAssets.copyFileOrDir(c, path + "/" + assets[i]);
- if(result > 0) return 1l;
- }
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- Log.e("tag", "I/O Exception", ex);
- return 1l;
- }
- return 0l;
+ private void copyFileOrDir(AssetManager assetManager, File target, String assetPath) throws IOException {
+ try {
+ FileUtils.writeStreamToFile(assetManager.open(assetPath), target);
+ } catch(FileNotFoundException e) {
+ /*
+ * I can't find a better way to figure out whether an asset entry is
+ * a file or a directory. Checking if assetManager.list(assetPath)
+ * is empty is a bit cleaner, but SLOW.
+ */
+ if (!target.isDirectory() && !target.mkdir()) {
+ throw new IOException("Unable to create directory "+target);
+ }
+ for (String asset : assetManager.list(assetPath)) {
+ copyFileOrDir(assetManager, new File(target, asset), assetPath + "/" + asset);
+ }
+ }
}
- private static Long copyFile(Context c, String filename) {
- AssetManager assetManager = c.getAssets();
-
- InputStream in = null;
- OutputStream out = null;
- try {
- in = assetManager.open(filename);
- in = new BufferedInputStream(in, 8192);
-
- String newFileName = Utils.getCachePath(c) + filename;
- out = new FileOutputStream(newFileName);
- out = new BufferedOutputStream(out, 8192);
-
- int read;
- while ((read = in.read(buffer)) != -1) {
- out.write(buffer, 0, read);
- }
- in.close();
- in = null;
- out.flush();
- out.close();
- out = null;
- } catch (Exception e) {
- e.printStackTrace();
- Log.e("tag", e.getMessage());
- return 1l;
- }
- return 0l;
-
- }
-
- protected Long doInBackground(Object... params) {
- Utils.resRawToFilesDir(act,R.array.schemes, Scheme.DIRECTORY_SCHEME);
- Utils.resRawToFilesDir(act, R.array.weapons, Weapon.DIRECTORY_WEAPON);
- Utils.resRawToFilesDir(act, R.array.teams, Team.DIRECTORY_TEAMS);
- buffer = new byte[8192];//allocate the buffer
- return DownloadAssets.copyFileOrDir(act, "Data");
+ @Override
+ protected Boolean doInBackground(Object... params) {
+ try {
+ FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.schemes_builtin), Schemes.getBuiltinSchemesFile(act));
+ FileUtils.writeStreamToFile(act.getResources().openRawResource(R.raw.weapons_builtin), Weaponsets.getBuiltinWeaponsetsFile(act));
+ FileUtils.resRawToFilesDir(act, R.array.teams, R.array.teamFilenames, Team.DIRECTORY_TEAMS);
+ copyFileOrDir(act.getAssets(), FileUtils.getDataPathFile(act), "Data");
+ copyFileOrDir(act.getAssets(), new File(FileUtils.getCachePath(act), VERSION_FILENAME), VERSION_FILENAME);
+ return Boolean.TRUE;
+ } catch(IOException e) {
+ Log.e("DownloadAssets", e.getMessage(), e);
+ return Boolean.FALSE;
+ }
}
- protected void onPostExecute(Long result){
- act.onAssetsDownloaded(result == 0);
- buffer = null;
+ @Override
+ protected void onPostExecute(Boolean result){
+ act.onAssetsDownloaded(result);
}
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java
index 4ca5b86..2d1936f 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadAsyncTask.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,7 +14,7 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@@ -107,7 +108,7 @@ public class DownloadAsyncTask extends AsyncTask<DownloadPackage, Object, Intege
entry = input.getNextEntry();
}catch(IOException e){
e.printStackTrace();
- if(conn != null) conn.disconnect();
+ conn.disconnect();
return EXIT_CONNERROR;
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java
index c14a450..3803b63 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadDialogFragment.java
@@ -1,3 +1,22 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.hedgewars.hedgeroid.Downloader;
import org.hedgewars.hedgeroid.R;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java
index a870c92..efe5be0 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadFragment.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,10 +14,9 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid.Downloader;
import org.hedgewars.hedgeroid.R;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java
index 1c81565..65734b7 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListActivity.java
@@ -1,3 +1,22 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.hedgewars.hedgeroid.Downloader;
import org.hedgewars.hedgeroid.R;
@@ -6,7 +25,6 @@ import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java
index 3ea85a9..f2215fe 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadListFragment.java
@@ -1,3 +1,22 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.hedgewars.hedgeroid.Downloader;
import java.io.BufferedReader;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java
index b193dc0..1eea4a7 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadPackage.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,14 +14,14 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.hedgewars.hedgeroid.Downloader;
import java.io.IOException;
-import org.hedgewars.hedgeroid.Utils;
+import org.hedgewars.hedgeroid.util.FileUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -29,7 +30,6 @@ import android.content.SharedPreferences;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.PreferenceManager;
-import android.util.Log;
public class DownloadPackage implements Parcelable{
private String url_without_suffix;
@@ -137,7 +137,7 @@ public class DownloadPackage implements Parcelable{
version = -1;
}
}else if(name.equals("path")){
- path = Utils.getDataPath(c) + text;
+ path = FileUtils.getDataPathFile(c, text).getAbsolutePath();
}else if(name.equals("representation")){
representation = text;
}else if(name.equals("description")){
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java
index 1d18c9c..b1e47ef 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Downloader/DownloadService.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,10 +14,9 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid.Downloader;
import java.util.LinkedList;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java
deleted file mode 100644
index f90fb11..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/EngineProtocolNetwork.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-public class EngineProtocolNetwork extends Thread{
-
- public static final String GAMEMODE_LOCAL = "TL";
- public static final String GAMEMODE_DEMO = "TD";
- public static final String GAMEMODE_NET = "TN";
- public static final String GAMEMODE_SAVE = "TS";
-
- public static final int BUFFER_SIZE = 255; //From iOS code which got it from the origional frontend
-
- public static final int MODE_GENLANDPREVIEW = 0;
- public static final int MODE_GAME = 1;
-
- private ServerSocket serverSocket;
- private InputStream input;
- private OutputStream output;
- public int port;
- private final GameConfig config;
- private boolean clientQuit = false;
-
- public EngineProtocolNetwork(GameConfig _config){
- config = _config;
- try {
- serverSocket = new ServerSocket(0);
- port = serverSocket.getLocalPort();
- Thread ipcThread = new Thread(this, "IPC - Thread");
- ipcThread.start();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public void run(){
- //if(mode == MODE_GENLANDPREVIEW) genLandPreviewIPC();
- /*else if (mode == MODE_GAME)*/ gameIPC();
- }
-
- private void gameIPC(){
- Socket sock = null;
- try{
- sock = serverSocket.accept();
- input = sock.getInputStream();
- output = sock.getOutputStream();
-
- int msgSize = 0;
- byte[] buffer = new byte[BUFFER_SIZE];
-
- while(!clientQuit){
- msgSize = 0;
-
- input.read(buffer, 0, 1);
- msgSize = buffer[0];
-
- input.read(buffer, 0, msgSize);
- System.out.println("IPC" + (char)buffer[0] + " : " + new String(buffer, 1,msgSize-1, "US_ASCII"));
- switch(buffer[0]){
- case 'C'://game init
- config.sendToEngine(this);
- break;
- case '?'://ping - pong
- sendToEngine("!");
- break;
- case 'e'://Send protocol version
- System.out.println(new String(buffer));
- break;
- case 'i'://game statistics
- switch(buffer[1]){
- case 'r'://winning team
- break;
- case 'D'://best shot
- break;
- case 'k'://best hedgehog
- break;
- case 'K'://# hogs killed
- break;
- case 'H'://team health graph
- break;
- case 'T':// local team stats
- break;
- case 'P'://teams ranking
- break;
- case 's'://self damage
- break;
- case 'S'://friendly fire
- break;
- case 'B'://turn skipped
- break;
- default:
- }
- break;
- case 'E'://error - quits game
- System.out.println(new String(buffer));
- return;
- case 'q'://game ended remove save file
-
- return;
- case 'Q'://game ended but not finished
-
- return;
- }
-
- }
- }catch(IOException e){
- e.printStackTrace();
- }finally{
- try {
- if(sock != null) sock.close();
- } catch (IOException e) {}
- try{
- if(serverSocket != null) serverSocket.close();
- } catch (IOException e) {}
- }
- }
-
- public void sendToEngine(String s){
- int length = s.length();
-
- try {
- output.write(length);
- output.write(s.getBytes(), 0, length);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public void quitIPC(){
- clientQuit = true;
- }
-
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java
deleted file mode 100644
index 52a91ef..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/GameConfig.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-package org.hedgewars.hedgeroid.EngineProtocol;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.UUID;
-
-import org.hedgewars.hedgeroid.Datastructures.GameMode;
-import org.hedgewars.hedgeroid.Datastructures.Map;
-import org.hedgewars.hedgeroid.Datastructures.Scheme;
-import org.hedgewars.hedgeroid.Datastructures.Team;
-import org.hedgewars.hedgeroid.Datastructures.Weapon;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-public class GameConfig implements Parcelable{
-
- public GameMode mode = GameMode.MODE_LOCAL;
- public Map map = null;
- public String theme = null;
- public Scheme scheme = null;
- public Weapon weapon = null;
-
- public String style = null;
- public String training = null;
- public String seed = null;
-
- public ArrayList<Team> teams = new ArrayList<Team>();
-
- public GameConfig(){
-
- }
-
- public GameConfig(Parcel in){
- readFromParcel(in);
- }
-
-
-
- public void sendToEngine(EngineProtocolNetwork epn) throws IOException{
- Log.d("HW_Frontend", "Sending Gameconfig...");
- int teamCount = 4;
- epn.sendToEngine("TL"); //Write game mode
- if(training != null) epn.sendToEngine(String.format("escript Scripts/Training/%s.lua", training));
- else if(style != null) epn.sendToEngine(String.format("escript Scripts/Multiplayer/%s.lua", style));
-
- //seed info
- epn.sendToEngine(String.format("eseed {%s}", UUID.randomUUID().toString()));
-
- map.sendToEngine(epn);
- //dimensions of the map
- //templatefilter_command
- //mapgen_command
- //mazesize_command
-
- epn.sendToEngine(String.format("etheme %s", theme));
-
- scheme.sendToEngine(epn);
-
- weapon.sendToEngine(epn, teamCount);
-
- for(Team t : teams){
- if(t != null)t.sendToEngine(epn, teamCount, scheme.health);
- }
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mode.name());
- dest.writeParcelable(map, flags);
- dest.writeString(theme);
- dest.writeParcelable(scheme, flags);
- dest.writeParcelable(weapon, flags);
- dest.writeString(style);
- dest.writeString(training);
- dest.writeString(seed);
- dest.writeParcelableArray((Team[])teams.toArray(new Team[1]), 0);
- }
-
- private void readFromParcel(Parcel src){
- mode = GameMode.valueOf(src.readString());
- map = src.readParcelable(Map.class.getClassLoader());
- theme = src.readString();
- scheme = src.readParcelable(Scheme.class.getClassLoader());
- weapon = src.readParcelable(Weapon.class.getClassLoader());
- style = src.readString();
- training = src.readString();
- seed = src.readString();
- Parcelable[] parcelables = src.readParcelableArray(Team[].class.getClassLoader());
- for(Parcelable team : parcelables){
- teams.add((Team)team);
- }
-
- }
-
- public static final Parcelable.Creator<GameConfig> CREATOR = new Parcelable.Creator<GameConfig>() {
- public GameConfig createFromParcel(Parcel source) {
- return new GameConfig(source);
- }
- public GameConfig[] newArray(int size) {
- return new GameConfig[size];
- }
- };
-
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java
index 01bd1c4..75f9ebe 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/EngineProtocol/PascalExports.java
@@ -1,10 +1,12 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,12 +15,13 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.hedgewars.hedgeroid.EngineProtocol;
public class PascalExports {
+ public static Object engineMutex = new Object();
static{
System.loadLibrary("SDL");
@@ -28,13 +31,18 @@ public class PascalExports {
System.loadLibrary("SDL_mixer");
System.loadLibrary("SDL_ttf");
System.loadLibrary("lua5.1");
+ System.loadLibrary("physfs");
+ System.loadLibrary("physlayer");
System.loadLibrary("hwengine");
}
- public static native int HWversionInfoNetProto();
- public static native String HWversionInfoVersion();
- public static native int HWgetNumberOfWeapons();
public static native int HWgetMaxNumberOfTeams();
- public static native int HWgetMaxNumberOfHogs();
- public static native int HWterminate(boolean b);
+ private static native void HWGenLandPreview(int port);
+
+ public static void synchronizedGenLandPreview(int port) {
+ synchronized(engineMutex) {
+ HWGenLandPreview(port);
+ }
+ }
+
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java
new file mode 100644
index 0000000..42937d3
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/GameConnection.java
@@ -0,0 +1,222 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.net.ConnectException;
+
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.BytesCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.GameconnPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.IntCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrBoolCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.VoidCallback;
+import org.hedgewars.hedgeroid.frontlib.NativeSizeT;
+import org.hedgewars.hedgeroid.netplay.GameMessageListener;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.util.TickHandler;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.util.Log;
+
+import com.sun.jna.Pointer;
+
+/**
+ * This class handles both talking to the engine (IPC) for running a game, and
+ * coordinating with the netconn if it is a netgame, using the frontlib for the
+ * actual IPC networking communication.
+ *
+ * After creating the GameConnection object, it will communicate with the engine
+ * on its own thread. It shuts itself down as soon as the connection to the engine
+ * is lost.
+ */
+public final class GameConnection {
+ private static final Handler mainHandler = new Handler(Looper.getMainLooper());
+
+ public final int port;
+ private final HandlerThread thread;
+ private final Handler handler;
+ private TickHandler tickHandler;
+ private final Netplay netplay; // ==null if not a netgame
+ private GameconnPtr conn;
+
+ private GameConnection(GameconnPtr conn, Netplay netplay) {
+ this.conn = conn;
+ this.port = Flib.INSTANCE.flib_gameconn_getport(conn);
+ this.netplay = netplay;
+ this.thread = new HandlerThread("IPCThread");
+ thread.start();
+ this.handler = new Handler(thread.getLooper());
+ }
+
+ private void setupConnection() {
+ tickHandler = new TickHandler(thread.getLooper(), 50, tickCb);
+ tickHandler.start();
+
+ if(netplay != null) {
+ mainHandler.post(new Runnable() {
+ public void run() {
+ netplay.registerGameMessageListener(gameMessageListener);
+ }
+ });
+ Flib.INSTANCE.flib_gameconn_onChat(conn, chatCb, null);
+ Flib.INSTANCE.flib_gameconn_onEngineMessage(conn, engineMessageCb, null);
+ }
+ Flib.INSTANCE.flib_gameconn_onConnect(conn, connectCb, null);
+ Flib.INSTANCE.flib_gameconn_onDisconnect(conn, disconnectCb, null);
+ Flib.INSTANCE.flib_gameconn_onErrorMessage(conn, errorMessageCb, null);
+ }
+
+ /**
+ * Start a new IPC server to communicate with the engine.
+ * Performs networking operations, don't run on the UI thread.
+ * @throws ConnectException if we can't set up the IPC server
+ */
+ public static GameConnection forNetgame(final GameConfig config, Netplay netplay) throws ConnectException {
+ final String playerName = netplay.getPlayerName();
+ GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create(playerName, GameSetupPtr.createJavaOwned(config), true);
+ if(conn == null) {
+ throw new ConnectException();
+ }
+ GameConnection result = new GameConnection(conn, netplay);
+ result.setupConnection();
+ return result;
+ }
+
+ /**
+ * Start a new IPC server to communicate with the engine.
+ * Performs networking operations, don't run on the UI thread.
+ * @throws ConnectException if we can't set up the IPC server
+ */
+ public static GameConnection forLocalGame(final GameConfig config) throws ConnectException {
+ GameconnPtr conn = Flib.INSTANCE.flib_gameconn_create("Player", GameSetupPtr.createJavaOwned(config), false);
+ if(conn == null) {
+ throw new ConnectException();
+ }
+ GameConnection result = new GameConnection(conn, null);
+ result.setupConnection();
+ return result;
+ }
+
+ private final Runnable tickCb = new Runnable() {
+ public void run() {
+ Flib.INSTANCE.flib_gameconn_tick(conn);
+ }
+ };
+
+ // runs on the IPCThread
+ private void shutdown() {
+ tickHandler.stop();
+ thread.quit();
+ Flib.INSTANCE.flib_gameconn_destroy(conn);
+ conn = null;
+ if(netplay != null) {
+ mainHandler.post(new Runnable() {
+ public void run() {
+ netplay.unregisterGameMessageListener(gameMessageListener);
+ }
+ });
+ }
+ }
+
+ // runs on the IPCThread
+ private final StrBoolCallback chatCb = new StrBoolCallback() {
+ public void callback(Pointer context, String message, boolean teamChat) {
+ if(teamChat) {
+ netplay.sendTeamChat(message);
+ } else {
+ netplay.sendChat(message);
+ }
+ }
+ };
+
+ // runs on the IPCThread
+ private final VoidCallback connectCb = new VoidCallback() {
+ public void callback(Pointer context) {
+ Log.i("GameConnection", "Connected");
+ }
+ };
+
+ // runs on the IPCThread
+ private final IntCallback disconnectCb = new IntCallback() {
+ public void callback(Pointer context, int reason) {
+ if(netplay != null) {
+ netplay.sendRoundFinished(reason==Frontlib.GAME_END_FINISHED);
+ }
+ shutdown();
+ }
+ };
+
+ // runs on the IPCThread
+ private final BytesCallback engineMessageCb = new BytesCallback() {
+ public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) {
+ netplay.sendEngineMessage(buffer.deref(size.intValue()));
+ }
+ };
+
+ // runs on the IPCThread
+ private final StrCallback errorMessageCb = new StrCallback() {
+ public void callback(Pointer context, String message) {
+ Log.e("GameConnection", message);
+ }
+ };
+
+ // runs on any thread
+ private final GameMessageListener gameMessageListener = new GameMessageListener() {
+ public void onNetDisconnected() {
+ handler.post(new Runnable() {
+ public void run() {
+ Flib.INSTANCE.flib_gameconn_send_quit(conn);
+ }
+ });
+ }
+
+ public void onMessage(final int type, final String message) {
+ handler.post(new Runnable() {
+ public void run() {
+ Flib.INSTANCE.flib_gameconn_send_textmsg(conn, type, message);
+ }
+ });
+ }
+
+ public void onEngineMessage(final byte[] em) {
+ handler.post(new Runnable() {
+ public void run() {
+ ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(em);
+ Flib.INSTANCE.flib_gameconn_send_enginemsg(conn, ptr, NativeSizeT.valueOf(em.length));
+ }
+ });
+ }
+
+ public void onChatMessage(final String nick, final String message) {
+ handler.post(new Runnable() {
+ public void run() {
+ Flib.INSTANCE.flib_gameconn_send_chatmsg(conn, nick, message);
+ }
+ });
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java
new file mode 100644
index 0000000..9d1e2c7
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyActivity.java
@@ -0,0 +1,140 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.NetplayStateFragment.NetplayStateListener;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+import org.hedgewars.hedgeroid.util.TextInputDialog;
+import org.hedgewars.hedgeroid.util.TextInputDialog.TextInputDialogListener;
+import org.hedgewars.hedgeroid.util.UiUtils;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+
+/**
+ * Activity for the server lobby of a hedgewars server. Allows you to chat, join
+ * and create rooms and interact with a list of players.
+ *
+ * Most of the functionality is handled by various fragments.
+ */
+public class LobbyActivity extends FragmentActivity implements TextInputDialogListener, NetplayStateListener {
+ private static final int DIALOG_CREATE_ROOM = 0;
+
+ private TabHost tabHost;
+ private Netplay netplay;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.activity_lobby);
+ ChatFragment chatFragment = (ChatFragment)getSupportFragmentManager().findFragmentById(R.id.chatFragment);
+ chatFragment.setInRoom(false);
+
+ FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
+ trans.add(new NetplayStateFragment(), "netplayFragment");
+ trans.commit();
+
+ netplay = Netplay.getAppInstance(getApplicationContext());
+
+ // Set up a tabbed UI for medium and small screens
+ tabHost = (TabHost)findViewById(android.R.id.tabhost);
+ if(tabHost != null) {
+ tabHost.setup();
+ tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL);
+
+ tabHost.addTab(tabHost.newTabSpec("rooms").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_rooms, R.drawable.roomlist_ingame)).setContent(R.id.roomListFragment));
+ tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_chat, R.drawable.edit)).setContent(R.id.chatFragment));
+ tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.lobby_tab_players, R.drawable.human)).setContent(R.id.playerListFragment));
+
+ if (icicle != null) {
+ tabHost.setCurrentTabByTag(icicle.getString("currentTab"));
+ }
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.lobby_options, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.room_create:
+ TextInputDialog dialog = new TextInputDialog(DIALOG_CREATE_ROOM, R.string.dialog_create_room_title, 0, R.string.dialog_create_room_hint);
+ dialog.show(getSupportFragmentManager(), "create_room_dialog");
+ return true;
+ case R.id.disconnect:
+ netplay.disconnect();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ netplay.disconnect();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ if(tabHost != null) {
+ icicle.putString("currentTab", tabHost.getCurrentTabTag());
+ }
+ }
+
+ public void onTextInputDialogSubmitted(int dialogId, String text) {
+ if(text != null && text.length()>0) {
+ netplay.sendCreateRoom(text);
+ }
+ }
+
+ public void onTextInputDialogCancelled(int dialogId) {
+ }
+
+ public void onNetplayStateChanged(State newState) {
+ switch(newState) {
+ case CONNECTING:
+ case NOT_CONNECTED:
+ finish();
+ break;
+ case ROOM:
+ startActivity(new Intent(getApplicationContext(), NetRoomActivity.class));
+ break;
+ case LOBBY:
+ // Do nothing
+ break;
+ default:
+ throw new IllegalStateException("Unknown connection state: "+newState);
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java
new file mode 100644
index 0000000..c707c2c
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistAdapter.java
@@ -0,0 +1,68 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.Comparator;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.Player;
+import org.hedgewars.hedgeroid.util.ObservableTreeMapAdapter;
+
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.StyleSpan;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Simple adapter for displaying the list of players in the lobby.
+ */
+public class LobbyPlayerlistAdapter extends ObservableTreeMapAdapter<String, Player> {
+ @Override
+ protected Comparator<Player> getEntryOrder() {
+ return Player.ADMIN_NAME_ORDER;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = LayoutInflater.from(parent.getContext());
+ v = vi.inflate(R.layout.listview_player, null);
+ }
+
+ Player player = getItem(position);
+ TextView username = (TextView) v.findViewById(android.R.id.text1);
+ Spannable spannable = new SpannableString(player.name);
+ if(player.registered) {
+ spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ if(player.admin) {
+ spannable.setSpan(new ForegroundColorSpan(Color.YELLOW), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ username.setText(spannable);
+ return v;
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java
new file mode 100644
index 0000000..011ac61
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LobbyPlayerlistFragment.java
@@ -0,0 +1,98 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.Player;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+/**
+ * Shows the list of players in the lobby and allows some interactions with them
+ * over the context menu.
+ */
+public class LobbyPlayerlistFragment extends ListFragment {
+ private Netplay netplay;
+ private LobbyPlayerlistAdapter adapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ netplay = Netplay.getAppInstance(getActivity().getApplicationContext());
+ adapter = new LobbyPlayerlistAdapter();
+ adapter.setSource(netplay.lobbyPlayerlist);
+ setListAdapter(adapter);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ adapter.invalidate();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ registerForContextMenu(getListView());
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
+ MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.lobby_playerlist_context, menu);
+ menu.setHeaderIcon(R.drawable.human);
+ menu.setHeaderTitle(adapter.getItem(info.position).name);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
+ Player player = adapter.getItem(info.position);
+ switch(item.getItemId()) {
+ case R.id.player_info:
+ netplay.sendPlayerInfoQuery(player.name);
+ return true;
+ case R.id.player_follow:
+ netplay.sendFollowPlayer(player.name);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_playerlist, container, false);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java
new file mode 100644
index 0000000..feb169c
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomActivity.java
@@ -0,0 +1,121 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.util.UiUtils;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+import android.widget.Toast;
+
+/**
+ * This activity is used to set up and start a local game.
+ */
+public class LocalRoomActivity extends FragmentActivity implements RoomStateManager.Provider, TeamAddDialog.Listener {
+ private TabHost tabHost;
+ private RoomStateManager stateManager;
+ private Button startButton;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // TODO find a better central location / way to set up the default scheme and weaponset
+ Netplay netplay = Netplay.getAppInstance(getApplicationContext());
+ stateManager = new LocalRoomStateManager(netplay.defaultScheme, netplay.defaultWeaponset);
+
+ setContentView(R.layout.activity_localroom);
+ startButton = (Button)findViewById(R.id.startGame);
+
+ startButton.setOnClickListener(startButtonClickListener);
+
+ // Set up a tabbed UI for medium and small screens
+ tabHost = (TabHost)findViewById(android.R.id.tabhost);
+ if(tabHost != null) {
+ tabHost.setup();
+ tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL);
+
+ tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment));
+ tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment));
+ tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistContainer));
+
+ if (icicle != null) {
+ tabHost.setCurrentTabByTag(icicle.getString("currentTab"));
+ }
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ if(tabHost != null) {
+ icicle.putString("currentTab", tabHost.getCurrentTabTag());
+ }
+ }
+
+ public void onTeamAddDialogSubmitted(Team newTeam) {
+ stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values()));
+ }
+
+ public RoomStateManager getRoomStateManager() {
+ return stateManager;
+ }
+
+ private final OnClickListener startButtonClickListener = new OnClickListener() {
+ public void onClick(View v) {
+ Map<String, TeamInGame> teams = stateManager.getTeams();
+ Set<Integer> clanColors = new TreeSet<Integer>();
+ for(TeamInGame t : teams.values()) {
+ clanColors.add(t.ingameAttribs.colorIndex);
+ }
+ if(clanColors.size()<2) {
+ if(tabHost != null) {
+ tabHost.setCurrentTabByTag("teams");
+ }
+ int errortext = teams.size()<2 ? R.string.not_enough_teams : R.string.not_enough_clans;
+ Toast.makeText(getApplicationContext(), errortext, Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ SDLActivity.startNetgame = false;
+ SDLActivity.startConfig = new GameConfig(
+ stateManager.getGameStyle(),
+ stateManager.getScheme(),
+ stateManager.getMapRecipe(),
+ new ArrayList<TeamInGame>(stateManager.getTeams().values()),
+ stateManager.getWeaponset());
+ startActivity(new Intent(LocalRoomActivity.this, SDLActivity.class));
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java
new file mode 100644
index 0000000..f2a0323
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/LocalRoomStateManager.java
@@ -0,0 +1,114 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+
+import android.util.Log;
+
+/**
+ * This RoomStateManager is responsible for keeping/changing the roomstate in local play.
+ * That is very straightforward, just react to every request by immediately changing the
+ * state.
+ */
+public class LocalRoomStateManager extends BasicRoomState {
+ private static final String TAG = LocalRoomStateManager.class.getSimpleName();
+
+ public LocalRoomStateManager(Scheme defaultScheme, Weaponset defaultWeaponset) {
+ setChief(true);
+ setGameStyle(GameConfig.DEFAULT_STYLE);
+ setMapRecipe(MapRecipe.makeRandomMap(0, MapRecipe.makeRandomSeed(), GameConfig.DEFAULT_THEME));
+ setScheme(defaultScheme);
+ setWeaponset(defaultWeaponset);
+ }
+
+ public void changeMapRecipe(MapRecipe map) {
+ setMapRecipe(map);
+ }
+
+ public void changeMapTheme(String theme) {
+ setMapRecipe(getMapRecipe().withTheme(theme));
+ }
+
+ public void changeMapNameAndGenerator(String mapName) {
+ int newGenerator = MapRecipe.generatorForMapname(mapName);
+ setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator));
+ }
+
+ public void changeMapTemplate(int template) {
+ setMapRecipe(getMapRecipe().withTemplateFilter(template));
+ }
+
+ public void changeMazeSize(int mazeSize) {
+ setMapRecipe(getMapRecipe().withMazeSize(mazeSize));
+ }
+
+ public void changeMapSeed(String seed) {
+ setMapRecipe(getMapRecipe().withSeed(seed));
+ }
+
+ public void changeMapDrawdata(byte[] drawdata) {
+ setMapRecipe(getMapRecipe().withDrawData(drawdata));
+ }
+
+ public void changeScheme(Scheme scheme) {
+ setScheme(scheme);
+ }
+
+ public void changeGameStyle(String style) {
+ setGameStyle(style);
+ }
+
+ public void changeWeaponset(Weaponset weaponset) {
+ setWeaponset(weaponset);
+ }
+
+ public void requestAddTeam(Team team, int colorIndex) {
+ putTeam(new TeamInGame(team, new TeamIngameAttributes("Player", colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false)));
+ }
+
+ public void requestRemoveTeam(String teamname) {
+ removeTeam(teamname);
+ }
+
+ public void changeTeamColorIndex(String teamname, int colorIndex) {
+ TeamInGame oldTeam = getTeams().get(teamname);
+ if(oldTeam != null) {
+ putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withColorIndex(colorIndex)));
+ } else {
+ Log.e(TAG, "Requested color change for unknown team "+ teamname);
+ }
+ }
+
+ public void changeTeamHogCount(String teamname, int hogcount) {
+ TeamInGame oldTeam = getTeams().get(teamname);
+ if(oldTeam != null) {
+ putTeam(oldTeam.withAttribs(oldTeam.ingameAttribs.withHogCount(hogcount)));
+ } else {
+ Log.e(TAG, "Requested hog count change for unknown team "+ teamname);
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java
index 2ad1c6f..d659985 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MainActivity.java
@@ -1,10 +1,12 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,66 +15,137 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
import org.hedgewars.hedgeroid.Downloader.DownloadAssets;
import org.hedgewars.hedgeroid.Downloader.DownloadListActivity;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+import org.hedgewars.hedgeroid.util.FileUtils;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.IntentFilter;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.content.LocalBroadcastManager;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends FragmentActivity {
-
- private Button downloader, startGame;
+ private static final int DIALOG_NO_SDCARD = 0;
+
+ private LocalBroadcastManager broadcastManager;
private ProgressDialog assetsDialog;
public void onCreate(Bundle sis){
super.onCreate(sis);
- setContentView(R.layout.main);
+ setContentView(R.layout.activity_main);
- downloader = (Button)findViewById(R.id.downloader);
- startGame = (Button)findViewById(R.id.startGame);
+ broadcastManager = LocalBroadcastManager.getInstance(getApplicationContext());
+ Button startLocalGame = (Button)findViewById(R.id.startGame);
+ Button startNetGame = (Button)findViewById(R.id.joinLobby);
- downloader.setOnClickListener(downloadClicker);
- startGame.setOnClickListener(startGameClicker);
+ startLocalGame.setOnClickListener(startGameListener);
+ startNetGame.setOnClickListener(startNetGameListener);
-
- String cacheDir = Utils.getCachePath(this);
- if(cacheDir == null){
- showDialog(0);
- }else{
- int versionCode = 0;
+ if(!FileUtils.isDataPathAvailable()){
+ showDialog(DIALOG_NO_SDCARD);
+ } else {
+ String existingVersion = "";
try {
- versionCode = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionCode;
- } catch (NameNotFoundException e) {
-
+ File versionFile = new File(FileUtils.getCachePath(this), "assetsversion.txt");
+ existingVersion = FileUtils.readToString(new FileInputStream(versionFile));
+ } catch(IOException e) {
}
- boolean assetsCopied = PreferenceManager.getDefaultSharedPreferences(this).getInt("latestAssets", 0) >= versionCode;
-
- if(!assetsCopied){
+
+ String newVersion = "";
+ try {
+ newVersion = FileUtils.readToString(getAssets().open("assetsversion.txt"));
+ } catch(IOException e) {
+ }
+
+ if(!existingVersion.equals(newVersion)) {
DownloadAssets assetsAsyncTask = new DownloadAssets(this);
- assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets...");
- assetsAsyncTask.execute((Object[])null);
+ assetsDialog = ProgressDialog.show(this, "Please wait a moment", "Moving assets to SD card...");
+ assetsAsyncTask.execute();
}
}
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ broadcastManager.registerReceiver(connectedReceiver, new IntentFilter(Netplay.ACTION_CONNECTED));
+ broadcastManager.registerReceiver(connectionFailedReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED));
+ broadcastManager.registerReceiver(passwordRequestedReceiver, new IntentFilter(Netplay.ACTION_PASSWORD_REQUESTED));
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ broadcastManager.unregisterReceiver(connectedReceiver);
+ broadcastManager.unregisterReceiver(connectionFailedReceiver);
+ broadcastManager.unregisterReceiver(passwordRequestedReceiver);
+ Netplay netplay = Netplay.getAppInstance(getApplicationContext());
+ if(netplay.getState() == State.CONNECTING) {
+ netplay.disconnect();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.main_options, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.download:
+ startActivityForResult(new Intent(this, DownloadListActivity.class), 0);
+ return true;
+ case R.id.preferences:
+ Toast.makeText(this, R.string.not_implemented_yet, Toast.LENGTH_SHORT).show();
+ return true;
+ case R.id.edit_weaponsets:
+ startActivity(new Intent(this, WeaponsetListActivity.class));
+ return true;
+ case R.id.edit_teams:
+ startActivity(new Intent(this, TeamListActivity.class));
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
public Dialog onCreateDialog(int id, Bundle args){
+ switch(id) {
+ case DIALOG_NO_SDCARD:
+ return createNoSdcardDialog();
+ default:
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ private Dialog createNoSdcardDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.sdcard_not_mounted_title);
builder.setMessage(R.string.sdcard_not_mounted);
@@ -84,30 +157,67 @@ public class MainActivity extends FragmentActivity {
return builder.create();
}
-
+
public void onAssetsDownloaded(boolean result){
- if(result){
- try {
- int versionCode = this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionCode;
- PreferenceManager.getDefaultSharedPreferences(this).edit().putInt("latestAssets", versionCode).commit();
- } catch (NameNotFoundException e) {}
-
- }else{
- Toast.makeText(this, R.string.download_failed, Toast.LENGTH_LONG);
+ if(!result){
+ Toast.makeText(this, R.string.download_failed, Toast.LENGTH_LONG).show();
}
assetsDialog.dismiss();
}
- private OnClickListener downloadClicker = new OnClickListener(){
+ private final OnClickListener startGameListener = new OnClickListener(){
public void onClick(View v){
- //startActivityForResult(new Intent(getApplicationContext(), DownloadActivity.class), 0);
- startActivityForResult(new Intent(getApplicationContext(), DownloadListActivity.class), 0);
+ startActivity(new Intent(getApplicationContext(), LocalRoomActivity.class));
}
};
-
- private OnClickListener startGameClicker = new OnClickListener(){
- public void onClick(View v){
- startActivity(new Intent(getApplicationContext(), StartGameActivity.class));
+
+ private final OnClickListener startNetGameListener = new OnClickListener() {
+ public void onClick(View v) {
+ State state = Netplay.getAppInstance(getApplicationContext()).getState();
+ switch(state) {
+ case NOT_CONNECTED:
+ FragmentManager fm = getSupportFragmentManager();
+ StartNetgameDialog startNetgameDialog = new StartNetgameDialog();
+ startNetgameDialog.show(fm, "start_netgame_dialog");
+ break;
+ case CONNECTING:
+ onNetConnectingStarted();
+ break;
+ default:
+ startActivity(new Intent(getApplicationContext(), LobbyActivity.class));
+ break;
+ }
}
};
+
+ private BroadcastReceiver connectedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ startActivity(new Intent(getApplicationContext(), LobbyActivity.class));
+ }
+ };
+
+ private BroadcastReceiver connectionFailedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) {
+ Toast.makeText(getApplicationContext(), intent.getStringExtra(Netplay.EXTRA_MESSAGE), Toast.LENGTH_LONG).show();
+ }
+ }
+ };
+
+ private BroadcastReceiver passwordRequestedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ FragmentManager fm = getSupportFragmentManager();
+ PasswordDialog passwordDialog = new PasswordDialog(intent.getStringExtra(Netplay.EXTRA_PLAYERNAME));
+ passwordDialog.show(fm, "fragment_password_dialog");
+ }
+ };
+
+ public void onNetConnectingStarted() {
+ FragmentManager fm = getSupportFragmentManager();
+ ConnectingDialog connectingDialog = new ConnectingDialog();
+ connectingDialog.show(fm, "fragment_connecting_dialog");
+ }
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java
new file mode 100644
index 0000000..1b5a36d
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapFragment.java
@@ -0,0 +1,274 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.MapFile;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+import org.hedgewars.hedgeroid.util.CalmDownHandler;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.TableRow;
+import android.widget.Toast;
+
+/**
+ * Display a map preview, and configuration options for the map.
+ *
+ * Mostly for layout reasons, this does not include the theme setting, which
+ * (arguably) is more a map setting than a general game setting.
+ */
+public class MapFragment extends Fragment {
+ private Spinner mapTypeSpinner, mapNameSpinner, templateSpinner, mazeSizeSpinner;
+ private TableRow nameRow, templateRow, mazeSizeRow;
+ private ImageView mapPreview;
+
+ private List<MapFile> mapFiles;
+ private RoomStateManager stateManager;
+ private Random random = new Random();
+ private CalmDownHandler mapPreviewHandler;
+
+ /*
+ * Rendering the preview can take a few seconds on Android, so we want to prevent preview
+ * requests from queueing up if maps are changed quickly. So if there is already a preview
+ * being generated, we store our latest request in the newPreviewRequest variable instead.
+ * Once the current preview is finished generating it will start on that one.
+ */
+ private boolean previewGenerationInProgress;
+ private MapRecipe newPreviewRequest;
+ private MapRecipe currentMap; // kept for reference on every change to find out what changed
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.fragment_map, container, false);
+ final Context appContext = getActivity().getApplicationContext();
+
+ /*
+ * This handler will start the map preview after none of the map settings
+ * have been updated for a short time.
+ */
+ mapPreviewHandler = new CalmDownHandler(getActivity().getMainLooper(), new Runnable() {
+ public void run() {
+ if(!previewGenerationInProgress) {
+ mapPreview.setImageResource(R.drawable.roomlist_preparing);
+ MapPreviewGenerator.startPreviewGeneration(appContext, stateManager.getMapRecipe(), mapPreviewListener);
+ previewGenerationInProgress = true;
+ } else {
+ newPreviewRequest = stateManager.getMapRecipe();
+ }
+ }
+ }, 250);
+
+ nameRow = (TableRow) v.findViewById(R.id.rowMapName);
+ templateRow = (TableRow) v.findViewById(R.id.rowTemplateFilter);
+ mazeSizeRow = (TableRow) v.findViewById(R.id.rowMazeSize);
+ mapPreview = (ImageView) v.findViewById(R.id.mapPreview);
+ mapPreview.setImageDrawable(null);;
+ mapPreview.setOnClickListener(mapClickListener);
+
+ try {
+ mapFiles = FrontendDataUtils.getMaps(getActivity());
+ } catch (IOException e) {
+ Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show();
+ getActivity().finish();
+ return null;
+ }
+ Collections.sort(mapFiles, MapFile.MISSIONS_FIRST_NAME_ORDER);
+
+ List<String> mapNames = MapFile.toDisplayNameList(mapFiles, getResources());
+ mapTypeSpinner = prepareSpinner(v, R.id.spinMapType, Arrays.asList(getResources().getStringArray(R.array.map_types)), mapTypeSelectedListener);
+ mapNameSpinner = prepareSpinner(v, R.id.spinMapName, mapNames, mapNameSelectedListener);
+ templateSpinner = prepareSpinner(v, R.id.spinTemplateFilter, Arrays.asList(getResources().getStringArray(R.array.map_templates)), mapTemplateSelectedListener);
+ mazeSizeSpinner = prepareSpinner(v, R.id.spinMazeSize, Arrays.asList(getResources().getStringArray(R.array.map_maze_sizes)), mazeSizeSelectedListener);
+
+ stateManager.addListener(roomStateChangeListener);
+ currentMap = stateManager.getMapRecipe();
+ if(currentMap != null) {
+ updateDisplay(currentMap);
+ }
+ setChiefState(stateManager.getChiefStatus());
+ mapPreviewHandler.activity();
+ return v;
+ }
+
+ private static Spinner prepareSpinner(View v, int id, List<String> items, OnItemSelectedListener itemSelectedListener) {
+ Spinner spinner = (Spinner)v.findViewById(id);
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(v.getContext(), R.layout.listview_item, items);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ spinner.setOnItemSelectedListener(itemSelectedListener);
+ return spinner;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ try {
+ stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager();
+ } catch(ClassCastException e) {
+ throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapPreviewHandler.stop();
+ newPreviewRequest = null;
+
+ stateManager.removeListener(roomStateChangeListener);
+ }
+
+ private void setChiefState(boolean chiefState) {
+ mapTypeSpinner.setEnabled(chiefState);
+ mapNameSpinner.setEnabled(chiefState);
+ templateSpinner.setEnabled(chiefState);
+ mazeSizeSpinner.setEnabled(chiefState);
+ mapPreview.setEnabled(chiefState);
+
+ if(chiefState) {
+ sendMapnameAndGenerator();
+ stateManager.changeMapTemplate(templateSpinner.getSelectedItemPosition());
+ stateManager.changeMazeSize(mazeSizeSpinner.getSelectedItemPosition());
+ }
+ }
+
+ private void updateDisplay(MapRecipe map) {
+ nameRow.setVisibility(map.mapgen == Frontlib.MAPGEN_NAMED ? View.VISIBLE : View.GONE);
+ templateRow.setVisibility(map.mapgen == Frontlib.MAPGEN_REGULAR ? View.VISIBLE : View.GONE);
+ mazeSizeRow.setVisibility(map.mapgen == Frontlib.MAPGEN_MAZE ? View.VISIBLE : View.GONE);
+
+ mapTypeSpinner.setSelection(map.mapgen);
+ int mapPosition = findMapPosition(mapFiles, map.name);
+ if(mapPosition >= 0) {
+ mapNameSpinner.setSelection(mapPosition);
+ }
+ templateSpinner.setSelection(map.templateFilter);
+ mazeSizeSpinner.setSelection(map.mazeSize);
+ }
+
+ private static int findMapPosition(List<MapFile> mapFiles, String mapName) {
+ for(int i=0; i<mapFiles.size(); i++) {
+ if(mapName.equals(mapFiles.get(i).name)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void sendMapnameAndGenerator() {
+ int mapType = mapTypeSpinner.getSelectedItemPosition();
+ String mapName = mapFiles.get(mapNameSpinner.getSelectedItemPosition()).name;
+ stateManager.changeMapNameAndGenerator(MapRecipe.mapnameForGenerator(mapType, mapName));
+ }
+
+ private final OnItemSelectedListener mapTypeSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ sendMapnameAndGenerator();
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener mapNameSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ sendMapnameAndGenerator();
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener mapTemplateSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeMapTemplate(position);
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener mazeSizeSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeMazeSize(position);
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnClickListener mapClickListener = new OnClickListener() {
+ public void onClick(View v) {
+ stateManager.changeMapSeed(MapRecipe.makeRandomSeed());
+ if(mapTypeSpinner.getSelectedItemPosition() == Frontlib.MAPGEN_NAMED) {
+ mapNameSpinner.setSelection(random.nextInt(mapNameSpinner.getCount()));
+ }
+ }
+ };
+
+ private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() {
+ @Override
+ public void onChiefStatusChanged(boolean isChief) {
+ setChiefState(isChief);
+ };
+
+ @Override
+ public void onMapChanged(MapRecipe recipe) {
+ // Only trigger a preview update if a relevant field changed (not theme)
+ if(currentMap==null
+ || currentMap.mapgen != recipe.mapgen
+ || currentMap.mazeSize != recipe.mazeSize
+ || !currentMap.name.equals(recipe.name)
+ || !currentMap.seed.equals(recipe.seed)
+ || currentMap.templateFilter != recipe.templateFilter
+ || !Arrays.equals(currentMap.getDrawData(), recipe.getDrawData())) {
+ mapPreviewHandler.activity();
+ }
+ updateDisplay(recipe);
+ currentMap = recipe;
+ };
+ };
+
+ private MapPreviewGenerator.Listener mapPreviewListener = new MapPreviewGenerator.Listener() {
+ public void onMapPreviewResult(Drawable preview) {
+ if(newPreviewRequest != null) {
+ MapPreviewGenerator.startPreviewGeneration(getActivity().getApplicationContext(), newPreviewRequest, mapPreviewListener);
+ newPreviewRequest = null;
+ } else {
+ if(mapPreview != null) {
+ mapPreview.setImageDrawable(preview);
+ }
+ previewGenerationInProgress = false;
+ }
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java
new file mode 100644
index 0000000..0d14dd1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/MapPreviewGenerator.java
@@ -0,0 +1,223 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import org.hedgewars.hedgeroid.Datastructures.MapFile;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.MapRecipePtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.MapconnPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.MapimageCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrCallback;
+import org.hedgewars.hedgeroid.util.FileUtils;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import com.sun.jna.Pointer;
+
+/**
+ * A class that asynchronously generates a map preview from a MapRecipe.
+ *
+ * For named maps, this will load the preview image from the filesystem. For others,
+ * it will call the Hedgewars engine to generate a preview image. The result is sent
+ * back to a listener on the UI thread.
+ */
+public final class MapPreviewGenerator implements Runnable {
+ private static final String TAG = MapPreviewGenerator.class.getSimpleName();
+ private static final Handler mainHandler = new Handler(Looper.getMainLooper());
+ private static final long TIMEOUT_NS = 20l * 1000 * 1000 * 1000;
+
+ private final Context appContext;
+ private final MapRecipe map;
+ private final Listener listener;
+
+ private boolean resultAvailable;
+ private Drawable result;
+
+ public static interface Listener {
+ /**
+ * This is called on the UI thread once the preview is ready or failed.
+ * In case of failure, null is passed.
+ */
+ void onMapPreviewResult(Drawable preview);
+ }
+
+ private MapPreviewGenerator(Context appContext, MapRecipe map, Listener listener) {
+ this.appContext = appContext;
+ this.map = map;
+ this.listener = listener;
+ }
+
+ public void run() {
+ if (map.mapgen == Frontlib.MAPGEN_NAMED) {
+ postToListener(loadPreviewFromFile(appContext, map.name));
+ } else {
+ resultAvailable = false;
+ result = null;
+ MapconnPtr conn = Flib.INSTANCE.flib_mapconn_create(MapRecipePtr.createJavaOwned(map));
+ if (conn == null) {
+ postToListener(null);
+ return;
+ }
+ try {
+ int port = Flib.INSTANCE.flib_mapconn_getport(conn);
+ Flib.INSTANCE.flib_mapconn_onSuccess(conn, successCb, null);
+ Flib.INSTANCE.flib_mapconn_onFailure(conn, failureCb, null);
+
+ String configPath;
+ try {
+ configPath = FileUtils.getCachePath(appContext).getAbsolutePath();
+ } catch(FileNotFoundException e) {
+ return;
+ }
+
+ startEngine(configPath, port);
+ long startTime = System.nanoTime();
+ do {
+ Flib.INSTANCE.flib_mapconn_tick(conn);
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ if(System.nanoTime()-startTime > TIMEOUT_NS) {
+ Log.w(TAG, "Error generating map preview: timeout");
+ resultAvailable = true;
+ }
+ } while(!resultAvailable);
+ } finally {
+ Flib.INSTANCE.flib_mapconn_destroy(conn);
+ postToListener(result);
+ }
+ }
+ }
+
+ public static void startPreviewGeneration(Context appContext, MapRecipe map, Listener listener) {
+ new Thread(new MapPreviewGenerator(appContext, map, listener)).start();
+ }
+
+ private static Drawable loadPreviewFromFile(Context appContext, String mapName) {
+ if(!mapName.startsWith("+")) {
+ try {
+ File previewFile = MapFile.getPreviewFile(appContext, mapName);
+ return Drawable.createFromPath(previewFile.getAbsolutePath());
+ } catch (FileNotFoundException e) {
+ Log.w("MapPreviewGenerator", "Preview for map "+mapName+" not found.");
+ }
+ }
+ return null;
+ }
+
+ private static void startEngine(final String configPath, final int port) {
+ new Thread(new Runnable() {
+ public void run() {
+ Log.d(TAG, "Starting engine "+port);
+ PascalExports.synchronizedGenLandPreview(port);
+ Log.d(TAG, "Engine finished");
+ }
+ }).start();
+ }
+
+ private void postToListener(final Drawable result) {
+ mainHandler.post(new Runnable() {
+ public void run() {
+ listener.onMapPreviewResult(result);
+ }
+ });
+ }
+
+ /**
+ * Let's be extra nice here and clip off the left and right sides, so the preview is centered...
+ * Since the image is present in bytes, we can save some effort by checking entire byte-columns first.
+ */
+ private final MapimageCallback successCb = new MapimageCallback() {
+ public void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount) {
+ byte[] mapdata = buffer.deref(Frontlib.MAPIMAGE_BYTES);
+
+ int leftmostPixel = Frontlib.MAPIMAGE_WIDTH;
+ int rightmostPixel = -1;
+ int bytesPerLine = Frontlib.MAPIMAGE_WIDTH/8;
+
+ // Find the leftmost pixel
+ for(int xbyte=0; xbyte<bytesPerLine; xbyte++) {
+ for(int y=0; y<Frontlib.MAPIMAGE_HEIGHT; y++) {
+ int b = 0xff&mapdata[xbyte+y*bytesPerLine];
+ if(b != 0) {
+ leftmostPixel = Math.min(leftmostPixel, Integer.numberOfLeadingZeros(b)-24+xbyte*8);
+ }
+ }
+ if(leftmostPixel!=Frontlib.MAPIMAGE_WIDTH) break;
+ }
+
+ // Find the rightmost pixel
+ for(int xbyte=bytesPerLine-1; xbyte>=0; xbyte--) {
+ for(int y=0; y<Frontlib.MAPIMAGE_HEIGHT; y++) {
+ int b = mapdata[xbyte+y*bytesPerLine];
+ if(b != 0) {
+ rightmostPixel = Math.max(rightmostPixel, xbyte*8+7-Integer.numberOfTrailingZeros(b));
+ }
+ }
+ if(rightmostPixel!=-1) break;
+ }
+
+ // No pixel was set at all -> use default width
+ if(rightmostPixel==-1) {
+ leftmostPixel = 0;
+ rightmostPixel = Frontlib.MAPIMAGE_WIDTH-1;
+ }
+
+ Bitmap bitmap = Bitmap.createBitmap(rightmostPixel-leftmostPixel+1, Frontlib.MAPIMAGE_HEIGHT, Config.ARGB_8888);
+ for(int y=0; y<Frontlib.MAPIMAGE_HEIGHT; y++) {
+ for(int x=0; x<bitmap.getWidth(); x++) {
+ bitmap.setPixel(x, y, isPixelSet(mapdata, x+leftmostPixel, y) ? Color.YELLOW : Color.TRANSPARENT);
+ }
+ }
+ result = new BitmapDrawable(bitmap);
+ resultAvailable = true;
+ }
+ };
+
+ private static boolean isPixelSet(byte[] imgdata, int x, int y) {
+ int pixelnum = x+Frontlib.MAPIMAGE_WIDTH*y;
+ return (imgdata[pixelnum>>3] & (128>>(pixelnum&7))) != 0;
+ }
+
+ private final StrCallback failureCb = new StrCallback() {
+ public void callback(Pointer context, String reason) {
+ Log.w(TAG, "Error generating map preview: "+reason);
+ result = null;
+ resultAvailable = true;
+ }
+ };
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java
new file mode 100644
index 0000000..64178f0
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetRoomActivity.java
@@ -0,0 +1,151 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.NetplayStateFragment.NetplayStateListener;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.RunGameListener;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+import org.hedgewars.hedgeroid.util.UiUtils;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+
+/**
+ * This activity is used to set up and start a game on the server.
+ */
+public class NetRoomActivity extends FragmentActivity implements NetplayStateListener, TeamAddDialog.Listener, RoomStateManager.Provider, RunGameListener {
+ private TabHost tabHost;
+ private Netplay netplay;
+ private RoomStateManager stateManager;
+ private Button startButton;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ netplay = Netplay.getAppInstance(getApplicationContext());
+ netplay.registerRunGameListener(this);
+ stateManager = netplay.getRoomStateManager();
+ stateManager.addListener(roomStateChangeListener);
+
+ setContentView(R.layout.activity_netroom);
+ startButton = (Button)findViewById(R.id.startGame);
+
+ ChatFragment chatFragment = (ChatFragment)getSupportFragmentManager().findFragmentById(R.id.chatFragment);
+ chatFragment.setInRoom(true);
+
+ FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
+ trans.add(new NetplayStateFragment(), "netplayFragment");
+ trans.commit();
+
+ startButton.setVisibility(netplay.isChief() ? View.VISIBLE : View.GONE);
+ startButton.setOnClickListener(startButtonClickListener);
+
+ // Set up a tabbed UI for medium and small screens
+ tabHost = (TabHost)findViewById(android.R.id.tabhost);
+ if(tabHost != null) {
+ tabHost.setup();
+ tabHost.getTabWidget().setOrientation(LinearLayout.VERTICAL);
+
+ tabHost.addTab(tabHost.newTabSpec("map").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_map, 0)).setContent(R.id.mapFragment));
+ tabHost.addTab(tabHost.newTabSpec("settings").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_settings, 0)).setContent(R.id.settingsFragment));
+ tabHost.addTab(tabHost.newTabSpec("teams").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_teams, 0)).setContent(R.id.teamlistFragment));
+ tabHost.addTab(tabHost.newTabSpec("chat").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_chat, 0)).setContent(R.id.chatFragment));
+ tabHost.addTab(tabHost.newTabSpec("players").setIndicator(UiUtils.createVerticalTabIndicator(tabHost, R.string.room_tab_players, 0)).setContent(R.id.playerListContainer));
+
+ if (icicle != null) {
+ tabHost.setCurrentTabByTag(icicle.getString("currentTab"));
+ }
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ stateManager.removeListener(roomStateChangeListener);
+ netplay.unregisterRunGameListener(this);
+ }
+
+ @Override
+ public void onBackPressed() {
+ netplay.sendLeaveRoom(null);
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ if(tabHost != null) {
+ icicle.putString("currentTab", tabHost.getCurrentTabTag());
+ }
+ }
+
+ public void onNetplayStateChanged(State newState) {
+ switch(newState) {
+ case NOT_CONNECTED:
+ case CONNECTING:
+ case LOBBY:
+ finish();
+ break;
+ case ROOM:
+ // Do nothing
+ break;
+ default:
+ throw new IllegalStateException("Unknown connection state: "+newState);
+ }
+ }
+
+ public void onTeamAddDialogSubmitted(Team newTeam) {
+ stateManager.requestAddTeam(newTeam, TeamInGame.getUnusedOrRandomColorIndex(stateManager.getTeams().values()));
+ }
+
+ public RoomStateManager getRoomStateManager() {
+ return stateManager;
+ }
+
+ private final OnClickListener startButtonClickListener = new OnClickListener() {
+ public void onClick(View v) {
+ netplay.sendStartGame();
+ }
+ };
+
+ private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() {
+ @Override
+ public void onChiefStatusChanged(boolean isChief) {
+ startButton.setVisibility(isChief ? View.VISIBLE : View.GONE);
+ }
+ };
+
+ public void runGame(GameConfig config) {
+ SDLActivity.startConfig = config;
+ SDLActivity.startNetgame = true;
+ startActivity(new Intent(this, SDLActivity.class));
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java
new file mode 100644
index 0000000..f71523f
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/NetplayStateFragment.java
@@ -0,0 +1,137 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.netplay.Netplay.State;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.content.LocalBroadcastManager;
+import android.widget.Toast;
+
+/**
+ * Fragment for use by an activity that depends on the state of the network
+ * connection. The activity must implement the NetplayStateListener interface.
+ *
+ * This fragment manages reacting to changes in the networking state by calling
+ * a callback method on the activity.
+ */
+public class NetplayStateFragment extends Fragment {
+ private Netplay netplay;
+ private Context appContext;
+ private LocalBroadcastManager broadcastManager;
+ private NetplayStateListener listener;
+ private State knownState;
+
+ interface NetplayStateListener {
+ /**
+ * This is called while the activity is running, and every time during resume, if
+ * a change in the networking state is detected. It is also called once
+ * with the initial state (which could be called a change from the "unknown" state).
+ */
+ void onNetplayStateChanged(State newState);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ listener = (NetplayStateListener) activity;
+ } catch(ClassCastException e) {
+ throw new ClassCastException("Activity " + activity + " must implement NetplayStateListener to use NetplayStateFragment.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ listener = null;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ appContext = getActivity().getApplicationContext();
+ broadcastManager = LocalBroadcastManager.getInstance(appContext);
+ netplay = Netplay.getAppInstance(appContext);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ broadcastManager.registerReceiver(disconnectReceiver, new IntentFilter(Netplay.ACTION_DISCONNECTED));
+ broadcastManager.registerReceiver(leaveRoomReceiver, new IntentFilter(Netplay.ACTION_LEFT_ROOM));
+ broadcastManager.registerReceiver(stateChangeReceiver, new IntentFilter(Netplay.ACTION_STATE_CHANGED));
+
+ State newState = netplay.getState();
+ if(knownState != newState) {
+ listener.onNetplayStateChanged(newState);
+ knownState = newState;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ broadcastManager.unregisterReceiver(disconnectReceiver);
+ broadcastManager.unregisterReceiver(leaveRoomReceiver);
+ broadcastManager.unregisterReceiver(stateChangeReceiver);
+ }
+
+ private final BroadcastReceiver disconnectReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(intent.getBooleanExtra(Netplay.EXTRA_HAS_ERROR, true)) {
+ String message = intent.getStringExtra(Netplay.EXTRA_MESSAGE);
+ String toastText = getString(R.string.toast_disconnected, message);
+ Toast.makeText(appContext, toastText, Toast.LENGTH_LONG).show();
+ }
+ }
+ };
+
+ private final BroadcastReceiver leaveRoomReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int reason = intent.getIntExtra(Netplay.EXTRA_REASON, -1);
+ if(reason == Frontlib.NETCONN_ROOMLEAVE_ABANDONED) {
+ Toast.makeText(appContext, R.string.toast_room_abandoned, Toast.LENGTH_LONG).show();
+ } else if(reason == Frontlib.NETCONN_ROOMLEAVE_KICKED) {
+ Toast.makeText(appContext, R.string.toast_kicked, Toast.LENGTH_LONG).show();
+ }
+ }
+ };
+
+ private final BroadcastReceiver stateChangeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ State newState = netplay.getState();
+ listener.onNetplayStateChanged(newState);
+ knownState = newState;
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java
new file mode 100644
index 0000000..56221f7
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/PasswordDialog.java
@@ -0,0 +1,82 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.text.InputType;
+import android.text.method.PasswordTransformationMethod;
+import android.widget.EditText;
+
+/**
+ * Shown when connecting to the server, and the server requests a password.
+ */
+public class PasswordDialog extends ConnectionDependendDialogFragment {
+ String username;
+
+ public PasswordDialog() {
+ }
+
+ public PasswordDialog(String username) {
+ this.username = username;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ icicle.putString("username", username);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ if(savedInstanceState != null) {
+ username = savedInstanceState.getString("username");
+ }
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ final EditText editText = new EditText(getActivity());
+ final Netplay netplay = Netplay.getAppInstance(getActivity().getApplicationContext());
+
+ editText.setHint(R.string.dialog_password_hint);
+ editText.setId(android.R.id.text1);
+ editText.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ editText.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ builder.setView(editText);
+ builder.setTitle(R.string.dialog_password_title);
+ builder.setMessage(getString(R.string.dialog_password_message, username));
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ String password = editText.getText().toString();
+ editText.setText("");
+ netplay.sendPassword(password);
+ }
+ });
+ return builder.create();
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+ Netplay.getAppInstance(getActivity().getApplicationContext()).disconnect();
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java
new file mode 100644
index 0000000..c6425d9
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistAdapter.java
@@ -0,0 +1,60 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.Comparator;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom;
+import org.hedgewars.hedgeroid.util.ObservableTreeMapAdapter;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class RoomPlayerlistAdapter extends ObservableTreeMapAdapter<String, PlayerInRoom> {
+ @Override
+ protected Comparator<PlayerInRoom> getEntryOrder() {
+ return AlphabeticalOrderComparator.INSTANCE;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = LayoutInflater.from(parent.getContext());
+ v = vi.inflate(R.layout.listview_player, null);
+ }
+
+ PlayerInRoom player = getItem(position);
+ TextView username = (TextView) v.findViewById(android.R.id.text1);
+ username.setText(player.player.name);
+ int readyDrawable = player.ready ? R.drawable.lightbulb_on : R.drawable.lightbulb_off;
+ username.setCompoundDrawablesWithIntrinsicBounds(readyDrawable, 0, 0, 0);
+ return v;
+ }
+
+ private static final class AlphabeticalOrderComparator implements Comparator<PlayerInRoom> {
+ public static final AlphabeticalOrderComparator INSTANCE = new AlphabeticalOrderComparator();
+ public int compare(PlayerInRoom lhs, PlayerInRoom rhs) {
+ return lhs.player.name.compareToIgnoreCase(rhs.player.name);
+ };
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java
new file mode 100644
index 0000000..f69d570
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomPlayerlistFragment.java
@@ -0,0 +1,110 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.Player;
+import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class RoomPlayerlistFragment extends ListFragment implements OnItemClickListener {
+ private Netplay netplay;
+ private RoomPlayerlistAdapter adapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ netplay = Netplay.getAppInstance(getActivity().getApplicationContext());
+ adapter = new RoomPlayerlistAdapter();
+ adapter.setSource(netplay.roomPlayerlist);
+ setListAdapter(adapter);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ adapter.invalidate();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ registerForContextMenu(getListView());
+ getListView().setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo;
+ String playerName = adapter.getItem(info.position).player.name;
+
+ MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.room_playerlist_context, menu);
+ if(netplay.isChief() && !playerName.equals(netplay.getPlayerName())) {
+ inflater.inflate(R.menu.room_playerlist_chief_context, menu);
+ }
+ menu.setHeaderIcon(R.drawable.human);
+ menu.setHeaderTitle(playerName);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
+ PlayerInRoom player = adapter.getItem(info.position);
+ switch(item.getItemId()) {
+ case R.id.player_info:
+ netplay.sendPlayerInfoQuery(player.player.name);
+ return true;
+ case R.id.player_kick:
+ netplay.sendKick(player.player.name);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_playerlist, container, false);
+ }
+
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ Player player = adapter.getItem(position).player;
+ if(player.name.equals(netplay.getPlayerName())) {
+ netplay.sendToggleReady();
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java
new file mode 100644
index 0000000..2b62bc8
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomStateManager.java
@@ -0,0 +1,110 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+
+/**
+ * This interface is supposed to abstract the handling of room state for several
+ * fragments that can display and manipulate it. The purpose of this is to allow
+ * using these fragments both for setting up networked and local games, despite
+ * the fact that for local games the settings can be changed immediately in
+ * memory, while they have to be sent out to the server for networked games.
+ *
+ * If/when the state changes as result of calling one of the "changeX" or
+ * "requestX" functions, that will also trigger the corresponding change
+ * listener method. There is no guarantee that calling a changeX method will
+ * actually change the setting (e.g. if you're not room chief).
+ *
+ * For local games, getChiefStatus is always true.
+ *
+ * Implementations of this interface are probably not thread safe and should
+ * only be used on the UI thread.
+ */
+public interface RoomStateManager {
+ // Query current state
+ MapRecipe getMapRecipe();
+ boolean getChiefStatus();
+ Scheme getScheme();
+ String getGameStyle();
+ Weaponset getWeaponset();
+ Map<String, TeamInGame> getTeams();
+
+ // Manipulate state
+ void changeMapRecipe(MapRecipe map);
+ void changeMapTheme(String theme);
+
+ /**
+ * This function sets both the map's name and generator. There is no function
+ * to change them independendly since e.g. the QtFrontend relies on them being
+ * consistent.
+ *
+ * If the name parameter is equal to one of the MapRecipe.MAPNAME_REGULAR, MAPNAME_MAZE
+ * or MAPNAME_DRAWN constants, the map generator is set accordingly. Otherwise, the
+ * map generator is set to represent a mapfile. The map's name is always set to
+ * the parameter.
+ */
+ void changeMapNameAndGenerator(String mapName);
+ void changeMapTemplate(int template);
+ void changeMazeSize(int mazeSize);
+ void changeMapSeed(String seed);
+ void changeMapDrawdata(byte[] drawdata);
+
+ void changeScheme(Scheme scheme);
+ void changeGameStyle(String style);
+ void changeWeaponset(Weaponset weaponset);
+
+ void requestAddTeam(Team team, int colorIndex);
+ void requestRemoveTeam(String teamname);
+ void changeTeamColorIndex(String teamname, int colorIndex);
+ void changeTeamHogCount(String teamname, int hogcount);
+
+ // Observe changes
+ void addListener(Listener observer);
+ void removeListener(Listener observer);
+
+ public interface Listener {
+ void onMapChanged(MapRecipe recipe);
+ void onChiefStatusChanged(boolean isChief);
+ void onSchemeChanged(Scheme scheme);
+ void onGameStyleChanged(String gameStyle);
+ void onWeaponsetChanged(Weaponset weaponset);
+ void onTeamsChanged(Map<String, TeamInGame> teams);
+ }
+
+ public static class ListenerAdapter implements Listener {
+ public void onMapChanged(MapRecipe recipe) {}
+ public void onChiefStatusChanged(boolean isChief) {}
+ public void onSchemeChanged(Scheme scheme) {}
+ public void onGameStyleChanged(String gameStyle) {}
+ public void onWeaponsetChanged(Weaponset weaponset) {}
+ public void onTeamsChanged(Map<String, TeamInGame> teams) {}
+ }
+
+ public interface Provider {
+ RoomStateManager getRoomStateManager();
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java
new file mode 100644
index 0000000..4351d91
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistAdapter.java
@@ -0,0 +1,113 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.Comparator;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.Room;
+import org.hedgewars.hedgeroid.Datastructures.RoomWithId;
+import org.hedgewars.hedgeroid.util.ObservableTreeMapAdapter;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Displays the list of all rooms in the lobby
+ */
+public class RoomlistAdapter extends ObservableTreeMapAdapter<String, RoomWithId> {
+ private Context context;
+
+ public RoomlistAdapter(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ protected Comparator<RoomWithId> getEntryOrder() {
+ return RoomWithId.NEWEST_FIRST_ORDER;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return getItem(position).id;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ private static CharSequence formatExtra(Resources res, Room room) {
+ String ownermsg = res.getString(R.string.roomlist_owner, room.owner);
+ String mapmsg = res.getString(R.string.roomlist_map, room.formatMapName(res));
+ String scheme = room.scheme.equals(room.weapons) ? room.scheme : room.scheme + " / " + room.weapons;
+ String schememsg = res.getString(R.string.roomlist_scheme, scheme);
+ return ownermsg + ". " + mapmsg + ", " + schememsg;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = LayoutInflater.from(context);
+ v = vi.inflate(R.layout.listview_room, null);
+ }
+
+ Room room = getItem(position).room;
+ int iconRes = room.inProgress ? R.drawable.roomlist_ingame : R.drawable.roomlist_preparing;
+
+ if(v.findViewById(android.R.id.text1) == null) {
+ // Tabular room list
+ TextView roomnameView = (TextView)v.findViewById(R.id.roomname);
+ TextView playerCountView = (TextView)v.findViewById(R.id.playercount);
+ TextView teamCountView = (TextView)v.findViewById(R.id.teamcount);
+ TextView ownerView = (TextView)v.findViewById(R.id.owner);
+ TextView mapView = (TextView)v.findViewById(R.id.map);
+ TextView schemeView = (TextView)v.findViewById(R.id.scheme);
+ TextView weaponView = (TextView)v.findViewById(R.id.weapons);
+
+ roomnameView.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0);
+ roomnameView.setText(room.name);
+ if(playerCountView != null) {
+ playerCountView.setText(String.valueOf(room.playerCount));
+ }
+ if(teamCountView != null) {
+ teamCountView.setText(String.valueOf(room.teamCount));
+ }
+ ownerView.setText(room.owner);
+ mapView.setText(room.formatMapName(context.getResources()));
+ schemeView.setText(room.scheme);
+ weaponView.setText(room.weapons);
+ } else {
+ // Small room list
+ TextView v1 = (TextView)v.findViewById(android.R.id.text1);
+ TextView v2 = (TextView)v.findViewById(android.R.id.text2);
+
+ v1.setCompoundDrawablesWithIntrinsicBounds(iconRes, 0, 0, 0);
+ v1.setText(room.name);
+ v2.setText(formatExtra(context.getResources(), room));
+ }
+
+ return v;
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java
new file mode 100644
index 0000000..37edc69
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/RoomlistFragment.java
@@ -0,0 +1,94 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.support.v4.app.ListFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+
+/**
+ * Displays the list of all rooms in the lobby
+ */
+public class RoomlistFragment extends ListFragment implements OnItemClickListener {
+ private static final int AUTO_REFRESH_INTERVAL_MS = 15000;
+
+ private Netplay netplay;
+ private RoomlistAdapter adapter;
+ private CountDownTimer autoRefreshTimer = new CountDownTimer(Long.MAX_VALUE, AUTO_REFRESH_INTERVAL_MS) {
+ @Override
+ public void onTick(long millisUntilFinished) {
+ netplay.sendRoomlistRequest();
+ }
+
+ @Override
+ public void onFinish() { }
+ };
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ netplay = Netplay.getAppInstance(getActivity().getApplicationContext());
+ adapter = new RoomlistAdapter(getActivity());
+ adapter.setSource(netplay.roomList);
+ setListAdapter(adapter);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_roomlist, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ getListView().setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ autoRefreshTimer.start();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ autoRefreshTimer.cancel();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ adapter.invalidate();
+ }
+
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ netplay.sendJoinRoom(adapter.getItem(position).room.name);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
index 1b6a340..a065402 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
@@ -1,14 +1,40 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
package org.hedgewars.hedgeroid;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.ConnectException;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
-import org.hedgewars.hedgeroid.EngineProtocol.EngineProtocolNetwork;
-import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
import org.hedgewars.hedgeroid.EngineProtocol.PascalExports;
+import org.hedgewars.hedgeroid.netplay.Netplay;
+import org.hedgewars.hedgeroid.util.FileUtils;
import android.app.Activity;
import android.content.Context;
@@ -22,8 +48,7 @@ import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
+import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
@@ -37,12 +62,17 @@ import android.view.View;
SDL Activity
*/
public class SDLActivity extends Activity {
-
+ /**
+ * Set startConfig to the desired config when starting this activity. This avoids having to parcel all
+ * the config objects into the Intent. Not particularly elegant, but it's actually a recommended
+ * way to do this (http://developer.android.com/guide/faq/framework.html#3)
+ */
+ public static volatile GameConfig startConfig;
+ public static volatile boolean startNetgame;
+
// Main components
public static SDLActivity mSingleton;
private static SDLSurface mSurface;
-
- // This is what SDL runs in. It invokes SDL_main(), eventually
private static Thread mSDLThread;
// Audio
@@ -59,26 +89,20 @@ public class SDLActivity extends Activity {
// Load the .so
static {
System.loadLibrary("SDL");
- //System.loadLibrary("SDL_image");
- //System.loadLibrary("SDL_mixer");
- //System.loadLibrary("SDL_ttf");
System.loadLibrary("main");
}
// Setup
protected void onCreate(Bundle savedInstanceState) {
- //Log.v("SDL", "onCreate()");
super.onCreate(savedInstanceState);
// So we can call stuff from static callbacks
mSingleton = this;
// Set up the surface
- GameConfig config = getIntent().getParcelableExtra("config");
-
- mSurface = new SDLSurface(getApplication(), config);
+ mSurface = new SDLSurface(getApplication(), startConfig, startNetgame);
+ startConfig = null;
setContentView(mSurface);
- SurfaceHolder holder = mSurface.getHolder();
}
// Events
@@ -106,42 +130,26 @@ public class SDLActivity extends Activity {
Log.v("SDL", "onDestroy()");
// Send a quit message to the application
SDLActivity.nativeQuit();
-
// Now wait for the SDL thread to quit
if (mSDLThread != null) {
try {
mSDLThread.join();
} catch(Exception e) {
- Log.v("SDL", "Problem stopping thread: " + e);
+ Log.w("SDL", "Problem stopping thread: " + e);
}
mSDLThread = null;
-
- //Log.v("SDL", "Finished waiting for SDL thread");
}
+ mSingleton = null;
}
-
- // Messages from the SDLMain thread
- static int COMMAND_CHANGE_TITLE = 1;
-
- // Handler for the messages
- Handler commandHandler = new Handler() {
- public void handleMessage(Message msg) {
- if (msg.arg1 == COMMAND_CHANGE_TITLE) {
- setTitle((String)msg.obj);
- }
+
+ public static void synchronizedNativeInit(String...args) {
+ synchronized(PascalExports.engineMutex) {
+ nativeInit(args);
}
- };
-
- // Send a message from the SDLMain thread
- void sendCommand(int command, Object data) {
- Message msg = commandHandler.obtainMessage();
- msg.arg1 = command;
- msg.obj = data;
- commandHandler.sendMessage(msg);
}
-
+
// C functions we call
- public static native void nativeInit(String...args);
+ private static native void nativeInit(String...args);
public static native void nativeQuit();
public static native void nativePause();
public static native void nativeResume();
@@ -165,22 +173,25 @@ public class SDLActivity extends Activity {
flipEGL();
}
- public static void setActivityTitle(String title) {
+ public static void setActivityTitle(final String title) {
// Called from SDLMain() thread and can't directly affect the view
- mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
+ mSingleton.runOnUiThread(new Runnable() {
+ public void run() {
+ mSingleton.setTitle(title);
+ }
+ });
}
public static Context getContext() {
return mSingleton;
}
- public static void startApp(int width, int height, GameConfig config) {
+ public static void startApp(final int width, final int height, GameConfig config, boolean netgame) {
// Start up the C app thread
if (mSDLThread == null) {
- mSDLThread = new Thread(new SDLMain(width, height, config), "SDLThread");
+ mSDLThread = new Thread(new SDLMain(width, height, config, netgame));
mSDLThread.start();
- }
- else {
+ } else {
SDLActivity.nativeResume();
}
}
@@ -188,8 +199,6 @@ public class SDLActivity extends Activity {
// EGL functions
public static boolean initEGL(int majorVersion, int minorVersion) {
if (SDLActivity.mEGLDisplay == null) {
- //Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
-
try {
EGL10 egl = (EGL10)EGLContext.getEGL();
@@ -207,7 +216,6 @@ public class SDLActivity extends Activity {
renderableType = EGL_OPENGL_ES_BIT;
}
int[] configSpec = {
- //EGL10.EGL_DEPTH_SIZE, 16,
EGL10.EGL_RENDERABLE_TYPE, renderableType,
EGL10.EGL_NONE
};
@@ -219,15 +227,6 @@ public class SDLActivity extends Activity {
}
EGLConfig config = configs[0];
- /*int EGL_CONTEXT_CLIENT_VERSION=0x3098;
- int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, majorVersion, EGL10.EGL_NONE };
- EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, contextAttrs);
-
- if (ctx == EGL10.EGL_NO_CONTEXT) {
- Log.e("SDL", "Couldn't create context");
- return false;
- }
- SDLActivity.mEGLContext = ctx;*/
SDLActivity.mEGLDisplay = dpy;
SDLActivity.mEGLConfig = config;
SDLActivity.mGLMajor = majorVersion;
@@ -413,37 +412,74 @@ public class SDLActivity extends Activity {
Simple nativeInit() runnable
*/
class SDLMain implements Runnable {
-
- private int surfaceWidth, surfaceHeight;
- private GameConfig config;
-
- public SDLMain(int width, int height, GameConfig _config) {
- config = _config;
+ public static final String TAG = "SDLMain";
+
+ public static final int RQ_LOWRES = 0x00000001; // use half land array
+ public static final int RQ_BLURRY_LAND = 0x00000002; // downscaled terrain
+ public static final int RQ_NO_BACKGROUND = 0x00000004; // don't draw background
+ public static final int RQ_SIMPLE_ROPE = 0x00000008; // avoid drawing rope
+ public static final int RQ_2D_WATER = 0x00000010; // disabe 3D water effect
+ public static final int RQ_SIMPLE_EXPLOSIONS = 0x00000020; // no fancy explosion effects
+ public static final int RQ_NO_FLAKES = 0x00000040; // no flakes
+ public static final int RQ_NO_MENU_ANIM = 0x00000080; // ammomenu appears with no animation
+ public static final int RQ_NO_DROPLETS = 0x00000100; // no droplets
+ public static final int RQ_NO_CLAMPING = 0x00000200; // don't clamp textures
+ public static final int RQ_NO_TOOLTIPS = 0x00000400; // tooltips are not drawn
+ public static final int RQ_NO_VSYNC = 0x00000800; // don't sync on vblank
+
+ private final int surfaceWidth, surfaceHeight;
+ private final String playerName;
+ private final GameConfig config;
+ private final boolean netgame;
+
+ public SDLMain(int width, int height, GameConfig config, boolean netgame) {
surfaceWidth = width;
surfaceHeight = height;
+ if(netgame) {
+ playerName = Netplay.getAppInstance(SDLActivity.getContext().getApplicationContext()).getPlayerName();
+ } else {
+ playerName = "Player";
+ }
+ this.config = config;
+ this.netgame = netgame;
}
public void run() {
//Set up the IPC socket server to communicate with the engine
- EngineProtocolNetwork ipc = new EngineProtocolNetwork(config);
-
- String path = Utils.getDataPath(SDLActivity.mSingleton);//This represents the data directory
- path = path.substring(0, path.length()-1);//remove the trailing '/'
-
-
- // Runs SDL_main() with added parameters
- SDLActivity.nativeInit(new String[] { String.valueOf(ipc.port),
- String.valueOf(surfaceWidth), String.valueOf(surfaceHeight),
- "0", "en.txt", "xeli", "1", "1", "1", path, "" });
-
+ GameConnection gameConn;
+ String path;
try {
- ipc.quitIPC();
- ipc.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
+ if(netgame) {
+ Netplay netplay = Netplay.getAppInstance(SDLActivity.mSingleton.getApplicationContext());
+ gameConn = GameConnection.forNetgame(config, netplay);
+ } else {
+ gameConn = GameConnection.forLocalGame(config);
+ }
+
+ path = FileUtils.getDataPathFile(SDLActivity.mSingleton).getAbsolutePath();
+ Log.d(TAG, "Starting engine");
+ // Runs SDL_main() with added parameters
+ try {
+ String pPort = String.valueOf(gameConn.port);
+ String pWidth = String.valueOf(surfaceWidth);
+ String pHeight = String.valueOf(surfaceHeight);
+ String pQuality = Integer.toString(RQ_NO_FLAKES|RQ_NO_DROPLETS|RQ_SIMPLE_EXPLOSIONS);
+ String pPlayerName = Base64.encodeToString(playerName.getBytes("UTF-8"), 0);
+ SDLActivity.synchronizedNativeInit(new String[] { pPort, pWidth, pHeight, pQuality, "en.txt", pPlayerName, "1", "1", "1", path, "" });
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError(e); // never happens
+ }
+ Log.d(TAG, "Engine stopped");
+ } catch(ConnectException e) {
+ Log.e(TAG, "Error starting IPC connection");
+ } catch (IOException e) {
+ Log.e(TAG, "Missing SDCard");
}
- Log.v("SDL", "SDL thread terminated");
- //Log.v("SDL", "SDL thread terminated");
+ SDLActivity.mSingleton.runOnUiThread(new Runnable() { public void run() {
+ if(SDLActivity.mSingleton != null) {
+ SDLActivity.mSingleton.finish();
+ }
+ }});
}
}
@@ -458,12 +494,13 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
private GameConfig config;
-
+ private boolean netgame;
+
// Sensors
private static SensorManager mSensorManager;
// Startup
- public SDLSurface(Context context, GameConfig _config) {
+ public SDLSurface(Context context, GameConfig _config, boolean netgame) {
super(context);
getHolder().addCallback(this);
@@ -475,6 +512,7 @@ View.OnKeyListener, View.OnTouchListener, SensorEventListener {
mSensorManager = (SensorManager)context.getSystemService("sensor");
config = _config;
+ this.netgame = netgame;
}
// Called when we have a valid drawing surface
@@ -544,7 +582,7 @@ View.OnKeyListener, View.OnTouchListener, SensorEventListener {
SDLActivity.onNativeResize(width, height, sdlFormat);
Log.v("SDL", "Window size:" + width + "x"+height);
- SDLActivity.startApp(width, height, config);
+ SDLActivity.startApp(width, height, config, netgame);
}
// unused
@@ -557,8 +595,9 @@ View.OnKeyListener, View.OnTouchListener, SensorEventListener {
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch(keyCode){
case KeyEvent.KEYCODE_BACK:
- PascalExports.HWterminate(true);
- return true;
+ Log.d("SDL", "KEYCODE_BACK");
+ SDLActivity.nativeQuit();
+ return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE:
@@ -580,34 +619,29 @@ View.OnKeyListener, View.OnTouchListener, SensorEventListener {
// Touch events
public boolean onTouch(View v, MotionEvent event) {
- {
- final int touchDevId = event.getDeviceId();
- final int pointerCount = event.getPointerCount();
- // touchId, pointerId, action, x, y, pressure
- int actionPointerIndex = event.getActionIndex();
- int pointerFingerId = event.getPointerId(actionPointerIndex);
- int action = event.getActionMasked();
-
- float x = event.getX(actionPointerIndex);
- float y = event.getY(actionPointerIndex);
- float p = event.getPressure(actionPointerIndex);
-
- if (action == MotionEvent.ACTION_MOVE && pointerCount > 1) {
- // TODO send motion to every pointer if its position has
- // changed since prev event.
- for (int i = 0; i < pointerCount; i++) {
- pointerFingerId = event.getPointerId(i);
- x = event.getX(i);
- y = event.getY(i);
- p = event.getPressure(i);
- SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
- }
- } else {
- SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
+ final int action = event.getAction() & MotionEvent.ACTION_MASK;
+ final int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+
+ if (action == MotionEvent.ACTION_MOVE) {
+ // TODO send motion to every pointer if its position has
+ // changed since prev event.
+ for (int i = 0; i < event.getPointerCount(); i++) {
+ sendNativeTouch(event, action, i);
}
+ } else {
+ sendNativeTouch(event, action, actionPointerIndex);
}
return true;
}
+
+ private static void sendNativeTouch(MotionEvent event, int action, int pointerIndex) {
+ int touchDevId = event.getDeviceId();
+ int pointerFingerId = event.getPointerId(pointerIndex);
+ float x = event.getX(pointerIndex);
+ float y = event.getY(pointerIndex);
+ float pressure = event.getPressure(pointerIndex);
+ SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, pressure);
+ }
// Sensor events
public void enableSensor(int sensortype, boolean enabled) {
@@ -633,6 +667,5 @@ View.OnKeyListener, View.OnTouchListener, SensorEventListener {
event.values[2] / SensorManager.GRAVITY_EARTH);
}
}
-
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeCreatorActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeCreatorActivity.java
new file mode 100644
index 0000000..e9d05d4
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeCreatorActivity.java
@@ -0,0 +1,8 @@
+package org.hedgewars.hedgeroid;
+
+import android.app.Activity;
+
+// TODO stub for the actual scheme editor
+public class SchemeCreatorActivity extends Activity {
+
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeListActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeListActivity.java
new file mode 100644
index 0000000..11aec8b
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SchemeListActivity.java
@@ -0,0 +1,8 @@
+package org.hedgewars.hedgeroid;
+
+import android.app.Activity;
+
+// TODO
+public class SchemeListActivity extends Activity {
+
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java
new file mode 100644
index 0000000..49d672b
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SettingsFragment.java
@@ -0,0 +1,227 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Schemes;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+import org.hedgewars.hedgeroid.Datastructures.Weaponsets;
+import org.hedgewars.hedgeroid.util.FileUtils;
+
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.Spinner;
+import android.widget.Toast;
+
+public class SettingsFragment extends Fragment {
+ private Spinner styleSpinner, schemeSpinner, weaponsetSpinner, themeSpinner;
+ private ImageView themeIcon;
+
+ private List<String> styles;
+ private List<Scheme> schemes;
+ private List<Weaponset> weaponsets;
+ private List<String> themes;
+
+ private RoomStateManager stateManager;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.fragment_settings, container, false);
+ themeIcon = (ImageView)v.findViewById(R.id.imgTheme);
+
+ try {
+ styles = FrontendDataUtils.getGameStyles(getActivity());
+ schemes = Schemes.loadAllSchemes(getActivity());
+ weaponsets = Weaponsets.loadAllWeaponsets(getActivity());
+ themes = FrontendDataUtils.getThemes(getActivity());
+ } catch (IOException e) {
+ Toast.makeText(getActivity().getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show();
+ getActivity().finish();
+ return null;
+ }
+
+ Collections.sort(styles, String.CASE_INSENSITIVE_ORDER);
+ Collections.sort(schemes, Scheme.NAME_ORDER);
+ Collections.sort(weaponsets, Weaponset.NAME_ORDER);
+ Collections.sort(themes, String.CASE_INSENSITIVE_ORDER);
+
+ styleSpinner = prepareSpinner(v, R.id.spinGameplay, styles, styleSelectedListener);
+ schemeSpinner = prepareSpinner(v, R.id.spinGamescheme, Schemes.toNameList(schemes), schemeSelectedListener);
+ weaponsetSpinner = prepareSpinner(v, R.id.spinweapons, Weaponsets.toNameList(weaponsets), weaponsetSelectedListener);
+ themeSpinner = prepareSpinner(v, R.id.spinTheme, themes, themeSelectedListener);
+
+ stateManager.addListener(roomStateChangeListener);
+
+ if(stateManager.getGameStyle() != null) {
+ styleSpinner.setSelection(styles.indexOf(stateManager.getGameStyle()), false);
+ }
+ if(stateManager.getScheme() != null) {
+ schemeSpinner.setSelection(getSchemePosition(schemes, stateManager.getScheme().name), false);
+ }
+ if(stateManager.getWeaponset() != null) {
+ weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, stateManager.getWeaponset().name), false);
+ }
+ if(stateManager.getMapRecipe() != null) {
+ themeSpinner.setSelection(themes.indexOf(stateManager.getMapRecipe().theme), false);
+ }
+
+ setChiefState(stateManager.getChiefStatus());
+
+ return v;
+ }
+
+ private static Spinner prepareSpinner(View v, int id, List<String> items, OnItemSelectedListener itemSelectedListener) {
+ Spinner spinner = (Spinner)v.findViewById(id);
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(v.getContext(), R.layout.listview_item, items);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ spinner.setOnItemSelectedListener(itemSelectedListener);
+ return spinner;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ try {
+ stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager();
+ } catch(ClassCastException e) {
+ throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ stateManager.removeListener(roomStateChangeListener);
+ }
+
+ private static int getSchemePosition(List<Scheme> schemes, String scheme) {
+ for(int i=0; i<schemes.size(); i++) {
+ if(schemes.get(i).name.equals(scheme)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static int getWeaponsetPosition(List<Weaponset> weaponsets, String weaponset) {
+ for(int i=0; i<weaponsets.size(); i++) {
+ if(weaponsets.get(i).name.equals(weaponset)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void setChiefState(boolean chiefState) {
+ styleSpinner.setEnabled(chiefState);
+ schemeSpinner.setEnabled(chiefState);
+ weaponsetSpinner.setEnabled(chiefState);
+ themeSpinner.setEnabled(chiefState);
+
+ if(chiefState) {
+ stateManager.changeGameStyle(styles.get(styleSpinner.getSelectedItemPosition()));
+ stateManager.changeScheme(schemes.get(schemeSpinner.getSelectedItemPosition()));
+ stateManager.changeWeaponset(weaponsets.get(weaponsetSpinner.getSelectedItemPosition()));
+ stateManager.changeMapTheme(themes.get(themeSpinner.getSelectedItemPosition()));
+ }
+ }
+
+ private final OnItemSelectedListener styleSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeGameStyle(styles.get(position));
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener schemeSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeScheme(schemes.get(position));
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener weaponsetSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeWeaponset(weaponsets.get(position));
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {}
+ };
+
+ private final OnItemSelectedListener themeSelectedListener = new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> adapter, View v, int position, long arg3) {
+ stateManager.changeMapTheme(themes.get(position));
+ String theme = themes.get(position);
+ try {
+ File iconFile = FileUtils.getDataPathFile(getActivity(), "Themes", theme, "icon at 2X.png");
+ Drawable themeIconDrawable = Drawable.createFromPath(iconFile.getAbsolutePath());
+ themeIcon.setImageDrawable(themeIconDrawable);
+ } catch (FileNotFoundException e) {
+ Log.e("SettingsFragment", "Unable to find preview for theme "+theme, e);
+ }
+ };
+ public void onNothingSelected(AdapterView<?> arg0) {};
+ };
+
+ private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.Listener() {
+ public void onWeaponsetChanged(Weaponset weaponset) {
+ weaponsetSpinner.setSelection(getWeaponsetPosition(weaponsets, weaponset.name));
+ }
+
+ public void onTeamsChanged(Map<String, TeamInGame> teams) {}
+
+ public void onSchemeChanged(Scheme scheme) {
+ schemeSpinner.setSelection(getSchemePosition(schemes, scheme.name));
+ }
+
+ public void onMapChanged(MapRecipe recipe) {
+ themeSpinner.setSelection(themes.indexOf(recipe.theme));
+ }
+
+ public void onGameStyleChanged(String gameStyle) {
+ styleSpinner.setSelection(styles.indexOf(gameStyle));
+ }
+
+ public void onChiefStatusChanged(boolean isChief) {
+ setChiefState(isChief);
+ }
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java
deleted file mode 100644
index 4c96d9e..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartGameActivity.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid;
-
-import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
-import org.hedgewars.hedgeroid.Datastructures.Map;
-import org.hedgewars.hedgeroid.Datastructures.Map.MapType;
-import org.hedgewars.hedgeroid.Datastructures.Scheme;
-import org.hedgewars.hedgeroid.Datastructures.Team;
-import org.hedgewars.hedgeroid.Datastructures.Weapon;
-import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.preference.PreferenceManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.ArrayAdapter;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.Spinner;
-import android.widget.Toast;
-
-public class StartGameActivity extends Activity {
-
- public static final int ACTIVITY_TEAM_SELECTOR = 0;
-
- private GameConfig config = null;
- private ImageButton start, back, team;
- private Spinner maps, gameplay, gamescheme, weapons, themes;
- private ImageView themeIcon, mapPreview, teamCount;
-
- public void onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
-
- Scheme.parseBasicFlags(this);
- config = new GameConfig();
-
- setContentView(R.layout.starting_game);
-
- back = (ImageButton) findViewById(R.id.btnBack);
- team = (ImageButton) findViewById(R.id.btnTeams);
- start = (ImageButton) findViewById(R.id.btnStart);
-
- maps = (Spinner) findViewById(R.id.spinMaps);
- gameplay = (Spinner) findViewById(R.id.spinGameplay);
- gamescheme = (Spinner) findViewById(R.id.spinGamescheme);
- weapons = (Spinner) findViewById(R.id.spinweapons);
- themes = (Spinner) findViewById(R.id.spinTheme);
-
- themeIcon = (ImageView) findViewById(R.id.imgTheme);
- mapPreview = (ImageView) findViewById(R.id.mapPreview);
- teamCount = (ImageView) findViewById(R.id.imgTeamsCount);
-
- start.setOnClickListener(startClicker);
- back.setOnClickListener(backClicker);
- team.setOnClickListener(teamClicker);
-
- ArrayAdapter<?> adapter = new ArrayAdapter<Map>(this, R.layout.listview_item, FrontendDataUtils.getMaps(this));
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- maps.setAdapter(adapter);
- maps.setOnItemSelectedListener(mapsClicker);
- //set to first nonmap
- for(int i = 0; i < adapter.getCount(); i++){
- if(((Map)adapter.getItem(i)).getType() == MapType.TYPE_DEFAULT){
- maps.setSelection(i, false);
- break;
- }
- }
-
- adapter = new ArrayAdapter<String>(this, R.layout.listview_item, FrontendDataUtils.getGameplay(this));
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- gameplay.setAdapter(adapter);
- gameplay.setOnItemSelectedListener(gameplayClicker);
- //set to first nonmap
- for(int i = 0; i < adapter.getCount(); i++){
- if(((String)adapter.getItem(i)).equals("None")){
- gameplay.setSelection(i, false);
- break;
- }
- }
-
- adapter = new ArrayAdapter<Scheme>(this, R.layout.listview_item, FrontendDataUtils.getSchemes(this));
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- gamescheme.setAdapter(adapter);
- gamescheme.setOnItemSelectedListener(schemeClicker);
- //set to first nonmap
- for(int i = 0; i < adapter.getCount(); i++){
- if(((Scheme)adapter.getItem(i)).toString().equals("Default")){
- gamescheme.setSelection(i, false);
- break;
- }
- }
-
-
- adapter = new ArrayAdapter<Weapon>(this, R.layout.listview_item, FrontendDataUtils.getWeapons(this));
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- weapons.setAdapter(adapter);
- weapons.setOnItemSelectedListener(weaponClicker);
- for(int i = 0; i < adapter.getCount(); i++){
- if(((Weapon)adapter.getItem(i)).toString().equals("Crazy")){
- weapons.setSelection(i, false);
- break;
- }
- }
- adapter = new ArrayAdapter<String>(this, R.layout.listview_item, FrontendDataUtils.getThemes(this));
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- themes.setAdapter(adapter);
- themes.setOnItemSelectedListener(themesClicker);
- }
-
- private void startTeamsActivity(){
- Intent i = new Intent(StartGameActivity.this, TeamSelectionActivity.class);
- i.putParcelableArrayListExtra("teams", config.teams);
- startActivityForResult(i, ACTIVITY_TEAM_SELECTOR);
- }
-
- public void onActivityResult(int requestCode, int resultCode, Intent data){
- switch(requestCode){
- case ACTIVITY_TEAM_SELECTOR:
- if(resultCode == Activity.RESULT_OK){
- Parcelable[] parcelables = (Parcelable[])data.getParcelableArrayExtra("teams");
- config.teams.clear();
- for(Parcelable t : parcelables){
- config.teams.add((Team)t);
- }
- teamCount.getDrawable().setLevel(config.teams.size());
- }
- break;
- }
- }
-
-
- private OnItemSelectedListener themesClicker = new OnItemSelectedListener(){
-
- public void onItemSelected(AdapterView<?> arg0, View view, int position, long rowId) {
- String themeName = (String) arg0.getAdapter().getItem(position);
- Drawable themeIconDrawable = Drawable.createFromPath(Utils.getDataPath(StartGameActivity.this) + "Themes/" + themeName + "/icon at 2X.png");
- themeIcon.setImageDrawable(themeIconDrawable);
- config.theme = themeName;
- }
-
- public void onNothingSelected(AdapterView<?> arg0) {
- }
-
- };
-
- private OnItemSelectedListener mapsClicker = new OnItemSelectedListener(){
-
- public void onItemSelected(AdapterView<?> arg0, View view, int position,long rowId) {
- Map map = (Map)arg0.getAdapter().getItem(position);
- mapPreview.setImageDrawable(map.getDrawable());
- config.map = map;
- }
-
- public void onNothingSelected(AdapterView<?> arg0) {
- }
-
- };
-
- private OnItemSelectedListener weaponClicker = new OnItemSelectedListener(){
- public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- config.weapon = (Weapon)arg0.getAdapter().getItem(arg2);
- }
- public void onNothingSelected(AdapterView<?> arg0) {
-
- }
- };
- private OnItemSelectedListener schemeClicker = new OnItemSelectedListener(){
- public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- config.scheme = (Scheme)arg0.getAdapter().getItem(arg2);
- }
- public void onNothingSelected(AdapterView<?> arg0) {
-
- }
- };
- private OnItemSelectedListener gameplayClicker = new OnItemSelectedListener(){
- public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- //config = ()arg0.getAdapter().getItem(arg2);
- }
- public void onNothingSelected(AdapterView<?> arg0) {
-
- }
- };
-
- private OnClickListener startClicker = new OnClickListener(){
- public void onClick(View v) {
- if(config.teams.size() < 2){
- Toast.makeText(StartGameActivity.this, R.string.not_enough_teams, Toast.LENGTH_LONG).show();
- startTeamsActivity();
- }
- else{
- Intent i = new Intent(StartGameActivity.this, SDLActivity.class);
- i.putExtra("config", config);
- startActivity(i);}
- }
- };
-
- private OnClickListener backClicker = new OnClickListener(){
- public void onClick(View v) {
- finish();
- }
- };
-
- private OnClickListener teamClicker = new OnClickListener(){
- public void onClick(View v) {
- startTeamsActivity();
- }
- };
-
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java
new file mode 100644
index 0000000..70661a1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/StartNetgameDialog.java
@@ -0,0 +1,95 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import org.hedgewars.hedgeroid.netplay.Netplay;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+public class StartNetgameDialog extends DialogFragment {
+ private static final String PREF_PLAYERNAME = "playerName";
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE);
+ final String playerName = prefs.getString(PREF_PLAYERNAME, "Player");
+ final EditText editText = new EditText(getActivity());
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ editText.setText(playerName);
+ editText.setHint(R.string.start_netgame_dialog_playername_hint);
+ editText.setId(android.R.id.text1);
+ editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
+ editText.setSingleLine();
+
+ builder.setTitle(R.string.start_netgame_dialog_title);
+ builder.setMessage(R.string.start_netgame_dialog_message);
+ builder.setView(editText);
+ builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ editText.setText(playerName);
+ }
+ });
+
+ editText.setOnEditorActionListener(new OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ boolean handled = false;
+ if(actionId == EditorInfo.IME_ACTION_DONE) {
+ startConnection(v.getText().toString());
+ handled = true;
+ }
+ return handled;
+ }
+ });
+
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ startConnection(editText.getText().toString());
+ }
+ });
+
+ return builder.create();
+ }
+
+ private void startConnection(String username) {
+ if(username.length() > 0) {
+ SharedPreferences prefs = getActivity().getSharedPreferences("settings", Context.MODE_PRIVATE);
+ Editor edit = prefs.edit();
+ edit.putString(PREF_PLAYERNAME, username);
+ edit.commit();
+
+ Netplay.getAppInstance(getActivity().getApplicationContext()).connectToDefaultServer(username);
+ getDialog().dismiss();
+ ((MainActivity)getActivity()).onNetConnectingStarted();
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java
new file mode 100644
index 0000000..82d9dad
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamAddDialog.java
@@ -0,0 +1,112 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+
+public class TeamAddDialog extends DialogFragment {
+ private static final String STATE_TEAMS_ALREADY_IN_GAME = "teamAlreadyInGame";
+ private ArrayList<String> teamsAlreadyInGame;
+ private List<Team> availableTeams;
+ private Listener listener;
+
+ public static interface Listener {
+ void onTeamAddDialogSubmitted(Team newTeam);
+ }
+
+ public TeamAddDialog() {
+ // Only for reflection-based instantiation by the framework
+ }
+
+ TeamAddDialog(Collection<String> teamsAlreadyInGame) {
+ this.teamsAlreadyInGame = new ArrayList<String>(teamsAlreadyInGame);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ listener = (Listener) activity;
+ } catch(ClassCastException e) {
+ throw new ClassCastException("Activity " + activity + " must implement TeamAddDialog.Listener to use TeamAddDialog.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ listener = null;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if(savedInstanceState != null) {
+ teamsAlreadyInGame = savedInstanceState.getStringArrayList(STATE_TEAMS_ALREADY_IN_GAME);
+ }
+ availableTeams = new ArrayList<Team>();
+ List<Team> teams = FrontendDataUtils.getTeams(getActivity());
+ for(Team team : teams) {
+ if(!teamsAlreadyInGame.contains(team.name)) {
+ availableTeams.add(team);
+ }
+ }
+ Collections.sort(availableTeams, Team.NAME_ORDER);
+ }
+
+ // TODO use icons for the teams (corresponding to botlevel)
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.dialog_addteam_title);
+ builder.setIcon(R.drawable.human);
+ String[] teamNames = new String[availableTeams.size()];
+ for(int i=0; i<availableTeams.size(); i++) {
+ teamNames[i] = availableTeams.get(i).name;
+ }
+ builder.setItems(teamNames, new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ listener.onTeamAddDialogSubmitted(availableTeams.get(which));
+ }
+ });
+ return builder.create();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putStringArrayList(STATE_TEAMS_ALREADY_IN_GAME, teamsAlreadyInGame);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java
index bd0e8cb..1668c96 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamCreatorActivity.java
@@ -1,10 +1,12 @@
/*
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,31 +15,32 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Hog;
import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.util.FileUtils;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Bundle;
+import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
@@ -49,33 +52,50 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
+import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;
-public class TeamCreatorActivity extends Activity implements Runnable{
-
+/**
+ * Edit or create a team. If a team should be edited, it is supplied in the extras
+ * as parameter oldTeamName.
+ */
+public class TeamCreatorActivity extends Activity implements Runnable {
+ public static final String PARAMETER_EXISTING_TEAMNAME = "existingTeamName";
+ private static final String TAG = TeamCreatorActivity.class.getSimpleName();
+
private TextView name;
private Spinner difficulty, grave, flag, voice, fort;
private ImageView imgFort;
private ArrayList<ImageButton> hogDice = new ArrayList<ImageButton>();
private ArrayList<Spinner> hogHat = new ArrayList<Spinner>();
private ArrayList<EditText> hogName = new ArrayList<EditText>();
- private ImageButton back, save, voiceButton;
+ private ImageButton voiceButton;
private ScrollView scroller;
private MediaPlayer mp = null;
- private boolean settingsChanged = false;
- private boolean saved = false;
- private String fileName = null;
+ private boolean initComplete = false;
+
+ private String existingTeamName = null;
- private final List<HashMap<String, ?>> flagsData = new ArrayList<HashMap<String, ?>>();
- private final List<HashMap<String, ?>> typesData = new ArrayList<HashMap<String, ?>>();
- private final List<HashMap<String, ?>> gravesData = new ArrayList<HashMap<String, ?>>();
- private final List<HashMap<String, ?>> hatsData = new ArrayList<HashMap<String, ?>>();
+ private final List<Map<String, ?>> flagsData = new ArrayList<Map<String, ?>>();
+ private final List<Map<String, ?>> typesData = new ArrayList<Map<String, ?>>();
+ private final List<Map<String, ?>> gravesData = new ArrayList<Map<String, ?>>();
+ private final List<Map<String, ?>> hatsData = new ArrayList<Map<String, ?>>();
private final List<String> voicesData = new ArrayList<String>();
private final List<String> fortsData = new ArrayList<String>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ initComplete = false;
+
+ // Restore state and read parameters
+ if(savedInstanceState != null) {
+ existingTeamName = savedInstanceState.getString(PARAMETER_EXISTING_TEAMNAME);
+ } else {
+ existingTeamName = getIntent().getStringExtra(PARAMETER_EXISTING_TEAMNAME);
+ }
+
+ // Set up view
setContentView(R.layout.team_creation);
name = (TextView) findViewById(R.id.txtName);
@@ -87,15 +107,11 @@ public class TeamCreatorActivity extends Activity implements Runnable{
imgFort = (ImageView) findViewById(R.id.imgFort);
- back = (ImageButton) findViewById(R.id.btnBack);
- save = (ImageButton) findViewById(R.id.btnSave);
voiceButton = (ImageButton) findViewById(R.id.btnPlay);
scroller = (ScrollView) findViewById(R.id.scroller);
- save.setOnClickListener(saveClicker);
- back.setOnClickListener(backClicker);
-
+ // Wire view elements
LinearLayout ll = (LinearLayout) findViewById(R.id.HogsContainer);
for (int i = 0; i < ll.getChildCount(); i++) {
RelativeLayout team_creation_entry = (RelativeLayout) ll.getChildAt(i);
@@ -108,107 +124,116 @@ public class TeamCreatorActivity extends Activity implements Runnable{
.findViewById(R.id.txtTeam1));
}
- SimpleAdapter sa = new SimpleAdapter(this, gravesData,
- R.layout.spinner_textimg_entry, new String[] { "txt", "img" },
- new int[] { R.id.spinner_txt, R.id.spinner_img });
- sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
- sa.setViewBinder(viewBinder);
- grave.setAdapter(sa);
- grave.setOnFocusChangeListener(focusser);
-
- sa = new SimpleAdapter(this, flagsData, R.layout.spinner_textimg_entry,
- new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
- R.id.spinner_img });
- sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
- sa.setViewBinder(viewBinder);
- flag.setAdapter(sa);
- flag.setOnFocusChangeListener(focusser);
-
- sa = new SimpleAdapter(this, typesData, R.layout.spinner_textimg_entry,
- new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
- R.id.spinner_img });
- sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
- difficulty.setAdapter(sa);
- difficulty.setOnFocusChangeListener(focusser);
-
- sa = new SimpleAdapter(this, hatsData, R.layout.spinner_textimg_entry,
- new String[] { "txt", "img" }, new int[] { R.id.spinner_txt,
- R.id.spinner_img });
- sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
- sa.setViewBinder(viewBinder);
+ grave.setAdapter(createMapSpinnerAdapter(gravesData));
+ flag.setAdapter(createMapSpinnerAdapter(flagsData));
+ difficulty.setAdapter(createMapSpinnerAdapter(typesData));
+ SpinnerAdapter hatAdapter = createMapSpinnerAdapter(hatsData);
for (Spinner spin : hogHat) {
- spin.setAdapter(sa);
+ spin.setAdapter(hatAdapter);
}
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.listview_item, voicesData);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- voice.setAdapter(adapter);
- voice.setOnFocusChangeListener(focusser);
+
+ voice.setAdapter(createListSpinnerAdapter(voicesData));
voiceButton.setOnClickListener(voiceClicker);
- adapter = new ArrayAdapter<String>(this, R.layout.listview_item, fortsData);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- fort.setAdapter(adapter);
+ fort.setAdapter(createListSpinnerAdapter(fortsData));
fort.setOnItemSelectedListener(fortSelector);
- fort.setOnFocusChangeListener(focusser);
new Thread(this).start();
}
+ private SpinnerAdapter createMapSpinnerAdapter(List<? extends Map<String, ?>> data) {
+ SimpleAdapter sa = new SimpleAdapter(this, data,
+ R.layout.spinner_textimg_entry, new String[] { "txt", "img" },
+ new int[] { R.id.spinner_txt, R.id.spinner_img });
+ sa.setDropDownViewResource(R.layout.spinner_textimg_dropdown_entry);
+ sa.setViewBinder(viewBinder);
+ return sa;
+ }
+
+ private SpinnerAdapter createListSpinnerAdapter(List<String> data) {
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.listview_item, data);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ return adapter;
+ }
+
public void run(){
- final ArrayList<HashMap<String, ?>> gravesDataNew = FrontendDataUtils.getGraves(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(gravesData, gravesDataNew);
- ((SimpleAdapter)grave.getAdapter()).notifyDataSetChanged();
- }
- });
-
- final ArrayList<HashMap<String, ?>> flagsDataNew = FrontendDataUtils.getFlags(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(flagsData, flagsDataNew);
- ((SimpleAdapter)flag.getAdapter()).notifyDataSetChanged();
- }
- });
-
- final ArrayList<HashMap<String, ?>> typesDataNew = FrontendDataUtils.getTypes(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(typesData, typesDataNew);
- ((SimpleAdapter)difficulty.getAdapter()).notifyDataSetChanged();
- }
- });
-
- final ArrayList<HashMap<String, ?>> hatsDataNew = FrontendDataUtils.getHats(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(hatsData, hatsDataNew);
- ((SimpleAdapter)hogHat.get(0).getAdapter()).notifyDataSetChanged();
- }
- });
-
- final ArrayList<String> voicesDataNew = FrontendDataUtils.getVoices(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(voicesData, voicesDataNew);
- ((ArrayAdapter<String>)voice.getAdapter()).notifyDataSetChanged();
- }
- });
-
- final ArrayList<String> fortsDataNew = FrontendDataUtils.getForts(this);
- this.runOnUiThread(new Runnable(){
- public void run() {
- copy(fortsData, fortsDataNew);
- ((ArrayAdapter<String>)fort.getAdapter()).notifyDataSetChanged();
+ try {
+ final List<Map<String, ?>> gravesDataNew = FrontendDataUtils.getGraves(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ gravesData.addAll(gravesDataNew);
+ ((SimpleAdapter)grave.getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ final List<Map<String, ?>> flagsDataNew = FrontendDataUtils.getFlags(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ flagsData.addAll(flagsDataNew);
+ ((SimpleAdapter)flag.getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ final List<Map<String, ?>> typesDataNew = FrontendDataUtils.getTypes(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ typesData.addAll(typesDataNew);
+ ((SimpleAdapter)difficulty.getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ final List<Map<String, ?>> hatsDataNew = FrontendDataUtils.getHats(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ hatsData.addAll(hatsDataNew);
+ ((SimpleAdapter)hogHat.get(0).getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ final List<String> voicesDataNew = FrontendDataUtils.getVoices(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ voicesData.addAll(voicesDataNew);
+ ((ArrayAdapter<?>)voice.getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ final List<String> fortsDataNew = FrontendDataUtils.getForts(this);
+ runOnUiThread(new Runnable(){
+ public void run() {
+ fortsData.addAll(fortsDataNew);
+ ((ArrayAdapter<?>)fort.getAdapter()).notifyDataSetChanged();
+ }
+ });
+
+ if(existingTeamName!=null) {
+ final Team loadedTeam = Team.load(Team.getTeamfileByName(getApplicationContext(), existingTeamName));
+ if(loadedTeam==null) {
+ existingTeamName = null;
+ } else {
+ runOnUiThread(new Runnable(){
+ public void run() {
+ setTeamValues(loadedTeam);
+ }
+ });
+ }
}
- });
+ runOnUiThread(new Runnable(){
+ public void run() {
+ initComplete = true;
+ }
+ });
+ } catch(FileNotFoundException e) {
+ this.runOnUiThread(new Runnable(){
+ public void run() {
+ Toast.makeText(getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show();
+ finish();
+ }
+ });
+ }
}
- private static <T> void copy(List<T> dest, List<T> src){
- for(T t: src) dest.add(t);
- }
-
public void onDestroy() {
super.onDestroy();
if (mp != null) {
@@ -217,101 +242,70 @@ public class TeamCreatorActivity extends Activity implements Runnable{
}
}
- private OnFocusChangeListener focusser = new OnFocusChangeListener() {
- public void onFocusChange(View v, boolean hasFocus) {
- settingsChanged = true;
- }
-
- };
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(PARAMETER_EXISTING_TEAMNAME, existingTeamName);
+ }
public void onBackPressed() {
- onFinishing();
+ if(initComplete) {
+ saveTeam();
+ }
+ setResult(RESULT_OK);
super.onBackPressed();
-
}
- private OnClickListener backClicker = new OnClickListener() {
- public void onClick(View v) {
- onFinishing();
- finish();
+ private void saveTeam() {
+ String teamName = name.getText().toString();
+ String teamFlag = (String)((Map<String, Object>) flag.getSelectedItem()).get("txt");
+ String teamFort = fort.getSelectedItem().toString();
+ String teamGrave = (String)((Map<String, Object>) grave.getSelectedItem()).get("txt");
+ String teamVoice = voice.getSelectedItem().toString();
+ int levelInt = (Integer)((Map<String, Object>) difficulty.getSelectedItem()).get("level");
+
+ List<Hog> hogs = new ArrayList<Hog>();
+ for (int i = 0; i < hogName.size(); i++) {
+ String name = hogName.get(i).getText().toString();
+ String hat = ((Map<String, Object>) hogHat.get(i).getSelectedItem()).get("txt").toString();
+ hogs.add(new Hog(name, hat, levelInt));
}
- };
-
- private void onFinishing() {
- if (settingsChanged) {
- setResult(RESULT_OK);
- } else {
- setResult(RESULT_CANCELED);
+
+ Team team = new Team(teamName, teamGrave, teamFlag, teamVoice, teamFort, hogs);
+ File teamsDir = new File(getFilesDir(), Team.DIRECTORY_TEAMS);
+ if (!teamsDir.exists()) teamsDir.mkdir();
+
+ File newFile = Team.getTeamfileByName(this, teamName);
+ File oldFile = null;
+ if(existingTeamName != null) {
+ oldFile = Team.getTeamfileByName(this, existingTeamName);
}
- }
-
- private OnClickListener saveClicker = new OnClickListener() {
- public void onClick(View v) {
- Toast.makeText(TeamCreatorActivity.this, R.string.saved, Toast.LENGTH_SHORT).show();
- saved = true;
- Team team = new Team();
- team.name = name.getText().toString();
- HashMap<String, Object> hashmap = (HashMap<String, Object>) flag.getSelectedItem();
-
- team.flag = (String) hashmap.get("txt");
- team.fort = fort.getSelectedItem().toString();
- hashmap = (HashMap<String, Object>) grave.getSelectedItem();
- team.grave = hashmap.get("txt").toString();
- team.hash = "0";
- team.voice = voice.getSelectedItem().toString();
- team.file = fileName;
-
- hashmap = ((HashMap<String, Object>) difficulty.getSelectedItem());
- String levelString = hashmap.get("txt").toString();
- int levelInt;
- if (levelString.equals(getString(R.string.human))) {
- levelInt = 0;
- } else if (levelString.equals(getString(R.string.bot5))) {
- levelInt = 1;
- } else if (levelString.equals(getString(R.string.bot4))) {
- levelInt = 2;
- } else if (levelString.equals(getString(R.string.bot3))) {
- levelInt = 3;
- } else if (levelString.equals(getString(R.string.bot2))) {
- levelInt = 4;
- } else {
- levelInt = 5;
- }
-
- for (int i = 0; i < hogName.size(); i++) {
- team.hogNames[i] = hogName.get(i).getText().toString();
- hashmap = (HashMap<String, Object>) hogHat.get(i).getSelectedItem();
- team.hats[i] = hashmap.get("txt").toString();
- team.levels[i] = levelInt;
- }
- try {
- File teamsDir = new File(getFilesDir().getAbsolutePath() + '/' + Team.DIRECTORY_TEAMS);
- if (!teamsDir.exists()) teamsDir.mkdir();
- if(team.file == null){
- team.setFileName(TeamCreatorActivity.this);
- }
- FileOutputStream fos = new FileOutputStream(String.format("%s/%s", teamsDir.getAbsolutePath(), team.file));
- team.writeToXml(fos);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
+ try {
+ team.save(newFile);
+ // If the team was renamed, delete the old file.
+ if(oldFile != null && oldFile.isFile() && !oldFile.equals(newFile)) {
+ oldFile.delete();
}
+ existingTeamName = teamName;
+ } catch(IOException e) {
+ Toast.makeText(getApplicationContext(), R.string.error_save_failed, Toast.LENGTH_SHORT).show();
}
-
};
private OnItemSelectedListener fortSelector = new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3) {
- settingsChanged = true;
String fortName = (String) arg0.getAdapter().getItem(position);
- Drawable fortIconDrawable = Drawable.createFromPath(Utils
- .getDataPath(TeamCreatorActivity.this)
- + "Forts/"
- + fortName + "L.png");
- imgFort.setImageDrawable(fortIconDrawable);
+ try {
+ File fortImage = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Forts", fortName, "L.png");
+ Drawable fortIconDrawable = Drawable.createFromPath(fortImage.getAbsolutePath());
+ imgFort.setImageDrawable(fortIconDrawable);
+ } catch(IOException e) {
+ Log.e(TAG, "Unable to show fort image", e);
+ }
scroller.fullScroll(ScrollView.FOCUS_DOWN);// Scroll the scrollview
// to the bottom, work
- // around for scollview
+ // around for scrollview
// invalidation (scrolls
// back to top)
}
@@ -324,9 +318,7 @@ public class TeamCreatorActivity extends Activity implements Runnable{
private OnClickListener voiceClicker = new OnClickListener() {
public void onClick(View v) {
try {
- File dir = new File(String.format("%sSounds/voices/%s",
- Utils.getDataPath(TeamCreatorActivity.this),
- voice.getSelectedItem()));
+ File dir = FileUtils.getDataPathFile(TeamCreatorActivity.this, "Sounds", "voices", (String)voice.getSelectedItem());
String file = "";
File[] dirs = dir.listFiles();
File f = dirs[(int) Math.round(Math.random() * dirs.length)];
@@ -341,64 +333,58 @@ public class TeamCreatorActivity extends Activity implements Runnable{
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
- e.printStackTrace();
+ Log.e(TAG, "Unable to play voice sample", e);
} catch (IllegalStateException e) {
- e.printStackTrace();
+ Log.e(TAG, "Unable to play voice sample", e);
} catch (IOException e) {
- e.printStackTrace();
+ Log.e(TAG, "Unable to play voice sample", e);
}
}
};
+ @SuppressWarnings("unchecked")
private void setTeamValues(Team t){
-
- if (t != null) {
+ if (t == null) {
+ return;
+ }
+
+ try {
name.setText(t.name);
- int position = ((ArrayAdapter<String>) voice.getAdapter()).getPosition(t.voice);
- voice.setSelection(position);
-
- position = ((ArrayAdapter<String>) fort.getAdapter()).getPosition(t.fort);
- fort.setSelection(position);
-
- position = 0;
- for (HashMap<String, ?> hashmap : typesData) {
- if (hashmap.get("txt").equals(t.levels[0])) {
- difficulty.setSelection(position);
- break;
- }
- }
-
- position = 0;
- for (HashMap<String, ?> hashmap : gravesData) {
- if (hashmap.get("txt").equals(t.grave)) {
- grave.setSelection(position);
- break;
- }
- }
-
- position = 0;
- for (HashMap<String, ?> hashmap : typesData) {
- if (hashmap.get("txt").equals(t.flag)) {
- flag.setSelection(position);
- break;
- }
+ voice.setSelection(findPosition((ArrayAdapter<String>) voice.getAdapter(), t.voice));
+ fort.setSelection(findPosition((ArrayAdapter<String>) fort.getAdapter(), t.fort));
+ difficulty.setSelection(findPosition(typesData, "level", Integer.valueOf(t.hogs.get(0).level)));
+ grave.setSelection(findPosition(gravesData, "txt", t.grave));
+ flag.setSelection(findPosition(flagsData, "txt", t.flag));
+
+ for (int i = 0; i < Team.HEDGEHOGS_PER_TEAM; i++) {
+ hogHat.get(i).setSelection(findPosition(hatsData, "txt", t.hogs.get(i).hat));
+ hogName.get(i).setText(t.hogs.get(i).name);
}
+ } catch(NoSuchElementException e) {
+ Toast.makeText(getApplicationContext(), R.string.error_team_attribute_not_found, Toast.LENGTH_LONG).show();
+ finish();
+ }
+ }
- for (int i = 0; i < Team.maxNumberOfHogs; i++) {
- position = 0;
- for (HashMap<String, ?> hashmap : hatsData) {
- if (hashmap.get("txt").equals(t.hats[i])) {
- hogHat.get(i).setSelection(position);
- }
- }
-
- hogName.get(i).setText(t.hogNames[i]);
+ int findPosition(ArrayAdapter<String> adapter, String value) throws NoSuchElementException {
+ int position = adapter.getPosition(value);
+ if(position<0) {
+ throw new NoSuchElementException();
+ }
+ return position;
+ }
+
+ int findPosition(List<? extends Map<String, ?>> data, String key, Object value) throws NoSuchElementException {
+ int position = 0;
+ for (Map<String, ?> map : data) {
+ if (map.get(key).equals(value)) {
+ return position;
}
- this.fileName = t.file;
+ position++;
}
+ throw new NoSuchElementException();
}
-
private SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() {
public boolean setViewValue(View view, Object data,
@@ -412,5 +398,4 @@ public class TeamCreatorActivity extends Activity implements Runnable{
}
}
};
-
}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java
new file mode 100644
index 0000000..b2b5d0d
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamListActivity.java
@@ -0,0 +1,129 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageButton;
+import android.widget.SimpleAdapter;
+
+public class TeamListActivity extends ListActivity implements OnItemClickListener {
+ private List<Team> teams;
+ private ImageButton addButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_teamlist);
+ addButton = (ImageButton)findViewById(R.id.btnAdd);
+ addButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ editTeam(null);
+ }
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateList();
+ getListView().setOnItemClickListener(this);
+ registerForContextMenu(getListView());
+ }
+
+ public void onItemClick(AdapterView<?> adapterView, View v, int position, long arg3) {
+ editTeam(teams.get(position).name);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){
+ menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit);
+ menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item){
+ AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
+ int position = menuInfo.position;
+ Team team = teams.get(position);
+ switch(item.getItemId()){
+ case 0:
+ editTeam(team.name);
+ return true;
+ case 1:
+ Team.getTeamfileByName(getApplicationContext(), team.name).delete();
+ updateList();
+ return true;
+ }
+ return false;
+ }
+
+ private void updateList() {
+ teams = FrontendDataUtils.getTeams(getApplicationContext());
+ Collections.sort(teams, Team.NAME_ORDER);
+ SimpleAdapter adapter = new SimpleAdapter(this, teamsToMaps(teams), R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty});
+ setListAdapter(adapter);
+ }
+
+ private void editTeam(String teamName) {
+ Intent i = new Intent(this, TeamCreatorActivity.class);
+ i.putExtra(TeamCreatorActivity.PARAMETER_EXISTING_TEAMNAME, teamName);
+ startActivity(i);
+ }
+
+ private static final int[] botlevelDrawables = new int[] {
+ R.drawable.human, R.drawable.bot5, R.drawable.bot4, R.drawable.bot3, R.drawable.bot2, R.drawable.bot1
+ };
+
+ private List<Map<String, ?>> teamsToMaps(List<Team> teams) {
+ List<Map<String, ?>> result = new ArrayList<Map<String,?>>();
+ for(Team t : teams) {
+ HashMap<String, Object> map = new HashMap<String, Object>();
+ map.put("team", t);
+ map.put("txt", t.name);
+ int botlevel = t.hogs.get(0).level;
+ if(botlevel<0 || botlevel>=botlevelDrawables.length) {
+ map.put("img", R.drawable.bot1);
+ } else {
+ map.put("img", botlevelDrawables[botlevel]);
+ }
+ result.add(map);
+ }
+ return result;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java
deleted file mode 100644
index 628aa7b..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamSelectionActivity.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.hedgewars.hedgeroid.Datastructures.FrontendDataUtils;
-import org.hedgewars.hedgeroid.Datastructures.Team;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.view.ContextMenu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-import android.widget.SimpleAdapter;
-import android.widget.SimpleAdapter.ViewBinder;
-import android.widget.TextView;
-
-public class TeamSelectionActivity extends Activity implements Runnable{
-
- private static final int ACTIVITY_TEAMCREATION = 0;
-
- private ImageButton addTeam, back;
- private ListView availableTeams, selectedTeams;
- private List<HashMap<String, Object>> availableTeamsList, selectedTeamsList;
- private TextView txtInfo;
-
- public void onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.team_selector);
-
- addTeam = (ImageButton) findViewById(R.id.btnAdd);
- back = (ImageButton) findViewById(R.id.btnBack);
- txtInfo = (TextView) findViewById(R.id.txtInfo);
- selectedTeams = (ListView) findViewById(R.id.selectedTeams);
- availableTeams = (ListView) findViewById(R.id.availableTeams);
- addTeam.setOnClickListener(addTeamClicker);
- back.setOnClickListener(backClicker);
-
- availableTeamsList = new ArrayList<HashMap<String, Object>>();
- SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry_simple, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty});
- availableTeams.setAdapter(adapter);
- availableTeams.setOnItemClickListener(availableClicker);
- registerForContextMenu(availableTeams);
-
- selectedTeamsList = new ArrayList<HashMap<String, Object>>();
- adapter = new SimpleAdapter(this, selectedTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img", "color", "count"}, new int[]{R.id.txtName, R.id.imgDifficulty, R.id.teamColor, R.id.teamCount});
- adapter.setViewBinder(viewBinder);
- selectedTeams.setAdapter(adapter);
- selectedTeams.setOnItemClickListener(selectedClicker);
-
- txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeams.getChildCount()));
-
- new Thread(this).start();//load the teams from xml async
- }
-
- public void run(){
- List<HashMap<String, Object>> teamsList = FrontendDataUtils.getTeams(this);//teams from xml
- ArrayList<Team> teamsStartGame = getIntent().getParcelableArrayListExtra("teams");//possible selected teams
-
- for(HashMap<String, Object> hashmap : teamsList){
- boolean added = false;
- for(Team t : teamsStartGame){
- if(((Team)hashmap.get("team")).equals(t)){//add to available or add to selected
- selectedTeamsList.add(FrontendDataUtils.teamToMap(t));//create a new hashmap to ensure all variables are entered into the map
- added = true;
- break;
- }
- }
- if(!added) availableTeamsList.add(hashmap);
- }
-
- this.runOnUiThread(new Runnable(){
- public void run() {
- ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged();
- ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged();
- }
- });
- }
-
- private ViewBinder viewBinder = new ViewBinder(){
- public boolean setViewValue(View view, Object data, String textRepresentation) {
- switch(view.getId()){
- case R.id.teamColor:
- setTeamColor(view, (Integer)data);
- return true;
- case R.id.teamCount:
- setTeamHogCount((ImageView)view, (Integer)data);
- return true;
- default:
- return false;
- }
- }
- };
-
- public void onActivityResult(int requestCode, int resultCode, Intent data){
- if(requestCode == ACTIVITY_TEAMCREATION){
- if(resultCode == Activity.RESULT_OK){
- updateListViews();
- }
- }else{
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-
- /*
- * Updates the list view when TeamCreationActivity is shutdown and the user returns to this point
- */
- private void updateListViews(){
- unregisterForContextMenu(availableTeams);
- availableTeamsList = FrontendDataUtils.getTeams(this);
- ArrayList<HashMap<String, Object>> toBeRemoved = new ArrayList<HashMap<String, Object>>();
- for(HashMap<String, Object> hashmap : selectedTeamsList){
- String name = (String)hashmap.get("txt");
-
- for(HashMap<String, Object> hash : availableTeamsList){
- if(name.equals((String)hash.get("txt"))){
- toBeRemoved.add(hash);
- }
- }
- }
- for(HashMap<String, Object> hash: toBeRemoved) availableTeamsList.remove(hash);
-
- SimpleAdapter adapter = new SimpleAdapter(this, availableTeamsList, R.layout.team_selection_entry, new String[]{"txt", "img"}, new int[]{R.id.txtName, R.id.imgDifficulty});
- availableTeams.setAdapter(adapter);
- registerForContextMenu(availableTeams);
- availableTeams.setOnItemClickListener(availableClicker);
-
-
- }
-
- private void setTeamColor(int position, int color){
- View iv = ((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount);
- setTeamColor(iv, color);
- }
- private void setTeamColor(View iv, int color){
- iv.setBackgroundColor(0xFF000000 + color);
- }
-
- private void setTeamHogCount(int position, int count){
- ImageView iv = (ImageView)((RelativeLayout)selectedTeams.getChildAt(position)).findViewById(R.id.teamCount);
- setTeamHogCount(iv, count);
- }
-
- private void setTeamHogCount(ImageView iv, int count){
-
- switch(count){
- case 0:
- iv.setImageResource(R.drawable.teamcount0);
- break;
- case 1:
- iv.setImageResource(R.drawable.teamcount1);
- break;
- case 2:
- iv.setImageResource(R.drawable.teamcount2);
- break;
- case 3:
- iv.setImageResource(R.drawable.teamcount3);
- break;
- case 4:
- iv.setImageResource(R.drawable.teamcount4);
- break;
- case 5:
- iv.setImageResource(R.drawable.teamcount5);
- break;
- case 6:
- iv.setImageResource(R.drawable.teamcount6);
- break;
- case 7:
- iv.setImageResource(R.drawable.teamcount7);
- break;
- case 8:
- iv.setImageResource(R.drawable.teamcount8);
- break;
- case 9:
- iv.setImageResource(R.drawable.teamcount9);
- break;
- }
- }
-
- public void onBackPressed(){
- returnTeams();
- super.onBackPressed();
- }
-
- private OnClickListener addTeamClicker = new OnClickListener(){
- public void onClick(View v) {
- startActivityForResult(new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class), ACTIVITY_TEAMCREATION);
- }
- };
-
- private OnClickListener backClicker = new OnClickListener(){
- public void onClick(View v){
- returnTeams();
- finish();
- }
- };
-
- private OnItemClickListener availableClicker = new OnItemClickListener(){
- public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3) {
- selectAvailableTeamsItem(position);
- }
- };
- private OnItemClickListener selectedClicker = new OnItemClickListener(){
- public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3) {
- availableTeamsList.add((HashMap<String, Object>) selectedTeamsList.get(position));
- selectedTeamsList.remove(position);
- ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged();
- ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged();
-
- txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size()));
- }
-
- };
-
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){
- menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.select);
- menu.add(ContextMenu.NONE, 2, ContextMenu.NONE, R.string.edit);
- menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete);
-
- }
- public boolean onContextItemSelected(MenuItem item){
- AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
- int position = menuInfo.position;
- switch(item.getItemId()){
- case 0://select
- selectAvailableTeamsItem(position);
- return true;
- case 1://delete
- Team team = (Team)availableTeamsList.get(position).get("team");
- File f = new File(String.format("%s/%s/%s", TeamSelectionActivity.this.getFilesDir(), Team.DIRECTORY_TEAMS, team.file));
- f.delete();
- availableTeamsList.remove(position);
- ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged();
- return true;
- case 2://edit
- Intent i = new Intent(TeamSelectionActivity.this, TeamCreatorActivity.class);
- Team t = (Team)availableTeamsList.get(position).get("team");
- i.putExtra("team", t);
- startActivityForResult(i, ACTIVITY_TEAMCREATION);
- return true;
- }
- return false;
- }
-
- private void selectAvailableTeamsItem(int position){
- HashMap<String, Object> hash = (HashMap<String, Object>) availableTeamsList.get(position);
- Team t = (Team)hash.get("team");
- int[] illegalcolors = new int[selectedTeamsList.size()];
- for(int i = 0; i < selectedTeamsList.size(); i++){
- illegalcolors[i] = ((Team)selectedTeamsList.get(i).get("team")).color;
- }
- t.setRandomColor(illegalcolors);
- hash.put("color", t.color);
- hash.put("count", t.hogCount);
-
- selectedTeamsList.add(hash);
- availableTeamsList.remove(position);
- ((SimpleAdapter)availableTeams.getAdapter()).notifyDataSetChanged();
- ((SimpleAdapter)selectedTeams.getAdapter()).notifyDataSetChanged();
-
- txtInfo.setText(String.format(getResources().getString(R.string.teams_info_template), selectedTeamsList.size()));
- }
-
- private void returnTeams(){
- int teamsCount = selectedTeamsList.size();
- Intent i = new Intent();
- Parcelable[] teams = new Parcelable[teamsCount];
- for(int x = 0 ; x < teamsCount; x++){
- teams[x] = (Team)selectedTeamsList.get(x).get("team");
- }
- i.putExtra("teams", teams);
- setResult(Activity.RESULT_OK, i);
-
- }
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java
new file mode 100644
index 0000000..bc47126
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistAdapter.java
@@ -0,0 +1,154 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.TextView;
+
+public class TeamlistAdapter extends BaseAdapter {
+ private boolean colorHogcountEnabled = false;
+ private Listener listener;
+ private List<TeamInGame> teams = new ArrayList<TeamInGame>();
+
+ public void setColorHogcountEnabled(boolean colorHogcountEnabled) {
+ this.colorHogcountEnabled = colorHogcountEnabled;
+ notifyDataSetChanged();
+ }
+
+ public void setListener(Listener listener) {
+ this.listener = listener;
+ }
+
+ public int getCount() {
+ return teams.size();
+ }
+
+ public TeamInGame getItem(int position) {
+ return teams.get(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ public void updateTeamlist(Collection<TeamInGame> newTeams) {
+ teams.clear();
+ teams.addAll(newTeams);
+ Collections.sort(teams, TeamInGame.NAME_ORDER);
+ notifyDataSetChanged();
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater vi = LayoutInflater.from(parent.getContext());
+ v = vi.inflate(R.layout.listview_team, null);
+ }
+
+ TeamInGame team = getItem(position);
+ TextView teamNameView = (TextView) v.findViewById(android.R.id.text1);
+ ImageButton colorButton = (ImageButton) v.findViewById(R.id.colorButton);
+ ImageButton hogCountButton = (ImageButton) v.findViewById(R.id.hogCountButton);
+
+ teamNameView.setText(team.team.name);
+ int teamImage;
+ if(team.ingameAttribs.remoteDriven) {
+ teamImage = R.drawable.team_net_by_level;
+ } else {
+ teamImage = R.drawable.team_local_by_level;
+ }
+
+ Drawable d = parent.getContext().getResources().getDrawable(teamImage).mutate();
+ d.setLevel(team.team.hogs.get(0).level);
+ teamNameView.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null);
+ hogCountButton.getDrawable().setLevel(team.ingameAttribs.hogCount);
+ colorButton.setImageDrawable(new ColorDrawable(TeamIngameAttributes.TEAM_COLORS[team.ingameAttribs.colorIndex]));
+
+ colorButton.setEnabled(colorHogcountEnabled);
+ hogCountButton.setEnabled(colorHogcountEnabled);
+
+ colorButton.setOnClickListener(new ButtonClickListener(team, Type.COLOR_BUTTON));
+ hogCountButton.setOnClickListener(new ButtonClickListener(team, Type.HOGCOUNT_BUTTON));
+
+ if(team.ingameAttribs.remoteDriven) {
+ teamNameView.setClickable(false);
+ } else {
+ teamNameView.setOnClickListener(new ButtonClickListener(team, Type.TEAM_VIEW));
+ }
+
+ return v;
+ }
+
+ private static enum Type {COLOR_BUTTON, HOGCOUNT_BUTTON, TEAM_VIEW}
+ private final class ButtonClickListener implements OnClickListener {
+ private final TeamInGame team;
+ private final Type type;
+
+ public ButtonClickListener(TeamInGame team, Type type) {
+ this.team = team;
+ this.type = type;
+ }
+
+ public void onClick(View v) {
+ if(listener != null) {
+ switch(type) {
+ case COLOR_BUTTON:
+ listener.onColorClicked(team);
+ break;
+ case HOGCOUNT_BUTTON:
+ listener.onHogcountClicked(team);
+ break;
+ case TEAM_VIEW:
+ listener.onTeamClicked(team);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ }
+ }
+ }
+
+ public interface Listener {
+ void onTeamClicked(TeamInGame team);
+ void onColorClicked(TeamInGame team);
+ void onHogcountClicked(TeamInGame team);
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java
new file mode 100644
index 0000000..2d070df
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TeamlistFragment.java
@@ -0,0 +1,119 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class TeamlistFragment extends ListFragment implements TeamlistAdapter.Listener {
+ private TeamlistAdapter adapter;
+ private Button addTeamButton;
+ private RoomStateManager stateManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ try {
+ stateManager = ((RoomStateManager.Provider)getActivity()).getRoomStateManager();
+ } catch(ClassCastException e) {
+ throw new RuntimeException("Hosting activity must implement RoomStateManager.Provider.", e);
+ }
+ adapter = new TeamlistAdapter();
+ adapter.updateTeamlist(stateManager.getTeams().values());
+ adapter.setColorHogcountEnabled(stateManager.getChiefStatus());
+ adapter.setListener(this);
+ setListAdapter(adapter);
+ stateManager.addListener(roomStateChangeListener);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.fragment_teamlist, container, false);
+ addTeamButton = (Button)v.findViewById(R.id.addTeamButton);
+ addTeamButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ new TeamAddDialog(getCurrentTeamNames()).show(getFragmentManager(), "team_add_dialog");
+ }
+ });
+
+ addTeamButton.setEnabled(stateManager.getTeams().size() < Team.maxNumberOfTeams);
+
+ return v;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ adapter.setListener(null);
+ stateManager.removeListener(roomStateChangeListener);
+ }
+
+ private Collection<String> getCurrentTeamNames() {
+ List<String> names = new ArrayList<String>();
+ for(TeamInGame team : stateManager.getTeams().values()) {
+ names.add(team.team.name);
+ }
+ return names;
+ }
+
+ public void onColorClicked(TeamInGame team) {
+ stateManager.changeTeamColorIndex(team.team.name, (team.ingameAttribs.colorIndex+1)%TeamIngameAttributes.TEAM_COLORS.length);
+ }
+
+ public void onHogcountClicked(TeamInGame team) {
+ int newHogCount = team.ingameAttribs.hogCount+1;
+ if(newHogCount>Team.HEDGEHOGS_PER_TEAM) {
+ newHogCount = 1;
+ }
+ stateManager.changeTeamHogCount(team.team.name, newHogCount);
+ }
+
+ public void onTeamClicked(TeamInGame team) {
+ stateManager.requestRemoveTeam(team.team.name);
+ }
+
+ private final RoomStateManager.Listener roomStateChangeListener = new RoomStateManager.ListenerAdapter() {
+ @Override
+ public void onChiefStatusChanged(boolean isChief) {
+ adapter.setColorHogcountEnabled(isChief);
+ };
+
+ @Override
+ public void onTeamsChanged(Map<String, TeamInGame> teams) {
+ adapter.updateTeamlist(teams.values());
+ addTeamButton.setEnabled(teams.size() < Team.maxNumberOfTeams);
+ };
+ };
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java
index 6082e44..3076c7e 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/TextImageAdapter.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,10 +14,9 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java
index 6d7567f..454effb 100644
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/UserInput/TouchInterface.java
@@ -2,9 +2,10 @@
* Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
* Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,9 +14,8 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.hedgewars.hedgeroid.UserInput;
import org.hedgewars.hedgeroid.SDLActivity;
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java
deleted file mode 100644
index 5ccff91..0000000
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/Utils.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
- * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.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
- */
-
-
-package org.hedgewars.hedgeroid;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.Build;
-import android.os.Environment;
-import android.util.Log;
-
-public class Utils {
-
- private static final String ROOT_DIR = "Data/";
-
- /**
- * get the path to which we should download all the data files
- * @param c context
- * @return absolute path
- */
- public static String getCachePath(Context c){
- if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO
- return PreFroyoSDCardDir.getDownloadPath(c) + '/';
- }else{
- return FroyoSDCardDir.getDownloadPath(c) + '/';
- }
- }
-
- public static String getDataPath(Context c){
- return getCachePath(c) + ROOT_DIR;
- }
-
- static class FroyoSDCardDir{
- public static String getDownloadPath(Context c){
- File f = c.getExternalCacheDir();
- if(f != null){
- return f.getAbsolutePath();
- }else{
- return null;
- }
- }
- }
-
- static class PreFroyoSDCardDir{
- public static String getDownloadPath(Context c){
- if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
- if(Environment.getExternalStorageDirectory() != null)
- return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Hedgewars/";
- }
- return null;
- }
- }
-
- /**
- * Get files from dirName, dir name is relative to {@link getDownloadPath}
- * @param dirName
- * @param c context
- * @return string of files
- */
- public static String[] getFileNamesFromRelativeDir(Context c, String dirName){
- String prefix = getDataPath(c);
- File f = new File(prefix + dirName);
-
- if(f.exists() && f.isDirectory()) return f.list();
- else{
-
- Log.e("Utils::", "Couldn't find dir: " + dirName);
- return new String[0];
- }
- }
-
- /**
- * Return a File array with all the files from dirName
- * @param c
- * @param dirName
- * @return
- */
- public static File[] getFilesFromRelativeDir(Context c, String dirName){
- String prefix = getDataPath(c);
- File f = new File(prefix + dirName);
-
- if(f.exists() && f.isDirectory()) return f.listFiles();
- else {
- Log.e("Utils::", "Dir not found: " + dirName);
- return new File[0];
- }
- }
-
- /**
- * Checks if this directory has a file with suffix suffix
- * @param f - directory
- * @return
- */
- public static boolean hasFileWithSuffix(File f, String suffix){
- if(f.isDirectory()){
- for(String s : f.list()){
- if(s.endsWith(suffix)) return true;
- }
- return false;
- }else{
- return false;
- }
- }
-
- /**
- * Gives back all dirs which contain a file with suffix fileSuffix
- * @param c
- * @param path
- * @param fileSuffix
- * @return
- */
- public static List<String> getDirsWithFileSuffix(Context c, String path, String fileSuffix){
- File[] files = getFilesFromRelativeDir(c,path);
- ArrayList<String> ret = new ArrayList<String>();
-
- for(File f : files){
- if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName());
- }
- return ret;
- }
-
- /**
- * Get all files from directory dir which have the given suffix
- * @param c
- * @param dir
- * @param suffix
- * @param removeSuffix
- * @return
- */
- public static ArrayList<String> getFilesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix){
- String[] files = Utils.getFileNamesFromRelativeDir(c, dir);
- ArrayList<String> ret = new ArrayList<String>();
- for(String s : files){
- if(s.endsWith(suffix)){
- if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length()));
- else ret.add(s);
- }
- }
- return ret;
- }
-
- /**
- * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
- * @param c
- * @param sourceResId
- * @param directory
- */
- public static void resRawToFilesDir(Context c, int sourceResId, String directory){
- byte[] buffer = new byte[1024];
- InputStream bis = null;
- BufferedOutputStream bos = null;
- File schemesDirFile = new File(c.getFilesDir().getAbsolutePath() + '/' + directory);
- schemesDirFile.mkdirs();
- String schemesDirPath = schemesDirFile.getAbsolutePath() + '/';
-
- //Get an array with the resource files ID
- TypedArray ta = c.getResources().obtainTypedArray(sourceResId);
- int[] resIds = new int[ta.length()];
- for(int i = 0; i < ta.length(); i++){
- resIds[i] = ta.getResourceId(i, 0);
- }
-
- for(int id : resIds){
- String fileName = c.getResources().getResourceEntryName(id);
- File f = new File(schemesDirPath + fileName);
- try {
- if(!f.createNewFile()){
- f.delete();
- f.createNewFile();
- }
-
- bis = c.getResources().openRawResource(id);
- bos = new BufferedOutputStream(new FileOutputStream(f), 1024);
- int read = 0;
- while((read = bis.read(buffer)) != -1){
- bos.write(buffer, 0, read);
- }
-
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- if(bis != null)
- try {
- bis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- if(bos != null)
- try {
- bos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java
new file mode 100644
index 0000000..5e51c56
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetCreatorActivity.java
@@ -0,0 +1,8 @@
+package org.hedgewars.hedgeroid;
+
+import android.support.v4.app.FragmentActivity;
+
+// TODO
+public class WeaponsetCreatorActivity extends FragmentActivity {
+ public static final String PARAMETER_EXISTING_WEAPONSETNAME="existingWeaponsetName";
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java
new file mode 100644
index 0000000..01f7b7d
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/WeaponsetListActivity.java
@@ -0,0 +1,126 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+import org.hedgewars.hedgeroid.Datastructures.Weaponsets;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.ContextMenu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.ListAdapter;
+import android.widget.SimpleAdapter;
+import android.widget.Toast;
+
+public class WeaponsetListActivity extends ListActivity implements OnItemClickListener {
+ private List<Weaponset> userWeaponsets;
+ private Button addButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_weaponsetlist);
+ addButton = (Button)findViewById(R.id.addButton);
+ addButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ editWeaponset(null);
+ }
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateList();
+ getListView().setOnItemClickListener(this);
+ registerForContextMenu(getListView());
+ }
+
+ private List<Map<String, ?>> weaponsetsToMap(List<Weaponset> weaponsets) {
+ List<Map<String, ?>> result = new ArrayList<Map<String, ?>>();
+ for(Weaponset weaponset : weaponsets) {
+ result.add(Collections.singletonMap("txt", weaponset.name));
+ }
+ return result;
+ }
+
+ public void onItemClick(AdapterView<?> adapterView, View v, int position, long arg3) {
+ editWeaponset(userWeaponsets.get(position).name);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo){
+ menu.add(ContextMenu.NONE, 0, ContextMenu.NONE, R.string.edit);
+ menu.add(ContextMenu.NONE, 1, ContextMenu.NONE, R.string.delete);
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item){
+ AdapterView.AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
+ int position = menuInfo.position;
+ Weaponset weaponset = userWeaponsets.get(position);
+ switch(item.getItemId()){
+ case 0:
+ editWeaponset(weaponset.name);
+ return true;
+ case 1:
+ try {
+ Weaponsets.deleteUserWeaponset(this, weaponset.name);
+ } catch (IOException e) {
+ Toast.makeText(this.getApplicationContext(), R.string.error_missing_sdcard_or_files, Toast.LENGTH_SHORT).show();
+ }
+ updateList();
+ return true;
+ }
+ return false;
+ }
+
+ private void updateList() {
+ try {
+ userWeaponsets = Weaponsets.loadUserWeaponsets(this);
+ } catch (IOException e) {
+ Toast.makeText(this, R.string.error_missing_sdcard_or_files, Toast.LENGTH_LONG).show();
+ finish();
+ }
+ Collections.sort(userWeaponsets, Weaponset.NAME_ORDER);
+ ListAdapter adapter = new SimpleAdapter(this, weaponsetsToMap(userWeaponsets), android.R.layout.simple_list_item_1, new String[]{"txt"}, new int[]{android.R.id.text1});
+ setListAdapter(adapter);
+ }
+
+ private void editWeaponset(String weaponsetName) {
+ Intent i = new Intent(this, WeaponsetCreatorActivity.class);
+ i.putExtra(WeaponsetCreatorActivity.PARAMETER_EXISTING_WEAPONSETNAME, weaponsetName);
+ startActivity(i);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java
new file mode 100644
index 0000000..5974bf1
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/AndroidTypeMapper.java
@@ -0,0 +1,63 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.frontlib;
+
+import com.sun.jna.DefaultTypeMapper;
+import com.sun.jna.FromNativeContext;
+import com.sun.jna.ToNativeContext;
+import com.sun.jna.TypeConverter;
+import com.sun.jna.TypeMapper;
+
+class AndroidTypeMapper extends DefaultTypeMapper {
+ static final int NATIVE_INT_SIZE = 4;
+ static final int NATIVE_SIZE_T_SIZE = 4;
+ static final int NATIVE_BOOL_SIZE = 1;
+ public static final TypeMapper INSTANCE = new AndroidTypeMapper();
+
+ protected AndroidTypeMapper() {
+ addTypeConverter(Boolean.class, new BooleanConverter());
+ addTypeConverter(NativeSizeT.class, new SizeTConverter());
+ }
+
+ private static final class BooleanConverter implements TypeConverter {
+ public Class<Byte> nativeType() {
+ return Byte.class;
+ }
+ public Object fromNative(Object value, FromNativeContext context) {
+ return ((Byte)value).intValue() != 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
+ public Object toNative(Object value, ToNativeContext context) {
+ return Byte.valueOf((byte)(Boolean.TRUE.equals(value) ? 1 : 0));
+ }
+ }
+
+ private static final class SizeTConverter implements TypeConverter {
+ public Class<Integer> nativeType() {
+ return Integer.class;
+ }
+ public Object fromNative(Object value, FromNativeContext context) {
+ return NativeSizeT.valueOf((Integer)value);
+ }
+ public Object toNative(Object value, ToNativeContext context) {
+ return Integer.valueOf(value==null ? 0 : ((NativeSizeT)value).intValue());
+ }
+ }
+}
+
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java
new file mode 100644
index 0000000..ef5b6d8
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Flib.java
@@ -0,0 +1,62 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.frontlib;
+
+import java.util.Collections;
+
+import android.util.Log;
+
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
+public class Flib {
+ static {
+ System.loadLibrary("SDL");
+ System.loadLibrary("SDL_net");
+ System.setProperty("jna.encoding", "UTF8"); // Ugly global setting, but it seems JNA doesn't allow setting this per-library...
+ }
+ public static final Frontlib INSTANCE = (Frontlib)Native.loadLibrary("frontlib", Frontlib.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, AndroidTypeMapper.INSTANCE));
+
+ static {
+ // We'll just do it here and never quit it again...
+ if(Flib.INSTANCE.flib_init() != 0) {
+ throw new RuntimeException("Unable to initialize frontlib");
+ }
+ }
+
+ // Hook frontlib logging into Android logging
+ private static final Frontlib.LogCallback logCb = new Frontlib.LogCallback() {
+ public void callback(int level, String message) {
+ if(level >= Frontlib.FLIB_LOGLEVEL_ERROR) {
+ Log.e("Frontlib", message);
+ } else if(level == Frontlib.FLIB_LOGLEVEL_WARNING){
+ Log.w("Frontlib", message);
+ } else if(level == Frontlib.FLIB_LOGLEVEL_INFO){
+ Log.i("Frontlib", message);
+ } else if(level <= Frontlib.FLIB_LOGLEVEL_DEBUG){
+ Log.d("Frontlib", message);
+ }
+ }
+ };
+ static {
+ INSTANCE.flib_log_setLevel(Frontlib.FLIB_LOGLEVEL_INFO);
+ INSTANCE.flib_log_setCallback(logCb);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java
new file mode 100644
index 0000000..f8b93c0
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java
@@ -0,0 +1,1263 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+package org.hedgewars.hedgeroid.frontlib;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hedgewars.hedgeroid.Datastructures.Hog;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.MetaScheme;
+import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod;
+import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting;
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.Room;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+
+import com.sun.jna.Callback;
+import com.sun.jna.Library;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.PointerType;
+import com.sun.jna.Structure;
+
+/**
+ * Here is an introduction to the most important aspects of the JNA code.
+ *
+ * This interface permits access to the Hedgewars frontend library (frontlib)
+ * from Java. Each function directly contained in the Frontlib interface
+ * represents a mapped C function. The Structure classes (ending in -Struct) are
+ * mappings of C structs, and the PointerType classes (ending in -Ptr) represent
+ * pointers to structs.
+ *
+ * Quick notes for USING these classes from outside this package:
+ *
+ * Usage should be fairly straightforward, but there are a few surprising
+ * gotchas. First, when you implement callbacks, YOU are responsible for
+ * ensuring that the callback objects are not garbage-collected while they might
+ * still be called! So make sure you keep them in member variables or similar,
+ * because Java will not know if there are still native references to them.
+ *
+ * When using Frontlib from outside its package, you only interact with structs
+ * via the PointerType classes. They allow you to get at the data of the struct
+ * with a function called deref(), which creates a plain normal Java object
+ * representing the data (e.g. SchemePtr.deref() will give you a Scheme object).
+ *
+ * Remember that you usually have to destroy structs that you receive from the
+ * library, because they are owned by the native code, not Java. The recommended
+ * pattern for most cases is to call deref() on the pointer to get a Java object
+ * (that you can keep as long as you like), and then immediately destroy the
+ * struct if it needs destroying. To find out whether and how the struct needs
+ * to be destroyed, see the library's documentation of the function that you got
+ * the struct from.
+ *
+ * To pass new structs to the library, you can use the static createJavaOwned()
+ * function in each PointerType, which creates a new struct from the Java object
+ * you provide, and returns a pointer to that struct that you can pass to
+ * library functions. This new structure's memory is owned and managed by Java
+ * code, so do not destroy it with frontlib functions!
+ *
+ * There is a slight mismatch between the data model for the game setup. The
+ * frontlib supports setting initial health and weaponset per-hog, because the
+ * engine allows for that, but currently neither the networking protocol nor the
+ * PC frontend support this feature, so the Android version does not take
+ * advantage of it either and treats both as per-game settings. The initial
+ * health is contained in the game scheme, the weaponset is explicitly part of
+ * the GameConfig. When converting GameConfig to a native flib_gamesetup, both
+ * are automatically copied to all hogs in the game, and for the reverse
+ * conversion the weaponset of the first hog of the first team is used as the
+ * GameConfig weaponset. This means that GameConfig.weaponset will be null if
+ * there are no teams in the game.
+ *
+ * When starting a network game, you only need to query the GameSetupPtr from
+ * the netconn and use it to create the gameconn - this is preferable to using
+ * your own recreation of the game setup, because that way the same piece of
+ * code is used to determine the game setup on all platforms.
+ *
+ * The "context" parameter of the callbacks is never needed here because JNA
+ * generates function code for each callback object. Don't worry about it, just
+ * pass null for context and ignore the context parameter in the callbacks.
+ *
+ * Finally, the library functions are documented in the actual library, not
+ * here, so check the docs there to find out what exactly each function does!
+ *
+ * Notes about the structure of this class (for the next one who has to touch
+ * this...):
+ *
+ * Java/C interop is quite fiddly and error-prone, so as long as things work,
+ * try to stick to the established patterns.
+ *
+ * Structure types should always be hidden from the outside world, because they
+ * can be misused too easily. For example, if you get a Structure from the
+ * library, change a String value in there and pass it back, JNA will re-write
+ * that string using Java-owned memory without freeing the old native-owned
+ * string, which causes a memory leak and possibly a double-free or other Bad
+ * Things (tm). To avoid problems like this, Structure types are only used
+ * internally, to map existing structures to Java types (without modifying them)
+ * or to create brand-new, Java-owned structures. Both operations are exposed to
+ * the outside through the PointerType classes corresponding to the structures
+ * in question.
+ *
+ * Since all of the struct mapping happens in Java, it is never checked against
+ * the actual struct declarations in the library. That means strange things can
+ * start happening at runtime if the frontlib structs are modified without
+ * changing the mappings here to match. This also applies to the function
+ * signatures: JNA checks whether the functions actually exist when loading the
+ * library, but it has no way of knowing whether the signatures are correct. If
+ * the signatures here deviate from those in the frontlib, you might get stack
+ * corruption.
+ *
+ * In order to check at least the function signatures, take a look at the file
+ * extra/jnacontrol.c in the frontlib sources. You can validate whether the
+ * function signatures are still correct by copy-pasting them into jnaControl.c
+ * and compiling it against the frontlib headers. The typedefs and #defines in
+ * that file will make the compiler see the Java method signatures as C function
+ * declarations. Since the same functions are already declared in the frontlib
+ * headers, the compiler will give you errors if the signatures don't match.
+ */
+public interface Frontlib extends Library {
+ public static class NetconnPtr extends PointerType { }
+ public static class MapconnPtr extends PointerType { }
+ public static class GameconnPtr extends PointerType { }
+
+ public static class MetaschemePtr extends PointerType {
+ public MetaScheme deref() {
+ return deref(getPointer());
+ }
+
+ public static MetaScheme deref(Pointer p) {
+ MetaschemeStruct struct = new MetaschemeStruct(p);
+ struct.read();
+ return struct.toMetaScheme();
+ }
+ }
+
+ public static class RoomArrayPtr extends PointerType {
+ public Room[] getRooms(int count) {
+ Pointer ptr = getPointer();
+ if(ptr == null) {
+ return new Room[0];
+ }
+ Pointer[] untypedPtrs = ptr.getPointerArray(0, count);
+ Room[] result = new Room[count];
+ for(int i=0; i<count; i++) {
+ result[i] = RoomPtr.deref(untypedPtrs[i]);
+ }
+ return result;
+ }
+ }
+
+ public static class RoomPtr extends PointerType {
+ public Room deref() {
+ return deref(getPointer());
+ }
+
+ public static Room deref(Pointer p) {
+ RoomStruct struct = new RoomStruct(p);
+ struct.read();
+ return struct.toRoomlistRoom();
+ }
+ }
+
+ public static class TeamPtr extends PointerType {
+ private TeamStruct javaOwnedInstance;
+
+ public TeamInGame deref() {
+ TeamStruct struct = new TeamStruct(getPointer());
+ struct.read();
+ return struct.toTeamInGame();
+ }
+
+ public static TeamPtr createJavaOwned(Team t) {
+ return createJavaOwned(new TeamInGame(t, null));
+ }
+
+ public static TeamPtr createJavaOwned(TeamInGame ingameTeam) {
+ TeamPtr result = new TeamPtr();
+ result.javaOwnedInstance = new TeamStruct();
+ result.javaOwnedInstance.fillFrom(ingameTeam.team, ingameTeam.ingameAttribs);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class WeaponsetPtr extends PointerType {
+ private WeaponsetStruct javaOwnedInstance;
+
+ public Weaponset deref() {
+ WeaponsetStruct struct = new WeaponsetStruct(getPointer());
+ struct.read();
+ return struct.toWeaponset();
+ }
+
+ public static WeaponsetPtr createJavaOwned(Weaponset weaponset) {
+ WeaponsetPtr result = new WeaponsetPtr();
+ result.javaOwnedInstance = new WeaponsetStruct();
+ result.javaOwnedInstance.fillFrom(weaponset);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class WeaponsetListPtr extends PointerType {
+ private WeaponsetListStruct javaOwnedInstance;
+
+ public List<Weaponset> deref() {
+ WeaponsetListStruct struct = new WeaponsetListStruct(getPointer());
+ struct.read();
+ return struct.toWeaponsetList();
+ }
+
+ public static WeaponsetListPtr createJavaOwned(List<Weaponset> list) {
+ WeaponsetListPtr result = new WeaponsetListPtr();
+ result.javaOwnedInstance = new WeaponsetListStruct();
+ result.javaOwnedInstance.fillFrom(list);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class MapRecipePtr extends PointerType {
+ private MapRecipeStruct javaOwnedInstance;
+
+ public MapRecipe deref() {
+ MapRecipeStruct struct = new MapRecipeStruct(getPointer());
+ struct.read();
+ return struct.toMapRecipe();
+ }
+
+ public static MapRecipePtr createJavaOwned(MapRecipe recipe) {
+ MapRecipePtr result = new MapRecipePtr();
+ result.javaOwnedInstance = new MapRecipeStruct();
+ result.javaOwnedInstance.fillFrom(recipe);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class SchemePtr extends PointerType {
+ private SchemeStruct javaOwnedInstance;
+
+ public Scheme deref() {
+ SchemeStruct struct = new SchemeStruct(getPointer());
+ struct.read();
+ return struct.toScheme();
+ }
+
+ public static SchemePtr createJavaOwned(Scheme scheme) {
+ SchemePtr result = new SchemePtr();
+ result.javaOwnedInstance = new SchemeStruct();
+ result.javaOwnedInstance.fillFrom(scheme);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class SchemelistPtr extends PointerType {
+ private SchemelistStruct javaOwnedInstance;
+
+ public List<Scheme> deref() {
+ SchemelistStruct struct = new SchemelistStruct(getPointer());
+ struct.read();
+ return struct.toSchemeList();
+ }
+
+ public static SchemelistPtr createJavaOwned(List<Scheme> schemes) {
+ SchemelistPtr result = new SchemelistPtr();
+ result.javaOwnedInstance = new SchemelistStruct();
+ result.javaOwnedInstance.fillFrom(schemes);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class GameSetupPtr extends PointerType {
+ private GameSetupStruct javaOwnedInstance;
+
+ public GameConfig deref() {
+ GameSetupStruct struct = new GameSetupStruct(getPointer());
+ struct.read();
+ return struct.toGameConfig();
+ }
+
+ public static GameSetupPtr createJavaOwned(GameConfig conf) {
+ GameSetupPtr result = new GameSetupPtr();
+ result.javaOwnedInstance = new GameSetupStruct();
+ result.javaOwnedInstance.fillFrom(conf);
+ result.javaOwnedInstance.autoWrite();
+ result.setPointer(result.javaOwnedInstance.getPointer());
+ return result;
+ }
+ }
+
+ public static class ByteArrayPtr extends PointerType {
+ public byte[] deref(int size) {
+ return getPointer().getByteArray(0, size);
+ }
+
+ public static byte[] deref(ByteArrayPtr ptr, int size) {
+ if(ptr==null && size==0) {
+ return null;
+ } else {
+ return ptr.deref(size);
+ }
+ }
+
+ public static ByteArrayPtr createJavaOwned(byte[] buffer) {
+ if(buffer == null || buffer.length == 0) {
+ return null;
+ }
+ // no need for javaOwnedInstance here because PointerType
+ // remembers the memory as its Pointer
+ Pointer ptr = new Memory(buffer.length);
+ ptr.write(0, buffer, 0, buffer.length);
+ ByteArrayPtr result = new ByteArrayPtr();
+ result.setPointer(ptr);
+ return result;
+ }
+ }
+
+ static class HogStruct extends Structure {
+ public static class ByVal extends HogStruct implements Structure.ByValue {}
+ public static class ByRef extends HogStruct implements Structure.ByReference {}
+
+ public HogStruct() { super(); }
+ public HogStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset");
+ }
+
+ public void fillFrom(Hog hog) {
+ difficulty = hog.level;
+ hat = hog.hat;
+ name = hog.name;
+ }
+
+ public Hog toHog() {
+ return new Hog(name, hat, difficulty);
+ }
+
+ public String name;
+ public String hat;
+
+ public int rounds;
+ public int kills;
+ public int deaths;
+ public int suicides;
+
+ public int difficulty;
+
+ public int initialHealth;
+ public WeaponsetStruct.ByRef weaponset;
+ }
+
+ static class TeamStruct extends Structure {
+ public static class ByVal extends TeamStruct implements Structure.ByValue {}
+ public static class ByRef extends TeamStruct implements Structure.ByReference {}
+
+ public TeamStruct() { super(); }
+ public TeamStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName");
+ }
+
+ public void fillFrom(Team team, TeamIngameAttributes attrs) {
+ if(team != null) {
+ name = team.name;
+ grave = team.grave;
+ flag = team.flag;
+ voicepack = team.voice;
+ fort = team.fort;
+ if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) {
+ throw new IllegalArgumentException();
+ }
+ for(int i=0; i<hogs.length; i++) {
+ hogs[i] = new HogStruct();
+ hogs[i].fillFrom(team.hogs.get(i));
+ }
+ }
+
+ if(attrs != null) {
+ hogsInGame = attrs.hogCount;
+ ownerName = attrs.ownerName;
+ colorIndex = attrs.colorIndex;
+ remoteDriven = attrs.remoteDriven;
+ }
+ }
+
+ public void fillFrom(TeamInGame team, WeaponsetStruct.ByRef weaponset, int initialHealth) {
+ fillFrom(team.team, team.ingameAttribs);
+ for(int i=0; i<hogs.length; i++) {
+ hogs[i].initialHealth = initialHealth;
+ hogs[i].weaponset = weaponset;
+ }
+ }
+
+ public Team toTeam() {
+ List<Hog> hogList = new ArrayList<Hog>();
+ for(int i=0; i<hogs.length; i++) {
+ hogList.add(hogs[i].toHog());
+ }
+ return new Team(name, grave, flag, voicepack, fort, hogList);
+ }
+
+ public TeamIngameAttributes toTeamIngameAttributes() {
+ return new TeamIngameAttributes(ownerName, colorIndex, hogsInGame, remoteDriven);
+ }
+
+ public TeamInGame toTeamInGame() {
+ return new TeamInGame(toTeam(), toTeamIngameAttributes());
+ }
+
+ public HogStruct[] hogs = new HogStruct[Team.HEDGEHOGS_PER_TEAM];
+ public String name;
+ public String grave;
+ public String fort;
+ public String voicepack;
+ public String flag;
+
+ public Pointer bindings;
+ public int bindingCount;
+
+ public int rounds;
+ public int wins;
+ public int campaignProgress;
+
+ public int colorIndex;
+ public int hogsInGame;
+ public boolean remoteDriven;
+ public String ownerName;
+ }
+
+ static class WeaponsetStruct extends Structure {
+ public static class ByVal extends WeaponsetStruct implements Structure.ByValue {}
+ public static class ByRef extends WeaponsetStruct implements Structure.ByReference {}
+
+ public WeaponsetStruct() { super(); }
+ public WeaponsetStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("loadout", "crateprob", "crateammo", "delay", "name");
+ }
+
+ public void fillFrom(Weaponset weaponset) {
+ fillWeaponInfo(loadout, weaponset.loadout);
+ fillWeaponInfo(crateprob, weaponset.crateProb);
+ fillWeaponInfo(crateammo, weaponset.crateAmmo);
+ fillWeaponInfo(delay, weaponset.delay);
+ name = weaponset.name;
+ }
+
+ private static void fillWeaponInfo(byte[] array, String str) {
+ for(int i=0; i<array.length-1; i++) {
+ array[i] = (byte) (i<str.length() ? str.charAt(i) : '0');
+ }
+ array[array.length-1] = (byte)0;
+ }
+
+ public Weaponset toWeaponset() {
+ return new Weaponset(name, weaponInfoToString(loadout), weaponInfoToString(crateprob), weaponInfoToString(crateammo), weaponInfoToString(delay));
+ }
+
+ private static String weaponInfoToString(byte[] array) {
+ try {
+ return new String(array, 0, array.length-1, "ASCII");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ }
+
+ public byte[] loadout = new byte[Weaponset.WEAPONS_COUNT+1];
+ public byte[] crateprob = new byte[Weaponset.WEAPONS_COUNT+1];
+ public byte[] crateammo = new byte[Weaponset.WEAPONS_COUNT+1];
+ public byte[] delay = new byte[Weaponset.WEAPONS_COUNT+1];
+ public String name;
+ }
+
+ /**
+ * Represents a flib_weaponset*, for use as part of a flib_weaponset**
+ */
+ static class WeaponsetPointerByReference extends Structure implements Structure.ByReference {
+ public WeaponsetPointerByReference() { super(); }
+ public WeaponsetPointerByReference(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("weaponset");
+ }
+
+ public WeaponsetStruct.ByRef weaponset;
+ }
+
+ static class WeaponsetListStruct extends Structure {
+ public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {}
+ public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {}
+
+ public WeaponsetListStruct() { super(); }
+ public WeaponsetListStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("weaponsetCount", "weaponsets");
+ }
+
+ public void fillFrom(List<Weaponset> list) {
+ weaponsetCount = list.size();
+ if(weaponsetCount<=0) {
+ weaponsets = null;
+ } else {
+ weaponsets = new WeaponsetPointerByReference();
+ Structure[] structs = weaponsets.toArray(weaponsetCount);
+
+ for(int i=0; i<weaponsetCount; i++) {
+ WeaponsetPointerByReference pstruct = (WeaponsetPointerByReference)structs[i];
+ pstruct.weaponset = new WeaponsetStruct.ByRef();
+ pstruct.weaponset.fillFrom(list.get(i));
+ }
+ }
+ }
+
+ /**
+ * Only use on native-owned structs!
+ * Calling this method on a Java-owned struct could cause garbage collection of referenced
+ * structures.
+ */
+ public List<Weaponset> toWeaponsetList() {
+ if(weaponsetCount<=0) {
+ return new ArrayList<Weaponset>();
+ } else {
+ List<Weaponset> list = new ArrayList<Weaponset>(weaponsetCount);
+ Structure[] structs = weaponsets.toArray(weaponsetCount);
+
+ for(int i=0; i<weaponsetCount; i++) {
+ WeaponsetPointerByReference pstruct = (WeaponsetPointerByReference)structs[i];
+ list.add(pstruct.weaponset.toWeaponset());
+ }
+ return list;
+ }
+ }
+
+ public int weaponsetCount;
+ public WeaponsetPointerByReference weaponsets;
+ }
+
+ static class RoomStruct extends Structure {
+ public static class ByVal extends RoomStruct implements Structure.ByValue {}
+ public static class ByRef extends RoomStruct implements Structure.ByReference {}
+
+ public RoomStruct() { super(); }
+ public RoomStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons");
+ }
+
+ public Room toRoomlistRoom() {
+ return new Room(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress);
+ }
+
+ public boolean inProgress;
+ public String name;
+ public int playerCount;
+ public int teamCount;
+ public String owner;
+ public String map;
+ public String scheme;
+ public String weapons;
+ }
+
+ static class MapRecipeStruct extends Structure {
+ public static class ByVal extends MapRecipeStruct implements Structure.ByValue {}
+ public static class ByRef extends MapRecipeStruct implements Structure.ByReference {}
+
+ public MapRecipeStruct() { super(); }
+ public MapRecipeStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize");
+ }
+
+ public void fillFrom(MapRecipe map) {
+ mapgen = map.mapgen;
+ name = map.name;
+ seed = map.seed;
+ theme = map.theme;
+ byte[] buf = map.getDrawData();
+ drawData = ByteArrayPtr.createJavaOwned(buf);
+ drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length);
+ templateFilter = map.templateFilter;
+ mazeSize = map.mazeSize;
+ }
+
+ public MapRecipe toMapRecipe() {
+ byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue());
+ return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf);
+ }
+
+ public int mapgen;
+ public String name;
+ public String seed;
+ public String theme;
+ public ByteArrayPtr drawData;
+ public NativeSizeT drawDataSize;
+ public int templateFilter;
+ public int mazeSize;
+ }
+
+ static class MetaschemeSettingStruct extends Structure {
+ public static class ByVal extends MetaschemeSettingStruct implements Structure.ByValue {}
+ public static class ByRef extends MetaschemeSettingStruct implements Structure.ByReference {}
+
+ public MetaschemeSettingStruct() { super(); }
+ public MetaschemeSettingStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("name", "engineCommand", "maxMeansInfinity", "times1000", "min", "max", "def");
+ }
+
+ public void fillFrom(Setting setting) {
+ name = setting.name;
+ engineCommand = setting.engineCommand;
+ maxMeansInfinity = setting.maxMeansInfinity;
+ times1000 = setting.times1000;
+ min = setting.min;
+ max = setting.max;
+ def = setting.def;
+ }
+
+ public MetaScheme.Setting toMetaSchemeSetting() {
+ return new MetaScheme.Setting(name, engineCommand, maxMeansInfinity, times1000, min, max, def);
+ }
+
+ public String name;
+ public String engineCommand;
+ public boolean maxMeansInfinity;
+ public boolean times1000;
+ public int min;
+ public int max;
+ public int def;
+ }
+
+ static class MetaschemeModStruct extends Structure {
+ public static class ByVal extends MetaschemeModStruct implements Structure.ByValue {}
+ public static class ByRef extends MetaschemeModStruct implements Structure.ByReference {}
+
+ public MetaschemeModStruct() { super(); }
+ public MetaschemeModStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("name", "bitmaskIndex");
+ }
+
+ public void fillFrom(Mod mod) {
+ name = mod.name;
+ bitmaskIndex = mod.bitmaskIndex;
+ }
+
+ public MetaScheme.Mod toMetaSchemeMod() {
+ return new MetaScheme.Mod(name, bitmaskIndex);
+ }
+
+ public String name;
+ public int bitmaskIndex;
+
+ }
+
+ static class MetaschemeStruct extends Structure {
+ public static class ByVal extends MetaschemeStruct implements Structure.ByValue {}
+ public static class ByRef extends MetaschemeStruct implements Structure.ByReference {}
+
+ public MetaschemeStruct() { super(); }
+ public MetaschemeStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("settingCount", "modCount", "settings", "mods");
+ }
+
+ /**
+ * Only use on native-owned structs!
+ * Calling this method on a Java-owned struct could cause garbage collection of referenced
+ * structures.
+ */
+ public MetaScheme toMetaScheme() {
+ List<MetaScheme.Setting> settingList = new ArrayList<MetaScheme.Setting>(settingCount);
+ List<MetaScheme.Mod> modList = new ArrayList<MetaScheme.Mod>(modCount);
+
+ Structure[] settingStructs = settings.toArray(settingCount);
+ Structure[] modStructs = mods.toArray(modCount);
+
+ for(int i=0; i<settingCount; i++) {
+ MetaschemeSettingStruct mss = (MetaschemeSettingStruct)settingStructs[i];
+ settingList.add(mss.toMetaSchemeSetting());
+ }
+
+ for(int i=0; i<modCount; i++) {
+ MetaschemeModStruct mms = (MetaschemeModStruct)modStructs[i];
+ modList.add(mms.toMetaSchemeMod());
+ }
+
+ return new MetaScheme(modList, settingList);
+ }
+
+ public int settingCount;
+ public int modCount;
+ public MetaschemeSettingStruct.ByRef settings;
+ public MetaschemeModStruct.ByRef mods;
+ }
+
+ static class SchemeStruct extends Structure {
+ public static class ByVal extends SchemeStruct implements Structure.ByValue {}
+ public static class ByRef extends SchemeStruct implements Structure.ByReference {}
+
+ public SchemeStruct() { super(); }
+ public SchemeStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("name", "settings", "mods");
+ }
+
+ public void fillFrom(Scheme scheme) {
+ MetaScheme meta = MetaScheme.INSTANCE;
+ name = scheme.name;
+ settings = new Memory(AndroidTypeMapper.NATIVE_INT_SIZE * meta.settings.size());
+ for(int i=0; i<meta.settings.size(); i++) {
+ Integer value = scheme.settings.get(meta.settings.get(i).name);
+ settings.setInt(AndroidTypeMapper.NATIVE_INT_SIZE*i, value);
+ }
+ mods = new Memory(AndroidTypeMapper.NATIVE_BOOL_SIZE * meta.mods.size());
+ for(int i=0; i<meta.mods.size(); i++) {
+ Boolean value = scheme.mods.get(meta.mods.get(i).name);
+ mods.setByte(AndroidTypeMapper.NATIVE_BOOL_SIZE*i, (byte)(value ? 1 : 0));
+ }
+ }
+
+ public Scheme toScheme() {
+ Map<String, Integer> settingsMap = new HashMap<String, Integer>();
+ MetaScheme meta = MetaScheme.INSTANCE;
+ for(int i=0; i<meta.settings.size(); i++) {
+ settingsMap.put(meta.settings.get(i).name, settings.getInt(AndroidTypeMapper.NATIVE_INT_SIZE*i));
+ }
+ Map<String, Boolean> modsMap = new HashMap<String, Boolean>();
+ for(int i=0; i<meta.mods.size(); i++) {
+ modsMap.put(meta.mods.get(i).name, mods.getByte(i) != 0 ? Boolean.TRUE : Boolean.FALSE);
+ }
+ return new Scheme(name, settingsMap, modsMap);
+ }
+
+ public String name;
+ public Pointer settings;
+ public Pointer mods;
+ }
+
+ /**
+ * Represents a flib_scheme*, for use as part of a flib_scheme**
+ */
+ static class SchemePointerByReference extends Structure implements Structure.ByReference {
+ public SchemePointerByReference() { super(); }
+ public SchemePointerByReference(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("scheme");
+ }
+
+ public SchemeStruct.ByRef scheme;
+ }
+
+ static class SchemelistStruct extends Structure {
+ public static class ByVal extends SchemelistStruct implements Structure.ByValue {}
+ public static class ByRef extends SchemelistStruct implements Structure.ByReference {}
+
+ public SchemelistStruct() { super(); }
+ public SchemelistStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("schemeCount", "schemes");
+ }
+
+ public void fillFrom(List<Scheme> schemeList) {
+ schemeCount = schemeList.size();
+ if(schemeCount<=0) {
+ schemes = null;
+ } else {
+ schemes = new SchemePointerByReference();
+ Structure[] schemePtrStructs = schemes.toArray(schemeCount);
+
+ for(int i=0; i<this.schemeCount; i++) {
+ SchemePointerByReference spbr = (SchemePointerByReference)schemePtrStructs[i];
+ spbr.scheme = new SchemeStruct.ByRef();
+ spbr.scheme.fillFrom(schemeList.get(i));
+ }
+ }
+ }
+
+ /**
+ * Only use on native-owned structs!
+ * Calling this method on a Java-owned struct could cause garbage collection of referenced
+ * structures.
+ */
+ public List<Scheme> toSchemeList() {
+ if(schemeCount<=0) {
+ return new ArrayList<Scheme>();
+ } else {
+ List<Scheme> schemeList = new ArrayList<Scheme>(schemeCount);
+
+ Structure[] schemePtrStructs = schemes.toArray(schemeCount);
+
+ for(int i=0; i<schemeCount; i++) {
+ SchemePointerByReference spbr2 = (SchemePointerByReference)schemePtrStructs[i];
+ schemeList.add(spbr2.scheme.toScheme());
+ }
+ return schemeList;
+ }
+ }
+
+ public int schemeCount;
+ public SchemePointerByReference schemes;
+ }
+
+ /**
+ * Represents a flib_team*, for use as part of a flib_team**
+ */
+ static class TeamPointerByReference extends Structure implements Structure.ByReference {
+ public TeamPointerByReference() { super(); }
+ public TeamPointerByReference(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("team");
+ }
+
+ public TeamStruct.ByRef team;
+ }
+
+ static class TeamlistStruct extends Structure {
+ public static class ByVal extends TeamlistStruct implements Structure.ByValue {}
+ public static class ByRef extends TeamlistStruct implements Structure.ByReference {}
+
+ public TeamlistStruct() { super(); }
+ public TeamlistStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("teamCount", "teams");
+ }
+
+ public void fillFrom(List<TeamInGame> teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) {
+ teamCount = teamList.size();
+ if(teamCount <= 0) {
+ teams = null;
+ } else {
+ teams = new TeamPointerByReference();
+ Structure[] teamPtrStructs = teams.toArray(teamCount);
+
+ for(int i=0; i<this.teamCount; i++) {
+ TeamPointerByReference tpbr = (TeamPointerByReference)teamPtrStructs[i];
+ tpbr.team = new TeamStruct.ByRef();
+ tpbr.team.fillFrom(teamList.get(i), weaponset, initialHealth);
+ }
+ }
+ }
+
+ public List<TeamInGame> toTeamInGameList() {
+ if(teamCount<=0) {
+ return new ArrayList<TeamInGame>();
+ } else {
+ List<TeamInGame> result = new ArrayList<TeamInGame>(teamCount);
+ Structure[] structs = teams.toArray(teamCount);
+
+ for(int i=0; i<teamCount; i++) {
+ TeamPointerByReference struct = (TeamPointerByReference)structs[i];
+ result.add(struct.team.toTeamInGame());
+ }
+ return result;
+ }
+ }
+
+ public int teamCount;
+ public TeamPointerByReference teams;
+ }
+
+ static class GameSetupStruct extends Structure {
+ public static class ByVal extends GameSetupStruct implements Structure.ByValue {}
+ public static class ByRef extends GameSetupStruct implements Structure.ByReference {}
+
+ public GameSetupStruct() { super(); }
+ public GameSetupStruct(Pointer ptr) { super(ptr); }
+
+ @Override
+ protected List<String> getFieldOrder() {
+ return Arrays.asList("script", "gamescheme", "map", "teamlist");
+ }
+
+ public void fillFrom(GameConfig conf) {
+ script = conf.style;
+ gamescheme = new SchemeStruct.ByRef();
+ gamescheme.fillFrom(conf.scheme);
+ map = new MapRecipeStruct.ByRef();
+ map.fillFrom(conf.map);
+
+ /*
+ * At this point we deviate from the usual copying pattern because the frontlib
+ * expects per-hog weapons and initial health, but the UI models them as per-
+ * game, so we extract them from the config here and pass them on to be included
+ * in each hog.
+ */
+ WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef();
+ wss.fillFrom(conf.weaponset);
+ int initialHealth = conf.scheme.getHealth();
+
+ teamlist = new TeamlistStruct.ByRef();
+ teamlist.fillFrom(conf.teams, wss, initialHealth);
+ }
+
+ public GameConfig toGameConfig() {
+ Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null;
+ MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null;
+ List<TeamInGame> teams = teamlist != null ? teamlist.toTeamInGameList() : null;
+
+ WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null;
+ Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null;
+ return new GameConfig(script, scheme, mapRecipe, teams, weaponset);
+ }
+
+ public String script;
+ public SchemeStruct.ByRef gamescheme;
+ public MapRecipeStruct.ByRef map;
+ public TeamlistStruct.ByRef teamlist;
+ }
+
+ /*
+ * Callback interfaces. The context parameter is never needed here and
+ * should always be ignored. Be sure to keep a reference to each callback
+ * for as long as they might be called by native code, to avoid premature
+ * garbage collection.
+ */
+ public static interface VoidCallback extends Callback {
+ void callback(Pointer context);
+ }
+
+ public static interface StrCallback extends Callback {
+ void callback(Pointer context, String arg1);
+ }
+
+ public static interface IntCallback extends Callback {
+ void callback(Pointer context, int arg1);
+ }
+
+ public static interface IntStrCallback extends Callback {
+ void callback(Pointer context, int arg1, String arg2);
+ }
+
+ public static interface StrIntCallback extends Callback {
+ void callback(Pointer context, String arg1, int arg2);
+ }
+
+ public static interface StrStrCallback extends Callback {
+ void callback(Pointer context, String arg1, String arg2);
+ }
+
+ public static interface StrStrBoolCallback extends Callback {
+ void callback(Pointer context, String arg1, String arg2, boolean arg3);
+ }
+
+ public static interface RoomCallback extends Callback {
+ void callback(Pointer context, RoomPtr arg1);
+ }
+
+ public static interface RoomListCallback extends Callback {
+ void callback(Pointer context, RoomArrayPtr arg1, int count);
+ }
+
+ public static interface StrRoomCallback extends Callback {
+ void callback(Pointer context, String arg1, RoomPtr arg2);
+ }
+
+ public static interface BoolCallback extends Callback {
+ void callback(Pointer context, boolean arg1);
+ }
+
+ public static interface StrBoolCallback extends Callback {
+ void callback(Pointer context, String arg1, boolean arg2);
+ }
+
+ public static interface TeamCallback extends Callback {
+ void callback(Pointer context, TeamPtr arg1);
+ }
+
+ public static interface BytesCallback extends Callback {
+ void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size);
+ }
+
+ public static interface BytesBoolCallback extends Callback {
+ void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3);
+ }
+
+ public static interface SchemeCallback extends Callback {
+ void callback(Pointer context, SchemePtr arg1);
+ }
+
+ public static interface MapIntCallback extends Callback {
+ void callback(Pointer context, MapRecipePtr arg1, int arg2);
+ }
+
+ public static interface WeaponsetCallback extends Callback {
+ void callback(Pointer context, WeaponsetPtr arg1);
+ }
+
+ public static interface MapimageCallback extends Callback {
+ void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount);
+ }
+
+ public static interface LogCallback extends Callback {
+ void callback(int level, String logMessage);
+ }
+
+ // frontlib.h
+ int flib_init();
+ void flib_quit();
+
+ // hwconsts.h
+ int flib_get_teamcolor(int colorIndex);
+ int flib_get_teamcolor_count();
+ int flib_get_hedgehogs_per_team();
+ int flib_get_weapons_count();
+ MetaschemePtr flib_get_metascheme();
+
+ // net/netconn.h
+ static final int NETCONN_STATE_CONNECTING = 0;
+ static final int NETCONN_STATE_LOBBY = 1;
+ static final int NETCONN_STATE_ROOM = 2;
+ static final int NETCONN_STATE_DISCONNECTED = 10;
+
+ static final int NETCONN_DISCONNECT_NORMAL = 0;
+ static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1;
+ static final int NETCONN_DISCONNECT_AUTH_FAILED = 2;
+ static final int NETCONN_DISCONNECT_CONNLOST = 3;
+ static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100;
+
+ static final int NETCONN_ROOMLEAVE_ABANDONED = 0;
+ static final int NETCONN_ROOMLEAVE_KICKED = 1;
+
+ static final int NETCONN_MSG_TYPE_PLAYERINFO = 0;
+ static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1;
+ static final int NETCONN_MSG_TYPE_WARNING = 2;
+ static final int NETCONN_MSG_TYPE_ERROR = 3;
+
+ static final int NETCONN_MAPCHANGE_FULL = 0;
+ static final int NETCONN_MAPCHANGE_MAP = 1;
+ static final int NETCONN_MAPCHANGE_MAPGEN = 2;
+ static final int NETCONN_MAPCHANGE_DRAWNMAP = 3;
+ static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4;
+ static final int NETCONN_MAPCHANGE_TEMPLATE = 5;
+ static final int NETCONN_MAPCHANGE_THEME = 6;
+ static final int NETCONN_MAPCHANGE_SEED = 7;
+
+ NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port);
+ void flib_netconn_destroy(NetconnPtr conn);
+
+ void flib_netconn_tick(NetconnPtr conn);
+ boolean flib_netconn_is_chief(NetconnPtr conn);
+ String flib_netconn_get_playername(NetconnPtr conn);
+ GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn);
+ int flib_netconn_send_quit(NetconnPtr conn, String quitmsg);
+ int flib_netconn_send_chat(NetconnPtr conn, String chat);
+ int flib_netconn_send_teamchat(NetconnPtr conn, String msg);
+ int flib_netconn_send_password(NetconnPtr conn, String passwd);
+ int flib_netconn_send_nick(NetconnPtr conn, String nick);
+ int flib_netconn_send_request_roomlist(NetconnPtr conn);
+ int flib_netconn_send_joinRoom(NetconnPtr conn, String room);
+ int flib_netconn_send_createRoom(NetconnPtr conn, String room);
+ int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName);
+ int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg);
+ int flib_netconn_send_toggleReady(NetconnPtr conn);
+ int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team);
+ int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname);
+ int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size);
+ int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount);
+ int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex);
+ int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset);
+ int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map);
+ int flib_netconn_send_mapName(NetconnPtr conn, String mapName);
+ int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen);
+ int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter);
+ int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize);
+ int flib_netconn_send_mapSeed(NetconnPtr conn, String seed);
+ int flib_netconn_send_mapTheme(NetconnPtr conn, String theme);
+ int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size);
+ int flib_netconn_send_script(NetconnPtr conn, String scriptName);
+ int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme);
+ int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError);
+ int flib_netconn_send_ban(NetconnPtr conn, String playerName);
+ int flib_netconn_send_kick(NetconnPtr conn, String playerName);
+ int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName);
+ int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName);
+ int flib_netconn_send_startGame(NetconnPtr conn);
+ int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn);
+ int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn);
+ int flib_netconn_send_clearAccountsCache(NetconnPtr conn);
+ int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value);
+ int flib_netconn_send_getServerVars(NetconnPtr conn);
+
+ void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context);
+ void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context);
+ void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context);
+ void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context);
+ void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context);
+ void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context);
+ void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context);
+ void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context);
+ void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context);
+ void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context);
+ void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context);
+ void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context);
+ void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context);
+ void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context);
+ void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context);
+ void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context);
+ void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context);
+ void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context);
+ void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context);
+ void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context);
+ void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context);
+ void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context);
+
+ // ipc/gameconn.h
+ static final int GAME_END_FINISHED = 0;
+ static final int GAME_END_INTERRUPTED = 1;
+ static final int GAME_END_HALTED = 2;
+ static final int GAME_END_ERROR = 3;
+
+ GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame);
+ GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size);
+ GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size);
+ GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script);
+
+ void flib_gameconn_destroy(GameconnPtr conn);
+ int flib_gameconn_getport(GameconnPtr conn);
+ void flib_gameconn_tick(GameconnPtr conn);
+
+ int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len);
+ int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg);
+ int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg);
+ int flib_gameconn_send_quit(GameconnPtr conn);
+ int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString);
+
+ void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context);
+ void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context);
+ void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context);
+ void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context);
+ void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context);
+ void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context);
+
+ // ipc/mapconn.h
+ public static final int MAPIMAGE_WIDTH = 256;
+ public static final int MAPIMAGE_HEIGHT = 128;
+ public static final int MAPIMAGE_BYTES = (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT);
+
+ MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc);
+ void flib_mapconn_destroy(MapconnPtr conn);
+ int flib_mapconn_getport(MapconnPtr conn);
+ void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context);
+ void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context);
+ void flib_mapconn_tick(MapconnPtr conn);
+
+ // model/map.h
+ public static final int MAPGEN_REGULAR = 0;
+ public static final int MAPGEN_MAZE = 1;
+ public static final int MAPGEN_DRAWN = 2;
+ public static final int MAPGEN_NAMED = 3;
+
+ public static final int TEMPLATEFILTER_ALL = 0;
+ public static final int TEMPLATEFILTER_SMALL = 1;
+ public static final int TEMPLATEFILTER_MEDIUM = 2;
+ public static final int TEMPLATEFILTER_LARGE = 3;
+ public static final int TEMPLATEFILTER_CAVERN = 4;
+ public static final int TEMPLATEFILTER_WACKY = 5;
+
+ public static final int MAZE_SIZE_SMALL_TUNNELS = 0;
+ public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1;
+ public static final int MAZE_SIZE_LARGE_TUNNELS = 2;
+ public static final int MAZE_SIZE_SMALL_ISLANDS = 3;
+ public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4;
+ public static final int MAZE_SIZE_LARGE_ISLANDS = 5;
+
+ // model/schemelist.h
+ SchemelistPtr flib_schemelist_from_ini(String filename);
+ int flib_schemelist_to_ini(String filename, SchemelistPtr list);
+ void flib_schemelist_destroy(SchemelistPtr list);
+
+ // model/team.h
+ TeamPtr flib_team_from_ini(String filename);
+ int flib_team_to_ini(String filename, TeamPtr team);
+ void flib_team_destroy(TeamPtr team);
+
+ // model/weapon.h
+ WeaponsetListPtr flib_weaponsetlist_from_ini(String filename);
+ int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets);
+ void flib_weaponsetlist_destroy(WeaponsetListPtr list);
+
+ // model/gamesetup.h
+ void flib_gamesetup_destroy(GameSetupPtr gamesetup);
+
+ // util/logging.h
+ public static final int FLIB_LOGLEVEL_ALL = -100;
+ public static final int FLIB_LOGLEVEL_DEBUG = -1;
+ public static final int FLIB_LOGLEVEL_INFO = 0;
+ public static final int FLIB_LOGLEVEL_WARNING = 1;
+ public static final int FLIB_LOGLEVEL_ERROR = 2;
+ public static final int FLIB_LOGLEVEL_NONE = 100;
+
+ void flib_log_setLevel(int level);
+ void flib_log_setCallback(LogCallback callback);
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java
new file mode 100644
index 0000000..b70b61d
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/NativeSizeT.java
@@ -0,0 +1,58 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.frontlib;
+
+/**
+ * This class represents the native C type size_t. On Android, this type could be mapped with int,
+ * but we use a separate type to make it easier to adapt for other platforms if anyone wants to use
+ * the mappings elsewhere.
+ */
+public final class NativeSizeT extends Number {
+ private static final long serialVersionUID = 1L;
+ private final long value;
+
+ private NativeSizeT(long value) {
+ this.value = value;
+ }
+
+ public static NativeSizeT valueOf(long l) {
+ return new NativeSizeT(l);
+ }
+
+ @Override
+ public int intValue() {
+ return (int)value;
+ }
+
+ @Override
+ public long longValue() {
+ return value;
+ }
+
+ @Override
+ public double doubleValue() {
+ return value;
+ }
+
+ @Override
+ public float floatValue() {
+ return value;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java
new file mode 100644
index 0000000..273f614
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ClientFlagsUpdate.java
@@ -0,0 +1,48 @@
+package org.hedgewars.hedgeroid.netplay;
+
+import org.hedgewars.hedgeroid.Datastructures.Player;
+import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom;
+
+final class ClientFlagsUpdate {
+ public static final char FLAG_ADMIN = 'a';
+ public static final char FLAG_CHIEF = 'h';
+ public static final char FLAG_READY = 'r';
+ public static final char FLAG_REGISTERED = 'u';
+
+ public final String nick, flags;
+ public final boolean newFlagState;
+
+ public ClientFlagsUpdate(String nick, String flags, boolean newFlagState) {
+ this.nick = nick;
+ this.flags = flags;
+ this.newFlagState = newFlagState;
+ }
+
+ public Player applyTo(Player p) {
+ return new Player(
+ p.name,
+ updatedFlag(FLAG_REGISTERED, p.registered),
+ updatedFlag(FLAG_ADMIN, p.admin));
+ }
+
+ public PlayerInRoom applyTo(PlayerInRoom p) {
+ return new PlayerInRoom(
+ this.applyTo(p.player),
+ updatedFlag(FLAG_READY, p.ready),
+ updatedFlag(FLAG_CHIEF, p.roomChief));
+ }
+
+ public boolean appliesTo(char flag) {
+ return flags.indexOf(flag) != -1;
+ }
+
+ private boolean updatedFlag(char flag, boolean oldValue) {
+ return appliesTo(flag) ? newFlagState : oldValue;
+ }
+
+ @Override
+ public String toString() {
+ return "ClientFlagsUpdate [nick=" + nick + ", flags=" + flags
+ + ", newFlagState=" + newFlagState + "]";
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java
new file mode 100644
index 0000000..a7f9e85
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/GameMessageListener.java
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+/**
+ * Interface with several event callbacks that represent network messages which are interesting
+ * for a running game, e.g. because they concern the lifecycle of the game or because they contain
+ * data that needs to be passed on.
+ *
+ * These functions might be called on any thread.
+ */
+public interface GameMessageListener {
+ void onChatMessage(String nick, String message);
+ void onEngineMessage(byte[] em);
+ void onMessage(int type, String message);
+ void onNetDisconnected();
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java
new file mode 100644
index 0000000..22feae6
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/MessageLog.java
@@ -0,0 +1,169 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.text.Html;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.style.ForegroundColorSpan;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.StyleSpan;
+import android.util.Log;
+
+public class MessageLog {
+ private static final int BACKLOG_LINES = 200;
+
+ private static final int INFO_COLOR = Color.GRAY;
+ private static final int PLAYERINFO_COLOR = Color.GREEN;
+ private static final int CHAT_COLOR = Color.GREEN;
+ private static final int MECHAT_COLOR = Color.CYAN;
+ private static final int WARN_COLOR = Color.RED;
+ private static final int ERROR_COLOR = Color.RED;
+
+ private final Context context;
+ private List<Listener> observers = new LinkedList<Listener>();
+ private List<CharSequence> log = new LinkedList<CharSequence>();
+
+ public MessageLog(Context context) {
+ this.context = context;
+ }
+
+ private Spanned makeLogTime() {
+ String time = DateFormat.getTimeFormat(context).format(new Date());
+ return withColor("[" + time + "] ", INFO_COLOR);
+ }
+
+ private static Spanned span(CharSequence s, Object o) {
+ Spannable spannable = new SpannableString(s);
+ spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return spannable;
+ }
+
+ private static Spanned withColor(CharSequence s, int color) {
+ return span(s, new ForegroundColorSpan(color));
+ }
+
+ private static Spanned bold(CharSequence s) {
+ return span(s, new StyleSpan(Typeface.BOLD));
+ }
+
+ private void append(CharSequence msg) {
+ SpannableStringBuilder ssb = new SpannableStringBuilder();
+ ssb.append(makeLogTime()).append(msg);
+ appendRaw(ssb);
+ }
+
+ private void appendRaw(CharSequence msg) {
+ if(log.size() > BACKLOG_LINES) {
+ log.remove(0);
+ for(Listener o : observers) {
+ o.lineRemoved();
+ }
+ }
+ log.add(msg);
+ for(Listener o : observers) {
+ o.lineAdded(msg);
+ }
+ }
+
+ void appendPlayerJoin(String playername) {
+ append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR));
+ }
+
+ void appendPlayerLeave(String playername, String partMsg) {
+ String msg = "***";
+ if(partMsg != null) {
+ msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg);
+ } else {
+ msg += context.getResources().getString(R.string.log_player_leave, playername);
+ }
+ append(withColor(msg, INFO_COLOR));
+ }
+
+ void appendChat(String playerName, String msg) {
+ if(msg.startsWith("/me ")) {
+ append(withColor("*"+playerName+" "+msg.substring(4), MECHAT_COLOR));
+ } else {
+ Spanned name = bold(playerName+": ");
+ Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR);
+ append(fullMessage);
+ }
+ }
+
+ void appendMessage(int type, String msg) {
+ switch(type) {
+ case Frontlib.NETCONN_MSG_TYPE_ERROR:
+ append(withColor("***"+msg, ERROR_COLOR));
+ break;
+ case Frontlib.NETCONN_MSG_TYPE_WARNING:
+ append(withColor("***"+msg, WARN_COLOR));
+ break;
+ case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO:
+ append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR));
+ break;
+ case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE:
+ appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f)));
+ break;
+ default:
+ Log.e("MessageLog", "Unknown messagetype "+type);
+ }
+ }
+
+ void clear() {
+ for(Listener o : observers) {
+ o.clear();
+ }
+ log.clear();
+ }
+
+ public void addListener(Listener o) {
+ observers.add(o);
+ }
+
+ public void removeListener(Listener o) {
+ observers.remove(o);
+ }
+
+ public static interface Listener {
+ void lineAdded(CharSequence text);
+ void lineRemoved();
+ void clear();
+ }
+
+ public Collection<CharSequence> getLog() {
+ return Collections.unmodifiableList(log);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java
new file mode 100644
index 0000000..5846f4d
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/NetRoomState.java
@@ -0,0 +1,185 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import static org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType.*;
+import static org.hedgewars.hedgeroid.util.ObjectUtils.equal;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.hedgewars.hedgeroid.BasicRoomState;
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Team;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+import org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType;
+
+/**
+ * This class manages the room state in a network game.
+ */
+class NetRoomState extends BasicRoomState {
+ final Map<String, TeamInGame> requestedTeams = new TreeMap<String, TeamInGame>();
+ private Netplay netplay;
+
+ public NetRoomState(Netplay netplay) {
+ this.netplay = netplay;
+ initRoomState(false);
+ }
+
+ public void changeWeaponset(Weaponset weaponset) {
+ if(getChiefStatus() && !equal(weaponset, getWeaponset())) {
+ sendToNet(MSG_SEND_WEAPONSET, weaponset);
+ setWeaponset(weaponset);
+ }
+ }
+
+ public void changeMapRecipe(MapRecipe mapRecipe) {
+ if(getChiefStatus() && !equal(mapRecipe, getMapRecipe())) {
+ sendToNet(MSG_SEND_MAP, mapRecipe);
+ setMapRecipe(mapRecipe);
+ }
+ }
+
+ public void changeMapNameAndGenerator(String mapName) {
+ if(getChiefStatus() && !equal(mapName, getMapRecipe().name)) {
+ int newGenerator = MapRecipe.generatorForMapname(mapName);
+ if(newGenerator != getMapRecipe().mapgen) {
+ sendToNet(MSG_SEND_MAP_GENERATOR, newGenerator, null);
+ }
+ sendToNet(MSG_SEND_MAP_NAME, mapName);
+ setMapRecipe(getMapRecipe().withName(mapName).withMapgen(newGenerator));
+ }
+ }
+
+ public void changeMapTemplate(int template) {
+ if(getChiefStatus() && template != getMapRecipe().templateFilter) {
+ sendToNet(MSG_SEND_MAP_TEMPLATE, template, null);
+ setMapRecipe(getMapRecipe().withTemplateFilter(template));
+ }
+ }
+
+ public void changeMazeSize(int mazeSize) {
+ if(getChiefStatus() && mazeSize != getMapRecipe().mazeSize) {
+ sendToNet(MSG_SEND_MAZE_SIZE, mazeSize, 0);
+ setMapRecipe(getMapRecipe().withMazeSize(mazeSize));
+ }
+ }
+
+ public void changeMapSeed(String seed) {
+ if(getChiefStatus() && !equal(seed, getMapRecipe().seed)) {
+ sendToNet(MSG_SEND_MAP_SEED, seed);
+ setMapRecipe(getMapRecipe().withSeed(seed));
+ }
+ }
+
+ public void changeMapTheme(String theme) {
+ if(getChiefStatus() && !equal(theme, getMapRecipe().theme)) {
+ sendToNet(MSG_SEND_MAP_THEME, theme);
+ setMapRecipe(getMapRecipe().withTheme(theme));
+ }
+ }
+
+ public void changeMapDrawdata(byte[] drawdata) {
+ if(getChiefStatus() && !Arrays.equals(drawdata, getMapRecipe().getDrawData())) {
+ sendToNet(MSG_SEND_MAP_DRAWDATA, drawdata);
+ setMapRecipe(getMapRecipe().withDrawData(drawdata));
+ }
+ }
+
+ public void changeGameStyle(String gameStyle) {
+ if(getChiefStatus() && !equal(gameStyle, getGameStyle())) {
+ sendToNet(MSG_SEND_GAMESTYLE, gameStyle);
+ setGameStyle(gameStyle);
+ }
+ }
+
+ public void changeScheme(Scheme scheme) {
+ if(getChiefStatus() && !equal(scheme, getScheme())) {
+ sendToNet(MSG_SEND_SCHEME, scheme);
+ setScheme(scheme);
+ }
+ }
+
+ void initRoomState(boolean chief) {
+ setTeams(Collections.<String, TeamInGame>emptyMap());
+ requestedTeams.clear();
+
+ setChief(chief);
+ setGameStyle(GameConfig.DEFAULT_STYLE);
+ setMapRecipe(MapRecipe.makeRandomMap(0, "seed", GameConfig.DEFAULT_THEME));
+ setScheme(netplay.defaultScheme);
+ setWeaponset(netplay.defaultWeaponset);
+ sendFullConfig();
+ }
+
+ void sendFullConfig() {
+ if(getChiefStatus()) {
+ sendToNet(MSG_SEND_GAMESTYLE, getGameStyle());
+ sendToNet(MSG_SEND_SCHEME, getScheme());
+ sendToNet(MSG_SEND_WEAPONSET, getWeaponset());
+ sendToNet(MSG_SEND_MAP, getMapRecipe());
+ }
+ }
+
+ private boolean sendToNet(ToNetMsgType what, Object obj) {
+ return netplay.sendToNet(what, 0, obj);
+ }
+
+ private boolean sendToNet(ToNetMsgType what, int arg1, Object obj) {
+ return netplay.sendToNet(what, arg1, obj);
+ }
+
+ public void requestAddTeam(Team team, int colorIndex) {
+ TeamIngameAttributes tia = new TeamIngameAttributes(netplay.getPlayerName(), colorIndex, TeamIngameAttributes.DEFAULT_HOG_COUNT, false);
+ TeamInGame newTeamInGame = new TeamInGame(team, tia);
+ requestedTeams.put(team.name, newTeamInGame);
+ sendToNet(MSG_SEND_ADD_TEAM, newTeamInGame);
+ }
+
+ public void requestRemoveTeam(String teamname) {
+ sendToNet(MSG_SEND_REMOVE_TEAM, teamname);
+ }
+
+ public void changeTeamColorIndex(String teamname, int colorIndex) {
+ if(getChiefStatus()) {
+ TeamInGame team = getTeams().get(teamname);
+ if(team.ingameAttribs.colorIndex != colorIndex) {
+ sendToNet(MSG_SEND_TEAM_COLOR_INDEX, colorIndex, teamname);
+ putTeam(team.withAttribs(team.ingameAttribs.withColorIndex(colorIndex)));
+ }
+ }
+ }
+
+ public void changeTeamHogCount(String teamname, int hogcount) {
+ if(getChiefStatus()) {
+ TeamInGame team = getTeams().get(teamname);
+ if(team.ingameAttribs.hogCount != hogcount) {
+ sendToNet(MSG_SEND_TEAM_HOG_COUNT, hogcount, teamname);
+ putTeam(team.withAttribs(team.ingameAttribs.withHogCount(hogcount)));
+ }
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java
new file mode 100644
index 0000000..6fa3481
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netplay.java
@@ -0,0 +1,535 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import static org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType.*;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.RoomStateManager;
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Player;
+import org.hedgewars.hedgeroid.Datastructures.PlayerInRoom;
+import org.hedgewars.hedgeroid.Datastructures.Room;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.Schemes;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+import org.hedgewars.hedgeroid.Datastructures.Weaponsets;
+import org.hedgewars.hedgeroid.netplay.ThreadedNetConnection.ToNetMsgType;
+import org.hedgewars.hedgeroid.util.ObservableTreeMap;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.util.Pair;
+
+
+/**
+ * This class manages the application's networking state.
+ */
+public class Netplay {
+ public static enum State { NOT_CONNECTED, CONNECTING, LOBBY, ROOM }
+
+ // Extras in broadcasts
+ public static final String EXTRA_PLAYERNAME = "playerName";
+ public static final String EXTRA_MESSAGE = "message";
+ public static final String EXTRA_HAS_ERROR = "hasError";
+ public static final String EXTRA_REASON = "reason";
+
+ private static final String ACTIONPREFIX = "org.hedgewars.hedgeroid.netconn.";
+ public static final String ACTION_DISCONNECTED = ACTIONPREFIX+"DISCONNECTED";
+ public static final String ACTION_CONNECTED = ACTIONPREFIX+"CONNECTED";
+ public static final String ACTION_PASSWORD_REQUESTED = ACTIONPREFIX+"PASSWORD_REQUESTED";
+ public static final String ACTION_ENTERED_ROOM_FROM_LOBBY = ACTIONPREFIX+"ENTERED_ROOM";
+ public static final String ACTION_LEFT_ROOM = ACTIONPREFIX+"LEFT_ROOM";
+ public static final String ACTION_STATE_CHANGED = ACTIONPREFIX+"STATE_CHANGED";
+
+ public static final String DEFAULT_SERVER = "netserver.hedgewars.org";
+ public static final int DEFAULT_PORT = 46631;
+
+ private final Context appContext;
+ private final LocalBroadcastManager broadcastManager;
+ private final FromNetHandler fromNetHandler = new FromNetHandler();
+ public final Scheme defaultScheme;
+ public final Weaponset defaultWeaponset;
+
+ private State state = State.NOT_CONNECTED;
+ private String playerName;
+
+ // null or stale if not in room state
+ private final NetRoomState netRoomState = new NetRoomState(this);
+
+ // null if there is no running connection (==state is NOT_CONNECTED)
+ private ThreadedNetConnection connection;
+
+ public final ObservableTreeMap<String, Player> lobbyPlayerlist = new ObservableTreeMap<String, Player>();
+ public final ObservableTreeMap<String, PlayerInRoom> roomPlayerlist = new ObservableTreeMap<String, PlayerInRoom>();
+ public final Roomlist roomList = new Roomlist();
+ public final MessageLog lobbyChatlog;
+ public final MessageLog roomChatlog;
+
+ private final List<GameMessageListener> gameMessageListeners = new LinkedList<GameMessageListener>();
+ private final List<RunGameListener> runGameListeners = new LinkedList<RunGameListener>();
+
+ public Netplay(Context appContext, Scheme defaultScheme, Weaponset defaultWeaponset) {
+ this.appContext = appContext;
+ broadcastManager = LocalBroadcastManager.getInstance(appContext);
+ lobbyChatlog = new MessageLog(appContext);
+ roomChatlog = new MessageLog(appContext);
+ this.defaultScheme = defaultScheme;
+ this.defaultWeaponset = defaultWeaponset;
+ }
+
+ public RoomStateManager getRoomStateManager() {
+ return netRoomState;
+ }
+
+ private void clearLobbyState() {
+ lobbyPlayerlist.clear();
+ roomList.clear();
+ lobbyChatlog.clear();
+ }
+
+ private void initRoomState(boolean chief) {
+ roomChatlog.clear();
+ roomPlayerlist.clear();
+ netRoomState.initRoomState(chief);
+ }
+
+ public void registerGameMessageListener(GameMessageListener listener) {
+ gameMessageListeners.add(listener);
+ }
+
+ public void unregisterGameMessageListener(GameMessageListener listener) {
+ gameMessageListeners.remove(listener);
+ }
+
+ public void registerRunGameListener(RunGameListener listener) {
+ runGameListeners.add(listener);
+ }
+
+ public void unregisterRunGameListener(RunGameListener listener) {
+ runGameListeners.remove(listener);
+ }
+
+ public void connectToDefaultServer(String playerName) {
+ connect(playerName, DEFAULT_SERVER, DEFAULT_PORT);
+ }
+
+ /**
+ * Establish a new connection. Only call if the current state is NOT_CONNECTED.
+ *
+ * The state will switch to CONNECTING immediately. After that, it can asynchronously change to any other state.
+ * State changes are indicated by broadcasts. In particular, if an error occurs while trying to connect, the state
+ * will change back to NOT_CONNECTED and an ACTION_DISCONNECTED broadcast is sent.
+ */
+ public void connect(String name, String host, int port) {
+ playerName = name;
+ if(state != State.NOT_CONNECTED) {
+ throw new IllegalStateException("Attempt to start a new connection while the old one was still running.");
+ }
+
+ clearLobbyState();
+ changeState(State.CONNECTING);
+ connection = ThreadedNetConnection.startConnection(appContext, fromNetHandler, name, host, port);
+ connection.setFastTickRate(true);
+ }
+
+ public void sendNick(String nick) {
+ playerName = nick;
+ sendToNet(MSG_SEND_NICK, nick);
+ }
+ public void sendPassword(String password) { sendToNet(MSG_SEND_PASSWORD, password); }
+ public void sendQuit(String message) { sendToNet(MSG_SEND_QUIT, message); }
+ public void sendRoomlistRequest() { sendToNet(MSG_SEND_ROOMLIST_REQUEST); }
+ public void sendPlayerInfoQuery(String name) { sendToNet(MSG_SEND_PLAYER_INFO_REQUEST, name); }
+ public void sendChat(String s) { sendToNet(MSG_SEND_CHAT, s); }
+ public void sendTeamChat(String s) { sendToNet(MSG_SEND_TEAMCHAT, s); }
+ public void sendFollowPlayer(String nick) { sendToNet(MSG_SEND_FOLLOW_PLAYER, nick); }
+ public void sendJoinRoom(String name) { sendToNet(MSG_SEND_JOIN_ROOM, name); }
+ public void sendCreateRoom(String name) { sendToNet(MSG_SEND_CREATE_ROOM, name); }
+ public void sendLeaveRoom(String message) { sendToNet(MSG_SEND_LEAVE_ROOM, message); }
+ public void sendKick(String player) { sendToNet(MSG_SEND_KICK, player); }
+ public void sendEngineMessage(byte[] engineMessage) { sendToNet(MSG_SEND_ENGINE_MESSAGE, engineMessage); }
+ public void sendRoundFinished(boolean withoutError) { sendToNet(MSG_SEND_ROUND_FINISHED, Boolean.valueOf(withoutError)); }
+ public void sendToggleReady() { sendToNet(MSG_SEND_TOGGLE_READY); }
+ public void sendStartGame() { sendToNet(MSG_SEND_START_GAME); }
+
+ public void disconnect() { sendToNet(MSG_DISCONNECT, "User Quit"); }
+
+ private static Netplay instance;
+
+ /**
+ * Retrieve the single app-wide instance of the netplay interface, creating it if it
+ * does not exist yet.
+ *
+ * @param applicationContext
+ * @return
+ */
+ public static Netplay getAppInstance(Context applicationContext) {
+ if(instance == null) {
+ // We will need some default values for rooms, best load them here
+ Scheme defaultScheme = null;
+ Weaponset defaultWeaponset = null;
+ try {
+ List<Scheme> schemes = Schemes.loadBuiltinSchemes(applicationContext);
+ for(Scheme scheme : schemes) {
+ if(scheme.name.equals(GameConfig.DEFAULT_SCHEME)) {
+ defaultScheme = scheme;
+ }
+ }
+ List<Weaponset> weaponsets = Weaponsets.loadBuiltinWeaponsets(applicationContext);
+ for(Weaponset weaponset : weaponsets) {
+ if(weaponset.name.equals(GameConfig.DEFAULT_WEAPONSET)) {
+ defaultWeaponset = weaponset;
+ }
+ }
+ } catch(IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ if(defaultScheme==null || defaultWeaponset==null) {
+ throw new RuntimeException("Unable to load default scheme or weaponset");
+ }
+
+ instance = new Netplay(applicationContext, defaultScheme, defaultWeaponset);
+ }
+ return instance;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ private void changeState(State newState) {
+ if(newState != state) {
+ state = newState;
+ broadcastManager.sendBroadcastSync(new Intent(ACTION_STATE_CHANGED));
+ }
+ }
+
+ public boolean isChief() {
+ if(netRoomState != null) {
+ return netRoomState.getChiefStatus();
+ } else {
+ return false;
+ }
+ }
+
+ public String getPlayerName() {
+ return playerName;
+ }
+
+ boolean sendToNet(ToNetMsgType what) {
+ return sendToNet(what, 0, null);
+ }
+
+ boolean sendToNet(ToNetMsgType what, Object obj) {
+ return sendToNet(what, 0, obj);
+ }
+
+ boolean sendToNet(ToNetMsgType what, int arg1, Object obj) {
+ if(connection != null) {
+ Handler handler = connection.toNetHandler;
+ return handler.sendMessage(handler.obtainMessage(what.ordinal(), arg1, 0, obj));
+ } else {
+ return false;
+ }
+ }
+
+ private MessageLog getCurrentLog() {
+ if(state == State.ROOM) {
+ return roomChatlog;
+ } else {
+ return lobbyChatlog;
+ }
+ }
+
+ public static enum FromNetMsgType {
+ MSG_LOBBY_JOIN,
+ MSG_LOBBY_LEAVE,
+ MSG_ROOM_JOIN,
+ MSG_ROOM_LEAVE,
+ MSG_CLIENT_FLAGS,
+ MSG_CHAT,
+ MSG_MESSAGE,
+ MSG_ROOM_ADD,
+ MSG_ROOM_UPDATE,
+ MSG_ROOM_DELETE,
+ MSG_ROOMLIST,
+ MSG_CONNECTED,
+ MSG_DISCONNECTED,
+ MSG_PASSWORD_REQUEST,
+ MSG_ENTER_ROOM_FROM_LOBBY,
+ MSG_LEAVE_ROOM,
+ MSG_TEAM_ADDED,
+ MSG_TEAM_DELETED,
+ MSG_TEAM_ACCEPTED,
+ MSG_TEAM_COLOR_CHANGED,
+ MSG_HOG_COUNT_CHANGED,
+ MSG_ENGINE_MESSAGE,
+ MSG_RUN_GAME,
+ MSG_SCHEME_CHANGED,
+ MSG_MAP_CHANGED,
+ MSG_SCRIPT_CHANGED,
+ MSG_WEAPONSET_CHANGED;
+
+ static final List<FromNetMsgType> values = Collections.unmodifiableList(Arrays.asList(FromNetMsgType.values()));
+ }
+
+ /**
+ * Processes messages from the networking system. Always runs on the main thread.
+ */
+ @SuppressLint("HandlerLeak")
+ final class FromNetHandler extends Handler {
+ public FromNetHandler() {
+ super(Looper.getMainLooper());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void handleMessage(Message msg) {
+ switch(FromNetMsgType.values.get(msg.what)) {
+ case MSG_LOBBY_JOIN: {
+ String name = (String)msg.obj;
+ lobbyPlayerlist.put(name, new Player(name, false, false));
+ lobbyChatlog.appendPlayerJoin(name);
+ break;
+ }
+ case MSG_LOBBY_LEAVE: {
+ Pair<String, String> args = (Pair<String, String>)msg.obj;
+ lobbyPlayerlist.remove(args.first);
+ lobbyChatlog.appendPlayerLeave(args.first, args.second);
+ break;
+ }
+ case MSG_ROOM_JOIN: {
+ String name = (String)msg.obj;
+ Player p = lobbyPlayerlist.get(name);
+ if(p==null) {
+ Log.w("Netplay", "Unknown player joined room: "+name);
+ p = new Player(name, false, false);
+ }
+ roomPlayerlist.put(name, new PlayerInRoom(p, false, false));
+ roomChatlog.appendPlayerJoin(name);
+ break;
+ }
+ case MSG_ROOM_LEAVE: {
+ Pair<String, String> args = (Pair<String, String>)msg.obj;
+ roomPlayerlist.remove(args.first);
+ roomChatlog.appendPlayerLeave(args.first, args.second);
+ break;
+ }
+ case MSG_CLIENT_FLAGS: {
+ ClientFlagsUpdate upd = (ClientFlagsUpdate)msg.obj;
+ PlayerInRoom pir = roomPlayerlist.get(upd.nick);
+ if(pir != null) {
+ roomPlayerlist.put(upd.nick, upd.applyTo(pir));
+ }
+ Player p = lobbyPlayerlist.get(upd.nick);
+ if(p != null) {
+ lobbyPlayerlist.put(upd.nick, upd.applyTo(p));
+ } else {
+ Log.w("Netplay", "Received client flags for unknown player "+upd.nick);
+ }
+ if(playerName.equals(upd.nick) && upd.appliesTo(ClientFlagsUpdate.FLAG_CHIEF)) {
+ netRoomState.setChief(upd.newFlagState);
+ }
+ break;
+ }
+ case MSG_CHAT: {
+ Pair<String, String> args = (Pair<String, String>)msg.obj;
+ getCurrentLog().appendChat(args.first, args.second);
+ for(GameMessageListener listener : gameMessageListeners) {
+ listener.onChatMessage(args.first, args.second);
+ }
+ break;
+ }
+ case MSG_MESSAGE: {
+ getCurrentLog().appendMessage(msg.arg1, (String)msg.obj);
+ for(GameMessageListener listener : gameMessageListeners) {
+ listener.onMessage(1, (String)msg.obj);
+ }
+ break;
+ }
+ case MSG_ROOM_ADD: {
+ Room room = (Room)msg.obj;
+ roomList.addRoomWithNewId(room);
+ break;
+ }
+ case MSG_ROOM_UPDATE: {
+ Pair<String, Room> args = (Pair<String, Room>)msg.obj;
+ roomList.updateRoom(args.first, args.second);
+ break;
+ }
+ case MSG_ROOM_DELETE: {
+ roomList.remove((String)msg.obj);
+ break;
+ }
+ case MSG_ROOMLIST: {
+ Room[] rooms = (Room[])msg.obj;
+ roomList.updateList(rooms);
+ break;
+ }
+ case MSG_CONNECTED: {
+ playerName = (String)msg.obj;
+ changeState(State.LOBBY);
+ broadcastManager.sendBroadcast(new Intent(ACTION_CONNECTED));
+ break;
+ }
+ case MSG_DISCONNECTED: {
+ Pair<Boolean, String> args = (Pair<Boolean, String>)msg.obj;
+ for(GameMessageListener listener : gameMessageListeners) {
+ listener.onNetDisconnected();
+ }
+ changeState(State.NOT_CONNECTED);
+ connection = null;
+ Intent intent = new Intent(ACTION_DISCONNECTED);
+ intent.putExtra(EXTRA_HAS_ERROR, args.first);
+ intent.putExtra(EXTRA_MESSAGE, args.second);
+ broadcastManager.sendBroadcastSync(intent);
+ break;
+ }
+ case MSG_PASSWORD_REQUEST: {
+ Intent intent = new Intent(ACTION_PASSWORD_REQUESTED);
+ intent.putExtra(EXTRA_PLAYERNAME, (String)msg.obj);
+ broadcastManager.sendBroadcast(intent);
+ break;
+ }
+ case MSG_ENTER_ROOM_FROM_LOBBY: {
+ initRoomState((Boolean)msg.obj);
+ changeState(State.ROOM);
+ Intent intent = new Intent(ACTION_ENTERED_ROOM_FROM_LOBBY);
+ broadcastManager.sendBroadcastSync(intent);
+ break;
+ }
+ case MSG_LEAVE_ROOM: {
+ changeState(State.LOBBY);
+ Intent intent = new Intent(ACTION_LEFT_ROOM);
+ intent.putExtra(EXTRA_MESSAGE, (String)msg.obj);
+ intent.putExtra(EXTRA_REASON, msg.arg1);
+ broadcastManager.sendBroadcastSync(intent);
+ break;
+ }
+ case MSG_TEAM_ADDED: {
+ TeamInGame newTeam = (TeamInGame)msg.obj;
+ if(isChief()) {
+ int freeColor = TeamInGame.getUnusedOrRandomColorIndex(netRoomState.getTeams().values());
+ sendToNet(MSG_SEND_TEAM_HOG_COUNT, newTeam.ingameAttribs.hogCount, newTeam.team.name);
+ sendToNet(MSG_SEND_TEAM_COLOR_INDEX, freeColor, newTeam.team.name);
+ newTeam = newTeam.withAttribs(newTeam.ingameAttribs.withColorIndex(freeColor));
+ }
+ netRoomState.putTeam(newTeam);
+ break;
+ }
+ case MSG_TEAM_DELETED: {
+ netRoomState.removeTeam((String)msg.obj);
+ break;
+ }
+ case MSG_TEAM_ACCEPTED: {
+ TeamInGame requestedTeam = netRoomState.requestedTeams.remove(msg.obj);
+ if(requestedTeam!=null) {
+ netRoomState.putTeam(requestedTeam);
+ if(isChief()) {
+ // Not strictly necessary, but QtFrontend does it...
+ sendToNet(MSG_SEND_TEAM_HOG_COUNT, requestedTeam.ingameAttribs.hogCount, requestedTeam.team.name);
+ }
+ } else {
+ Log.e("Netplay", "Got accepted message for team that was never requested.");
+ }
+ break;
+ }
+ case MSG_TEAM_COLOR_CHANGED: {
+ TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj);
+ if(oldEntry != null) {
+ /*
+ * If we are chief, we ignore colors from the outside. They only come from the server
+ * when someone adds a team then, and we override that choice anyway.
+ * Worse, that color message arrives *after* we have overridden the color, so it would
+ * re-override it right back.
+ */
+ if(!isChief()) {
+ TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withColorIndex(msg.arg1);
+ netRoomState.putTeam(oldEntry.withAttribs(newAttribs));
+ }
+ } else {
+ Log.e("Netplay", "Color update for unknown team "+msg.obj);
+ }
+ break;
+ }
+ case MSG_HOG_COUNT_CHANGED: {
+ TeamInGame oldEntry = netRoomState.getTeams().get((String)msg.obj);
+ if(oldEntry != null) {
+ TeamIngameAttributes newAttribs = oldEntry.ingameAttribs.withHogCount(msg.arg1);
+ netRoomState.putTeam(oldEntry.withAttribs(newAttribs));
+ } else {
+ Log.e("Netplay", "Hog count update for unknown team "+msg.obj);
+ }
+ break;
+ }
+ case MSG_ENGINE_MESSAGE: {
+ byte[] em = (byte[])msg.obj;
+ for(GameMessageListener listener : gameMessageListeners) {
+ listener.onEngineMessage(em);
+ }
+ break;
+ }
+ case MSG_RUN_GAME: {
+ GameConfig config = (GameConfig)msg.obj;
+ for(RunGameListener listener : runGameListeners) {
+ listener.runGame(config);
+ }
+ break;
+ }
+ case MSG_MAP_CHANGED: {
+ netRoomState.setMapRecipe((MapRecipe)msg.obj);
+ break;
+ }
+ case MSG_SCHEME_CHANGED: {
+ netRoomState.setScheme((Scheme)msg.obj);
+ break;
+ }
+ case MSG_SCRIPT_CHANGED: {
+ netRoomState.setGameStyle((String)msg.obj);
+ break;
+ }
+ case MSG_WEAPONSET_CHANGED: {
+ netRoomState.setWeaponset((Weaponset)msg.obj);
+ break;
+ }
+ default: {
+ Log.e("FromNetHandler", "Unknown message type: "+msg.what);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java
new file mode 100644
index 0000000..717f647
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Roomlist.java
@@ -0,0 +1,58 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.hedgewars.hedgeroid.Datastructures.Room;
+import org.hedgewars.hedgeroid.Datastructures.RoomWithId;
+import org.hedgewars.hedgeroid.util.ObservableTreeMap;
+
+public class Roomlist extends ObservableTreeMap<String, RoomWithId> {
+ private long nextId = 1;
+
+ public void updateList(Room[] newRooms) {
+ Map<String, RoomWithId> newMap = new TreeMap<String, RoomWithId>();
+ for(Room room : newRooms) {
+ RoomWithId oldEntry = get(room.name);
+ if(oldEntry == null) {
+ newMap.put(room.name, new RoomWithId(room, nextId++));
+ } else {
+ newMap.put(room.name, new RoomWithId(room, oldEntry.id));
+ }
+ }
+ replaceContent(newMap);
+ }
+
+ public void addRoomWithNewId(Room room) {
+ put(room.name, new RoomWithId(room, nextId++));
+ }
+
+ public void updateRoom(String name, Room room) {
+ RoomWithId oldEntry = get(name);
+ if(oldEntry == null) {
+ addRoomWithNewId(room);
+ } else {
+ remove(name);
+ put(room.name, new RoomWithId(room, oldEntry.id));
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java
new file mode 100644
index 0000000..e20da57
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/RunGameListener.java
@@ -0,0 +1,26 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import org.hedgewars.hedgeroid.Datastructures.GameConfig;
+
+public interface RunGameListener {
+ void runGame(GameConfig config);
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java
new file mode 100644
index 0000000..ad7326a
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/ThreadedNetConnection.java
@@ -0,0 +1,578 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.netplay;
+
+import static org.hedgewars.hedgeroid.netplay.Netplay.FromNetMsgType.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.hedgewars.hedgeroid.R;
+import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
+import org.hedgewars.hedgeroid.Datastructures.Scheme;
+import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
+import org.hedgewars.hedgeroid.Datastructures.Weaponset;
+import org.hedgewars.hedgeroid.frontlib.Flib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.BoolCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.ByteArrayPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.BytesCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.GameSetupPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.IntStrCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.MapIntCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.MapRecipePtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.NetconnPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomArrayPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomListCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.RoomPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.SchemeCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.SchemePtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrIntCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrRoomCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrStrBoolCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.StrStrCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.TeamPtr;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.VoidCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.WeaponsetCallback;
+import org.hedgewars.hedgeroid.frontlib.Frontlib.WeaponsetPtr;
+import org.hedgewars.hedgeroid.frontlib.NativeSizeT;
+import org.hedgewars.hedgeroid.netplay.Netplay.FromNetHandler;
+import org.hedgewars.hedgeroid.netplay.Netplay.FromNetMsgType;
+import org.hedgewars.hedgeroid.util.FileUtils;
+import org.hedgewars.hedgeroid.util.TickHandler;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.util.Pair;
+
+import com.sun.jna.Pointer;
+
+/**
+ * This class handles the actual communication with the networking library, running on a separate thread.
+ *
+ * In order to process net messages, this class regularly runs a tick() function on the frontlib. This
+ * usually happens several times per second, but it can be slowed down a lot if no fast reaction to
+ * events is required (e.g. to conserve battery if the application is in the background).
+ */
+class ThreadedNetConnection {
+ private static final long TICK_INTERVAL_FAST = 100;
+ private static final long TICK_INTERVAL_SLOW = 5000;
+ private static final Frontlib FLIB = Flib.INSTANCE;
+
+ public final ToNetHandler toNetHandler;
+
+ private final Context appContext;
+ private final FromNetHandler fromNetHandler;
+ private final TickHandler tickHandler;
+
+ /**
+ * conn can only be null while connecting (the first thing in the thread), and directly after disconnecting,
+ * in the same message (the looper is shut down on disconnect, so there will be no messages after that).
+ */
+ private NetconnPtr conn;
+ private String playerName;
+
+ private ThreadedNetConnection(Context appContext, FromNetHandler fromNetHandler) {
+ this.appContext = appContext;
+ this.fromNetHandler = fromNetHandler;
+
+ HandlerThread thread = new HandlerThread("NetThread");
+ thread.start();
+ toNetHandler = new ToNetHandler(thread.getLooper());
+ tickHandler = new TickHandler(thread.getLooper(), TICK_INTERVAL_FAST, tickCb);
+ }
+
+ private void connect(final String name, final String host, final int port) {
+ toNetHandler.post(new Runnable() {
+ public void run() {
+ playerName = name == null ? "Player" : name;
+ File dataPath;
+ try {
+ dataPath = FileUtils.getDataPathFile(appContext);
+ } catch (FileNotFoundException e) {
+ shutdown(true, appContext.getString(R.string.sdcard_not_mounted));
+ return;
+ }
+ conn = FLIB.flib_netconn_create(playerName, dataPath.getAbsolutePath()+"/", host, port);
+ if(conn == null) {
+ shutdown(true, appContext.getString(R.string.error_connection_failed));
+ return;
+ }
+
+ FLIB.flib_netconn_onSchemeChanged(conn, cfgSchemeCb, null);
+ FLIB.flib_netconn_onClientFlags(conn, clientFlagsCb, null);
+ FLIB.flib_netconn_onChat(conn, chatCb, null);
+ FLIB.flib_netconn_onConnected(conn, connectedCb, null);
+ FLIB.flib_netconn_onDisconnected(conn, disconnectCb, null);
+ FLIB.flib_netconn_onEngineMessage(conn, engineMessageCb, null);
+ FLIB.flib_netconn_onEnterRoom(conn, enterRoomCb, null);
+ FLIB.flib_netconn_onHogCountChanged(conn, hogCountChangedCb, null);
+ FLIB.flib_netconn_onLeaveRoom(conn, leaveRoomCb, null);
+ FLIB.flib_netconn_onLobbyJoin(conn, lobbyJoinCb, null);
+ FLIB.flib_netconn_onLobbyLeave(conn, lobbyLeaveCb, null);
+ FLIB.flib_netconn_onMapChanged(conn, mapChangedCb, null);
+ FLIB.flib_netconn_onMessage(conn, messageCb, null);
+ FLIB.flib_netconn_onPasswordRequest(conn, passwordRequestCb, null);
+ FLIB.flib_netconn_onRoomAdd(conn, roomAddCb, null);
+ FLIB.flib_netconn_onRoomDelete(conn, roomDeleteCb, null);
+ FLIB.flib_netconn_onRoomJoin(conn, roomJoinCb, null);
+ FLIB.flib_netconn_onRoomLeave(conn, roomLeaveCb, null);
+ FLIB.flib_netconn_onRoomlist(conn, roomlistCb, null);
+ FLIB.flib_netconn_onRoomUpdate(conn, roomUpdateCb, null);
+ FLIB.flib_netconn_onRunGame(conn, runGameCb, null);
+ FLIB.flib_netconn_onScriptChanged(conn, scriptChangedCb, null);
+ // FLIB.flib_netconn_onServerVar(conn, serverVarCb, null);
+ FLIB.flib_netconn_onTeamAccepted(conn, teamAcceptedCb, null);
+ FLIB.flib_netconn_onTeamAdd(conn, teamAddedCb, null);
+ FLIB.flib_netconn_onTeamColorChanged(conn, teamColorChangedCb, null);
+ FLIB.flib_netconn_onTeamDelete(conn, teamDeletedCb, null);
+ FLIB.flib_netconn_onWeaponsetChanged(conn, weaponsetChangedCb, null);
+
+ tickHandler.start();
+ }
+ });
+ }
+
+ public static ThreadedNetConnection startConnection(Context appContext, FromNetHandler fromNetHandler, String playerName, String host, int port) {
+ ThreadedNetConnection result = new ThreadedNetConnection(appContext, fromNetHandler);
+ result.connect(playerName, host, port);
+ return result;
+ }
+
+ public void setFastTickRate(boolean fastTickRate) {
+ tickHandler.setInterval(fastTickRate ? TICK_INTERVAL_FAST : TICK_INTERVAL_SLOW);
+ }
+
+ private final Runnable tickCb = new Runnable() {
+ public void run() {
+ FLIB.flib_netconn_tick(conn);
+ }
+ };
+
+ private final SchemeCallback cfgSchemeCb = new SchemeCallback() {
+ public void callback(Pointer context, SchemePtr schemePtr) {
+ sendFromNet(MSG_SCHEME_CHANGED, schemePtr.deref());
+ }
+ };
+
+ private final MapIntCallback mapChangedCb = new MapIntCallback() {
+ public void callback(Pointer context, MapRecipePtr mapPtr, int updateType) {
+ sendFromNet(MSG_MAP_CHANGED, updateType, mapPtr.deref());
+ }
+ };
+
+ private final StrCallback scriptChangedCb = new StrCallback() {
+ public void callback(Pointer context, String script) {
+ sendFromNet(MSG_SCRIPT_CHANGED, script);
+ }
+ };
+
+ private final WeaponsetCallback weaponsetChangedCb = new WeaponsetCallback() {
+ public void callback(Pointer context, WeaponsetPtr weaponsetPtr) {
+ sendFromNet(MSG_WEAPONSET_CHANGED, weaponsetPtr.deref());
+ }
+ };
+
+ private final StrCallback lobbyJoinCb = new StrCallback() {
+ public void callback(Pointer context, String name) {
+ sendFromNet(MSG_LOBBY_JOIN, name);
+ }
+ };
+
+ private final StrStrCallback lobbyLeaveCb = new StrStrCallback() {
+ public void callback(Pointer context, String name, String msg) {
+ sendFromNet(MSG_LOBBY_LEAVE, Pair.create(name, msg));
+ }
+ };
+
+ private final StrCallback roomJoinCb = new StrCallback() {
+ public void callback(Pointer context, String name) {
+ sendFromNet(MSG_ROOM_JOIN, name);
+ }
+ };
+
+ private final StrStrCallback roomLeaveCb = new StrStrCallback() {
+ public void callback(Pointer context, String name, String message) {
+ sendFromNet(MSG_ROOM_LEAVE, Pair.create(name, message));
+ }
+ };
+
+ private final StrStrBoolCallback clientFlagsCb = new StrStrBoolCallback() {
+ public void callback(Pointer context, String nick, String flags, boolean newFlagsState) {
+ sendFromNet(MSG_CLIENT_FLAGS, new ClientFlagsUpdate(nick, flags, newFlagsState));
+ }
+ };
+
+ private final StrStrCallback chatCb = new StrStrCallback() {
+ public void callback(Pointer context, String name, String msg) {
+ sendFromNet(MSG_CHAT, Pair.create(name, msg));
+ }
+ };
+
+ private final IntStrCallback messageCb = new IntStrCallback() {
+ public void callback(Pointer context, int type, String msg) {
+ sendFromNet(MSG_MESSAGE, type, msg);
+ }
+ };
+
+ private final RoomCallback roomAddCb = new RoomCallback() {
+ public void callback(Pointer context, RoomPtr roomPtr) {
+ sendFromNet(MSG_ROOM_ADD, roomPtr.deref());
+ }
+ };
+
+ private final StrRoomCallback roomUpdateCb = new StrRoomCallback() {
+ public void callback(Pointer context, String name, RoomPtr roomPtr) {
+ sendFromNet(MSG_ROOM_UPDATE, Pair.create(name, roomPtr.deref()));
+ }
+ };
+
+ private final StrCallback roomDeleteCb = new StrCallback() {
+ public void callback(Pointer context, final String name) {
+ sendFromNet(MSG_ROOM_DELETE, name);
+ }
+ };
+
+ private final RoomListCallback roomlistCb = new RoomListCallback() {
+ public void callback(Pointer context, RoomArrayPtr arg1, int count) {
+ sendFromNet(MSG_ROOMLIST, arg1.getRooms(count));
+ }
+ };
+
+ private final VoidCallback connectedCb = new VoidCallback() {
+ public void callback(Pointer context) {
+ FLIB.flib_netconn_send_request_roomlist(conn);
+ playerName = FLIB.flib_netconn_get_playername(conn);
+ sendFromNet(MSG_CONNECTED, playerName);
+ }
+ };
+
+ private final StrCallback passwordRequestCb = new StrCallback() {
+ public void callback(Pointer context, String nickname) {
+ sendFromNet(MSG_PASSWORD_REQUEST, playerName);
+ }
+ };
+
+ private final BoolCallback enterRoomCb = new BoolCallback() {
+ public void callback(Pointer context, boolean isChief) {
+ sendFromNet(MSG_ENTER_ROOM_FROM_LOBBY, isChief);
+ }
+ };
+
+ private final IntStrCallback leaveRoomCb = new IntStrCallback() {
+ public void callback(Pointer context, int reason, String message) {
+ sendFromNet(MSG_LEAVE_ROOM, reason, message);
+ }
+ };
+
+ private final TeamCallback teamAddedCb = new TeamCallback() {
+ public void callback(Pointer context, TeamPtr team) {
+ sendFromNet(MSG_TEAM_ADDED, team.deref());
+ }
+ };
+
+ private final StrCallback teamDeletedCb = new StrCallback() {
+ public void callback(Pointer context, String teamName) {
+ sendFromNet(MSG_TEAM_DELETED, teamName);
+ }
+ };
+
+ private final StrCallback teamAcceptedCb = new StrCallback() {
+ public void callback(Pointer context, String teamName) {
+ sendFromNet(MSG_TEAM_ACCEPTED, teamName);
+ }
+ };
+
+ private final StrIntCallback teamColorChangedCb = new StrIntCallback() {
+ public void callback(Pointer context, String teamName, int colorIndex) {
+ sendFromNet(MSG_TEAM_COLOR_CHANGED, colorIndex, teamName);
+ }
+ };
+
+ private final StrIntCallback hogCountChangedCb = new StrIntCallback() {
+ public void callback(Pointer context, String teamName, int hogCount) {
+ sendFromNet(MSG_HOG_COUNT_CHANGED, hogCount, teamName);
+ }
+ };
+
+ private final BytesCallback engineMessageCb = new BytesCallback() {
+ public void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size) {
+ sendFromNet(MSG_ENGINE_MESSAGE, buffer.deref(size.intValue()));
+ }
+ };
+
+ private final VoidCallback runGameCb = new VoidCallback() {
+ public void callback(Pointer context) {
+ GameSetupPtr configPtr = FLIB.flib_netconn_create_gamesetup(conn);
+ sendFromNet(MSG_RUN_GAME, configPtr.deref());
+ FLIB.flib_gamesetup_destroy(configPtr);
+ }
+ };
+
+ private void shutdown(boolean error, String message) {
+ if(conn != null) {
+ FLIB.flib_netconn_destroy(conn);
+ conn = null;
+ }
+ tickHandler.stop();
+ toNetHandler.getLooper().quit();
+ sendFromNet(MSG_DISCONNECTED, Pair.create(error, message));
+ }
+
+ private final IntStrCallback disconnectCb = new IntStrCallback() {
+ public void callback(Pointer context, int reason, String message) {
+ Boolean error = reason != Frontlib.NETCONN_DISCONNECT_NORMAL;
+ String messageForUser = createDisconnectUserMessage(appContext.getResources(), reason, message);
+ shutdown(error, messageForUser);
+ }
+ };
+
+ private static String createDisconnectUserMessage(Resources res, int reason, String message) {
+ switch(reason) {
+ case Frontlib.NETCONN_DISCONNECT_AUTH_FAILED:
+ return res.getString(R.string.error_auth_failed);
+ case Frontlib.NETCONN_DISCONNECT_CONNLOST:
+ return res.getString(R.string.error_connection_lost);
+ case Frontlib.NETCONN_DISCONNECT_INTERNAL_ERROR:
+ return res.getString(R.string.error_unexpected, message);
+ case Frontlib.NETCONN_DISCONNECT_SERVER_TOO_OLD:
+ return res.getString(R.string.error_server_too_old);
+ default:
+ return message;
+ }
+ }
+
+ private boolean sendFromNet(FromNetMsgType what, Object obj) {
+ return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), obj));
+ }
+
+ private boolean sendFromNet(FromNetMsgType what, int arg1, Object obj) {
+ return fromNetHandler.sendMessage(fromNetHandler.obtainMessage(what.ordinal(), arg1, 0, obj));
+ }
+
+ static enum ToNetMsgType {
+ MSG_SEND_NICK,
+ MSG_SEND_PASSWORD,
+ MSG_SEND_QUIT,
+ MSG_SEND_ROOMLIST_REQUEST,
+ MSG_SEND_PLAYER_INFO_REQUEST,
+ MSG_SEND_CHAT,
+ MSG_SEND_TEAMCHAT,
+ MSG_SEND_FOLLOW_PLAYER,
+ MSG_SEND_JOIN_ROOM,
+ MSG_SEND_CREATE_ROOM,
+ MSG_SEND_LEAVE_ROOM,
+ MSG_SEND_KICK,
+ MSG_SEND_ADD_TEAM,
+ MSG_SEND_REMOVE_TEAM,
+ MSG_DISCONNECT,
+ MSG_SEND_TEAM_COLOR_INDEX,
+ MSG_SEND_TEAM_HOG_COUNT,
+ MSG_SEND_ENGINE_MESSAGE,
+ MSG_SEND_ROUND_FINISHED,
+ MSG_SEND_TOGGLE_READY,
+ MSG_SEND_START_GAME,
+ MSG_SEND_WEAPONSET,
+ MSG_SEND_MAP,
+ MSG_SEND_MAP_NAME,
+ MSG_SEND_MAP_GENERATOR,
+ MSG_SEND_MAP_TEMPLATE,
+ MSG_SEND_MAZE_SIZE,
+ MSG_SEND_MAP_SEED,
+ MSG_SEND_MAP_THEME,
+ MSG_SEND_MAP_DRAWDATA,
+ MSG_SEND_GAMESTYLE,
+ MSG_SEND_SCHEME;
+
+ static final List<ThreadedNetConnection.ToNetMsgType> values = Collections.unmodifiableList(Arrays.asList(ToNetMsgType.values()));
+ }
+
+ /**
+ * Processes messages to the networking system. Runs on a non-main thread.
+ */
+ @SuppressLint("HandlerLeak")
+ public final class ToNetHandler extends Handler {
+
+ public ToNetHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(ToNetMsgType.values.get(msg.what)) {
+ case MSG_SEND_NICK: {
+ FLIB.flib_netconn_send_nick(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_PASSWORD: {
+ FLIB.flib_netconn_send_password(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_QUIT: {
+ FLIB.flib_netconn_send_quit(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_ROOMLIST_REQUEST: {
+ FLIB.flib_netconn_send_request_roomlist(conn);
+ break;
+ }
+ case MSG_SEND_PLAYER_INFO_REQUEST: {
+ FLIB.flib_netconn_send_playerInfo(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_CHAT: {
+ if(FLIB.flib_netconn_send_chat(conn, (String)msg.obj) == 0) {
+ sendFromNet(MSG_CHAT, Pair.create(playerName, (String)msg.obj));
+ }
+ break;
+ }
+ case MSG_SEND_TEAMCHAT: {
+ FLIB.flib_netconn_send_teamchat(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_FOLLOW_PLAYER: {
+ FLIB.flib_netconn_send_playerFollow(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_JOIN_ROOM: {
+ FLIB.flib_netconn_send_joinRoom(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_CREATE_ROOM: {
+ FLIB.flib_netconn_send_createRoom(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_LEAVE_ROOM: {
+ if(FLIB.flib_netconn_send_leaveRoom(conn, (String)msg.obj) == 0) {
+ sendFromNet(MSG_LEAVE_ROOM, -1, "");
+ }
+ break;
+ }
+ case MSG_SEND_KICK: {
+ FLIB.flib_netconn_send_kick(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_ADD_TEAM: {
+ FLIB.flib_netconn_send_addTeam(conn, TeamPtr.createJavaOwned((TeamInGame)msg.obj));
+ break;
+ }
+ case MSG_SEND_REMOVE_TEAM: {
+ if(FLIB.flib_netconn_send_removeTeam(conn, (String)msg.obj)==0) {
+ sendFromNet(MSG_TEAM_DELETED, msg.obj);
+ }
+ break;
+ }
+ case MSG_DISCONNECT: {
+ FLIB.flib_netconn_send_quit(conn, (String)msg.obj);
+ shutdown(false, "User quit");
+ break;
+ }
+ case MSG_SEND_TEAM_COLOR_INDEX: {
+ FLIB.flib_netconn_send_teamColor(conn, (String)msg.obj, msg.arg1);
+ break;
+ }
+ case MSG_SEND_TEAM_HOG_COUNT: {
+ FLIB.flib_netconn_send_teamHogCount(conn, (String)msg.obj, msg.arg1);
+ break;
+ }
+ case MSG_SEND_ENGINE_MESSAGE: {
+ byte[] message = (byte[])msg.obj;
+ ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message);
+ FLIB.flib_netconn_send_engineMessage(conn, ptr, NativeSizeT.valueOf(message.length));
+ break;
+ }
+ case MSG_SEND_ROUND_FINISHED: {
+ FLIB.flib_netconn_send_roundfinished(conn, (Boolean)msg.obj);
+ break;
+ }
+ case MSG_SEND_TOGGLE_READY: {
+ FLIB.flib_netconn_send_toggleReady(conn);
+ break;
+ }
+ case MSG_SEND_START_GAME: {
+ FLIB.flib_netconn_send_startGame(conn);
+ break;
+ }
+ case MSG_SEND_WEAPONSET: {
+ FLIB.flib_netconn_send_weaponset(conn, WeaponsetPtr.createJavaOwned((Weaponset)msg.obj));
+ break;
+ }
+ case MSG_SEND_MAP: {
+ FLIB.flib_netconn_send_map(conn, MapRecipePtr.createJavaOwned((MapRecipe)msg.obj));
+ break;
+ }
+ case MSG_SEND_MAP_NAME: {
+ FLIB.flib_netconn_send_mapName(conn, (String)msg.obj);
+ break;
+ }
+ case MSG_SEND_MAP_GENERATOR: {
+ FLIB.flib_netconn_send_mapGen(conn, msg.arg1);
+ break;
+ }
+ case MSG_SEND_MAP_TEMPLATE: {
+ FLIB.flib_netconn_send_mapTemplate(conn, msg.arg1);
+ break;
+ }
+ case MSG_SEND_MAZE_SIZE: {
+ FLIB.flib_netconn_send_mapMazeSize(conn, msg.arg1);
+ break;
+ }
+ case MSG_SEND_MAP_SEED: {
+ FLIB.flib_netconn_send_mapSeed(conn, (String) msg.obj);
+ break;
+ }
+ case MSG_SEND_MAP_THEME: {
+ FLIB.flib_netconn_send_mapTheme(conn, (String) msg.obj);
+ break;
+ }
+ case MSG_SEND_MAP_DRAWDATA: {
+ byte[] message = (byte[])msg.obj;
+ ByteArrayPtr ptr = ByteArrayPtr.createJavaOwned(message);
+ FLIB.flib_netconn_send_mapDrawdata(conn, ptr, NativeSizeT.valueOf(message.length));
+ break;
+ }
+ case MSG_SEND_GAMESTYLE: {
+ FLIB.flib_netconn_send_script(conn, (String) msg.obj);
+ break;
+ }
+ case MSG_SEND_SCHEME: {
+ FLIB.flib_netconn_send_scheme(conn, SchemePtr.createJavaOwned((Scheme) msg.obj));
+ break;
+ }
+ default: {
+ Log.e("ToNetHandler", "Unknown message type: "+msg.what);
+ break;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java
new file mode 100644
index 0000000..42a88ae
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/CalmDownHandler.java
@@ -0,0 +1,62 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+/**
+ * This class allows you to define a runnable that is called when there has been
+ * no activity for a set amount of time, where activity is determined by calls
+ * to the activity() method of the handler. It is used to update the map preview
+ * when there have been no updates to the relevant map information for a time,
+ * to prevent triggering several updates at once when different parts of the
+ * information change.
+ */
+public final class CalmDownHandler extends Handler {
+ int runningMessagesCounter = 0;
+ final Runnable inactivityRunnable;
+ final long inactivityMs;
+ boolean stopped;
+
+ public CalmDownHandler(Looper looper, Runnable runnable, long inactivityMs) {
+ super(looper);
+ this.inactivityRunnable = runnable;
+ this.inactivityMs = inactivityMs;
+ }
+
+ public void activity() {
+ runningMessagesCounter++;
+ sendMessageDelayed(obtainMessage(), inactivityMs);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ runningMessagesCounter--;
+ if(runningMessagesCounter==0 && !stopped) {
+ inactivityRunnable.run();
+ }
+ }
+
+ public void stop() {
+ stopped = true;
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java
new file mode 100644
index 0000000..fdf83dc
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/FileUtils.java
@@ -0,0 +1,259 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (c) 2011-2012 Richard Deurwaarder <xeli at xelification.com>
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+public class FileUtils {
+ private static final String ROOT_DIR = "Data";
+ private static final String TAG = FileUtils.class.getSimpleName();
+
+ /**
+ * @return true if the data path is currently available. However, it can vanish at any time so
+ * normally you should just try to use it and rely on the exceptions.
+ */
+ public static boolean isDataPathAvailable() {
+ return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
+ }
+
+ /**
+ * get the path to which we should download all the data files
+ * @param c context
+ * @return The directory
+ * @throws FileNotFoundException if external storage is not available at the moment
+ */
+ public static File getCachePath(Context c) throws FileNotFoundException {
+ File cachePath = null;
+ if(Build.VERSION.SDK_INT < 8){//8 == Build.VERSION_CODES.FROYO
+ cachePath = PreFroyoSDCardDir.getDownloadPath(c);
+ } else {
+ cachePath = FroyoSDCardDir.getDownloadPath(c);
+ }
+ if(cachePath==null) {
+ throw new FileNotFoundException("External storage is currently unavailable");
+ } else {
+ return cachePath;
+ }
+ }
+
+ public static File getDataPathFile(Context c, String...subpath) throws FileNotFoundException {
+ File file = new File(getCachePath(c), ROOT_DIR);
+ for(String pathcomponent : subpath) {
+ file = new File(file, pathcomponent);
+ }
+ return file;
+ }
+
+ @TargetApi(8)
+ private static class FroyoSDCardDir{
+ public static File getDownloadPath(Context c){
+ return c.getExternalCacheDir();
+ }
+ }
+
+ private static class PreFroyoSDCardDir{
+ public static File getDownloadPath(Context c){
+ if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
+ File extStorageDir = Environment.getExternalStorageDirectory();
+ if(extStorageDir != null) {
+ return new File(extStorageDir, "Hedgewars");
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Return a File array with all the files from dirName
+ * @param c
+ * @param dirName
+ * @return
+ * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dirName" does not exist
+ */
+ public static File[] getFilesFromRelativeDir(Context c, String dirName) throws FileNotFoundException {
+ File f = getDataPathFile(c, dirName);
+
+ if(f.isDirectory()) {
+ return f.listFiles();
+ } else {
+ throw new FileNotFoundException("Directory "+dirName+" does not exist.");
+ }
+ }
+
+ /**
+ * Checks if this directory has a file with suffix suffix
+ * @param f - directory
+ * @return
+ */
+ public static boolean hasFileWithSuffix(File f, String suffix){
+ if(f.isDirectory()){
+ for(String s : f.list()){
+ if(s.endsWith(suffix)) return true;
+ }
+ return false;
+ }else{
+ return false;
+ }
+ }
+
+ /**
+ * Gives back all dirs which contain a file with suffix fileSuffix
+ * @param c
+ * @param path
+ * @param fileSuffix
+ * @return
+ * @throws FileNotFoundException If the sdcard is not available or the subdirectory "path" does not exist
+ */
+ public static List<String> getDirsWithFileSuffix(Context c, String path, String fileSuffix) throws FileNotFoundException{
+ File[] files = getFilesFromRelativeDir(c,path);
+ ArrayList<String> ret = new ArrayList<String>();
+
+ for(File f : files){
+ if(hasFileWithSuffix(f, fileSuffix)) ret.add(f.getName());
+ }
+ return ret;
+ }
+
+ /**
+ * Get all files from directory dir which have the given suffix
+ * @throws FileNotFoundException If the sdcard is not available or the subdirectory "dir" does not exist
+ */
+ public static List<String> getFileNamesFromDirWithSuffix(Context c, String dir, String suffix, boolean removeSuffix) throws FileNotFoundException{
+ File[] files = FileUtils.getFilesFromRelativeDir(c, dir);
+ List<String> ret = new ArrayList<String>();
+ for(File file : files){
+ String s = file.getName();
+ if(s.endsWith(suffix)){
+ if(removeSuffix) ret.add(s.substring(0, s.length()-suffix.length()));
+ else ret.add(s);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Close a resource (possibly null), ignoring any IOException.
+ */
+ public static void closeQuietly(Closeable c) {
+ if(c!=null) {
+ try {
+ c.close();
+ } catch(IOException e) {
+ Log.w(TAG, e);
+ }
+ }
+ }
+
+ /**
+ * Write all data from the input stream to the file, creating or overwriting it.
+ * The input stream will be closed.
+ *
+ * @throws IOException
+ */
+ public static void writeStreamToFile(InputStream is, File file) throws IOException {
+ OutputStream os = null;
+ byte[] buffer = new byte[8192];
+ try {
+ os = new FileOutputStream(file);
+ int size;
+ while((size=is.read(buffer)) != -1) {
+ os.write(buffer, 0, size);
+ }
+ os.close(); // Important to close this non-quietly, in case of exceptions when flushing
+ } finally {
+ FileUtils.closeQuietly(is);
+ FileUtils.closeQuietly(os);
+ }
+ }
+
+ /**
+ * Moves resources pointed to by sourceResId (from @res/raw/) to the app's private data directory
+ * @param c
+ * @param sourceResId
+ * @param directory
+ */
+ public static void resRawToFilesDir(Context c, int sourceResId, int targetFilenames, String directory) throws IOException {
+ File targetDir = new File(c.getFilesDir(), directory);
+ targetDir.mkdirs();
+
+ //Get an array with the resource files ID
+ Resources resources = c.getResources();
+ TypedArray ta = resources.obtainTypedArray(sourceResId);
+ TypedArray filenames = resources.obtainTypedArray(targetFilenames);
+ for(int i = 0; i < ta.length(); i++){
+ int resId = ta.getResourceId(i, 0);
+ String fileName = filenames.getString(i);
+ File f = new File(targetDir, fileName);
+ writeStreamToFile(resources.openRawResource(resId), f);
+ }
+ }
+
+ public static String readToString(InputStream is) throws IOException {
+ try {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int size;
+ while((size=is.read(buffer)) != -1) {
+ os.write(buffer, 0, size);
+ }
+ return new String(os.toByteArray());
+ } finally {
+ closeQuietly(is);
+ }
+ }
+
+ private static final char[] badFilenameChars = new char[] { '/', '\\', ':', '*', '?', '\"', '<', '>', '|', '.', '\0' };
+
+ /**
+ * Modify the given String so that it can be used as part of a filename
+ * without causing problems from illegal/special characters.
+ *
+ * The result should be similar to the input, but isn't necessarily
+ * reversible.
+ */
+ public static String replaceBadChars(String name) {
+ if (name == null || name.trim().length()==0) {
+ return "_";
+ }
+ name = name.trim();
+ for (char badChar : badFilenameChars) {
+ name = name.replace(badChar, '_');
+ }
+ return name;
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java
new file mode 100644
index 0000000..9502899
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObjectUtils.java
@@ -0,0 +1,32 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+public final class ObjectUtils {
+ public static boolean equal(Object o1, Object o2) {
+ if(o1==o2) {
+ return true;
+ } else if(o1==null || o2 == null) {
+ return false;
+ } else {
+ return o1.equals(o2);
+ }
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java
new file mode 100644
index 0000000..1d2ded6
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMap.java
@@ -0,0 +1,62 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.TreeMap;
+
+import android.database.DataSetObservable;
+
+public class ObservableTreeMap<K,V> extends DataSetObservable {
+ private final Map<K, V> map = new TreeMap<K, V>();
+
+ public void replaceContent(Map<? extends K, ? extends V> newMap) {
+ map.clear();
+ map.putAll(newMap);
+ notifyChanged();
+ }
+
+ public void put(K key, V value) {
+ map.put(key, value);
+ notifyChanged();
+ }
+
+ public V get(K key) {
+ return map.get(key);
+ }
+
+ public void remove(K key) {
+ if(map.remove(key) != null) {
+ notifyChanged();
+ }
+ }
+
+ public void clear() {
+ if(!map.isEmpty()) {
+ map.clear();
+ notifyChanged();
+ }
+ }
+
+ public Map<K, V> getMap() {
+ return Collections.unmodifiableMap(map);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java
new file mode 100644
index 0000000..6bd53fe
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/ObservableTreeMapAdapter.java
@@ -0,0 +1,94 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import android.database.DataSetObserver;
+import android.widget.BaseAdapter;
+
+public abstract class ObservableTreeMapAdapter<K,V> extends BaseAdapter {
+ private boolean sourceChanged = true;
+ private List<V> entries = new ArrayList<V>();
+ private ObservableTreeMap<K, V> source;
+
+ private DataSetObserver observer = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ sourceChanged = true;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ invalidate();
+ }
+ };
+
+ abstract protected Comparator<V> getEntryOrder();
+
+ protected List<V> getEntries() {
+ if(sourceChanged) {
+ entries.clear();
+ entries.addAll(source.getMap().values());
+ Collections.sort(entries, getEntryOrder());
+ sourceChanged = false;
+ }
+ return entries;
+ }
+
+ public int getCount() {
+ return getEntries().size();
+ }
+
+ public V getItem(int position) {
+ return getEntries().get(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ public void setSource(ObservableTreeMap<K,V> source) {
+ if(this.source != null) {
+ this.source.unregisterObserver(observer);
+ }
+ this.source = source;
+ this.source.registerObserver(observer);
+ sourceChanged = true;
+ notifyDataSetChanged();
+ }
+
+ public void invalidate() {
+ if(source != null) {
+ source.unregisterObserver(observer);
+ }
+ source = null;
+ notifyDataSetInvalidated();
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java
new file mode 100644
index 0000000..10b48c6
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TextInputDialog.java
@@ -0,0 +1,148 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+/**
+ * A generic text input dialog with configurable text. The Activity must implement the callback
+ * interface TextInputDialogListener, which will be called by the dialog if it is submitted or cancelled.
+ */
+public class TextInputDialog extends DialogFragment {
+ private static final String BUNDLE_DIALOG_ID = "dialogId";
+ private static final String BUNDLE_TITLE_TEXT = "title";
+ private static final String BUNDLE_MESSAGE_TEXT = "message";
+ private static final String BUNDLE_HINT_TEXT = "hint";
+
+ private int dialogId, titleText, messageText, hintText;
+ private TextInputDialogListener listener;
+
+ public interface TextInputDialogListener {
+ void onTextInputDialogSubmitted(int dialogId, String text);
+ void onTextInputDialogCancelled(int dialogId);
+ }
+
+ /**
+ * The dialogId is only used for passing back to the callback on the activity, the
+ * other parameters are text resource IDs. Pass 0 for any of them to not use this
+ * text.
+ */
+ public TextInputDialog(int dialogId, int titleText, int messageText, int hintText) {
+ this.dialogId = dialogId;
+ this.titleText = titleText;
+ this.messageText = messageText;
+ this.hintText = hintText;
+ }
+
+ public TextInputDialog() {
+ // Only for reflection-based instantiation by the framework
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ listener = (TextInputDialogListener) activity;
+ } catch(ClassCastException e) {
+ throw new ClassCastException("Activity " + activity + " must implement TextInputDialogListener to use TextInputDialog.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ listener = null;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ if(savedInstanceState != null) {
+ dialogId = savedInstanceState.getInt(BUNDLE_DIALOG_ID, dialogId);
+ titleText = savedInstanceState.getInt(BUNDLE_TITLE_TEXT, titleText);
+ messageText = savedInstanceState.getInt(BUNDLE_MESSAGE_TEXT, messageText);
+ hintText = savedInstanceState.getInt(BUNDLE_HINT_TEXT, hintText);
+ }
+
+ final EditText editText = new EditText(getActivity());
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ if(titleText != 0) {
+ builder.setTitle(titleText);
+ }
+ if(messageText != 0) {
+ builder.setTitle(messageText);
+ }
+ if(hintText != 0) {
+ editText.setHint(hintText);
+ }
+
+ editText.setId(android.R.id.text1);
+ editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
+ editText.setSingleLine();
+
+ builder.setView(editText);
+ builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ editText.setOnEditorActionListener(new OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ listener.onTextInputDialogSubmitted(dialogId, v.getText().toString());
+ dismiss();
+ return true;
+ }
+ });
+
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ listener.onTextInputDialogSubmitted(dialogId, editText.getText().toString());
+ }
+ });
+
+ return builder.create();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle icicle) {
+ super.onSaveInstanceState(icicle);
+ icicle.putInt(BUNDLE_DIALOG_ID, dialogId);
+ icicle.putInt(BUNDLE_TITLE_TEXT, titleText);
+ icicle.putInt(BUNDLE_MESSAGE_TEXT, messageText);
+ icicle.putInt(BUNDLE_HINT_TEXT, hintText);
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+ listener.onTextInputDialogCancelled(dialogId);
+ }
+}
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java
new file mode 100644
index 0000000..4035f47
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/TickHandler.java
@@ -0,0 +1,73 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+/**
+ * This class handles regularly calling a specified runnable
+ * on the looper provided in the constructor. The first call
+ * occurs without delay (though still via the looper), all
+ * following calls are delayed by (approximately) the interval.
+ * The interval can be changed at any time, which will cause
+ * an immediate execution of the runnable again.
+ */
+public class TickHandler extends Handler {
+ private final Runnable callback;
+ private int messageId;
+ private long interval;
+ private boolean running;
+
+ public TickHandler(Looper looper, long interval, Runnable callback) {
+ super(looper);
+ this.callback = callback;
+ this.interval = interval;
+ }
+
+ public synchronized void stop() {
+ messageId++;
+ running = false;
+ }
+
+ public synchronized void start() {
+ messageId++;
+ sendMessage(obtainMessage(messageId));
+ running = true;
+ }
+
+ public synchronized void setInterval(long interval) {
+ this.interval = interval;
+ if(running) {
+ start();
+ }
+ }
+
+ @Override
+ public synchronized void handleMessage(Message msg) {
+ if(msg.what == messageId) {
+ callback.run();
+ }
+ if(msg.what == messageId) {
+ sendMessageDelayed(obtainMessage(messageId), interval);
+ }
+ }
+}
\ No newline at end of file
diff --git a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java
new file mode 100644
index 0000000..c9e857c
--- /dev/null
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/util/UiUtils.java
@@ -0,0 +1,53 @@
+/*
+ * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game
+ * Copyright (C) 2012 Simeon Maxein <smaxein at googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.hedgewars.hedgeroid.util;
+
+import org.hedgewars.hedgeroid.R;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TabHost;
+import android.widget.TextView;
+
+public final class UiUtils {
+ private UiUtils() {
+ throw new AssertionError("This class is not meant to be instantiated");
+ }
+
+ public static View createVerticalTabIndicator(TabHost tabHost, int label, int icon) {
+ LayoutInflater inflater = (LayoutInflater) tabHost.getContext()
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ View view = inflater.inflate(R.layout.tab_indicator_vertical,
+ tabHost.getTabWidget(), false);
+
+ final TextView tv = (TextView) view.findViewById(R.id.title);
+ tv.setText(label);
+
+ if (icon != 0) {
+ ImageView iconView = (ImageView) view.findViewById(R.id.icon);
+ iconView.setImageResource(icon);
+ }
+
+ return view;
+ }
+}
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch2.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch2.ogg
deleted file mode 100755
index 93c3d18..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch2.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch3.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch3.ogg
deleted file mode 100755
index a4e715e..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch3.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch4.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch4.ogg
deleted file mode 100755
index 410b4ff..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch4.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch5.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch5.ogg
deleted file mode 100755
index d2a149e..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch5.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch6.ogg b/project_files/AudioMono/Sounds/voices/Pirate/Firepunch6.ogg
deleted file mode 100755
index 52c77bf..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Pirate/Firepunch6.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch2.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch2.ogg
deleted file mode 100755
index 0a02b8d..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Robot/Firepunch2.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch3.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch3.ogg
deleted file mode 100755
index 742ae5c..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Robot/Firepunch3.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch4.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch4.ogg
deleted file mode 100755
index 961b779..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Robot/Firepunch4.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch5.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch5.ogg
deleted file mode 100755
index b2c9b70..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Robot/Firepunch5.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Robot/Firepunch6.ogg b/project_files/AudioMono/Sounds/voices/Robot/Firepunch6.ogg
deleted file mode 100755
index c91eddb..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Robot/Firepunch6.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch2.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch2.ogg
deleted file mode 100755
index 29ec1e9..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Singer/Firepunch2.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch3.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch3.ogg
deleted file mode 100755
index 68a3064..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Singer/Firepunch3.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch4.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch4.ogg
deleted file mode 100755
index b547a86..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Singer/Firepunch4.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch5.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch5.ogg
deleted file mode 100755
index 8ce370d..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Singer/Firepunch5.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Singer/Firepunch6.ogg b/project_files/AudioMono/Sounds/voices/Singer/Firepunch6.ogg
deleted file mode 100755
index 5c7b6e6..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Singer/Firepunch6.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch2.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch2.ogg
deleted file mode 100755
index 5f061f0..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch2.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch3.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch3.ogg
deleted file mode 100755
index 82a917f..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch3.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch4.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch4.ogg
deleted file mode 100755
index 2755b24..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch4.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch5.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch5.ogg
deleted file mode 100755
index ff84b95..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch5.ogg and /dev/null differ
diff --git a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch6.ogg b/project_files/AudioMono/Sounds/voices/Surfer/Firepunch6.ogg
deleted file mode 100755
index 9eba55f..0000000
Binary files a/project_files/AudioMono/Sounds/voices/Surfer/Firepunch6.ogg and /dev/null differ
diff --git a/project_files/HedgewarsMobile/Classes/AboutViewController.h b/project_files/HedgewarsMobile/Classes/AboutViewController.h
new file mode 100644
index 0000000..4e6ea1d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/AboutViewController.h
@@ -0,0 +1,36 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface AboutViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
+ UITableView *tableView;
+ UISegmentedControl *segmentedControl;
+ NSArray *people;
+}
+
+ at property (nonatomic,retain) IBOutlet UITableView *tableView;
+ at property (nonatomic,retain) IBOutlet UISegmentedControl *segmentedControl;
+ at property (nonatomic,retain) NSArray *people;
+
+-(IBAction) buttonPressed:(id) sender;
+-(IBAction) segmentedControlChanged:(id) sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/AboutViewController.m b/project_files/HedgewarsMobile/Classes/AboutViewController.m
new file mode 100644
index 0000000..56defee
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/AboutViewController.m
@@ -0,0 +1,149 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "AboutViewController.h"
+
+
+ at implementation AboutViewController
+ at synthesize tableView, segmentedControl, people;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(void) viewDidLoad {
+ [self.tableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+ self.tableView.allowsSelection = NO;
+
+ NSArray *array = [[NSArray alloc] initWithContentsOfFile:CREDITS_FILE()];
+ self.people = array;
+ [array release];
+
+ NSString *imgName;
+ if (IS_IPAD())
+ imgName = @"smallerBackground~ipad.png";
+ else
+ imgName = @"smallerBackground~iphone.png";
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgName];
+ UIImageView *background = [[UIImageView alloc] initWithImage:img];
+ [img release];
+ background.frame = self.view.frame;
+ background.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view insertSubview:background atIndex:0];
+ [background release];
+
+ [super viewDidLoad];
+}
+
+-(IBAction) buttonPressed:(id) sender {
+ [[AudioManagerController mainManager] playBackSound];
+ [[self parentViewController] dismissModalViewControllerAnimated:YES];
+}
+
+-(IBAction) segmentedControlChanged:(id) sender {
+ [[AudioManagerController mainManager] playClickSound];
+ [self.tableView setContentOffset:CGPointMake(0, 0) animated:NO];
+ [self.tableView reloadData];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [[self.people objectAtIndex:self.segmentedControl.selectedSegmentIndex] count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
+
+ // first all the names, then the title (which is offset 5)
+ cell.textLabel.text = [[self.people objectAtIndex:self.segmentedControl.selectedSegmentIndex] objectAtIndex:[indexPath row]];
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.textLabel.minimumFontSize = 8;
+ cell.detailTextLabel.text = [[self.people objectAtIndex:(self.segmentedControl.selectedSegmentIndex + 5)] objectAtIndex:[indexPath row]];
+
+ return cell;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ // do nothing
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+ return 95;
+}
+
+-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger) section {
+ NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
+ char *fullver;
+ int proto;
+ HW_versionInfo(&proto, &fullver);
+
+ NSString *footerString = [[NSString alloc] initWithFormat:
+ @"You are running Hedgewars-iOS %@ based on Hedgewars version %s (protocol %d)",
+ version, fullver, proto];
+
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 50)];
+ footer.backgroundColor = [UIColor clearColor];
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width*80/100, 90)];
+ label.center = CGPointMake(self.tableView.frame.size.width/2, 45);
+ label.textAlignment = UITextAlignmentCenter;
+ label.font = [UIFont systemFontOfSize:16];
+ label.textColor = [UIColor lightGrayColor];
+ label.numberOfLines = 5;
+ label.text = footerString;
+
+ label.backgroundColor = [UIColor clearColor];
+ [footer addSubview:label];
+ [label release];
+ return [footer autorelease];
+}
+
+#pragma mark -
+#pragma mark Memory Management
+-(void) didReceiveMemoryWarning {
+ self.people = nil;
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.tableView = nil;
+ self.segmentedControl = nil;
+ self.people = nil;
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(tableView);
+ releaseAndNil(segmentedControl);
+ releaseAndNil(people);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/AboutViewController.xib b/project_files/HedgewarsMobile/Classes/AboutViewController.xib
new file mode 100644
index 0000000..05efcb8
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/AboutViewController.xib
@@ -0,0 +1,658 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1024</int>
+ <string key="IBDocument.SystemVersion">10F569</string>
+ <string key="IBDocument.InterfaceBuilderVersion">804</string>
+ <string key="IBDocument.AppKitVersion">1038.29</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">123</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="766721923">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUINavigationBar" id="241300702">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">290</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUISegmentedControl" id="674364401">
+ <reference key="NSNextResponder" ref="241300702"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{127, 7}, {289, 30}}</string>
+ <reference key="NSSuperview" ref="241300702"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBSegmentControlStyle">2</int>
+ <int key="IBNumberOfSegments">5</int>
+ <int key="IBSelectedSegmentIndex">0</int>
+ <object class="NSArray" key="IBSegmentTitles">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Code</string>
+ <string>Art</string>
+ <string>Sound</string>
+ <string>Locale</string>
+ <string>Special</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentWidths">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentEnabledStates">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentContentOffsets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentImages">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSNull" id="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{543, 44}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSArray" key="IBUIItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUINavigationItem" id="824792699">
+ <reference key="IBUINavigationBar" ref="241300702"/>
+ <object class="IBUIBarButtonItem" key="IBUILeftBarButtonItem" id="322694234">
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUINavigationItem" ref="824792699"/>
+ <int key="IBUISystemItemIdentifier">0</int>
+ </object>
+ <reference key="IBUITitleView" ref="674364401"/>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBUITableView" id="411460868">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 44}, {543, 577}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ </object>
+ <string key="NSFrameSize">{543, 621}</string>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="766721923"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="322694234"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">8</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="411460868"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="411460868"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">13</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="411460868"/>
+ </object>
+ <int key="connectionID">14</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">segmentedControlChanged:</string>
+ <reference key="source" ref="674364401"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">15</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">segmentedControl</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="674364401"/>
+ </object>
+ <int key="connectionID">16</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="766721923"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="241300702"/>
+ <reference ref="411460868"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="241300702"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="824792699"/>
+ </object>
+ <reference key="parent" ref="766721923"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="824792699"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="322694234"/>
+ <reference ref="674364401"/>
+ </object>
+ <reference key="parent" ref="241300702"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="322694234"/>
+ <reference key="parent" ref="824792699"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="411460868"/>
+ <reference key="parent" ref="766721923"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="674364401"/>
+ <reference key="parent" ref="824792699"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>10.IBPluginDependency</string>
+ <string>11.IBPluginDependency</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>6.IBPluginDependency</string>
+ <string>7.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>AboutViewController</string>
+ <string>UIResponder</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>{{376, 170}, {543, 621}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">16</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">AboutViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentedControlChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>segmentedControl</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UISegmentedControl</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>segmentedControl</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">segmentedControl</string>
+ <string key="candidateClassName">UISegmentedControl</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/AboutViewController.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="786211723">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarButtonItem</string>
+ <string key="superclassName">UIBarItem</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarItem</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="802309264">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UINavigationItem</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="802309264"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="786211723"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISegmentedControl</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1024" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">123</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/Appirater.h b/project_files/HedgewarsMobile/Classes/Appirater.h
new file mode 100644
index 0000000..745ba04
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/Appirater.h
@@ -0,0 +1,98 @@
+/*
+ This file is part of Appirater, http://arashpayan.com
+
+ Copyright (c) 2010, Arash Payan
+ All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+extern NSString *const kAppiraterLaunchDate;
+extern NSString *const kAppiraterLaunchCount;
+extern NSString *const kAppiraterCurrentVersion;
+extern NSString *const kAppiraterRatedCurrentVersion;
+extern NSString *const kAppiraterDeclinedToRate;
+
+/*
+ Place your Apple generated software id here.
+ */
+#define APPIRATER_APP_ID 391234866
+
+/*
+ Your app's name.
+ */
+#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
+
+/*
+ This is the message your users will see once they've passed the day+launches
+ threshold.
+ */
+#define APPIRATER_MESSAGE [NSString stringWithFormat:@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", APPIRATER_APP_NAME]
+
+/*
+ This is the title of the message alert that users will see.
+ */
+#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
+
+/*
+ The text of the button that rejects reviewing the app.
+ */
+#define APPIRATER_CANCEL_BUTTON NSLocalizedString(@"No thanks",@"")
+
+/*
+ Text of button that will send user to app review page.
+ */
+#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
+
+/*
+ Text for button to remind the user to review later.
+ */
+#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later",@"")
+
+/*
+ Users will need to have the same version of your app installed for this many
+ days before they will be prompted to rate it.
+ */
+#define DAYS_UNTIL_PROMPT 3 // double
+
+/*
+ Users will need to launch the same version of the app this many times before
+ they will be prompted to rate it.
+ */
+#define LAUNCHES_UNTIL_PROMPT 5 // integer
+
+/*
+ 'YES' will show the Appirater alert everytime. Useful for testing how your message
+ looks and making sure the link to your app's review page works.
+ */
+#define APPIRATER_DEBUG NO // bool
+
+ at interface Appirater : NSObject <UIAlertViewDelegate> {
+
+}
+
++(void) appLaunched;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/Appirater.m b/project_files/HedgewarsMobile/Classes/Appirater.m
new file mode 100644
index 0000000..d782650
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/Appirater.m
@@ -0,0 +1,159 @@
+/*
+ This file is part of Appirater, http://arashpayan.com
+
+ Copyright (c) 2010, Arash Payan
+ All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#import "Appirater.h"
+#import <SystemConfiguration/SCNetworkReachability.h>
+#import <netinet/in.h>
+
+NSString *const kAppiraterLaunchDate = @"kAppiraterLaunchDate";
+NSString *const kAppiraterLaunchCount = @"kAppiraterLaunchCount";
+NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion";
+NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion";
+NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate";
+
+NSString *templateReviewURL = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software";
+
+ at implementation Appirater
+
++(void) appLaunched {
+ Appirater *appirater = [[Appirater alloc] init];
+ [NSThread detachNewThreadSelector:@selector(appLaunchedHandler) toTarget:appirater withObject:nil];
+}
+
+-(void) appLaunchedHandler {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if (APPIRATER_DEBUG) {
+ [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
+ return;
+ }
+
+ BOOL willShowPrompt = NO;
+
+ // get the app's version
+ NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
+
+ // get the version number that we've been tracking
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
+ if (trackingVersion == nil) {
+ trackingVersion = version;
+ [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+ }
+
+ if (APPIRATER_DEBUG)
+ DLog(@"APPIRATER Tracking version: %@", trackingVersion);
+
+ if ([trackingVersion isEqualToString:version]) {
+ // get the launch date
+ NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterLaunchDate];
+ if (timeInterval == 0) {
+ timeInterval = [[NSDate date] timeIntervalSince1970];
+ [userDefaults setDouble:timeInterval forKey:kAppiraterLaunchDate];
+ }
+
+ NSTimeInterval secondsSinceLaunch = [[NSDate date] timeIntervalSinceDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
+ double secondsUntilPrompt = 60 * 60 * 24 * DAYS_UNTIL_PROMPT;
+
+ // get the launch count
+ int launchCount = [userDefaults integerForKey:kAppiraterLaunchCount];
+ launchCount++;
+ [userDefaults setInteger:launchCount forKey:kAppiraterLaunchCount];
+ if (APPIRATER_DEBUG)
+ NSLog(@"APPIRATER Launch count: %d", launchCount);
+
+ // have they previously declined to rate this version of the app?
+ BOOL declinedToRate = [userDefaults boolForKey:kAppiraterDeclinedToRate];
+
+ // have they already rated the app?
+ BOOL ratedApp = [userDefaults boolForKey:kAppiraterRatedCurrentVersion];
+
+ if (secondsSinceLaunch > secondsUntilPrompt &&
+ launchCount > LAUNCHES_UNTIL_PROMPT &&
+ !declinedToRate &&
+ !ratedApp) {
+ if ([HWUtils isNetworkReachable]) { // check if they can reach the app store
+ willShowPrompt = YES;
+ [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
+ }
+ }
+ } else {
+ // it's a new version of the app, so restart tracking
+ [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+ [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterLaunchDate];
+ [userDefaults setInteger:1 forKey:kAppiraterLaunchCount];
+ [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
+ [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
+ }
+
+ [userDefaults synchronize];
+ if (!willShowPrompt)
+ [self autorelease];
+
+ [pool release];
+}
+
+-(void) showPrompt {
+ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
+ message:APPIRATER_MESSAGE
+ delegate:self
+ cancelButtonTitle:APPIRATER_CANCEL_BUTTON
+ otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil];
+ [alertView show];
+ [alertView release];
+}
+
+-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger) buttonIndex {
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+
+ switch (buttonIndex) {
+ case 0:
+ // they don't want to rate it
+ [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
+ break;
+ case 1:
+ // they want to rate it
+ [[UIApplication sharedApplication] openURL:
+ [NSURL URLWithString:[templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]]]];
+
+ [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
+ break;
+ case 2:
+ // remind them later
+ break;
+ default:
+ break;
+ }
+
+ [userDefaults synchronize];
+
+ [self release];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/AudioManagerController.h b/project_files/HedgewarsMobile/Classes/AudioManagerController.h
new file mode 100644
index 0000000..ea356a7
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/AudioManagerController.h
@@ -0,0 +1,58 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import <AudioToolbox/AudioToolbox.h>
+
+
+ at class AVAudioPlayer;
+
+ at interface AudioManagerController : NSObject {
+ @private
+ AVAudioPlayer *backgroundMusic;
+ SystemSoundID clickSound;
+ SystemSoundID backSound;
+ SystemSoundID selSound;
+
+ NSOperationQueue *audioFaderQueue;
+}
+
+ at property (nonatomic,retain) AVAudioPlayer *backgroundMusic;
+ at property (assign) SystemSoundID clickSound;
+ at property (assign) SystemSoundID backSound;
+ at property (assign) SystemSoundID selSound;
+
+ at property (nonatomic,retain) NSOperationQueue *audioFaderQueue;
+
++(id) mainManager;
+
+-(void) playBackgroundMusic;
+-(void) pauseBackgroundMusic;
+-(void) stopBackgroundMusic;
+
+-(void) fadeInBackgroundMusic;
+-(void) fadeOutBackgroundMusic;
+
+-(void) playClickSound;
+-(void) playBackSound;
+-(void) playSelectSound;
+-(SystemSoundID) loadSound:(NSString *)snd;
+-(void) unloadSounds;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/AudioManagerController.m b/project_files/HedgewarsMobile/Classes/AudioManagerController.m
new file mode 100644
index 0000000..d5cddf6
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/AudioManagerController.m
@@ -0,0 +1,174 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "AudioManagerController.h"
+#import "AVFoundation/AVAudioPlayer.h"
+#import "MXAudioPlayerFadeOperation.h"
+
+
+#define DEFAULT_VOLUME 0.45f
+#define FADEOUT_DURATION 3.0f
+#define FADEIN_DURATION 2.0f
+
+static AudioManagerController *mainInstance;
+
+ at implementation AudioManagerController
+ at synthesize backgroundMusic, clickSound, backSound, selSound, audioFaderQueue;
+
++(id) mainManager {
+ if (mainInstance == nil)
+ mainInstance = [[self alloc] init];
+ return mainInstance;
+}
+
+-(id) init {
+ if ((self = [super init])) {
+ self.backgroundMusic = nil;
+ self.clickSound = -1;
+ self.backSound = -1;
+ self.selSound = -1;
+
+ self.audioFaderQueue = nil;
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [self unloadSounds];
+ releaseAndNil(backgroundMusic);
+ releaseAndNil(audioFaderQueue);
+ mainInstance = nil;
+ [super dealloc];
+}
+
+-(void) didReceiveMemoryWarning {
+ if (self.backgroundMusic.playing == NO)
+ self.backgroundMusic = nil;
+ if ([self.audioFaderQueue operationCount] == 0)
+ self.audioFaderQueue = nil;
+
+ [self unloadSounds];
+ MSG_MEMCLEAN();
+}
+
+#pragma mark -
+#pragma mark background music control
+-(void) playBackgroundMusic {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO)
+ return;
+
+ if (self.backgroundMusic == nil) {
+ NSString *musicString = [[NSBundle mainBundle] pathForResource:@"hwclassic" ofType:@"mp3"];
+ self.backgroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:musicString] error:nil];
+ self.backgroundMusic.delegate = nil;
+ self.backgroundMusic.numberOfLoops = -1;
+ }
+
+ self.backgroundMusic.volume = DEFAULT_VOLUME;
+ [self.backgroundMusic play];
+}
+
+-(void) pauseBackgroundMusic {
+ [self.backgroundMusic pause];
+}
+
+-(void) stopBackgroundMusic {
+ [self.backgroundMusic stop];
+}
+
+-(void) fadeOutBackgroundMusic {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO)
+ return;
+
+ if (self.audioFaderQueue == nil)
+ self.audioFaderQueue = [[NSOperationQueue alloc] init];
+
+ MXAudioPlayerFadeOperation *fadeOut = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:self.backgroundMusic
+ toVolume:0.0
+ overDuration:FADEOUT_DURATION];
+ [self.audioFaderQueue addOperation:fadeOut];
+ [fadeOut release];
+}
+
+-(void) fadeInBackgroundMusic {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"music"] boolValue] == NO)
+ return;
+
+ if (self.audioFaderQueue == nil)
+ self.audioFaderQueue = [[NSOperationQueue alloc] init];
+
+ [self playBackgroundMusic];
+ MXAudioPlayerFadeOperation *fadeIn = [[MXAudioPlayerFadeOperation alloc] initFadeWithAudioPlayer:self.backgroundMusic
+ toVolume:DEFAULT_VOLUME
+ overDuration:FADEIN_DURATION];
+ [audioFaderQueue addOperation:fadeIn];
+ [fadeIn release];
+}
+
+#pragma mark -
+#pragma mark sound effects control
+-(SystemSoundID) loadSound:(NSString *)snd {
+ SystemSoundID soundID;
+
+ // get the filename of the sound file in a NSURL format
+ NSString *path = [[NSBundle mainBundle] pathForResource:snd ofType:@"caf"];
+ NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
+
+ // use audio sevices to create and play the sound
+ AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
+ return soundID;
+}
+
+-(void) unloadSounds {
+ AudioServicesDisposeSystemSoundID(clickSound), clickSound = -1;
+ AudioServicesDisposeSystemSoundID(backSound), backSound = -1;
+ AudioServicesDisposeSystemSoundID(selSound), selSound = -1;
+}
+
+-(void) playClickSound {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO)
+ return;
+
+ if (self.clickSound == -1)
+ self.clickSound = [self loadSound:@"clickSound"];
+
+ AudioServicesPlaySystemSound(self.clickSound);
+}
+
+-(void) playBackSound {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO)
+ return;
+
+ if (self.backSound == -1)
+ self.backSound = [self loadSound:@"backSound"];
+
+ AudioServicesPlaySystemSound(self.backSound);
+}
+
+-(void) playSelectSound {
+ if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"sound"] boolValue] == NO)
+ return;
+
+ if (self.selSound == -1)
+ self.selSound = [self loadSound:@"selSound"];
+
+ AudioServicesPlaySystemSound(self.selSound);
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/CGPointUtils.c b/project_files/HedgewarsMobile/Classes/CGPointUtils.c
new file mode 100644
index 0000000..ad775b1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/CGPointUtils.c
@@ -0,0 +1,70 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2011 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include "CGPointUtils.h"
+#include "math.h"
+
+
+CGFloat distanceBetweenPoints (CGPoint first, CGPoint second) {
+ CGFloat deltaX = second.x - first.x;
+ CGFloat deltaY = second.y - first.y;
+ return sqrt(deltaX*deltaX + deltaY*deltaY );
+}
+
+CGFloat angleBetweenPoints(CGPoint first, CGPoint second) {
+ CGFloat height = second.y - first.y;
+ CGFloat width = first.x - second.x;
+ CGFloat rads = atan(height/width);
+ return radiansToDegrees(rads);
+}
+
+CGFloat angleBetweenLines(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
+ CGFloat a = line1End.x - line1Start.x;
+ CGFloat b = line1End.y - line1Start.y;
+ CGFloat c = line2End.x - line2Start.x;
+ CGFloat d = line2End.y - line2Start.y;
+ CGFloat rads = acos(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
+ return radiansToDegrees(rads);
+}
+
+CGFloat CGPointDot(CGPoint a,CGPoint b) {
+ return a.x*b.x+a.y*b.y;
+}
+
+CGFloat CGPointLen(CGPoint a) {
+ return sqrtf(a.x*a.x+a.y*a.y);
+}
+
+CGPoint CGPointSub(CGPoint a,CGPoint b) {
+ CGPoint c = {a.x-b.x,a.y-b.y};
+ return c;
+}
+
+CGFloat CGPointDist(CGPoint a,CGPoint b) {
+ CGPoint c = CGPointSub(a,b);
+ return CGPointLen(c);
+}
+
+CGPoint CGPointNorm(CGPoint a) {
+ CGFloat m = sqrtf(a.x*a.x+a.y*a.y);
+ CGPoint c;
+ c.x = a.x/m;
+ c.y = a.y/m;
+ return c;
+}
diff --git a/project_files/HedgewarsMobile/Classes/CGPointUtils.h b/project_files/HedgewarsMobile/Classes/CGPointUtils.h
new file mode 100644
index 0000000..ea03017
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/CGPointUtils.h
@@ -0,0 +1,40 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <CoreGraphics/CoreGraphics.h>
+
+
+#define degreesToRadians(x) ( M_PI * x / 180.0)
+#define radiansToDegrees(x) (180.0 * x / M_PI )
+
+#define HWX(x) (int)(x-screen.size.width/2)/HW_zoomFactor()
+#define HWY(x) (int)(screen.size.height-x)/HW_zoomFactor()+(IS_IPAD()?40:17.5)*HW_zoomLevel()/HW_zoomFactor()
+
+#define HWXZ(x) (int)(x-screen.size.width/2)
+#define HWYZ(x) (int)(screen.size.height-x)
+
+CGFloat distanceBetweenPoints (CGPoint first, CGPoint second);
+CGFloat angleBetweenPoints(CGPoint first, CGPoint second);
+CGFloat angleBetweenLines(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End);
+
+CGFloat CGPointDot(CGPoint a, CGPoint b);
+CGFloat CGPointLen(CGPoint a);
+CGPoint CGPointSub(CGPoint a, CGPoint b);
+CGFloat CGPointDist(CGPoint a, CGPoint b);
+CGPoint CGPointNorm(CGPoint a);
diff --git a/project_files/HedgewarsMobile/Classes/CreationChamber.h b/project_files/HedgewarsMobile/Classes/CreationChamber.h
new file mode 100644
index 0000000..162eed1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/CreationChamber.h
@@ -0,0 +1,41 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+
+ at interface CreationChamber : NSObject {
+
+}
+
++(void) createFirstLaunch;
++(void) createSettings;
+
++(void) createTeamNamed:(NSString *)nameWithoutExt;
++(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type;
++(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type controlledByAI:(BOOL) shouldAITakeOver;
+
++(void) createWeaponNamed:(NSString *)nameWithoutExt;
++(void) createWeaponNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type;
+
++(void) createSchemeNamed:(NSString *)nameWithoutExt;
++(void) createSchemeNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type;
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/CreationChamber.m b/project_files/HedgewarsMobile/Classes/CreationChamber.m
new file mode 100644
index 0000000..bc0fd40
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/CreationChamber.m
@@ -0,0 +1,399 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "CreationChamber.h"
+#import "weapons.h"
+
+ at implementation CreationChamber
+
+#pragma mark Checking status
++(void) createFirstLaunch {
+ DLog(@"Creating necessary files");
+ NSInteger index;
+
+ // SAVES - just delete and overwrite
+ if ([[NSFileManager defaultManager] fileExistsAtPath:SAVES_DIRECTORY()])
+ [[NSFileManager defaultManager] removeItemAtPath:SAVES_DIRECTORY() error:NULL];
+ [[NSFileManager defaultManager] createDirectoryAtPath:SAVES_DIRECTORY()
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:NULL];
+
+ // SCREENSHOTS - just create it the first time
+ if ([[NSFileManager defaultManager] fileExistsAtPath:SCREENSHOTS_DIRECTORY()] == NO)
+ [[NSFileManager defaultManager] createDirectoryAtPath:SCREENSHOTS_DIRECTORY()
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:NULL];
+
+ // SETTINGS - nsuserdefaults ftw
+ [self createSettings];
+
+ // TEAMS - update exisiting teams with new format
+ NSArray *teamNames = [[NSArray alloc] initWithObjects:@"Edit Me!",@"Ninjas",@"Pirates",@"Robots",nil];
+ index = 0;
+ for (NSString *name in teamNames)
+ [self createTeamNamed:name ofType:index++ controlledByAI:[name isEqualToString:@"Robots"]];
+ [teamNames release];
+
+ // SCHEMES - always overwrite and delete custom ones
+ if ([[NSFileManager defaultManager] fileExistsAtPath:SCHEMES_DIRECTORY()] == YES)
+ [[NSFileManager defaultManager] removeItemAtPath:SCHEMES_DIRECTORY() error:NULL];
+ NSArray *schemeNames = [[NSArray alloc] initWithObjects:@"Default",@"Pro Mode",@"Shoppa",@"Clean Slate",
+ @"Minefield",@"Barrel Mayhem",@"Tunnel Hogs",@"Fort Mode",@"Timeless",
+ @"Thinking with Portals",@"King Mode",nil];
+ index = 0;
+ for (NSString *name in schemeNames)
+ [self createSchemeNamed:name ofType:index++];
+ [schemeNames release];
+
+ // WEAPONS - always overwrite as merge is not needed (missing weaps are 0ed automatically)
+ NSArray *weaponNames = [[NSArray alloc] initWithObjects:@"Default",@"Crazy",@"Pro Mode",@"Shoppa",@"Clean Slate",
+ @"Minefield",@"Thinking with Portals",nil];
+ index = 0;
+ for (NSString *name in weaponNames)
+ [self createWeaponNamed:name ofType:index++];
+ [weaponNames release];
+}
+
+#pragma mark Settings
++(void) createSettings {
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+ [settings setObject:[NSNumber numberWithBool:NO] forKey:@"alternate"];
+ [settings setObject:[NSNumber numberWithBool:YES] forKey:@"music"];
+ [settings setObject:[NSNumber numberWithBool:YES] forKey:@"sound"];
+ [settings setObject:[NSNumber numberWithBool:YES] forKey:@"sync_ws"];
+
+ // don't overwrite these two strings when present
+ if ([settings objectForKey:@"username"] == nil)
+ [settings setObject:@"" forKey:@"username"];
+ if ([settings objectForKey:@"password"] == nil)
+ [settings setObject:@"" forKey:@"password"];
+
+ [settings synchronize];
+}
+
+#pragma mark Teams
++(void) createTeamNamed:(NSString *)nameWithoutExt {
+ [self createTeamNamed:nameWithoutExt ofType:0 controlledByAI:NO];
+}
+
++(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type {
+ [self createTeamNamed:nameWithoutExt ofType:type controlledByAI:NO];
+}
+
++(void) createTeamNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type controlledByAI:(BOOL) shouldAITakeOver {
+ NSString *teamsDirectory = TEAMS_DIRECTORY();
+
+ if (![[NSFileManager defaultManager] fileExistsAtPath: teamsDirectory]) {
+ [[NSFileManager defaultManager] createDirectoryAtPath:teamsDirectory
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:NULL];
+ }
+
+ NSArray *customNames;
+ NSArray *customHats;
+ NSString *flag, *grave, *voicepack, *fort;
+ switch (type) {
+ default: // default
+ customNames = [[NSArray alloc] initWithObjects:@"No Name",@"Unnamed",@"Anonymous",@"Nameless",@"Incognito",@"Unidentified",
+ @"Uknown",@"Secret",nil];
+ customHats = [[NSArray alloc] initWithObjects:@"NoHat",@"NoHat",@"NoHat",@"NoHat",@"NoHat",@"NoHat",@"NoHat",@"NoHat",nil];
+ flag = @"hedgewars";
+ grave = @"Statue";
+ voicepack = @"Default";
+ fort = @"Plane";
+ break;
+ case 1: // ninjas
+ customNames = [[NSArray alloc] initWithObjects:@"Shinobi",@"Ukemi",@"Godai",@"Ninpo",@"Tatsujin",@"Arashi",@"Bushi",@"Itami",nil];
+ customHats = [[NSArray alloc] initWithObjects:@"NinjaFull",@"NinjaStraight",@"NinjaTriangle",@"NinjaFull",@"NinjaStraight",
+ @"NinjaTriangle",@"NinjaFull",@"NinjaTriangle",nil];
+ flag = @"japan";
+ grave = @"bp2";
+ voicepack = @"Singer";
+ fort = @"Wood";
+ break;
+ case 2: // pirates
+ customNames = [[NSArray alloc] initWithObjects:@"Toothless Wayne",@"Long-nose Kidd",@"Eye-patch Jim",@"Rackham Blood",@"One-eyed Ayee",
+ @"Dirty Ben",@"Morris",@"Cruise Seymour",nil];
+ customHats = [[NSArray alloc] initWithObjects:@"pirate_jack_bandana",@"pirate_jack",@"dwarf",@"pirate_jack_bandana",@"pirate_jack",
+ @"dwarf",@"pirate_jack_bandana",@"pirate_jack",nil];
+ flag = @"cm_pirate";
+ grave = @"chest";
+ voicepack = @"Pirate";
+ fort = @"Hydrant";
+ break;
+ case 3: // robots
+ customNames = [[NSArray alloc] initWithObjects:@"HAL",@"R2-D2",@"Wall-E",@"Robocop",@"Optimus Prime",@"Terminator",@"C-3PO",@"KITT",nil];
+ customHats = [[NSArray alloc] initWithObjects:@"cyborg1",@"cyborg2",@"cyborg1",@"cyborg2",@"cyborg1",@"cyborg2",@"cyborg1",
+ @"cyborg2",nil];
+ flag = @"cm_binary";
+ grave = @"Rip";
+ voicepack = @"Robot";
+ fort = @"UFO";
+ break;
+ }
+
+ NSMutableArray *hedgehogs = [[NSMutableArray alloc] initWithCapacity:HW_getMaxNumberOfHogs()];
+ for (int i = 0; i < HW_getMaxNumberOfHogs(); i++) {
+ NSDictionary *hog = [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithInt:(shouldAITakeOver ? 4 : 0)],@"level",
+ [customNames objectAtIndex:i],@"hogname",
+ [customHats objectAtIndex:i],@"hat",
+ nil];
+ [hedgehogs addObject:hog];
+ [hog release];
+ }
+ [customHats release];
+ [customNames release];
+
+ NSDictionary *theTeam = [[NSDictionary alloc] initWithObjectsAndKeys:
+ @"0",@"hash",
+ grave,@"grave",
+ fort,@"fort",
+ voicepack,@"voicepack",
+ flag,@"flag",
+ hedgehogs,@"hedgehogs",
+ nil];
+ [hedgehogs release];
+
+ NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@.plist", teamsDirectory, nameWithoutExt];
+
+ [theTeam writeToFile:teamFile atomically:YES];
+ [teamFile release];
+ [theTeam release];
+}
+
+#pragma mark Weapons
++(void) createWeaponNamed:(NSString *)nameWithoutExt {
+ [self createWeaponNamed:nameWithoutExt ofType:0];
+}
+
++(void) createWeaponNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type {
+ NSString *weaponsDirectory = WEAPONS_DIRECTORY();
+
+ if (![[NSFileManager defaultManager] fileExistsAtPath: weaponsDirectory]) {
+ [[NSFileManager defaultManager] createDirectoryAtPath:weaponsDirectory
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:NULL];
+ }
+
+ NSInteger ammolineSize = HW_getNumberOfWeapons();
+ NSString *qt, *prob, *delay, *crate;
+ switch (type) {
+ default: //default
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_DEFAULT_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_DEFAULT_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_DEFAULT_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_DEFAULT_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 1: //crazy
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_CRAZY_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_CRAZY_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_CRAZY_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_CRAZY_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 2: //pro mode
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_PROMODE_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_PROMODE_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_PROMODE_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_PROMODE_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 3: //shoppa
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPA_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPA_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPA_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_SHOPPA_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 4: //clean slate
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_CLEAN_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_CLEAN_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_CLEAN_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_CLEAN_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 5: //minefield
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_MINES_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_MINES_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_MINES_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_MINES_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ case 6: //thinking with portals
+ qt = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_QT length:ammolineSize encoding:NSUTF8StringEncoding];
+ prob = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_PROB length:ammolineSize encoding:NSUTF8StringEncoding];
+ delay = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_DELAY length:ammolineSize encoding:NSUTF8StringEncoding];
+ crate = [[NSString alloc] initWithBytes:AMMOLINE_PORTALS_CRATE length:ammolineSize encoding:NSUTF8StringEncoding];
+ break;
+ }
+
+ NSDictionary *theWeapon = [[NSDictionary alloc] initWithObjectsAndKeys: qt,@"ammostore_initialqt",
+ prob,@"ammostore_probability", delay,@"ammostore_delay", crate,@"ammostore_crate", nil];
+ [qt release];
+ [prob release];
+ [delay release];
+ [crate release];
+
+ NSString *weaponFile = [[NSString alloc] initWithFormat:@"%@/%@.plist", weaponsDirectory, nameWithoutExt];
+ [theWeapon writeToFile:weaponFile atomically:YES];
+ [weaponFile release];
+ [theWeapon release];
+}
+
+#pragma mark Schemes
++(void) createSchemeNamed:(NSString *)nameWithoutExt {
+ [self createSchemeNamed:nameWithoutExt ofType:0];
+}
+
++(void) createSchemeNamed:(NSString *)nameWithoutExt ofType:(NSInteger) type {
+ NSString *schemesDirectory = SCHEMES_DIRECTORY();
+
+ if (![[NSFileManager defaultManager] fileExistsAtPath: schemesDirectory]) {
+ [[NSFileManager defaultManager] createDirectoryAtPath:schemesDirectory
+ withIntermediateDirectories:NO
+ attributes:nil
+ error:NULL];
+ }
+
+ // load data to get the size of the arrays and their default values
+ NSArray *basicSettings = [[NSArray alloc] initWithContentsOfFile:BASICFLAGS_FILE()];
+ NSMutableArray *basicArray = [[NSMutableArray alloc] initWithCapacity:[basicSettings count]];
+ for (NSDictionary *basicDict in basicSettings)
+ [basicArray addObject:[basicDict objectForKey:@"default"]];
+ [basicSettings release];
+
+ NSArray *mods = [[NSArray alloc] initWithContentsOfFile:GAMEMODS_FILE()];
+ NSMutableArray *gamemodArray= [[NSMutableArray alloc] initWithCapacity:[mods count]];
+ for (NSUInteger i = 0; i < [mods count]; i++)
+ [gamemodArray addObject:[NSNumber numberWithBool:NO]];
+ [mods release];
+
+ switch (type) {
+ default: // default
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 1: // pro mode
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:15]];
+ [basicArray replaceObjectAtIndex:7 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 2: // shoppa
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:30]];
+ [basicArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithInt:50]];
+ [basicArray replaceObjectAtIndex:7 withObject:[NSNumber numberWithInt:1]];
+ [basicArray replaceObjectAtIndex:8 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithInt:25]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:0]];
+ [gamemodArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:19 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 3: // clean slate
+ [gamemodArray replaceObjectAtIndex:6 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:18 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:19 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 4: // minefield
+ [basicArray replaceObjectAtIndex:0 withObject:[NSNumber numberWithInt:50]];
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:30]];
+ [basicArray replaceObjectAtIndex:7 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:80]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:0]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 5: // barrel mayhem
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:30]];
+ [basicArray replaceObjectAtIndex:7 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:40]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 6: // tunnel hogs
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:30]];
+ [basicArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithInt:3]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:10]];
+ [basicArray replaceObjectAtIndex:12 withObject:[NSNumber numberWithInt:10]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:10]];
+ [gamemodArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:14 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:15 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:16 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 7: // fort mode
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:0]];
+ [gamemodArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:3 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 8: // timeless
+ [basicArray replaceObjectAtIndex:2 withObject:[NSNumber numberWithInt:100]];
+ [basicArray replaceObjectAtIndex:4 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:5 withObject:[NSNumber numberWithInt:0]];
+ [basicArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithInt:30]];
+ [basicArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithInt:5]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:3]];
+ [basicArray replaceObjectAtIndex:12 withObject:[NSNumber numberWithInt:10]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:20 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 9: // thinking with portals
+ [basicArray replaceObjectAtIndex:7 withObject:[NSNumber numberWithInt:2]];
+ [basicArray replaceObjectAtIndex:8 withObject:[NSNumber numberWithInt:25]];
+ [basicArray replaceObjectAtIndex:10 withObject:[NSNumber numberWithInt:4]];
+ [basicArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithInt:5]];
+ [basicArray replaceObjectAtIndex:13 withObject:[NSNumber numberWithInt:5]];
+ [gamemodArray replaceObjectAtIndex:9 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ case 10: // king mode
+ [gamemodArray replaceObjectAtIndex:11 withObject:[NSNumber numberWithBool:YES]];
+ [gamemodArray replaceObjectAtIndex:12 withObject:[NSNumber numberWithBool:YES]];
+ break;
+ }
+
+ NSMutableDictionary *theScheme = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ basicArray,@"basic",
+ gamemodArray,@"gamemod",
+ nil];
+ [gamemodArray release];
+ [basicArray release];
+
+ NSString *schemeFile = [[NSString alloc] initWithFormat:@"%@/%@.plist", schemesDirectory, nameWithoutExt];
+
+ [theScheme writeToFile:schemeFile atomically:YES];
+ [schemeFile release];
+ [theScheme release];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/DefinesAndMacros.h b/project_files/HedgewarsMobile/Classes/DefinesAndMacros.h
new file mode 100644
index 0000000..36b2bd1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/DefinesAndMacros.h
@@ -0,0 +1,80 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+// some macros by http://www.cimgf.com/2010/05/02/my-current-prefix-pch-file/
+// and http://blog.coriolis.ch/2009/01/05/macros-for-xcode/
+
+
+#ifdef DEBUG
+ #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
+ #define ALog(...) [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSUTF8StringEncoding] file:[NSString stringWithCString:__FILE__ encoding:NSUTF8StringEncoding] lineNumber:__LINE__ description:__VA_ARGS__]
+ #define releaseAndNil(x) [x release]
+#else
+ #define DLog(...) do { } while (0)
+ #ifndef NS_BLOCK_ASSERTIONS
+ #define NS_BLOCK_ASSERTIONS
+ #endif
+ #define ALog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__])
+ #define releaseAndNil(x) [x release], x = nil
+#endif
+
+
+#define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0)
+#define rotationManager(x) (IS_IPAD() ? YES : (x == UIInterfaceOrientationLandscapeRight) || (x == UIInterfaceOrientationLandscapeLeft))
+
+#define START_TIMER() NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
+#define END_TIMER(msg) NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; DLog([NSString stringWithFormat:@"%@ Time = %f", msg, stop-start]);
+
+
+#define DOCUMENTS_FOLDER() [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
+
+#define DEBUG_FILE() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Logs/game0.log"]
+#define BASICFLAGS_FILE() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/basicFlags.plist"]
+#define GAMEMODS_FILE() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/gameMods.plist"]
+#define CREDITS_FILE() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/credits.plist"]
+
+#define TEAMS_DIRECTORY() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Teams/"]
+#define WEAPONS_DIRECTORY() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Weapons/"]
+#define SCHEMES_DIRECTORY() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Schemes/"]
+#define SAVES_DIRECTORY() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Saves/"]
+#define SCREENSHOTS_DIRECTORY() [DOCUMENTS_FOLDER() stringByAppendingString:@"/Screenshots/"]
+
+#define GRAPHICS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Graphics/"]
+#define ICONS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Graphics/Icons/"]
+#define HATS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Graphics/Hats/"]
+#define GRAVES_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Graphics/Graves/"]
+#define FLAGS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Graphics/Flags/"]
+#define FORTS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Forts/"]
+#define VOICES_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Sounds/voices/"]
+#define THEMES_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Themes/"]
+#define MAPS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Maps/"]
+#define MISSIONS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Missions/Maps/"]
+#define TRAININGS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Missions/Training/"]
+#define LOCALE_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Locale/"]
+#define SCRIPTS_DIRECTORY() [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/Data/Scripts/Multiplayer/"]
+
+#define MSG_MEMCLEAN() DLog(@"has cleaned up some memory");
+#define MSG_DIDUNLOAD() DLog(@"unloaded");
+
+#define IS_IPAD() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
+#define IS_ON_PORTRAIT() (IS_IPAD() && UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
+#define IS_NOT_POWERFUL(x) ([x hasPrefix:@"iPhone1"] || [x hasPrefix:@"iPod1,1"] || [x hasPrefix:@"iPod2,1"])
+#define IS_NOT_VERY_POWERFUL(x) ([x hasPrefix:@"iPad1"] || [x hasPrefix:@"iPhone2"] || [x hasPrefix:@"iPod3"] || [x hasPrefix:@"iPod4"])
+#define IS_VERY_POWERFUL(x) (IS_NOT_POWERFUL(x) == NO && IS_NOT_VERY_POWERFUL(x) == NO)
+
diff --git a/project_files/HedgewarsMobile/Classes/EditableCellView.h b/project_files/HedgewarsMobile/Classes/EditableCellView.h
new file mode 100644
index 0000000..ace1e61
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/EditableCellView.h
@@ -0,0 +1,53 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at protocol EditableCellViewDelegate <NSObject>
+
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue;
+
+ at end
+
+ at interface EditableCellView : UITableViewCell <UITextFieldDelegate> {
+ id<EditableCellViewDelegate> delegate;
+ UITextField *textField;
+ UILabel *titleLabel;
+ NSUInteger minimumCharacters;
+ NSUInteger maximumCharacters;
+ BOOL respectEditing;
+
+ at private
+ NSString *oldValue;
+}
+
+ at property (nonatomic,assign) id<EditableCellViewDelegate> delegate;
+ at property (nonatomic,retain,readonly) UITextField *textField;
+ at property (nonatomic,retain,readonly) UILabel *titleLabel;
+ at property (nonatomic,assign) NSUInteger minimumCharacters;
+ at property (nonatomic,assign) NSUInteger maximumCharacters;
+ at property (nonatomic,assign) BOOL respectEditing;
+ at property (nonatomic,retain) NSString *oldValue;
+
+-(void) replyKeyboard;
+-(void) cancel:(id) sender;
+-(void) save:(id) sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/EditableCellView.m b/project_files/HedgewarsMobile/Classes/EditableCellView.m
new file mode 100644
index 0000000..3aa899f
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/EditableCellView.m
@@ -0,0 +1,191 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "EditableCellView.h"
+
+
+ at implementation EditableCellView
+ at synthesize delegate, textField, titleLabel, minimumCharacters, maximumCharacters, respectEditing, oldValue;
+
+-(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+ if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
+ delegate = nil;
+
+ textField = [[UITextField alloc] initWithFrame:CGRectZero];
+ textField.backgroundColor = [UIColor clearColor];
+ textField.delegate = self;
+ textField.clearButtonMode = UITextFieldViewModeWhileEditing;
+ textField.clearsOnBeginEditing = NO;
+ textField.returnKeyType = UIReturnKeyDone;
+ textField.adjustsFontSizeToFitWidth = YES;
+ textField.minimumFontSize = 9;
+ textField.userInteractionEnabled = YES;
+ textField.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ [textField addTarget:self action:@selector(save:) forControlEvents:UIControlEventEditingDidEndOnExit];
+
+ [self.contentView addSubview:textField];
+ //[textField release];
+
+ titleLabel = [[UILabel alloc] init];
+ titleLabel.textAlignment = UITextAlignmentLeft;
+ titleLabel.backgroundColor = [UIColor clearColor];
+ titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ [self.contentView addSubview:titleLabel];
+ //[titleLabel release];
+
+ minimumCharacters = 1;
+ maximumCharacters = 64;
+ respectEditing = NO;
+ oldValue = nil;
+ }
+ return self;
+}
+
+-(void) layoutSubviews {
+ [super layoutSubviews];
+
+ CGRect contentRect = self.contentView.bounds;
+ CGFloat boundsX = contentRect.origin.x;
+
+ int offset = 0;
+ int skew = 0;
+ if (self.imageView != nil)
+ offset += self.imageView.frame.size.width;
+
+ if ([self.titleLabel.text length] == 0)
+ titleLabel.frame = CGRectZero;
+ else {
+ titleLabel.frame = CGRectMake(boundsX+offset+10, 10, 100, [UIFont labelFontSize] + 4);
+ offset += 100;
+ skew +=2;
+ }
+
+ textField.frame = CGRectMake(boundsX+offset+10, skew+10, 300, [UIFont labelFontSize] + 4);
+}
+
+-(void) setSelected:(BOOL)selected animated:(BOOL)animated {
+ [super setSelected:selected animated:animated];
+ // Configure the view for the selected state
+}
+
+-(void) dealloc {
+ self.delegate = nil;
+ releaseAndNil(oldValue);
+ releaseAndNil(titleLabel);
+ releaseAndNil(textField);
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark textField delegate
+// limit the size of the field to 64 characters like in original frontend
+-(BOOL) textField:(UITextField *)aTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
+ return !([aTextField.text length] > self.maximumCharacters && [string length] > range.length);
+}
+
+// allow editing only if delegate is set and conformant to protocol, and if editableOnlyWhileEditing
+-(BOOL) textFieldShouldBeginEditing:(UITextField *)aTextField {
+ return (delegate != nil) &&
+ [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] &&
+ (respectEditing) ? ((UITableView*)[self superview]).editing : YES;
+}
+
+// the textfield is being modified, update the navigation controller
+-(void) textFieldDidBeginEditing:(UITextField *)aTextField{
+ // don't interact with table below
+ ((UITableView*)[self superview]).scrollEnabled = NO;
+
+ self.oldValue = self.textField.text;
+
+ UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Cancel",@"")
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(cancel:)];
+ [(UITableViewController *)delegate navigationItem].leftBarButtonItem = cancelButton;
+ [cancelButton release];
+
+ UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Save",@"")
+ style:UIBarButtonItemStyleDone
+ target:self
+ action:@selector(save:)];
+ [(UITableViewController *)delegate navigationItem].rightBarButtonItem = saveButton;
+ [saveButton release];
+}
+
+/* with this a field might remain in editing status even if the view moved;
+ use method below instead that allows some more interaction
+// don't accept 0-length strings
+-(BOOL) textFieldShouldEndEditing:(UITextField *)aTextField {
+ return ([aTextField.text length] > 0);
+}
+*/
+
+-(BOOL) textFieldShouldReturn:(UITextField *)aTextField {
+ return ([aTextField.text length] >= self.minimumCharacters);
+}
+
+// the textfield has been modified, tell the delegate to do something
+-(void) textFieldDidEndEditing:(UITextField *)aTextField {
+ // this forces a save when user selects a new field
+ if ([self.textField.text isEqualToString:self.oldValue] == NO)
+ [self save:aTextField];
+
+ // restores default behaviour on caller
+ ((UITableView*)[self superview]).scrollEnabled = YES;
+ [(UITableViewController *)delegate navigationItem].rightBarButtonItem = [(UITableViewController *)delegate navigationItem].backBarButtonItem;
+ [(UITableViewController *)delegate navigationItem].leftBarButtonItem = nil;
+}
+
+#pragma mark -
+#pragma mark instance methods
+// the user wants to show the keyboard
+-(void) replyKeyboard {
+ [self.textField becomeFirstResponder];
+}
+
+// the user pressed cancel so hide keyboard
+-(void) cancel:(id) sender {
+ // reverts any changes and performs a fake save for removing the keyboard
+ self.textField.text = self.oldValue;
+ [self save:sender];
+}
+
+// send the value to the delegate (called before textFieldDidEndEditing)
+-(void) save:(id) sender {
+ if (delegate == nil || [delegate respondsToSelector:@selector(saveTextFieldValue:withTag:)] == NO)
+ return;
+
+ // don't save if the textfield is invalid
+ if ([self textFieldShouldReturn:textField] == NO)
+ return;
+
+ [delegate saveTextFieldValue:self.textField.text withTag:self.tag];
+ [self.textField resignFirstResponder];
+ self.oldValue = nil;
+}
+
+// when field is editable only when the tableview is editable, resign responder when exiting editing mode
+-(void) willTransitionToState:(UITableViewCellStateMask)state {
+ if (respectEditing && state == UITableViewCellStateDefaultMask)
+ [self save:nil];
+
+ [super willTransitionToState:state];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h
new file mode 100644
index 0000000..aed5c49
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.h
@@ -0,0 +1,54 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import "SDL_net.h"
+
+
+ at protocol EngineProtocolDelegate <NSObject>
+
+-(void) gameEndedWithStatistics:(NSArray *)stats;
+
+ at end
+
+
+ at interface EngineProtocolNetwork : NSObject {
+ id<EngineProtocolDelegate> delegate;
+ NSOutputStream *stream;
+ TCPsocket csd;
+ NSInteger enginePort;
+}
+
+ at property (nonatomic,assign) id<EngineProtocolDelegate> delegate;
+ at property (nonatomic,retain) NSOutputStream *stream;
+ at property (assign) TCPsocket csd;
+ at property (assign) NSInteger enginePort;
+
+-(id) init;
+-(id) initWithPort:(NSInteger) port;
+-(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary;
+-(void) engineProtocol:(id) object;
+
+-(int) sendToEngine:(NSString *)string;
+-(int) sendToEngineNoSave:(NSString *)string;
+-(void) provideTeamData:(NSString *)teamName forHogs:(NSInteger) numberOfPlayingHogs withHealth:(NSInteger) initialHealth ofColor:(NSNumber *)teamColor;
+-(void) provideAmmoData:(NSString *)ammostoreName forPlayingTeams:(NSInteger) numberOfTeams;
+-(NSInteger) provideScheme:(NSString *)schemeName;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m
new file mode 100644
index 0000000..ba32496
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m
@@ -0,0 +1,413 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "EngineProtocolNetwork.h"
+
+
+#define BUFFER_SIZE 255 // like in original frontend
+
+ at implementation EngineProtocolNetwork
+ at synthesize delegate, stream, csd, enginePort;
+
+-(id) initWithPort:(NSInteger) port {
+ if ((self = [super init])) {
+ self.delegate = nil;
+ self.csd = NULL;
+ self.stream = nil;
+ self.enginePort = port;
+ }
+ return self;
+}
+
+-(id) init {
+ return [self initWithPort:[HWUtils randomPort]];
+}
+
+-(void) dealloc {
+ self.delegate = nil;
+ releaseAndNil(stream);
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Spawner functions
+-(void) spawnThread:(NSString *)onSaveFile withOptions:(NSDictionary *)dictionary {
+ self.stream = (onSaveFile) ? [[NSOutputStream alloc] initToFileAtPath:onSaveFile append:YES] : nil;
+ [self.stream open];
+
+ // +detachNewThreadSelector retain/release self automatically
+ [NSThread detachNewThreadSelector:@selector(engineProtocol:)
+ toTarget:self
+ withObject:dictionary];
+}
+
+#pragma mark -
+#pragma mark Provider functions
+// unpacks team data from the selected team.plist to a sequence of engine commands
+-(void) provideTeamData:(NSString *)teamName forHogs:(NSInteger) numberOfPlayingHogs withHealth:(NSInteger) initialHealth ofColor:(NSNumber *)teamColor {
+ /*
+ addteam <32charsMD5hash> <color> <team name>
+ addhh <level> <health> <hedgehog name>
+ <level> is 0 for human, 1-5 for bots (5 is the most stupid)
+ */
+
+ NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@", TEAMS_DIRECTORY(), teamName];
+ NSDictionary *teamData = [[NSDictionary alloc] initWithContentsOfFile:teamFile];
+ [teamFile release];
+
+ NSString *teamHashColorAndName = [[NSString alloc] initWithFormat:@"eaddteam %@ %@ %@",
+ [teamData objectForKey:@"hash"], [teamColor stringValue], [teamName stringByDeletingPathExtension]];
+ [self sendToEngine: teamHashColorAndName];
+ [teamHashColorAndName release];
+
+ NSString *grave = [[NSString alloc] initWithFormat:@"egrave %@", [teamData objectForKey:@"grave"]];
+ [self sendToEngine: grave];
+ [grave release];
+
+ NSString *fort = [[NSString alloc] initWithFormat:@"efort %@", [teamData objectForKey:@"fort"]];
+ [self sendToEngine: fort];
+ [fort release];
+
+ NSString *voicepack = [[NSString alloc] initWithFormat:@"evoicepack %@", [teamData objectForKey:@"voicepack"]];
+ [self sendToEngine: voicepack];
+ [voicepack release];
+
+ NSString *flag = [[NSString alloc] initWithFormat:@"eflag %@", [teamData objectForKey:@"flag"]];
+ [self sendToEngine: flag];
+ [flag release];
+
+ NSArray *hogs = [teamData objectForKey:@"hedgehogs"];
+ for (int i = 0; i < numberOfPlayingHogs; i++) {
+ NSDictionary *hog = [hogs objectAtIndex:i];
+
+ NSString *hogLevelHealthAndName = [[NSString alloc] initWithFormat:@"eaddhh %@ %d %@",
+ [hog objectForKey:@"level"], initialHealth, [hog objectForKey:@"hogname"]];
+ [self sendToEngine: hogLevelHealthAndName];
+ [hogLevelHealthAndName release];
+
+ NSString *hogHat = [[NSString alloc] initWithFormat:@"ehat %@", [hog objectForKey:@"hat"]];
+ [self sendToEngine: hogHat];
+ [hogHat release];
+ }
+
+ [teamData release];
+}
+
+// unpacks ammostore data from the selected ammo.plist to a sequence of engine commands
+-(void) provideAmmoData:(NSString *)ammostoreName forPlayingTeams:(NSInteger) numberOfTeams {
+ NSString *weaponPath = [[NSString alloc] initWithFormat:@"%@/%@",WEAPONS_DIRECTORY(),ammostoreName];
+ NSDictionary *ammoData = [[NSDictionary alloc] initWithContentsOfFile:weaponPath];
+ [weaponPath release];
+
+ // if we're loading an older version of ammos fill the engine message with 0s
+ int diff = HW_getNumberOfWeapons() - [[ammoData objectForKey:@"ammostore_initialqt"] length];
+ NSString *update = @"";
+ while ((int)[update length] < diff)
+ update = [update stringByAppendingString:@"0"];
+
+ NSString *ammloadt = [[NSString alloc] initWithFormat:@"eammloadt %@%@", [ammoData objectForKey:@"ammostore_initialqt"], update];
+ [self sendToEngine: ammloadt];
+ [ammloadt release];
+
+ NSString *ammprob = [[NSString alloc] initWithFormat:@"eammprob %@%@", [ammoData objectForKey:@"ammostore_probability"], update];
+ [self sendToEngine: ammprob];
+ [ammprob release];
+
+ NSString *ammdelay = [[NSString alloc] initWithFormat:@"eammdelay %@%@", [ammoData objectForKey:@"ammostore_delay"], update];
+ [self sendToEngine: ammdelay];
+ [ammdelay release];
+
+ NSString *ammreinf = [[NSString alloc] initWithFormat:@"eammreinf %@%@", [ammoData objectForKey:@"ammostore_crate"], update];
+ [self sendToEngine: ammreinf];
+ [ammreinf release];
+
+ // send this for each team so it applies the same ammostore to all teams
+ NSString *ammstore = [[NSString alloc] initWithString:@"eammstore"];
+ for (int i = 0; i < numberOfTeams; i++)
+ [self sendToEngine: ammstore];
+ [ammstore release];
+
+ [ammoData release];
+}
+
+// unpacks scheme data from the selected scheme.plist to a sequence of engine commands
+-(NSInteger) provideScheme:(NSString *)schemeName {
+ NSString *schemePath = [[NSString alloc] initWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),schemeName];
+ NSDictionary *schemeDictionary = [[NSDictionary alloc] initWithContentsOfFile:schemePath];
+ [schemePath release];
+ NSArray *basicArray = [schemeDictionary objectForKey:@"basic"];
+ NSArray *gamemodArray = [schemeDictionary objectForKey:@"gamemod"];
+ int result = 0;
+ int mask = 0x00000004;
+
+ // pack the game modifiers in a single var and send it
+ for (NSNumber *value in gamemodArray) {
+ if ([value boolValue] == YES)
+ result |= mask;
+ mask <<= 1;
+ }
+ NSString *flags = [[NSString alloc] initWithFormat:@"e$gmflags %d",result];
+ [self sendToEngine:flags];
+ [flags release];
+
+ // basic game flags
+ result = [[basicArray objectAtIndex:0] intValue];
+ NSArray *basic = [[NSArray alloc] initWithContentsOfFile:BASICFLAGS_FILE()];
+
+ for (NSUInteger i = 1; i < [basicArray count]; i++) {
+ NSDictionary *dict = [basic objectAtIndex:i];
+ NSString *command = [dict objectForKey:@"command"];
+ NSInteger value = [[basicArray objectAtIndex:i] intValue];
+ if ([[dict objectForKey:@"checkOverMax"] boolValue] && value >= [[dict objectForKey:@"max"] intValue])
+ value = 9999;
+ if ([[dict objectForKey:@"times1000"] boolValue])
+ value = value * 1000;
+ NSString *strToSend = [[NSString alloc] initWithFormat:@"%@ %d",command,value];
+ [self sendToEngine:strToSend];
+ [strToSend release];
+ }
+ [basic release];
+
+ [schemeDictionary release];
+ return result;
+}
+
+#pragma mark -
+#pragma mark Network relevant code
+-(void) dumpRawData:(const char *)buffer ofSize:(uint8_t) length {
+ [self.stream write:&length maxLength:1];
+ [self.stream write:(const uint8_t *)buffer maxLength:length];
+}
+
+// wrapper that computes the length of the message and then sends the command string, saving the command on a file
+-(int) sendToEngine:(NSString *)string {
+ uint8_t length = [string length];
+
+ [self dumpRawData:[string UTF8String] ofSize:length];
+ SDLNet_TCP_Send(csd, &length, 1);
+ return SDLNet_TCP_Send(csd, [string UTF8String], length);
+}
+
+// wrapper that computes the length of the message and then sends the command string, skipping file writing
+-(int) sendToEngineNoSave:(NSString *)string {
+ uint8_t length = [string length];
+
+ SDLNet_TCP_Send(csd, &length, 1);
+ return SDLNet_TCP_Send(csd, [string UTF8String], length);
+}
+
+// this is launched as thread and handles all IPC with engine
+-(void) engineProtocol:(id) object {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSDictionary *gameConfig = (NSDictionary *)object;
+ NSMutableArray *statsArray = nil;
+ TCPsocket sd;
+ IPaddress ip;
+ int eProto;
+ BOOL clientQuit;
+ char const buffer[BUFFER_SIZE];
+ uint8_t msgSize;
+
+ clientQuit = NO;
+ csd = NULL;
+
+ if (SDLNet_Init() < 0) {
+ DLog(@"SDLNet_Init: %s", SDLNet_GetError());
+ clientQuit = YES;
+ }
+
+ // Resolving the host using NULL make network interface to listen
+ if (SDLNet_ResolveHost(&ip, NULL, self.enginePort) < 0 && !clientQuit) {
+ DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+ clientQuit = YES;
+ }
+
+ // Open a connection with the IP provided (listen on the host's port)
+ if (!(sd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
+ DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), self.enginePort);
+ clientQuit = YES;
+ }
+
+ DLog(@"Waiting for a client on port %d", self.enginePort);
+ while (csd == NULL)
+ csd = SDLNet_TCP_Accept(sd);
+ SDLNet_TCP_Close(sd);
+
+ while (!clientQuit) {
+ msgSize = 0;
+ memset((void *)buffer, '\0', BUFFER_SIZE);
+ if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
+ break;
+ if (SDLNet_TCP_Recv(csd, (void *)buffer, msgSize) <= 0)
+ break;
+
+ switch (buffer[0]) {
+ case 'C':
+ DLog(@"Sending game config...\n%@", gameConfig);
+
+ /*if (isNetGame == YES)
+ [self sendToEngineNoSave:@"TN"];
+ else*/
+ [self sendToEngineNoSave:@"TL"];
+ NSString *saveHeader = @"TS";
+ [self dumpRawData:[saveHeader UTF8String] ofSize:[saveHeader length]];
+
+ // lua script (if set)
+ NSString *script = [gameConfig objectForKey:@"mission_command"];
+ if ([script length] != 0)
+ [self sendToEngine:script];
+ // missions/tranings only need the script configuration set
+ if ([gameConfig count] == 1)
+ break;
+
+ // seed info
+ [self sendToEngine:[gameConfig objectForKey:@"seed_command"]];
+
+ // dimension of the map
+ [self sendToEngine:[gameConfig objectForKey:@"templatefilter_command"]];
+ [self sendToEngine:[gameConfig objectForKey:@"mapgen_command"]];
+ [self sendToEngine:[gameConfig objectForKey:@"mazesize_command"]];
+
+ // static land (if set)
+ NSString *staticMap = [gameConfig objectForKey:@"staticmap_command"];
+ if ([staticMap length] != 0)
+ [self sendToEngine:staticMap];
+
+ // theme info
+ [self sendToEngine:[gameConfig objectForKey:@"theme_command"]];
+
+ // scheme (returns initial health)
+ NSInteger health = [self provideScheme:[gameConfig objectForKey:@"scheme"]];
+
+ // send an ammostore for each team
+ NSArray *teamsConfig = [gameConfig objectForKey:@"teams_list"];
+ [self provideAmmoData:[gameConfig objectForKey:@"weapon"] forPlayingTeams:[teamsConfig count]];
+
+ // finally add hogs
+ for (NSDictionary *teamData in teamsConfig) {
+ [self provideTeamData:[teamData objectForKey:@"team"]
+ forHogs:[[teamData objectForKey:@"number"] intValue]
+ withHealth:health
+ ofColor:[teamData objectForKey:@"color"]];
+ }
+ break;
+ case '?':
+ DLog(@"Ping? Pong!");
+ [self sendToEngine:@"!"];
+ break;
+ case 'E':
+ DLog(@"ERROR - last console line: [%s]", &buffer[1]);
+ clientQuit = YES;
+ break;
+ case 'e':
+ [self dumpRawData:buffer ofSize:msgSize];
+
+ sscanf((char *)buffer, "%*s %d", &eProto);
+ int netProto;
+ char *versionStr;
+
+ HW_versionInfo(&netProto, &versionStr);
+ if (netProto == eProto) {
+ DLog(@"Setting protocol version %d (%s)", eProto, versionStr);
+ } else {
+ DLog(@"ERROR - wrong protocol number: %d (expecting %d)", netProto, eProto);
+ clientQuit = YES;
+ }
+ break;
+ case 'i':
+ if (statsArray == nil) {
+ statsArray = [[NSMutableArray alloc] initWithCapacity:10 - 2];
+ NSMutableArray *ranking = [[NSMutableArray alloc] initWithCapacity:4];
+ [statsArray insertObject:ranking atIndex:0];
+ [ranking release];
+ }
+ NSString *tempStr = [NSString stringWithUTF8String:&buffer[2]];
+ NSArray *info = [tempStr componentsSeparatedByString:@" "];
+ NSString *arg = [info objectAtIndex:0];
+ int index = [arg length] + 3;
+ switch (buffer[1]) {
+ case 'r': // winning team
+ [statsArray insertObject:[NSString stringWithUTF8String:&buffer[2]] atIndex:1];
+ break;
+ case 'D': // best shot
+ [statsArray addObject:[NSString stringWithFormat:@"The best shot award won by %s (with %@ points)", &buffer[index], arg]];
+ break;
+ case 'k': // best hedgehog
+ [statsArray addObject:[NSString stringWithFormat:@"The best killer is %s with %@ kill(s) in a turn", &buffer[index], arg]];
+ break;
+ case 'K': // number of hogs killed
+ [statsArray addObject:[NSString stringWithFormat:@"%@ hedgehog(s) were killed during this round", arg]];
+ break;
+ case 'H': // team health/graph
+ break;
+ case 'T': // local team stats
+ // still WIP in statsPage.cpp
+ break;
+ case 'P': // teams ranking
+ [[statsArray objectAtIndex:0] addObject:tempStr];
+ break;
+ case 's': // self damage
+ [statsArray addObject:[NSString stringWithFormat:@"%s thought it's good to shoot his own hedgehogs with %@ points", &buffer[index], arg]];
+ break;
+ case 'S': // friendly fire
+ [statsArray addObject:[NSString stringWithFormat:@"%s killed %@ of his own hedgehogs", &buffer[index], arg]];
+ break;
+ case 'B': // turn skipped
+ [statsArray addObject:[NSString stringWithFormat:@"%s was scared and skipped turn %@ times", &buffer[index], arg]];
+ break;
+ default:
+ DLog(@"Unhandled stat message, see statsPage.cpp");
+ break;
+ }
+ break;
+ case 'q':
+ // game ended and match finished, statsArray is full of delicious statistics
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(gameEndedWithStatistics:)])
+ [self.delegate gameEndedWithStatistics:statsArray];
+ [statsArray release];
+ [HWUtils setGameStatus:gsEnded];
+ // closing connection here would trigger a "IPC connection lost" error, so we have to wait until recv fails
+ break;
+ case 'Q':
+ // game exited but not completed, skip this message in the savefile
+ [HWUtils setGameStatus:gsInterrupted];
+ // same here, don't set clientQuit to YES
+ break;
+ default:
+ [self dumpRawData:buffer ofSize:msgSize];
+ break;
+ }
+ }
+ DLog(@"Engine exited, ending thread");
+
+ [self.stream close];
+ [self.stream release];
+
+ // Close the client socket
+ [HWUtils freePort:self.enginePort];
+ SDLNet_TCP_Close(csd);
+ SDLNet_Quit();
+
+ [pool release];
+ // Invoking this method should be avoided as it does not give your thread a chance
+ // to clean up any resources it allocated during its execution.
+ //[NSThread exit];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/ExtraCategories.h b/project_files/HedgewarsMobile/Classes/ExtraCategories.h
new file mode 100644
index 0000000..1638b60
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ExtraCategories.h
@@ -0,0 +1,71 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+
+ at interface UIScreen (safe)
+
+-(CGFloat) safeScale;
+-(CGRect) safeBounds;
+
+ at end
+
+
+ at interface UITableView (backgroundColor)
+
+-(void) setBackgroundColorForAnyTable:(UIColor *)color;
+
+ at end
+
+
+ at interface UIColor (HWColors)
+
++(UIColor *)darkYellowColor;
++(UIColor *)lightYellowColor;
++(UIColor *)darkBlueColor;
++(UIColor *)darkBlueColorTransparent;
++(UIColor *)blackColorTransparent;
+
+ at end
+
+
+ at interface UIButton (quickStyle)
+
+-(id) initWithFrame:(CGRect) frame andTitle:(NSString *)title;
+
+ at end
+
+
+ at interface UILabel (quickStyle)
+
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title;
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title withBorderWidth:(CGFloat) borderWidth;
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title withBorderWidth:(CGFloat) borderWidth
+ withBorderColor:(UIColor *)borderColor withBackgroundColor:(UIColor *)backColor;
+
+ at end
+
+
+ at interface NSString (MD5)
+
+-(NSString *)MD5hash;
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/ExtraCategories.m b/project_files/HedgewarsMobile/Classes/ExtraCategories.m
new file mode 100644
index 0000000..e390f8b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ExtraCategories.m
@@ -0,0 +1,174 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "ExtraCategories.h"
+#import <QuartzCore/QuartzCore.h>
+#import <CommonCrypto/CommonDigest.h>
+
+
+#pragma mark -
+ at implementation UIScreen (safe)
+
+-(CGFloat) safeScale {
+ CGFloat theScale = 1.0f;
+ if ([self respondsToSelector:@selector(scale)])
+ theScale = [self scale];
+ return theScale;
+}
+
+-(CGRect) safeBounds {
+ CGRect original = [self bounds];
+ if (IS_ON_PORTRAIT())
+ return original;
+ else
+ return CGRectMake(original.origin.x, original.origin.y, original.size.height, original.size.width);
+}
+
+ at end
+
+
+#pragma mark -
+ at implementation UITableView (backgroundColor)
+
+-(void) setBackgroundColorForAnyTable:(UIColor *) color {
+ if ([self respondsToSelector:@selector(backgroundView)]) {
+ UIView *backView = [[UIView alloc] initWithFrame:self.frame];
+ backView.backgroundColor = color;
+ self.backgroundView = backView;
+ [backView release];
+ self.backgroundColor = [UIColor clearColor];
+ } else
+ self.backgroundColor = color;
+}
+
+ at end
+
+
+#pragma mark -
+ at implementation UIColor (HWColors)
+
++(UIColor *)darkYellowColor {
+ return [UIColor colorWithRed:(CGFloat)0xFE/255 green:(CGFloat)0xC0/255 blue:0 alpha:1];
+}
+
++(UIColor *)lightYellowColor {
+ return [UIColor colorWithRed:(CGFloat)0xF0/255 green:(CGFloat)0xD0/255 blue:0 alpha:1];
+}
+
++(UIColor *)darkBlueColor {
+ return [UIColor colorWithRed:(CGFloat)0x0F/255 green:0 blue:(CGFloat)0x42/255 alpha:1];
+}
+
+// older devices don't get any transparency for performance reasons
++(UIColor *)darkBlueColorTransparent {
+ return [UIColor colorWithRed:(CGFloat)0x0F/255
+ green:0
+ blue:(CGFloat)0x55/255
+ alpha:IS_NOT_POWERFUL([HWUtils modelType]) ? 1 : 0.6f];
+}
+
++(UIColor *)blackColorTransparent {
+ return [UIColor colorWithRed:0
+ green:0
+ blue:0
+ alpha:IS_NOT_POWERFUL([HWUtils modelType]) ? 1 : 0.65f];
+}
+
+ at end
+
+
+#pragma mark -
+ at implementation UIButton (quickStyle)
+
+-(id) initWithFrame:(CGRect) frame andTitle:(NSString *)title {
+ [self initWithFrame:frame];
+ [self setTitle:title forState:UIControlStateNormal];
+ [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
+ [self setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
+ self.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ self.backgroundColor = [UIColor blackColorTransparent];
+
+ [self.layer setBorderWidth:1];
+ [self.layer setBorderColor:[[UIColor darkYellowColor] CGColor]];
+ [self.layer setCornerRadius:9.0f];
+ [self.layer setMasksToBounds:YES];
+
+ return self;
+}
+
+ at end
+
+
+#pragma mark -
+ at implementation UILabel (quickStyle)
+
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title {
+ return [self initWithFrame:frame
+ andTitle:title
+ withBorderWidth:1.5f
+ withBorderColor:[UIColor darkYellowColor]
+ withBackgroundColor:[UIColor darkBlueColor]];
+}
+
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title withBorderWidth:(CGFloat) borderWidth {
+ return [self initWithFrame:frame
+ andTitle:title
+ withBorderWidth:borderWidth
+ withBorderColor:[UIColor darkYellowColor]
+ withBackgroundColor:[UIColor darkBlueColorTransparent]];
+}
+
+-(id) initWithFrame:(CGRect)frame andTitle:(NSString *)title withBorderWidth:(CGFloat) borderWidth
+ withBorderColor:(UIColor *)borderColor withBackgroundColor:(UIColor *)backColor {
+ UILabel *theLabel = [self initWithFrame:frame];
+ theLabel.backgroundColor = backColor;
+
+ if (title != nil) {
+ theLabel.text = title;
+ theLabel.textColor = [UIColor lightYellowColor];
+ theLabel.textAlignment = UITextAlignmentCenter;
+ theLabel.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]*80/100];
+ }
+
+ [theLabel.layer setBorderWidth:borderWidth];
+ [theLabel.layer setBorderColor:borderColor.CGColor];
+ [theLabel.layer setCornerRadius:8.0f];
+ [theLabel.layer setMasksToBounds:YES];
+
+ return theLabel;
+}
+
+ at end
+
+
+#pragma mark -
+ at implementation NSString (MD5)
+
+-(NSString *)MD5hash {
+ const char *cStr = [self UTF8String];
+ unsigned char result[16];
+ CC_MD5( cStr, strlen(cStr), result );
+ return [NSString stringWithFormat:
+ @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ result[0], result[1], result[2], result[3], result[4], result[5],
+ result[6], result[7], result[8], result[9], result[10], result[11],
+ result[12], result[13], result[14], result[15]];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/FlagsViewController.h b/project_files/HedgewarsMobile/Classes/FlagsViewController.h
new file mode 100644
index 0000000..0abbcc7
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/FlagsViewController.h
@@ -0,0 +1,36 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface FlagsViewController : UITableViewController {
+ NSDictionary *teamDictionary;
+
+ NSArray *flagArray;
+ NSArray *communityArray;
+ NSIndexPath *lastIndexPath;
+}
+
+ at property (nonatomic,retain) NSDictionary * teamDictionary;
+ at property (nonatomic,retain) NSArray *flagArray;
+ at property (nonatomic,retain) NSArray *communityArray;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/FlagsViewController.m b/project_files/HedgewarsMobile/Classes/FlagsViewController.m
new file mode 100644
index 0000000..4c3f20c
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/FlagsViewController.m
@@ -0,0 +1,191 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "FlagsViewController.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+ at implementation FlagsViewController
+ at synthesize teamDictionary, flagArray, communityArray, lastIndexPath;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ NSMutableArray *array_na = [[NSMutableArray alloc] init];
+ NSMutableArray *array_cm = [[NSMutableArray alloc] init];
+
+ for (NSString *name in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:FLAGS_DIRECTORY() error:NULL]) {
+ if ([name hasPrefix:@"cm_"]) {
+ NSString *processed = [name substringFromIndex:3];
+ [array_cm addObject:processed];
+ } else
+ [array_na addObject:name];
+ }
+
+ self.flagArray = array_na;
+ [array_na release];
+ self.communityArray = array_cm;
+ [array_cm release];
+
+ self.title = NSLocalizedString(@"Set team flag",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ // reloadData needed because team might change
+ [self.tableView reloadData];
+ //[self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 2;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (section == 0)
+ return [self.flagArray count];
+ else
+ return [self.communityArray count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+ NSInteger row = [indexPath row];
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ NSString *flagName = nil;
+ NSArray *source = nil;
+ if ([indexPath section] == 0) {
+ source = self.flagArray;
+ flagName = [source objectAtIndex:row];
+ } else {
+ source = self.communityArray;
+ flagName = [NSString stringWithFormat:@"cm_%@",[source objectAtIndex:row]];
+ }
+ NSString *flagFile = [[NSString alloc] initWithFormat:@"%@/%@", FLAGS_DIRECTORY(), flagName];
+ UIImage *flagSprite = [[UIImage alloc] initWithContentsOfFile:flagFile];
+ [flagFile release];
+ cell.imageView.image = flagSprite;
+ [flagSprite release];
+ cell.imageView.layer.borderWidth = 1;
+ cell.imageView.layer.borderColor = [[UIColor blackColor] CGColor];
+
+ cell.textLabel.text = [[source objectAtIndex:row] stringByDeletingPathExtension];
+ if ([[flagName stringByDeletingPathExtension] isEqualToString:[self.teamDictionary objectForKey:@"flag"]]) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ return cell;
+}
+
+-(NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
+ NSString *sectionTitle = nil;
+ switch (section) {
+ case 0:
+ sectionTitle = NSLocalizedString(@"Worldwide", @"");
+ break;
+ case 1:
+ sectionTitle = NSLocalizedString(@"Community", @"");
+ break;
+ default:
+ DLog(@"nope");
+ break;
+ }
+ return sectionTitle;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+ int newSection = [indexPath section];
+ int oldSection = (lastIndexPath != nil) ? [lastIndexPath section] : -1;
+
+ if (newRow != oldRow || newSection != oldSection) {
+ NSString *flag = nil;
+ if ([indexPath section] == 0)
+ flag = [self.flagArray objectAtIndex:newRow];
+ else
+ flag = [NSString stringWithFormat:@"cm_%@",[self.communityArray objectAtIndex:newRow]];
+
+ // if the two selected rows differ update data on the hog dictionary and reload table content
+ [self.teamDictionary setValue:[flag stringByDeletingPathExtension] forKey:@"flag"];
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ newCell.accessoryType = UITableViewCellAccessoryCheckmark;
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+ oldCell.accessoryType = UITableViewCellAccessoryNone;
+ self.lastIndexPath = indexPath;
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.teamDictionary = nil;
+ self.lastIndexPath = nil;
+ self.flagArray = nil;
+ self.communityArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(teamDictionary);
+ releaseAndNil(lastIndexPath);
+ releaseAndNil(flagArray);
+ releaseAndNil(communityArray);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/FortsViewController.h b/project_files/HedgewarsMobile/Classes/FortsViewController.h
new file mode 100644
index 0000000..200b79b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/FortsViewController.h
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface FortsViewController : UITableViewController {
+ NSDictionary *teamDictionary;
+
+ NSArray *fortArray;
+ NSIndexPath *lastIndexPath;
+}
+
+ at property (nonatomic,retain) NSDictionary * teamDictionary;
+ at property (nonatomic,retain) NSArray *fortArray;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/FortsViewController.m b/project_files/HedgewarsMobile/Classes/FortsViewController.m
new file mode 100644
index 0000000..8f8d0b9
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/FortsViewController.m
@@ -0,0 +1,157 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "FortsViewController.h"
+
+
+#define IMGNUM_PER_FORT 6
+
+ at implementation FortsViewController
+ at synthesize teamDictionary, fortArray, lastIndexPath;
+
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:FORTS_DIRECTORY() error:NULL];
+ NSMutableArray *filteredContents = [[NSMutableArray alloc] initWithCapacity:([directoryContents count] / IMGNUM_PER_FORT)];
+ // we need to remove the double entries and the L.png suffix
+ for (NSUInteger i = 0; i < [directoryContents count]; i++) {
+ if (i % IMGNUM_PER_FORT == IMGNUM_PER_FORT-1) {
+ NSString *currentName = [directoryContents objectAtIndex:i];
+ NSString *correctName = [currentName substringToIndex:([currentName length] - 5)];
+ [filteredContents addObject:correctName];
+ }
+ }
+ self.fortArray = filteredContents;
+ [filteredContents release];
+
+ // statically set row height instead of using delegate method for performance reasons
+ self.tableView.rowHeight = 128;
+
+ self.title = NSLocalizedString(@"Choose team fort",@"");
+}
+
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [self.tableView reloadData];
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.fortArray count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
+ reuseIdentifier:CellIdentifier] autorelease];
+
+ NSString *fortName = [fortArray objectAtIndex:[indexPath row]];
+ cell.textLabel.text = fortName;
+
+ NSString *fortFile = [[NSString alloc] initWithFormat:@"%@/%@-preview.png", FORTS_DIRECTORY(), fortName];
+ UIImage *fortSprite = [[UIImage alloc] initWithContentsOfFile:fortFile];
+ [fortFile release];
+ cell.imageView.image = fortSprite;
+ [fortSprite release];
+
+ //cell.detailTextLabel.text = @"Insert funny description here";
+ if ([cell.textLabel.text isEqualToString:[self.teamDictionary objectForKey:@"fort"]]) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ // if the two selected rows differ update data on the hog dictionary and reload table content
+ [self.teamDictionary setValue:[fortArray objectAtIndex:newRow] forKey:@"fort"];
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ newCell.accessoryType = UITableViewCellAccessoryCheckmark;
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+ oldCell.accessoryType = UITableViewCellAccessoryNone;
+ self.lastIndexPath = indexPath;
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.teamDictionary = nil;
+ self.lastIndexPath = nil;
+ self.fortArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(teamDictionary);
+ releaseAndNil(lastIndexPath);
+ releaseAndNil(fortArray);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPad.xib b/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPad.xib
new file mode 100644
index 0000000..9a56cc5
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPad.xib
@@ -0,0 +1,1078 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="2"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="766721923">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="109536142">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{1024, 768}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIAutoresizesSubviews">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">background.png</string>
+ </object>
+ </object>
+ <object class="IBUIImageView" id="533754865">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{357, 17}, {309, 165}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">title~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="410546531">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{441, 702}, {142, 64}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">1</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="243320520">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="473179629">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="702849038">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">startGameButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="495854712">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 693}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="243320520"/>
+ <reference key="IBUIHighlightedTitleColor" ref="473179629"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="702849038"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">backButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="688316814">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">265</int>
+ <string key="NSFrame">{{940, 693}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">2</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="243320520"/>
+ <reference key="IBUIHighlightedTitleColor" ref="473179629"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="702849038"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">helpButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIView" id="123574818">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{0, 60}, {320, 620}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <object class="NSColor" key="IBUIBackgroundColor" id="720784738">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="983956256">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{337, 187}, {350, 505}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <reference key="IBUIBackgroundColor" ref="720784738"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUISlider" id="1000322445">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{269, 724}, {150, 23}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <float key="IBUIValue">0.05000000074505806</float>
+ <float key="IBUIMaxValue">0.05000000074505806</float>
+ </object>
+ </object>
+ <string key="NSFrameSize">{1024, 768}</string>
+ <reference key="NSSuperview"/>
+ <reference key="IBUIBackgroundColor" ref="473179629"/>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIViewController" id="1023023363">
+ <bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics" id="158576700">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ <object class="IBUIViewController" id="487135035">
+ <bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
+ <reference key="IBUISimulatedOrientationMetrics" ref="158576700"/>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ <object class="IBUIViewController" id="670598485">
+ <bool key="IBUIAutoresizesArchivedViewToFullSize">NO</bool>
+ <string key="IBUINibName">MapConfigViewController-iPad</string>
+ <reference key="IBUISimulatedOrientationMetrics" ref="158576700"/>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="766721923"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="495854712"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">35</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="410546531"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">36</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="688316814"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">37</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">teamConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="487135035"/>
+ </object>
+ <int key="connectionID">45</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="487135035"/>
+ <reference key="destination" ref="983956256"/>
+ </object>
+ <int key="connectionID">47</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="1023023363"/>
+ <reference key="destination" ref="123574818"/>
+ </object>
+ <int key="connectionID">50</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">schemeWeaponConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="1023023363"/>
+ </object>
+ <int key="connectionID">51</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">mapConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="670598485"/>
+ </object>
+ <int key="connectionID">57</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">sliderChanged:</string>
+ <reference key="source" ref="1000322445"/>
+ <reference key="destination" ref="670598485"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">66</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">sliderEndedChanging:</string>
+ <reference key="source" ref="1000322445"/>
+ <reference key="destination" ref="670598485"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">67</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">titleImage</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="533754865"/>
+ </object>
+ <int key="connectionID">68</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">slider</string>
+ <reference key="source" ref="670598485"/>
+ <reference key="destination" ref="1000322445"/>
+ </object>
+ <int key="connectionID">69</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="766721923"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="109536142"/>
+ <reference ref="533754865"/>
+ <reference ref="410546531"/>
+ <reference ref="495854712"/>
+ <reference ref="688316814"/>
+ <reference ref="123574818"/>
+ <reference ref="983956256"/>
+ <reference ref="1000322445"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">30</int>
+ <reference key="object" ref="109536142"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Background</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">31</int>
+ <reference key="object" ref="533754865"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Title</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">32</int>
+ <reference key="object" ref="410546531"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Start Button</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">33</int>
+ <reference key="object" ref="495854712"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Back Button</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">34</int>
+ <reference key="object" ref="688316814"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Help Button</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">44</int>
+ <reference key="object" ref="487135035"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">46</int>
+ <reference key="object" ref="983956256"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">TeamConfigViewController View</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">48</int>
+ <reference key="object" ref="1023023363"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">49</int>
+ <reference key="object" ref="123574818"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">SchemeWeaponConfigViewController View</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">55</int>
+ <reference key="object" ref="670598485"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">60</int>
+ <reference key="object" ref="1000322445"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">Filter Slider</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>30.IBPluginDependency</string>
+ <string>30.IBViewBoundsToFrameTransform</string>
+ <string>31.IBPluginDependency</string>
+ <string>31.IBViewBoundsToFrameTransform</string>
+ <string>32.IBPluginDependency</string>
+ <string>32.IBViewBoundsToFrameTransform</string>
+ <string>33.IBPluginDependency</string>
+ <string>33.IBViewBoundsToFrameTransform</string>
+ <string>34.IBPluginDependency</string>
+ <string>34.IBViewBoundsToFrameTransform</string>
+ <string>44.CustomClassName</string>
+ <string>44.IBEditorWindowLastContentRect</string>
+ <string>44.IBPluginDependency</string>
+ <string>46.IBPluginDependency</string>
+ <string>46.IBViewBoundsToFrameTransform</string>
+ <string>48.CustomClassName</string>
+ <string>48.IBEditorWindowLastContentRect</string>
+ <string>48.IBPluginDependency</string>
+ <string>49.IBPluginDependency</string>
+ <string>49.IBViewBoundsToFrameTransform</string>
+ <string>55.CustomClassName</string>
+ <string>55.IBEditorWindowLastContentRect</string>
+ <string>55.IBPluginDependency</string>
+ <string>60.CustomClassName</string>
+ <string>60.IBPluginDependency</string>
+ <string>60.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>GameConfigViewController</string>
+ <string>UIResponder</string>
+ <string>{{252, 239}, {1024, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABAoAAAxLrgAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDtQAAxGNAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABD3wAAxLqgAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABByAAAxLmAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABEbEAAxLmAAA</bytes>
+ </object>
+ <string>TeamConfigViewController</string>
+ <string>{{63, 355}, {1024, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUOogABDOwAAA</bytes>
+ </object>
+ <string>SchemeWeaponConfigViewController</string>
+ <string>{{84, 388}, {1024, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAxHqAAA</bytes>
+ </object>
+ <string>MapConfigViewController</string>
+ <string>{{126, 377}, {1024, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>MNEValueTrackingSlider</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUNRAABEMoAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">69</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">GameConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentPressed:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentPressed:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapConfigViewController</string>
+ <string>schemeWeaponConfigViewController</string>
+ <string>teamConfigViewController</string>
+ <string>titleImage</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MapConfigViewController</string>
+ <string>SchemeWeaponConfigViewController</string>
+ <string>TeamConfigViewController</string>
+ <string>UIImageView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapConfigViewController</string>
+ <string>schemeWeaponConfigViewController</string>
+ <string>teamConfigViewController</string>
+ <string>titleImage</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">mapConfigViewController</string>
+ <string key="candidateClassName">MapConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">schemeWeaponConfigViewController</string>
+ <string key="candidateClassName">SchemeWeaponConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">teamConfigViewController</string>
+ <string key="candidateClassName">TeamConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">titleImage</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/GameConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MNEValueTrackingSlider</string>
+ <string key="superclassName">UISlider</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MNEValueTrackingSlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">mapButtonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentedControlChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderEndedChanging:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>MapPreviewButtonView</string>
+ <string>UISegmentedControl</string>
+ <string>MNEValueTrackingSlider</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">maxLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewButton</string>
+ <string key="candidateClassName">MapPreviewButtonView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">segmentedControl</string>
+ <string key="candidateClassName">UISegmentedControl</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">slider</string>
+ <string key="candidateClassName">MNEValueTrackingSlider</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapPreviewButtonView</string>
+ <string key="superclassName">UIButton</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">delegate</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">delegate</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">delegate</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapPreviewButtonView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">SchemeWeaponConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/SchemeWeaponConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">TeamConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/TeamConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="106046383">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <reference key="sourceIdentifier" ref="106046383"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="106046383"/>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="786211723">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="786211723"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISegmentedControl</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISlider</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>backButton.png</string>
+ <string>background.png</string>
+ <string>helpButton.png</string>
+ <string>startGameButton.png</string>
+ <string>title~iphone.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{64, 64}</string>
+ <string>{1024, 768}</string>
+ <string>{64, 64}</string>
+ <string>{142, 64}</string>
+ <string>{270, 150}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPhone.xib b/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPhone.xib
new file mode 100644
index 0000000..347323d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController-iPhone.xib
@@ -0,0 +1,1014 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="30"/>
+ <integer value="2"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="766721923">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIToolbar" id="836721772">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">266</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUISegmentedControl" id="563596142">
+ <reference key="NSNextResponder" ref="836721772"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{96, 8}, {270, 30}}</string>
+ <reference key="NSSuperview" ref="836721772"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">12345</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBSegmentControlStyle">2</int>
+ <int key="IBNumberOfSegments">4</int>
+ <int key="IBSelectedSegmentIndex">0</int>
+ <object class="NSArray" key="IBSegmentTitles">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Map</string>
+ <string>Teams</string>
+ <string>Details</string>
+ <string>Help</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentWidths">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentEnabledStates">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentContentOffsets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentImages">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSNull" id="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ </object>
+ <object class="NSColor" key="IBTintColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC42IDAuNiAwLjYAA</bytes>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrame">{{0, 276}, {480, 44}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIBarStyle">1</int>
+ <object class="NSMutableArray" key="IBUIItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIBarButtonItem" id="80281356">
+ <string key="IBUITitle">Back</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUIToolbar" ref="836721772"/>
+ </object>
+ <object class="IBUIBarButtonItem" id="716161941">
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <reference key="IBUIToolbar" ref="836721772"/>
+ <int key="IBUISystemItemIdentifier">5</int>
+ </object>
+ <object class="IBUIBarButtonItem" id="530186890">
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <reference key="IBUICustomView" ref="563596142"/>
+ <reference key="IBUIToolbar" ref="836721772"/>
+ </object>
+ <object class="IBUIBarButtonItem" id="188600069">
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <reference key="IBUIToolbar" ref="836721772"/>
+ <int key="IBUISystemItemIdentifier">5</int>
+ </object>
+ <object class="IBUIBarButtonItem" id="919181414">
+ <int key="IBUITag">1</int>
+ <string key="IBUITitle">Start</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <float key="IBUIWidth">68</float>
+ <int key="IBUIStyle">2</int>
+ <reference key="IBUIToolbar" ref="836721772"/>
+ </object>
+ </object>
+ </object>
+ <object class="IBUIView" id="914954699">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{480, 276}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace" id="9020506">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="848489667">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{480, 276}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <reference key="NSCustomColorSpace" ref="9020506"/>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIViewController" id="682131721">
+ <string key="IBUINibName">MapConfigViewController-iPhone</string>
+ <object class="IBUISimulatedToolbarMetrics" key="IBUISimulatedBottomBarMetrics"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics" id="789431191">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ <object class="IBUIViewController" id="508843780">
+ <object class="IBUISimulatedToolbarMetrics" key="IBUISimulatedBottomBarMetrics" id="129104688">
+ <int key="IBUIBarStyle">1</int>
+ </object>
+ <reference key="IBUISimulatedOrientationMetrics" ref="789431191"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ <object class="IBUIViewController" id="290947091">
+ <reference key="IBUISimulatedBottomBarMetrics" ref="129104688"/>
+ <reference key="IBUISimulatedOrientationMetrics" ref="789431191"/>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIHorizontal">YES</bool>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="766721923"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="80281356"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">17</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="919181414"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">23</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">segmentPressed:</string>
+ <reference key="source" ref="563596142"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">29</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">mapConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="682131721"/>
+ </object>
+ <int key="connectionID">33</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">teamConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="508843780"/>
+ </object>
+ <int key="connectionID">34</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">schemeWeaponConfigViewController</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="290947091"/>
+ </object>
+ <int key="connectionID">35</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="508843780"/>
+ <reference key="destination" ref="914954699"/>
+ </object>
+ <int key="connectionID">42</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="290947091"/>
+ <reference key="destination" ref="848489667"/>
+ </object>
+ <int key="connectionID">43</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="766721923"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="836721772"/>
+ <reference ref="914954699"/>
+ <reference ref="848489667"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="836721772"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="80281356"/>
+ <reference ref="919181414"/>
+ <reference ref="188600069"/>
+ <reference ref="530186890"/>
+ <reference ref="716161941"/>
+ </object>
+ <reference key="parent" ref="766721923"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">16</int>
+ <reference key="object" ref="80281356"/>
+ <reference key="parent" ref="836721772"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">18</int>
+ <reference key="object" ref="919181414"/>
+ <reference key="parent" ref="836721772"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="188600069"/>
+ <reference key="parent" ref="836721772"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">21</int>
+ <reference key="object" ref="530186890"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="563596142"/>
+ </object>
+ <reference key="parent" ref="836721772"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">20</int>
+ <reference key="object" ref="563596142"/>
+ <reference key="parent" ref="530186890"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">22</int>
+ <reference key="object" ref="716161941"/>
+ <reference key="parent" ref="836721772"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">30</int>
+ <reference key="object" ref="682131721"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">31</int>
+ <reference key="object" ref="508843780"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">32</int>
+ <reference key="object" ref="290947091"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">40</int>
+ <reference key="object" ref="914954699"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">TeamConfigViewController View</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">41</int>
+ <reference key="object" ref="848489667"/>
+ <reference key="parent" ref="766721923"/>
+ <string key="objectName">SchemeWeaponConfigViewController View</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>15.IBPluginDependency</string>
+ <string>15.IBViewBoundsToFrameTransform</string>
+ <string>16.IBPluginDependency</string>
+ <string>18.IBPluginDependency</string>
+ <string>19.IBPluginDependency</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>20.IBPluginDependency</string>
+ <string>22.IBPluginDependency</string>
+ <string>30.CustomClassName</string>
+ <string>30.IBEditorWindowLastContentRect</string>
+ <string>30.IBPluginDependency</string>
+ <string>31.CustomClassName</string>
+ <string>31.IBEditorWindowLastContentRect</string>
+ <string>31.IBPluginDependency</string>
+ <string>32.CustomClassName</string>
+ <string>32.IBEditorWindowLastContentRect</string>
+ <string>32.IBPluginDependency</string>
+ <string>40.IBPluginDependency</string>
+ <string>40.IBViewBoundsToFrameTransform</string>
+ <string>41.IBPluginDependency</string>
+ <string>41.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>GameConfigViewController</string>
+ <string>UIResponder</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw58AAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>{{40, 217}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>MapConfigViewController</string>
+ <string>{{0, 825}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>TeamConfigViewController</string>
+ <string>{{21, 802}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>SchemeWeaponConfigViewController</string>
+ <string>{{42, 779}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw5QAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw5QAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">45</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">GameConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentPressed:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>buttonPressed:</string>
+ <string>segmentPressed:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapConfigViewController</string>
+ <string>schemeWeaponConfigViewController</string>
+ <string>teamConfigViewController</string>
+ <string>titleImage</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MapConfigViewController</string>
+ <string>SchemeWeaponConfigViewController</string>
+ <string>TeamConfigViewController</string>
+ <string>UIImageView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapConfigViewController</string>
+ <string>schemeWeaponConfigViewController</string>
+ <string>teamConfigViewController</string>
+ <string>titleImage</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">mapConfigViewController</string>
+ <string key="candidateClassName">MapConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">schemeWeaponConfigViewController</string>
+ <string key="candidateClassName">SchemeWeaponConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">teamConfigViewController</string>
+ <string key="candidateClassName">TeamConfigViewController</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">titleImage</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/GameConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">mapButtonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentedControlChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderEndedChanging:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>MapPreviewButtonView</string>
+ <string>UISegmentedControl</string>
+ <string>ValueTrackingSliderView</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">maxLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewButton</string>
+ <string key="candidateClassName">MapPreviewButtonView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">segmentedControl</string>
+ <string key="candidateClassName">UISegmentedControl</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">slider</string>
+ <string key="candidateClassName">ValueTrackingSliderView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapPreviewButtonView</string>
+ <string key="superclassName">UIButton</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">delegate</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">delegate</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">delegate</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapPreviewButtonView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">SchemeWeaponConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/SchemeWeaponConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">TeamConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/TeamConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="910572871">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="910572871"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">ValueTrackingSliderView</string>
+ <string key="superclassName">UISlider</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MNEValueTrackingSlider.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="786211723">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarButtonItem</string>
+ <string key="superclassName">UIBarItem</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarItem</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="786211723"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISegmentedControl</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISlider</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIToolbar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIToolbar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/GameConfigViewController.h b/project_files/HedgewarsMobile/Classes/GameConfigViewController.h
new file mode 100644
index 0000000..6d5738f
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController.h
@@ -0,0 +1,52 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class SchemeWeaponConfigViewController;
+ at class TeamConfigViewController;
+ at class MapConfigViewController;
+//@class HelpPageLobbyViewController;
+
+ at interface GameConfigViewController : UIViewController {
+ UIView *imgContainer;
+ UIImageView *titleImage;
+ UILabel *sliderBackground;
+
+ SchemeWeaponConfigViewController *schemeWeaponConfigViewController;
+ TeamConfigViewController *teamConfigViewController;
+ MapConfigViewController *mapConfigViewController;
+ //HelpPageLobbyViewController *helpPage;
+}
+
+ at property (retain) UIView *imgContainer;
+ at property (nonatomic,retain) UILabel * sliderBackground;
+ at property (nonatomic,retain) IBOutlet UIImageView *titleImage;
+ at property (nonatomic,retain) IBOutlet SchemeWeaponConfigViewController *schemeWeaponConfigViewController;
+ at property (nonatomic,retain) IBOutlet TeamConfigViewController *teamConfigViewController;
+ at property (nonatomic,retain) IBOutlet MapConfigViewController *mapConfigViewController;
+//@property (nonatomic,retain) HelpPageLobbyViewController *helpPage;
+
+-(IBAction) buttonPressed:(id) sender;
+-(IBAction) segmentPressed:(id) sender;
+-(void) startGame:(UIButton *)button;
+-(BOOL) isEverythingSet;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GameConfigViewController.m b/project_files/HedgewarsMobile/Classes/GameConfigViewController.m
new file mode 100644
index 0000000..3c79a8a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController.m
@@ -0,0 +1,429 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GameConfigViewController.h"
+#import "MapConfigViewController.h"
+#import "TeamConfigViewController.h"
+#import "SchemeWeaponConfigViewController.h"
+#import "GameInterfaceBridge.h"
+
+
+ at implementation GameConfigViewController
+ at synthesize imgContainer, titleImage, sliderBackground, //helpPage,
+ mapConfigViewController, teamConfigViewController, schemeWeaponConfigViewController;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(IBAction) buttonPressed:(id) sender {
+ UIButton *theButton = (UIButton *)sender;
+
+ switch (theButton.tag) {
+ case 0:
+ if ([self.mapConfigViewController busy]) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Wait for the Preview",@"")
+ message:NSLocalizedString(@"Before returning the preview needs to be generated",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ } else {
+ [[AudioManagerController mainManager] playBackSound];
+ [[self parentViewController] dismissModalViewControllerAnimated:YES];
+ }
+ break;
+ case 1:
+ [[AudioManagerController mainManager] playClickSound];
+ if ([self isEverythingSet] == NO)
+ return;
+ theButton.enabled = NO;
+ for (UIView *oneView in self.imgContainer.subviews) {
+ if ([oneView isMemberOfClass:[UIImageView class]]) {
+ UIImageView *anImageView = (UIImageView *)oneView;
+ [anImageView removeFromSuperview];
+ }
+ }
+ [self startGame:theButton];
+
+ break;
+ case 2:
+ [[AudioManagerController mainManager] playClickSound];
+ /*
+ if (self.helpPage == nil)
+ self.helpPage = [[HelpPageLobbyViewController alloc] initWithNibName:@"HelpPageLobbyViewController-iPad" bundle:nil];
+ self.helpPage.view.alpha = 0;
+ [self.view addSubview:self.helpPage.view];
+ [UIView beginAnimations:@"helplobby" context:NULL];
+ self.helpPage.view.alpha = 1;
+ [UIView commitAnimations];
+ */
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+}
+
+-(IBAction) segmentPressed:(id) sender {
+
+ UISegmentedControl *theSegment = (UISegmentedControl *)sender;
+
+ [[AudioManagerController mainManager] playSelectSound];
+ switch (theSegment.selectedSegmentIndex) {
+ case 0:
+ // this message is compulsory otherwise the table won't be loaded at all
+ [self.mapConfigViewController viewWillAppear:NO];
+ [self.view bringSubviewToFront:self.mapConfigViewController.view];
+ break;
+ case 1:
+ // this message is compulsory otherwise the table won't be loaded at all
+ [self.teamConfigViewController viewWillAppear:NO];
+ [self.view bringSubviewToFront:self.teamConfigViewController.view];
+ break;
+ case 2:
+ // this message is compulsory otherwise the table won't be loaded at all
+ [schemeWeaponConfigViewController viewWillAppear:NO];
+ [self.view bringSubviewToFront:schemeWeaponConfigViewController.view];
+ break;
+ case 3:
+ /*
+ if (helpPage == nil) {
+ helpPage = [[HelpPageLobbyViewController alloc] initWithNibName:@"HelpPageLobbyViewController-iPhone" bundle:nil];
+ [self.view addSubview:helpPage.view];
+ }
+ // this message is compulsory otherwise the table won't be loaded at all
+ [helpPage viewWillAppear:NO];
+ [self.view bringSubviewToFront:helpPage.view];
+ */
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+
+}
+
+-(BOOL) isEverythingSet {
+ // don't start playing if the preview is in progress
+ if ([self.mapConfigViewController busy]) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Wait for the Preview",@"")
+ message:NSLocalizedString(@"Before playing the preview needs to be generated",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ // play only if there is more than one team
+ if ([self.teamConfigViewController.listOfSelectedTeams count] < 2) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Too few teams playing",@"")
+ message:NSLocalizedString(@"Select at least two teams to play a game",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ // play if there's room for enough hogs in the selected map
+ int hogs = 0;
+ for (NSDictionary *teamData in teamConfigViewController.listOfSelectedTeams)
+ hogs += [[teamData objectForKey:@"number"] intValue];
+ if (hogs > self.mapConfigViewController.maxHogs) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Too many hogs",@"")
+ message:NSLocalizedString(@"The map is too small for that many hogs",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ // play if there aren't too many teams
+ if ((int)[self.teamConfigViewController.listOfSelectedTeams count] > HW_getMaxNumberOfTeams()) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Too many teams",@"")
+ message:NSLocalizedString(@"You exceeded the maximum number of tems allowed in a game",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ // play only if one scheme and one weapon are selected
+ if ([self.schemeWeaponConfigViewController.selectedScheme length] == 0 || [self.schemeWeaponConfigViewController.selectedWeapon length] == 0 ) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Missing detail",@"")
+ message:NSLocalizedString(@"Select one Scheme and one Weapon for this game",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ // play if the gameflags are set correctly (divideteam works only with 2 teams)
+ NSString *schemePath = [[NSString alloc] initWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),self.schemeWeaponConfigViewController.selectedScheme];
+ NSArray *gameFlags = [[NSDictionary dictionaryWithContentsOfFile:schemePath] objectForKey:@"gamemod"];
+ [schemePath release];
+ if ([[gameFlags objectAtIndex:2] boolValue] && [self.teamConfigViewController.listOfSelectedTeams count] != 2) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Scheme mismatch",@"")
+ message:NSLocalizedString(@"The scheme you selected allows only for two teams",@"")
+ delegate:nil
+ cancelButtonTitle:NSLocalizedString(@"Ok, got it",@"")
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ return NO;
+ }
+
+ return YES;
+}
+
+-(void) startGame:(UIButton *)button {
+ button.enabled = YES;
+
+ NSString *script = self.mapConfigViewController.missionCommand;
+ if ([script isEqualToString:@""])
+ script = self.schemeWeaponConfigViewController.scriptCommand;
+
+ // create the configuration file that is going to be sent to engine
+ NSDictionary *gameDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
+ self.mapConfigViewController.seedCommand,@"seed_command",
+ self.mapConfigViewController.templateFilterCommand,@"templatefilter_command",
+ self.mapConfigViewController.mapGenCommand,@"mapgen_command",
+ self.mapConfigViewController.mazeSizeCommand,@"mazesize_command",
+ self.mapConfigViewController.themeCommand,@"theme_command",
+ self.mapConfigViewController.staticMapCommand,@"staticmap_command",
+ self.teamConfigViewController.listOfSelectedTeams,@"teams_list",
+ self.schemeWeaponConfigViewController.selectedScheme,@"scheme",
+ self.schemeWeaponConfigViewController.selectedWeapon,@"weapon",
+ script,@"mission_command",
+ nil];
+
+ [GameInterfaceBridge registerCallingController:self];
+ [GameInterfaceBridge startLocalGame:gameDictionary];
+ [gameDictionary release];
+}
+
+-(void) loadNiceHogs {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ srand(time(NULL));
+ NSString *filePath = [[NSString alloc] initWithFormat:@"%@/Hedgehog/Idle.png",GRAPHICS_DIRECTORY()];
+ UIImage *hogSprite = [[UIImage alloc] initWithContentsOfFile:filePath];
+ [filePath release];
+
+ NSArray *hatArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:HATS_DIRECTORY() error:NULL];
+ int numberOfHats = [hatArray count];
+ int animationFrames = IS_VERY_POWERFUL([HWUtils modelType]) ? 18 : 1;
+
+ if (self.imgContainer != nil)
+ [self.imgContainer removeFromSuperview];
+
+ self.imgContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 40)];
+ NSInteger numberOfHogs = 1 + random() % 20;
+ DLog(@"Drawing %d nice hedgehogs", numberOfHogs);
+ for (int i = 0; i < numberOfHogs; i++) {
+ NSString *hat = [hatArray objectAtIndex:random()%numberOfHats];
+
+ NSString *hatFile = [[NSString alloc] initWithFormat:@"%@/%@", HATS_DIRECTORY(), hat];
+ UIImage *hatSprite = [[UIImage alloc] initWithContentsOfFile:hatFile];
+ NSMutableArray *animation = [[NSMutableArray alloc] initWithCapacity:animationFrames];
+ for (int j = 0; j < animationFrames; j++) {
+ int x = ((j*32)/(int)hatSprite.size.height)*32;
+ int y = (j*32)%(int)hatSprite.size.height;
+ UIImage *hatSpriteFrame = [hatSprite cutAt:CGRectMake(x, y, 32, 32)];
+ UIImage *hogSpriteFrame = [hogSprite cutAt:CGRectMake(x, y, 32, 32)];
+ UIImage *hogWithHat = [hogSpriteFrame mergeWith:hatSpriteFrame atPoint:CGPointMake(0, 5)];
+ [animation addObject:hogWithHat];
+ }
+ [hatSprite release];
+ [hatFile release];
+
+ UIImageView *hog = [[UIImageView alloc] initWithImage:[animation objectAtIndex:0]];
+ hog.animationImages = animation;
+ hog.animationDuration = 3;
+ [animation release];
+
+ int x = 20*i+random()%128;
+ if (x > 320 - 32)
+ x = i*random()%32;
+ hog.frame = CGRectMake(x, 25, hog.frame.size.width, hog.frame.size.height);
+ [self.imgContainer addSubview:hog];
+ [hog startAnimating];
+ [hog release];
+ }
+
+ // don't place the nice hogs if there is no space for them
+ if ((self.interfaceOrientation == UIInterfaceOrientationPortrait ||
+ self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown))
+ self.imgContainer.alpha = 0;
+
+ [self.view addSubview:self.imgContainer];
+ [hogSprite release];
+ [pool drain];
+}
+
+-(void) viewDidLoad {
+ self.view.backgroundColor = [UIColor blackColor];
+
+ CGRect screenRect = [[UIScreen mainScreen] safeBounds];
+ self.view.frame = screenRect;
+
+ if (IS_IPAD()) {
+ // the label for the filter slider
+ UILabel *backLabel = [[UILabel alloc] initWithFrame:CGRectMake(116, 714, 310, 40)
+ andTitle:nil
+ withBorderWidth:2.0f];
+ self.sliderBackground = backLabel;
+ [backLabel release];
+ [self.view addSubview:self.sliderBackground];
+
+ // the label for max hogs
+ UILabel *maxLabel = [[UILabel alloc] initWithFrame:CGRectMake(598, 714, 310, 40)
+ andTitle:NSLocalizedString(@"Loading...",@"")
+ withBorderWidth:2.0f];
+ maxLabel.font = [UIFont italicSystemFontOfSize:[UIFont labelFontSize]];
+ maxLabel.textColor = [UIColor whiteColor];
+ maxLabel.textAlignment = UITextAlignmentCenter;
+ [self.view addSubview:maxLabel];
+ self.mapConfigViewController.maxLabel = maxLabel;
+ [maxLabel release];
+ } else {
+ self.mapConfigViewController.view.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height-44);
+ }
+ [self.view addSubview:self.mapConfigViewController.view];
+ [self.view bringSubviewToFront:self.mapConfigViewController.slider];
+
+ [super viewDidLoad];
+}
+
+-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval) duration {
+ if (IS_IPAD() == NO)
+ return;
+
+ if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
+ toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
+ self.imgContainer.alpha = 1;
+ self.titleImage.frame = CGRectMake(357, 17, 309, 165);
+ self.schemeWeaponConfigViewController.view.frame = CGRectMake(0, 60, 320, 620);
+ self.mapConfigViewController.view.frame = CGRectMake(704, 0, 320, 680);
+ self.teamConfigViewController.view.frame = CGRectMake(337, 187, 350, 505);
+ self.mapConfigViewController.maxLabel.frame = CGRectMake(121, 714, 300, 40);
+ self.sliderBackground.frame = CGRectMake(603, 714, 300, 40);
+ self.mapConfigViewController.slider.frame = CGRectMake(653, 724, 200, 23);
+ } else {
+ self.imgContainer.alpha = 0;
+ self.titleImage.frame = CGRectMake(37, 28, 309, 165);
+ self.schemeWeaponConfigViewController.view.frame = CGRectMake(0, 214, 378, 366);
+ self.mapConfigViewController.view.frame = CGRectMake(390, 0, 378, 580);
+ self.teamConfigViewController.view.frame = CGRectMake(170, 590, 428, 366);
+ self.mapConfigViewController.maxLabel.frame = CGRectMake(104, 975, 200, 40);
+ self.sliderBackground.frame = CGRectMake(465, 975, 200, 40);
+ self.mapConfigViewController.slider.frame = CGRectMake(475, 983, 180, 23);
+ }
+
+ [self.schemeWeaponConfigViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation
+ duration:duration];
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ if (IS_IPAD())
+ [NSThread detachNewThreadSelector:@selector(loadNiceHogs) toTarget:self withObject:nil];
+
+ [self.mapConfigViewController viewWillAppear:animated];
+ [self.teamConfigViewController viewWillAppear:animated];
+ [self.schemeWeaponConfigViewController viewWillAppear:animated];
+ // add other controllers here and below
+
+ [super viewWillAppear:animated];
+}
+
+-(void) viewDidAppear:(BOOL)animated {
+ [self.mapConfigViewController viewDidAppear:animated];
+ [self.teamConfigViewController viewDidAppear:animated];
+ [self.schemeWeaponConfigViewController viewDidAppear:animated];
+ [super viewDidAppear:animated];
+}
+
+-(void) viewWillDisappear:(BOOL)animated {
+ [self.mapConfigViewController viewWillDisappear:animated];
+ [self.teamConfigViewController viewWillDisappear:animated];
+ [self.schemeWeaponConfigViewController viewWillDisappear:animated];
+ [super viewWillDisappear:animated];
+}
+
+-(void) viewDidDisappear:(BOOL)animated {
+ [self.mapConfigViewController viewDidDisappear:animated];
+ [self.teamConfigViewController viewDidDisappear:animated];
+ [self.schemeWeaponConfigViewController viewDidDisappear:animated];
+ [super viewDidDisappear:animated];
+}
+
+-(void) didReceiveMemoryWarning {
+ self.imgContainer = nil;
+
+ if (self.titleImage.superview == nil)
+ self.titleImage = nil;
+ if (self.sliderBackground.superview == nil)
+ self.sliderBackground = nil;
+
+ if (self.mapConfigViewController.view.superview == nil)
+ self.mapConfigViewController = nil;
+ if (self.teamConfigViewController.view.superview == nil)
+ self.teamConfigViewController = nil;
+ if (self.schemeWeaponConfigViewController.view.superview == nil)
+ self.schemeWeaponConfigViewController = nil;
+ //if (self.helpPage.view.superview == nil)
+ // self.helpPage = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.imgContainer = nil;
+ self.titleImage = nil;
+ self.sliderBackground = nil;
+ self.schemeWeaponConfigViewController = nil;
+ self.teamConfigViewController = nil;
+ self.mapConfigViewController = nil;
+ //self.helpPage = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(imgContainer);
+ releaseAndNil(titleImage);
+ releaseAndNil(sliderBackground);
+ releaseAndNil(schemeWeaponConfigViewController);
+ releaseAndNil(teamConfigViewController);
+ releaseAndNil(mapConfigViewController);
+ //releaseAndNil(helpPage);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h
new file mode 100644
index 0000000..65fbced
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h
@@ -0,0 +1,41 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import "EngineProtocolNetwork.h"
+
+
+ at interface GameInterfaceBridge : NSObject <EngineProtocolDelegate> {
+ UIView *blackView;
+ NSString *savePath;
+ NSInteger port;
+}
+
+ at property (nonatomic,retain) UIView *blackView;
+ at property (nonatomic,retain) NSString *savePath;
+ at property (assign) NSInteger port;
+
++(void) startLocalGame:(NSDictionary *)withOptions;
++(void) startSaveGame:(NSString *)atPath;
++(void) startMissionGame:(NSString *)withScript;
++(void) startSimpleGame;
+
++(void) registerCallingController:(UIViewController *)controller;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m
new file mode 100644
index 0000000..882b2c1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m
@@ -0,0 +1,314 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GameInterfaceBridge.h"
+#import "EngineProtocolNetwork.h"
+#import "StatsPageViewController.h"
+
+
+static UIViewController *callingController;
+
+ at implementation GameInterfaceBridge
+ at synthesize blackView, savePath, port;
+
+#pragma mark -
+#pragma mark Instance methods for engine interaction
+// prepares the controllers for hosting a game
+-(void) earlyEngineLaunch:(NSDictionary *)optionsOrNil {
+ [self retain];
+ [[AudioManagerController mainManager] fadeOutBackgroundMusic];
+
+ EngineProtocolNetwork *engineProtocol = [[EngineProtocolNetwork alloc] init];
+ self.port = engineProtocol.enginePort;
+ engineProtocol.delegate = self;
+ [engineProtocol spawnThread:self.savePath withOptions:optionsOrNil];
+ [engineProtocol release];
+
+ // add a black view hiding the background
+ UIWindow *thisWindow = [[HedgewarsAppDelegate sharedAppDelegate] uiwindow];
+ self.blackView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.blackView.opaque = YES;
+ self.blackView.backgroundColor = [UIColor blackColor];
+ self.blackView.alpha = 0;
+ self.blackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [UIView beginAnimations:@"fade out" context:NULL];
+ [UIView setAnimationDuration:1];
+ self.blackView.alpha = 1;
+ [UIView commitAnimations];
+ [thisWindow addSubview:self.blackView];
+ [self.blackView release];
+
+ // keep the point of return for games that completed loading
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:self.savePath forKey:@"savedGamePath"];
+ [userDefaults setObject:[NSNumber numberWithBool:NO] forKey:@"saveIsValid"];
+ [userDefaults synchronize];
+
+ // let's launch the engine using this -perfomSelector so that the runloop can deal with queued messages first
+ [self performSelector:@selector(engineLaunch) withObject:nil afterDelay:0.1f];
+}
+
+// cleans up everything
+-(void) lateEngineLaunch {
+ // notify views below that they are getting the spotlight again
+ [[[HedgewarsAppDelegate sharedAppDelegate] uiwindow] makeKeyAndVisible];
+ [callingController viewWillAppear:YES];
+
+ // remove completed games notification
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults setObject:@"" forKey:@"savedGamePath"];
+ [userDefaults synchronize];
+
+ // remove the cover view with a transition
+ self.blackView.alpha = 1;
+ [UIView beginAnimations:@"fade in" context:NULL];
+ [UIView setAnimationDuration:1];
+ self.blackView.alpha = 0;
+ [UIView commitAnimations];
+ [self.blackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
+
+ // can remove the savefile if the replay has ended
+ if ([HWUtils gameType] == gtSave)
+ [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil];
+
+ // restart music and we're done
+ [[AudioManagerController mainManager] fadeInBackgroundMusic];
+ [HWUtils setGameStatus:gsNone];
+ [HWUtils setGameType:gtNone];
+ [self release];
+}
+
+// main routine for calling the actual game engine
+-(void) engineLaunch {
+ CGFloat width, height;
+ CGFloat screenScale = [[UIScreen mainScreen] safeScale];
+ NSString *ipcString = [[NSString alloc] initWithFormat:@"%d",self.port];
+ NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt",[[NSLocale preferredLanguages] objectAtIndex:0]];
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+
+ CGRect screenBounds = [[UIScreen mainScreen] safeBounds];
+ width = screenBounds.size.width;
+ height = screenBounds.size.height;
+
+ NSString *horizontalSize = [[NSString alloc] initWithFormat:@"%d", (int)(width * screenScale)];
+ NSString *verticalSize = [[NSString alloc] initWithFormat:@"%d", (int)(height * screenScale)];
+ NSString *resourcePath = [[NSString alloc] initWithFormat:@"%@/Data", [[NSBundle mainBundle] resourcePath]];
+
+ NSString *modelId = [HWUtils modelType];
+ NSInteger tmpQuality;
+ if ([modelId hasPrefix:@"iPhone1"] || [modelId hasPrefix:@"iPod1,1"] || [modelId hasPrefix:@"iPod2,1"]) // = iPhone and iPhone 3G or iPod Touch or iPod Touch 2G
+ tmpQuality = 0x00000001 | 0x00000002 | 0x00000008 | 0x00000040; // rqLowRes | rqBlurryLand | rqSimpleRope | rqKillFlakes
+ else if ([modelId hasPrefix:@"iPhone2"] || [modelId hasPrefix:@"iPod3"]) // = iPhone 3GS or iPod Touch 3G
+ tmpQuality = 0x00000002 | 0x00000040; // rqBlurryLand | rqKillFlakes
+ else if ([modelId hasPrefix:@"iPad1"] || [modelId hasPrefix:@"iPod4"]) // = iPad 1G or iPod Touch 4G
+ tmpQuality = 0x00000002; // rqBlurryLand
+ else // = everything else
+ tmpQuality = 0; // full quality
+
+ // disable ammomenu animation
+ tmpQuality = tmpQuality | 0x00000080;
+ // disable tooltips on iPhone
+ if (IS_IPAD() == NO)
+ tmpQuality = tmpQuality | 0x00000400;
+ NSString *rawQuality = [NSString stringWithFormat:@"%d",tmpQuality];
+ NSString *documentsDirectory = DOCUMENTS_FOLDER();
+
+ NSMutableArray *gameParameters = [[NSMutableArray alloc] initWithObjects:
+ @"--internal",
+ @"--port", ipcString,
+ @"--width", horizontalSize,
+ @"--height", verticalSize,
+ @"--raw-quality", rawQuality,
+ @"--locale", localeString,
+ @"--prefix", resourcePath,
+ @"--user-prefix", documentsDirectory,
+ nil];
+ [verticalSize release];
+ [horizontalSize release];
+ [resourcePath release];
+ [localeString release];
+ [ipcString release];
+
+ NSString *username = [settings objectForKey:@"username"];
+ if ([username length] > 0) {
+ [gameParameters addObject:@"--nick"];
+ [gameParameters addObject: username];
+ }
+
+ if ([[settings objectForKey:@"sound"] boolValue] == NO)
+ [gameParameters addObject:@"--nosound"];
+
+ if ([[settings objectForKey:@"music"] boolValue] == NO)
+ [gameParameters addObject:@"--nomusic"];
+
+ if([[settings objectForKey:@"alternate"] boolValue] == YES)
+ [gameParameters addObject:@"--altdmg"];
+
+#ifdef DEBUG
+ [gameParameters addObject:@"--showfps"];
+#endif
+
+ if ([HWUtils gameType] == gtSave)
+ [gameParameters addObject:self.savePath];
+
+ [HWUtils setGameStatus:gsLoading];
+
+ int argc = [gameParameters count];
+ const char **argv = (const char **)malloc(sizeof(const char*)*argc);
+ for (int i = 0; i < argc; i++)
+ argv[i] = strdup([[gameParameters objectAtIndex:i] UTF8String]);
+ [gameParameters release];
+
+ // this is the pascal function that starts the game
+ Game(argc, argv);
+
+ // cleanup
+ for (int i = 0; i < argc; i++)
+ free((void *)argv[i]);
+ free(argv);
+
+ // moar cleanup
+ [self lateEngineLaunch];
+}
+
+-(void) dealloc {
+ releaseAndNil(blackView);
+ releaseAndNil(savePath);
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark EngineProtocolDelegate methods
+-(void) gameEndedWithStatistics:(NSArray *)stats {
+ if (stats != nil) {
+ StatsPageViewController *statsPage = [[StatsPageViewController alloc] init];
+ statsPage.statsArray = stats;
+ statsPage.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
+
+ [callingController presentModalViewController:statsPage animated:YES];
+ [statsPage release];
+ }
+}
+
+#pragma mark -
+#pragma mark Class methods for setting up the engine from outsite
++(void) registerCallingController:(UIViewController *)controller {
+ callingController = controller;
+}
+
++(void) startGame:(TGameType) type atPath:(NSString *)path withOptions:(NSDictionary *)config {
+ [HWUtils setGameType:type];
+ id bridge = [[self alloc] init];
+ [bridge setSavePath:path];
+ [bridge earlyEngineLaunch:config];
+ [bridge release];
+}
+
++(void) startLocalGame:(NSDictionary *)withOptions {
+ NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
+ [outputFormatter setDateFormat:@"yyyy-MM-dd '@' HH.mm"];
+ NSString *savePath = [[NSString alloc] initWithFormat:@"%@%@.hws",SAVES_DIRECTORY(),[outputFormatter stringFromDate:[NSDate date]]];
+ [outputFormatter release];
+
+ // in the rare case in which a savefile with the same name exists the older one must be removed (otherwise it gets corrupted)
+ if ([[NSFileManager defaultManager] fileExistsAtPath:savePath])
+ [[NSFileManager defaultManager] removeItemAtPath:savePath error:nil];
+
+ [self startGame:gtLocal atPath:savePath withOptions:withOptions];
+ [savePath release];
+}
+
++(void) startSaveGame:(NSString *)atPath {
+ [self startGame:gtSave atPath:atPath withOptions:nil];
+}
+
++(void) startMissionGame:(NSString *)withScript {
+ NSString *missionPath = [[NSString alloc] initWithFormat:@"escript Missions/Training/%@.lua",withScript];
+ NSDictionary *missionLine = [[NSDictionary alloc] initWithObjectsAndKeys:missionPath,@"mission_command",nil];
+ [missionPath release];
+
+ [self startGame:gtMission atPath:nil withOptions:missionLine];
+ [missionLine release];
+}
+
++(void) startSimpleGame {
+ srand(time(0));
+
+ // generate a seed
+ CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+ NSString *seed = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
+ CFRelease(uuid);
+ NSString *seedCmd = [[NSString alloc] initWithFormat:@"eseed {%@}", seed];
+ [seed release];
+
+ // pick a random static map
+ NSArray *listOfMaps = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:MAPS_DIRECTORY() error:NULL];
+ NSString *mapName = [listOfMaps objectAtIndex:random()%[listOfMaps count]];
+ NSString *fileCfg = [[NSString alloc] initWithFormat:@"%@/%@/map.cfg",MAPS_DIRECTORY(),mapName];
+ NSString *contents = [[NSString alloc] initWithContentsOfFile:fileCfg encoding:NSUTF8StringEncoding error:NULL];
+ [fileCfg release];
+ NSArray *split = [contents componentsSeparatedByString:@"\n"];
+ [contents release];
+ NSString *themeCommand = [[NSString alloc] initWithFormat:@"etheme %@", [split objectAtIndex:0]];
+ NSString *staticMapCommand = [[NSString alloc] initWithFormat:@"emap %@", mapName];
+
+ // select teams with two different colors
+ NSArray *colorArray = [HWUtils teamColors];
+ NSInteger firstColorIndex, secondColorIndex;
+ do {
+ firstColorIndex = random()%[colorArray count];
+ secondColorIndex = random()%[colorArray count];
+ } while (firstColorIndex == secondColorIndex);
+ unsigned int firstColor = [[colorArray objectAtIndex:firstColorIndex] intValue];
+ unsigned int secondColor = [[colorArray objectAtIndex:secondColorIndex] intValue];
+
+ NSDictionary *firstTeam = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:4],@"number",
+ [NSNumber numberWithUnsignedInt:firstColor],@"color",
+ @"Ninjas.plist",@"team",nil];
+ NSDictionary *secondTeam = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:4],@"number",
+ [NSNumber numberWithUnsignedInt:secondColor],@"color",
+ @"Robots.plist",@"team",nil];
+ NSArray *listOfTeams = [[NSArray alloc] initWithObjects:firstTeam,secondTeam,nil];
+ [firstTeam release];
+ [secondTeam release];
+
+ // create the configuration
+ NSDictionary *gameDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
+ seedCmd,@"seed_command",
+ @"e$template_filter 0",@"templatefilter_command",
+ @"e$mapgen 0",@"mapgen_command",
+ @"e$maze_size 0",@"mazesize_command",
+ themeCommand,@"theme_command",
+ staticMapCommand,@"staticmap_command",
+ listOfTeams,@"teams_list",
+ @"Default.plist",@"scheme",
+ @"Default.plist",@"weapon",
+ @"",@"mission_command",
+ nil];
+ [listOfTeams release];
+ [staticMapCommand release];
+ [themeCommand release];
+ [seedCmd release];
+
+ // launch game
+ [GameInterfaceBridge startLocalGame:gameDictionary];
+ [gameDictionary release];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.h b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.h
new file mode 100644
index 0000000..1458f0d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.h
@@ -0,0 +1,27 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface GeneralSettingsViewController : UITableViewController <EditableCellViewDelegate> {
+
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m
new file mode 100644
index 0000000..720835d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m
@@ -0,0 +1,257 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GeneralSettingsViewController.h"
+
+
+ at implementation GeneralSettingsViewController
+
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View Lifecycle
+-(void) viewDidLoad {
+ self.navigationItem.title = @"Edit game options";
+ [super viewDidLoad];
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+ [super viewWillAppear:animated];
+}
+
+-(void) viewWillDisappear:(BOOL)animated {
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ [userDefaults synchronize];
+ if ([[userDefaults objectForKey:@"music"] boolValue] == NO)
+ [[AudioManagerController mainManager] stopBackgroundMusic];
+
+ [super viewWillDisappear:animated];
+}
+
+#pragma mark -
+-(void) switchValueChanged:(id) sender {
+ UISwitch *theSwitch = (UISwitch *)sender;
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+
+ switch (theSwitch.tag) {
+ case 10: //soundSwitch
+ [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"sound"];
+ break;
+ case 20: //musicSwitch
+ [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"music"];
+ if (theSwitch.on)
+ [[AudioManagerController mainManager] playBackgroundMusic];
+ else
+ [[AudioManagerController mainManager] pauseBackgroundMusic];
+ break;
+ case 30: //alternateSwitch
+ [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"alternate"];
+ break;
+ case 90: //synched weapons/scheme
+ [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"sync_ws"];
+ break;
+ default:
+ DLog(@"Wrong tag");
+ break;
+ }
+}
+
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue {
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+
+ if (tagValue == 40)
+ [settings setObject:textString forKey:@"username"];
+ else
+ [settings setObject:[textString MD5hash] forKey:@"password"];
+}
+
+#pragma mark -
+#pragma mark TableView Methods
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 3;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger )section {
+ switch (section) {
+ case 0: // user and pass
+ return 1; // set 2 here to show the password field
+ break;
+ case 1: // audio
+ return 2;
+ break;
+ case 2: // other options
+ return 2;
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ return 0;
+}
+
+-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+ NSString *sectionTitle = nil;
+ switch (section) {
+ case 0:
+ sectionTitle = NSLocalizedString(@"Main Configuration", @"from the settings table");
+ break;
+ case 1:
+ sectionTitle = NSLocalizedString(@"Audio Preferences", @"from the settings table");
+ break;
+ case 2:
+ sectionTitle = NSLocalizedString(@"Other Settings", @"from the settings table");
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ return sectionTitle;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *cellIdentifier0 = @"Cell0";
+ static NSString *cellIdentifier1 = @"Cell1";
+ static NSString *cellIdentifier2 = @"Cell2";
+ NSInteger row = [indexPath row];
+ NSInteger section = [indexPath section];
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+
+ UITableViewCell *cell = nil;
+ EditableCellView *editableCell = nil;
+ UISwitch *switchContent = nil;
+ switch(section) {
+ case 0:
+ editableCell = (EditableCellView *)[aTableView dequeueReusableCellWithIdentifier:cellIdentifier0];
+ if (nil == editableCell) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier0] autorelease];
+ editableCell.minimumCharacters = 0;
+ editableCell.delegate = self;
+ editableCell.textField.font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
+ editableCell.textField.textColor = [UIColor blackColor];
+ }
+
+ if (row == 0) {
+ editableCell.titleLabel.text = NSLocalizedString(@"Nickname","from the settings table");
+ editableCell.textField.placeholder = NSLocalizedString(@"Insert your username (if you have one)",@"from the settings table");
+ editableCell.textField.text = [settings objectForKey:@"username"];
+ editableCell.textField.secureTextEntry = NO;
+ editableCell.tag = 40;
+ } else {
+ editableCell.titleLabel.text = NSLocalizedString(@"Password","from the settings table");
+ editableCell.textField.placeholder = NSLocalizedString(@"Insert your password",@"from the settings table");
+ editableCell.textField.text = [settings objectForKey:@"password"];
+ editableCell.textField.secureTextEntry = YES;
+ editableCell.tag = 50;
+ }
+
+ editableCell.accessoryView = nil;
+ cell = editableCell;
+ break;
+ case 1:
+ cell = [aTableView dequeueReusableCellWithIdentifier:cellIdentifier1];
+ if (nil == cell) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier1] autorelease];
+ UISwitch *theSwitch = [[UISwitch alloc] init];
+ [theSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
+ cell.accessoryView = theSwitch;
+ [theSwitch release];
+ }
+
+ switchContent = (UISwitch *)cell.accessoryView;
+ if (row == 0) {
+ cell.textLabel.text = NSLocalizedString(@"Sound Effects", @"from the settings table");
+ switchContent.on = [[settings objectForKey:@"sound"] boolValue];
+ switchContent.tag = 10;
+ } else {
+ cell.textLabel.text = NSLocalizedString(@"Music", @"from the settings table");
+ switchContent.on = [[settings objectForKey:@"music"] boolValue];
+ switchContent.tag = 20;
+ }
+ break;
+ case 2:
+ cell = [aTableView dequeueReusableCellWithIdentifier:cellIdentifier2];
+ if (nil == cell) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier2] autorelease];
+ UISwitch *theSwitch = [[UISwitch alloc] init];
+ [theSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
+ cell.accessoryView = theSwitch;
+ [theSwitch release];
+ }
+
+ switchContent = (UISwitch *)cell.accessoryView;
+ cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
+ switch (row) {
+ case 0:
+ cell.textLabel.text = NSLocalizedString(@"Alternate Damage", @"from the settings table");
+ cell.detailTextLabel.text = NSLocalizedString(@"Damage popups will notify you on every single hit", @"from the settings table");
+ switchContent.on = [[settings objectForKey:@"alternate"] boolValue];
+ switchContent.tag = 30;
+ break;
+ case 1:
+ cell.textLabel.text = NSLocalizedString(@"Sync Schemes and Weapons", @"");
+ cell.detailTextLabel.text = NSLocalizedString(@"Choosing a Scheme will select its associated Weapon", @"from the settings table");
+ switchContent.on = [[settings objectForKey:@"sync_ws"] boolValue];
+ switchContent.tag = 90;
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ cell.imageView.image = nil;
+
+ return cell;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
+ if (0 == [indexPath section]) {
+ EditableCellView *cell = (EditableCellView *)[aTableView cellForRowAtIndexPath:indexPath];
+ [cell replyKeyboard];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GravesViewController.h b/project_files/HedgewarsMobile/Classes/GravesViewController.h
new file mode 100644
index 0000000..8f9c714
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GravesViewController.h
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface GravesViewController : UITableViewController {
+ NSMutableDictionary *teamDictionary;
+
+ NSArray *graveArray;
+ NSIndexPath *lastIndexPath;
+}
+
+ at property (nonatomic,retain) NSMutableDictionary *teamDictionary;
+ at property (nonatomic,retain) NSArray *graveArray;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/GravesViewController.m b/project_files/HedgewarsMobile/Classes/GravesViewController.m
new file mode 100644
index 0000000..256c296
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/GravesViewController.m
@@ -0,0 +1,137 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GravesViewController.h"
+
+
+ at implementation GravesViewController
+ at synthesize teamDictionary, graveArray, lastIndexPath;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ // load all the grave names and store them into graveArray
+ self.graveArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:GRAVES_DIRECTORY() error:NULL];
+
+ self.title = NSLocalizedString(@"Choose hedgehog graves",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+ [self.tableView reloadData];
+ // this moves the tableview to the top
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.graveArray count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+
+ NSString *grave = [self.graveArray objectAtIndex:[indexPath row]];
+ cell.textLabel.text = [grave stringByDeletingPathExtension];
+
+ if ([grave isEqualToString:[self.teamDictionary objectForKey:@"grave"]]) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ NSString *graveFilePath = [[NSString alloc] initWithFormat:@"%@/%@",GRAVES_DIRECTORY(),grave];
+ // because we also have multi frame graves, let's take the first one only
+ UIImage *graveSprite = [[UIImage alloc] initWithContentsOfFile:graveFilePath andCutAt:CGRectMake(0, 0, 32, 32)];
+ [graveFilePath release];
+ cell.imageView.image = graveSprite;
+ [graveSprite release];
+
+ return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ [teamDictionary setObject:[[graveArray objectAtIndex:newRow] stringByDeletingPathExtension] forKey:@"grave"];
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ newCell.accessoryType = UITableViewCellAccessoryCheckmark;
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+ oldCell.accessoryType = UITableViewCellAccessoryNone;
+ self.lastIndexPath = indexPath;
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.lastIndexPath = nil;
+ self.teamDictionary = nil;
+ self.graveArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(graveArray);
+ releaseAndNil(teamDictionary);
+ releaseAndNil(lastIndexPath);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/HWUtils.h b/project_files/HedgewarsMobile/Classes/HWUtils.h
new file mode 100644
index 0000000..4c7bd1e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HWUtils.h
@@ -0,0 +1,47 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+
+typedef enum {gtNone, gtLocal, gtSave, gtMission, gtNet} TGameType;
+typedef enum {gsNone, gsLoading, gsInGame, gsInterrupted, gsEnded} TGameStatus;
+
+ at interface HWUtils : NSObject {
+
+}
+
++(TGameType) gameType;
++(void) setGameType:(TGameType) type;
++(TGameStatus) gameStatus;
++(void) setGameStatus:(TGameStatus) status;
++(BOOL) isGameLaunched;
++(BOOL) isGameRunning;
+
++(NSString *)modelType;
++(NSArray *)teamColors;
++(void) releaseCache;
+
++(NSInteger) randomPort;
++(void) freePort:(NSInteger) port;
++(BOOL) isNetworkReachable;
+//+(UIView *)mainSDLViewInstance;
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/HWUtils.m b/project_files/HedgewarsMobile/Classes/HWUtils.m
new file mode 100644
index 0000000..ed103c2
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HWUtils.m
@@ -0,0 +1,172 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "HWUtils.h"
+#import <sys/types.h>
+#import <sys/sysctl.h>
+#import <netinet/in.h>
+#import <SystemConfiguration/SCNetworkReachability.h>
+#import "hwconsts.h"
+
+static NSString *cachedModel = nil;
+static NSArray *cachedColors = nil;
+static NSMutableArray *activePorts = nil;
+
+static TGameType gameType = gtNone;
+static TGameStatus gameStatus = gsNone;
+
+ at implementation HWUtils
+
+#pragma mark -
+#pragma mark game status and type info
++(TGameType) gameType {
+ return gameType;
+}
+
++(void) setGameType:(TGameType) type {
+ gameType = type;
+}
+
++(TGameStatus) gameStatus {
+ return gameStatus;
+}
+
++(void) setGameStatus:(TGameStatus) status {
+ gameStatus = status;
+}
+
++(BOOL) isGameLaunched {
+ return ((gameStatus == gsLoading) || (gameStatus == gsInGame));
+}
+
++(BOOL) isGameRunning {
+ return (gameStatus == gsInGame);
+}
+
+#pragma mark -
+#pragma mark Helper Functions with cache
++(NSString *)modelType {
+ if (cachedModel == nil) {
+ size_t size;
+ // set 'oldp' parameter to NULL to get the size of the data returned so we can allocate appropriate amount of space
+ sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+ char *name = (char *)malloc(sizeof(char) * size);
+ // get the platform name
+ sysctlbyname("hw.machine", name, &size, NULL, 0);
+
+ cachedModel = [[NSString stringWithUTF8String:name] retain];
+ free(name);
+ }
+ return cachedModel;
+}
+
++(NSArray *)teamColors {
+ if (cachedColors == nil) {
+ // by default colors are ARGB but we do computation over RGB, hence we have to "& 0x00FFFFFF" before processing
+ unsigned int colors[] = HW_TEAMCOLOR_ARRAY;
+ NSMutableArray *array = [[NSMutableArray alloc] init];
+
+ int i = 0;
+ while(colors[i] != 0)
+ [array addObject:[NSNumber numberWithUnsignedInt:(colors[i++] & 0x00FFFFFF)]];
+
+ cachedColors = [[NSArray arrayWithArray:array] retain];
+ [array release];
+ }
+ return cachedColors;
+}
+
++(void) releaseCache {
+ [cachedModel release], cachedModel = nil;
+ [cachedColors release], cachedColors = nil;
+ // don't release activePorts here
+}
+
+#pragma mark -
+#pragma mark Helper Functions without cache
++(NSInteger) randomPort {
+ // set a new feed only at initialization time and forbid connecting to the server port
+ if (activePorts == nil) {
+ srandom(time(NULL));
+ activePorts = [[NSMutableArray arrayWithObject:[NSNumber numberWithInt:NETGAME_DEFAULT_PORT]] retain];
+ }
+
+ // pick a random number from the free ports list
+ NSInteger res = 0;
+ do {
+ res = (random() % 64511) + 1024;
+ } while ([activePorts containsObject:[NSNumber numberWithInt:res]]);
+
+ // add this number to the forbdding list
+ [activePorts addObject:[NSNumber numberWithInt:res]];
+ return res;
+}
+
++(void) freePort:(NSInteger) port {
+ [activePorts removeObject:[NSNumber numberWithInt:port]];
+}
+
++(BOOL) isNetworkReachable {
+ // Create zero addy
+ struct sockaddr_in zeroAddress;
+ bzero(&zeroAddress, sizeof(zeroAddress));
+ zeroAddress.sin_len = sizeof(zeroAddress);
+ zeroAddress.sin_family = AF_INET;
+
+ // Recover reachability flags
+ SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
+ SCNetworkReachabilityFlags flags;
+
+ BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
+ CFRelease(defaultRouteReachability);
+
+ if (!didRetrieveFlags) {
+ NSLog(@"Error. Could not recover network reachability flags");
+ return NO;
+ }
+
+ BOOL isReachable = flags & kSCNetworkFlagsReachable;
+ BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
+ BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
+
+ NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
+ NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL
+ cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
+ timeoutInterval:20.0];
+ NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:nil];
+ BOOL testResult = testConnection ? YES : NO;
+ [testConnection release];
+
+ return ((isReachable && !needsConnection) || nonWiFi) ? testResult : NO;
+}
+
+/*
++(UIView *)mainSDLViewInstance {
+ SDL_Window *window = HW_getSDLWindow();
+ if (window == NULL) {
+ SDL_SetError("Window does not exist");
+ return nil;
+ }
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+ SDL_uikitview *view = data != NULL ? data->view : nil;
+ return view;
+}
+*/
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h
new file mode 100644
index 0000000..246d8a8
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h
@@ -0,0 +1,35 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "../src/video/uikit/SDL_uikitappdelegate.h"
+
+
+ at class MainMenuViewController;
+
+ at interface HedgewarsAppDelegate : SDLUIKitDelegate {
+ MainMenuViewController *mainViewController; // required to dismiss the SettingsBaseViewController
+ UIWindow *uiwindow;
+}
+
+ at property (nonatomic,retain) MainMenuViewController *mainViewController;
+ at property (nonatomic,retain) UIWindow *uiwindow;
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m
new file mode 100644
index 0000000..1907f1a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m
@@ -0,0 +1,86 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "HedgewarsAppDelegate.h"
+#import "MainMenuViewController.h"
+
+
+ at implementation SDLUIKitDelegate (customDelegate)
+
+// hijack the the SDL_UIKitAppDelegate to use the UIApplicationDelegate we implement here
++(NSString *)getAppDelegateClassName {
+ return @"HedgewarsAppDelegate";
+}
+
+ at end
+
+ at implementation HedgewarsAppDelegate
+ at synthesize mainViewController, uiwindow;
+
+#pragma mark -
+#pragma mark AppDelegate methods
+-(id) init {
+ if ((self = [super init])) {
+ mainViewController = nil;
+ uiwindow = nil;
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [mainViewController release];
+ [uiwindow release];
+ [super dealloc];
+}
+
+// override the direct execution of SDL_main to allow us to implement our own frontend
+-(void) postFinishLaunch {
+ [[UIApplication sharedApplication] setStatusBarHidden:YES];
+
+ self.uiwindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.uiwindow.backgroundColor = [UIColor blackColor];
+
+ NSString *controllerName = (IS_IPAD() ? @"MainMenuViewController-iPad" : @"MainMenuViewController-iPhone");
+ self.mainViewController = [[MainMenuViewController alloc] initWithNibName:controllerName bundle:nil];
+ [self.uiwindow addSubview:self.mainViewController.view];
+ [self.mainViewController release];
+
+ [self.uiwindow makeKeyAndVisible];
+}
+
+-(void) applicationDidReceiveMemoryWarning:(UIApplication *)application {
+ [HWUtils releaseCache];
+ // don't stop music if it is playing
+ if ([HWUtils isGameLaunched]) {
+ [[AudioManagerController mainManager] didReceiveMemoryWarning];
+ HW_memoryWarningCallback();
+ }
+ MSG_MEMCLEAN();
+ // don't clean mainMenuViewController here!!!
+}
+
+// true multitasking with SDL works only on 4.2 and above; we close the game to avoid a black screen at return
+-(void) applicationWillResignActive:(UIApplication *)application {
+ if ([HWUtils isGameLaunched] && [[[UIDevice currentDevice] systemVersion] floatValue] < 4.2f)
+ HW_terminate(NO);
+
+ [super applicationWillResignActive:application];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/HogHatViewController.h b/project_files/HedgewarsMobile/Classes/HogHatViewController.h
new file mode 100644
index 0000000..9873b30
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HogHatViewController.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface HogHatViewController : UITableViewController {
+ NSDictionary *teamDictionary;
+ NSInteger selectedHog;
+
+ NSArray *hatArray;
+ UIImage *normalHogSprite;
+ NSIndexPath *lastIndexPath;
+}
+
+ at property (nonatomic,retain) NSDictionary *teamDictionary;
+ at property (nonatomic) NSInteger selectedHog;
+ at property (nonatomic,retain) NSArray *hatArray;
+ at property (nonatomic,retain) UIImage *normalHogSprite;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/HogHatViewController.m b/project_files/HedgewarsMobile/Classes/HogHatViewController.m
new file mode 100644
index 0000000..35194f6
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HogHatViewController.m
@@ -0,0 +1,159 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "HogHatViewController.h"
+
+
+ at implementation HogHatViewController
+ at synthesize teamDictionary, hatArray, normalHogSprite, lastIndexPath, selectedHog;
+
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ // load all the hat file names and store them into hatArray
+ NSString *hatsDirectory = HATS_DIRECTORY();
+ NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:hatsDirectory error:NULL];
+ self.hatArray = array;
+
+ // load the base hog image, drawing will occure in cellForRow...
+ NSString *normalHogFile = [[NSString alloc] initWithFormat:@"%@/basehat-hedgehog.png",[[NSBundle mainBundle] resourcePath]];
+ UIImage *hogSprite = [[UIImage alloc] initWithContentsOfFile:normalHogFile];
+ [normalHogFile release];
+ self.normalHogSprite = hogSprite;
+ [hogSprite release];
+
+ self.title = NSLocalizedString(@"Change hedgehogs' hat",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ // this updates the hog name and its hat
+ [self.tableView reloadData];
+ // this moves the tableview to the top
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.hatArray count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+
+ NSDictionary *hog = [[self.teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:selectedHog];
+ NSString *hat = [hatArray objectAtIndex:[indexPath row]];
+ cell.textLabel.text = [hat stringByDeletingPathExtension];
+
+ NSString *hatFile = [[NSString alloc] initWithFormat:@"%@/%@", HATS_DIRECTORY(), hat];
+ UIImage *hatSprite = [[UIImage alloc] initWithContentsOfFile: hatFile andCutAt:CGRectMake(0, 0, 32, 32)];
+ [hatFile release];
+ cell.imageView.image = [self.normalHogSprite mergeWith:hatSprite atPoint:CGPointMake(0, 5)];
+ [hatSprite release];
+
+ if ([hat isEqualToString:[hog objectForKey:@"hat"]]) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ // if the two selected rows differ update data on the hog dictionary and reload table content
+ // TODO: maybe this section could be cleaned up
+ NSDictionary *oldHog = [[teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:selectedHog];
+
+ NSMutableDictionary *newHog = [[NSMutableDictionary alloc] initWithDictionary: oldHog];
+ [newHog setObject:[[hatArray objectAtIndex:newRow] stringByDeletingPathExtension] forKey:@"hat"];
+ [[teamDictionary objectForKey:@"hedgehogs"] replaceObjectAtIndex:selectedHog withObject:newHog];
+ [newHog release];
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ newCell.accessoryType = UITableViewCellAccessoryCheckmark;
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+ oldCell.accessoryType = UITableViewCellAccessoryNone;
+ self.lastIndexPath = indexPath;
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+ [self.navigationController popViewControllerAnimated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.lastIndexPath = nil;
+ self.normalHogSprite = nil;
+ self.teamDictionary = nil;
+ self.hatArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(hatArray);
+ releaseAndNil(teamDictionary);
+ releaseAndNil(normalHogSprite);
+ releaseAndNil(lastIndexPath);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/HoldTableViewCell.h b/project_files/HedgewarsMobile/Classes/HoldTableViewCell.h
new file mode 100644
index 0000000..2de2603
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HoldTableViewCell.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at protocol HoldTableViewCellDelegate <NSObject>
+
+-(void) holdAction:(NSString *)content onTable:(UITableView *)aTableView;
+
+ at end
+
+ at interface HoldTableViewCell : UITableViewCell {
+ id<HoldTableViewCellDelegate> delegate;
+ NSTimeInterval time;
+}
+
+ at property (nonatomic,assign) id<HoldTableViewCellDelegate> delegate;
+
+-(void) holdAction;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/HoldTableViewCell.m b/project_files/HedgewarsMobile/Classes/HoldTableViewCell.m
new file mode 100644
index 0000000..f55c51b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/HoldTableViewCell.m
@@ -0,0 +1,68 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "HoldTableViewCell.h"
+
+
+ at implementation HoldTableViewCell
+ at synthesize delegate;
+
+#define SWIPE_DRAG_HORIZ_MIN 10
+#define SWIPE_DRAG_VERT_MAX 40
+
+-(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+ if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
+ delegate = nil;
+ }
+ return self;
+}
+
+-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+ UITouch *touch = [[event allTouches] anyObject];
+
+ time = touch.timestamp;
+ [self performSelector:@selector(holdAction) withObject:nil afterDelay:0.25];
+
+ [super touchesBegan:touches withEvent:event];
+}
+
+-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+ UITouch *touch = [[event allTouches] anyObject];
+
+ if ( touch.timestamp - time < 0.25 ) {
+ [NSObject cancelPreviousPerformRequestsWithTarget:self
+ selector:@selector(holdAction)
+ object:nil];
+
+ [super touchesEnded:touches withEvent:event];
+ } else
+ [super touchesCancelled:touches withEvent:event];
+}
+
+-(void) holdAction {
+ if (self.delegate != nil && [self.delegate respondsToSelector:@selector(holdAction:onTable:)])
+ [self.delegate holdAction:self.textLabel.text onTable:(UITableView *)self.superview];
+}
+
+-(void) dealloc {
+ self.delegate = nil;
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/LevelViewController.h b/project_files/HedgewarsMobile/Classes/LevelViewController.h
new file mode 100644
index 0000000..ecba9fd
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/LevelViewController.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface LevelViewController : UITableViewController {
+ NSDictionary *teamDictionary;
+
+ NSArray *levelArray;
+ NSArray *levelSprites;
+ NSIndexPath *lastIndexPath;
+
+ NSInteger numberOfSections;
+}
+
+ at property (nonatomic,retain) NSDictionary *teamDictionary;
+ at property (nonatomic,retain) NSArray *levelArray;
+ at property (nonatomic,retain) NSArray *levelSprites;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/LevelViewController.m b/project_files/HedgewarsMobile/Classes/LevelViewController.m
new file mode 100644
index 0000000..0e4dd1d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/LevelViewController.m
@@ -0,0 +1,207 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
+ */
+
+
+#import "LevelViewController.h"
+
+
+ at implementation LevelViewController
+ at synthesize teamDictionary, levelArray, levelSprites, lastIndexPath;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+ srandom(time(NULL));
+
+ NSArray *array = [[NSArray alloc] initWithObjects:
+ NSLocalizedString(@"Brutal",@""),
+ NSLocalizedString(@"Aggressive",@""),
+ NSLocalizedString(@"Bully",@""),
+ NSLocalizedString(@"Average",@""),
+ NSLocalizedString(@"Weaky",@""),
+ nil];
+ self.levelArray = array;
+ [array release];
+
+ self.title = NSLocalizedString(@"Set difficulty level",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ if ([[[[self.teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:0] objectForKey:@"level"] intValue] == 0)
+ numberOfSections = 1;
+ else
+ numberOfSections = 2;
+
+ [self.tableView reloadData];
+ // this moves the tableview to the top
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+-(void) viewWillDisappear:(BOOL)animated {
+ // stuff like checking that at least 1 field was selected
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return numberOfSections;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
+ if (section == 0)
+ return 1;
+ else
+ return 5;
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ static NSString *CellIdentifier1 = @"Cell1";
+
+ NSInteger row = [indexPath row];
+ NSInteger section = [indexPath section];
+ UITableViewCell *cell;
+
+ if (section == 0) {
+ cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier0] autorelease];
+ UISwitch *theSwitch = [[UISwitch alloc] init];
+ [theSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
+ cell.accessoryView = theSwitch;
+ [theSwitch release];
+ }
+ UISwitch *theSwitch = (UISwitch *)cell.accessoryView;
+ if (numberOfSections == 1)
+ theSwitch.on = NO;
+ else
+ theSwitch.on = YES;
+ cell.textLabel.text = NSLocalizedString(@"Hogs controlled by AI",@"");
+ } else {
+ cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
+
+ cell.textLabel.text = [levelArray objectAtIndex:row];
+ NSDictionary *hog = [[self.teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:0];
+ if ([[hog objectForKey:@"level"] intValue] == row+1) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ NSString *botlevelPath = [[NSString alloc] initWithFormat:@"%@/bot%d.png",[[NSBundle mainBundle] resourcePath],row+1];
+ UIImage *levelImage = [[UIImage alloc] initWithContentsOfFile:botlevelPath];
+ [botlevelPath release];
+ cell.imageView.image = levelImage;
+ [levelImage release];
+ }
+
+ return cell;
+}
+
+-(void) switchValueChanged:(id) sender {
+ UISwitch *theSwitch = (UISwitch *)sender;
+ NSIndexSet *sections = [[NSIndexSet alloc] initWithIndex:1];
+ NSMutableArray *hogs = [self.teamDictionary objectForKey:@"hedgehogs"];
+ NSInteger level;
+
+ if (theSwitch.on) {
+ numberOfSections = 2;
+ [self.tableView insertSections:sections withRowAnimation:UITableViewRowAnimationFade];
+ level = 1 + (random() % ([levelArray count] - 1));
+ } else {
+ numberOfSections = 1;
+ [self.tableView deleteSections:sections withRowAnimation:UITableViewRowAnimationFade];
+ level = 0;
+ }
+ [sections release];
+
+ DLog(@"New level is %d",level);
+ for (NSMutableDictionary *hog in hogs)
+ [hog setObject:[NSNumber numberWithInt:level] forKey:@"level"];
+
+ [self.tableView reloadData];
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (self.lastIndexPath != nil) ? [self.lastIndexPath row] : -1;
+
+ if ([indexPath section] != 0) {
+ if (newRow != oldRow) {
+ NSMutableArray *hogs = [self.teamDictionary objectForKey:@"hedgehogs"];
+
+ NSInteger level = newRow + 1;
+ for (NSMutableDictionary *hog in hogs)
+ [hog setObject:[NSNumber numberWithInt:level] forKey:@"level"];
+ DLog(@"New level is %d",level);
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+ [self.tableView reloadData];
+
+ self.lastIndexPath = indexPath;
+ [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ }
+ [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.lastIndexPath = nil;
+ self.teamDictionary = nil;
+ self.levelArray = nil;
+ self.levelSprites = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(levelArray);
+ releaseAndNil(levelSprites);
+ releaseAndNil(teamDictionary);
+ releaseAndNil(lastIndexPath);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/LICENCE.rtf b/project_files/HedgewarsMobile/Classes/MGSplitViewController/LICENCE.rtf
new file mode 100755
index 0000000..02c5e35
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/LICENCE.rtf
@@ -0,0 +1,104 @@
+{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf320
+{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
+{\colortbl;\red255\green255\blue255;\red51\green51\blue51;\red0\green180\blue128;\red255\green0\blue0;
+\red31\green105\blue199;\red119\green119\blue119;}
+{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid1\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
+{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
+\deftab720
+\pard\pardeftab720\ql\qnatural
+
+\f0\b\fs24 \cf2 Matt Legend Gemmell / Instinctive Code Source Code License\
+
+\b0\fs22 Last updated: 9th May 2010
+\fs24 \
+\
+\
+Thanks for downloading some of our source code!\
+\
+This is the license agreement for the source code which this document accompanies (don\'92t worry: you\'92re allowed to use it in your own products, commercial or otherwise).\
+\
+The full license text is further down this page, and you should only use the source code if you agree to the terms in that text. For convenience, though, we\'92ve put together a human-readable
+\b non-authoritative
+\b0 interpretation of the license which will hopefully answer any questions you have.\
+\
+\
+
+\b \cf3 Green
+\b0 \cf2 text shows
+\b \cf3 what you can do with the code
+\b0 \cf2 .\
+
+\b \cf4 Red
+\b0 \cf2 text means
+\b \cf4 restrictions you must abide by
+\b0 \cf2 .\
+\
+Basically, the license says that:\
+\
+\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural
+\ls1\ilvl0\cf2 {\listtext 1. }You can
+\b \cf3 use the code in your own products, including commercial and/or closed-source products
+\b0 \cf2 .\
+{\listtext 2. }You can
+\b \cf3 modify the code
+\b0 \cf0 as you wish\cf2 , and
+\b \cf3 use the modified code in your products
+\b0 \cf2 .\
+{\listtext 3. }You can
+\b \cf3 redistribute the original, unmodified code
+\b0 \cf2 , but you
+\b \cf4 have to include the full license text below
+\b0 \cf2 .\
+{\listtext 4. }You can
+\b \cf3 redistribute the modified code
+\b0 \cf2 as you wish (
+\b \cf4 without the full license text below
+\b0 \cf2 ).\
+{\listtext 5. }In all cases, you
+\b \cf4 must include a credit mentioning Matt Legend Gemmell
+\b0 \cf2 as the original author of the source.\
+{\listtext 6. }Matt Legend Gemmell is \cf0 not liable for anything you do with the code\cf2 , no matter what. So be sensible.\
+{\listtext 7. }You
+\b \cf4 can\'92t use the name Matt Legend Gemmell, the name Instinctive Code, the Instinctive Code logo or any other related marks to promote your products
+\b0 \cf2 based on the code.\
+{\listtext 8. }If you agree to all of that, go ahead and use the source. Otherwise, don\'92t!\
+\pard\pardeftab720\ql\qnatural
+\cf2 \
+
+\b \
+\
+Suggested Attribution Format\
+
+\b0 \
+The license requires that you give credit to Matt Legend Gemmell, as the original author of any of our source that you use. The placement and format of the credit is up to you, but we prefer the credit to be in the software\'92s \'93About\'94 window. Alternatively, you could put the credit in a list of acknowledgements within the software, in the software\'92s documentation, or on the web page for the software. The suggested format for the attribution is:\
+\
+\pard\pardeftab720\ql\qnatural
+
+\b \cf0 Includes <Name of Code> code by {\field{\*\fldinst{HYPERLINK "http://mattgemmell.com/"}}{\fldrslt \cf5 Matt Legend Gemmell}}\cf6 .
+\b0 \
+\pard\pardeftab720\ql\qnatural
+\cf2 \
+where <Name of Code> would be replaced by the name of the specific source-code package you made use of. Where possible, please link the text \'93Matt Legend Gemmell\'94 to the following URL, or include the URL as plain text: {\field{\*\fldinst{HYPERLINK "http://mattgemmell.com/"}}{\fldrslt \cf5 http://mattgemmell.com/}}\
+\
+\
+
+\b Full Source Code License Text\
+\
+
+\b0 Below you can find the actual text of the license agreement.
+\b \
+\
+\pard\pardeftab720\ql\qnatural
+\cf6 \
+License Agreement for Source Code provided by Matt Legend Gemmell
+\b0 \
+\
+This software is supplied to you by Matt Legend Gemmell in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this software.\
+\
+In consideration of your agreement to abide by the following terms, and subject to these terms, Matt Legend Gemmell grants you a personal, non-exclusive license, to use, reproduce, modify and redistribute the software, with or without modifications, in source and/or binary forms; provided that if you redistribute the software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the software, and that in all cases attribution of Matt Legend Gemmell as the original author of the source code shall be included in all such resulting software products or distributions.\uc0\u8232 \
+Neither the name, trademarks, service marks or logos of Matt Legend Gemmell or Instinctive Code may be used to endorse or promote products derived from the software without specific prior written permission from Matt Legend Gemmell. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Matt Legend Gemmell herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the software may be incorporated.\
+\
+The software is provided by Matt Legend Gemmell on an "AS IS" basis. MATT LEGEND GEMMELL AND INSTINCTIVE CODE MAKE NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.\
+\
+IN NO EVENT SHALL MATT LEGEND GEMMELL OR INSTINCTIVE CODE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF MATT LEGEND GEMMELL OR INSTINCTIVE CODE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\
+}
\ No newline at end of file
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.h
new file mode 100755
index 0000000..9e1d08f
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.h
@@ -0,0 +1,31 @@
+//
+// MGSplitCornersView.h
+// MGSplitView
+//
+// Created by Matt Gemmell on 28/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef enum _MGCornersPosition {
+ MGCornersPositionLeadingVertical = 0, // top of screen for a left/right split.
+ MGCornersPositionTrailingVertical = 1, // bottom of screen for a left/right split.
+ MGCornersPositionLeadingHorizontal = 2, // left of screen for a top/bottom split.
+ MGCornersPositionTrailingHorizontal = 3 // right of screen for a top/bottom split.
+} MGCornersPosition;
+
+ at class MGSplitViewController;
+ at interface MGSplitCornersView : UIView {
+ float cornerRadius;
+ MGSplitViewController *splitViewController;
+ MGCornersPosition cornersPosition;
+ UIColor *cornerBackgroundColor;
+}
+
+ at property (nonatomic, assign) float cornerRadius;
+ at property (nonatomic, assign) MGSplitViewController *splitViewController; // weak ref.
+ at property (nonatomic, assign) MGCornersPosition cornersPosition; // don't change this manually; let the splitViewController manage it.
+ at property (nonatomic, retain) UIColor *cornerBackgroundColor;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m
new file mode 100755
index 0000000..dea9d1e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitCornersView.m
@@ -0,0 +1,223 @@
+//
+// MGSplitCornersView.m
+// MGSplitView
+//
+// Created by Matt Gemmell on 28/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import "MGSplitCornersView.h"
+#import "CGPointUtils.h"
+
+ at implementation MGSplitCornersView
+
+
+#pragma mark -
+#pragma mark Setup and teardown
+
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+ self.contentMode = UIViewContentModeRedraw;
+ self.userInteractionEnabled = NO;
+ self.opaque = NO;
+ self.backgroundColor = [UIColor clearColor];
+ cornerRadius = 0.0; // actual value is set by the splitViewController.
+ cornersPosition = MGCornersPositionLeadingVertical;
+ }
+
+ return self;
+}
+
+
+- (void)dealloc
+{
+ self.cornerBackgroundColor = nil;
+
+ [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+
+- (void)drawRect:(CGRect)rect
+{
+ // Draw two appropriate corners, with cornerBackgroundColor behind them.
+ if (cornerRadius > 0) {
+ if (NO) { // just for debugging.
+ [[UIColor redColor] set];
+ UIRectFill(self.bounds);
+ }
+
+ float maxX = CGRectGetMaxX(self.bounds);
+ float maxY = CGRectGetMaxY(self.bounds);
+ UIBezierPath *path = [UIBezierPath bezierPath];
+ CGPoint pt = CGPointZero;
+ switch (cornersPosition) {
+ case MGCornersPositionLeadingVertical: // top of screen for a left/right split
+ [path moveToPoint:pt];
+ pt.y += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]];
+ pt.x += cornerRadius;
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path addLineToPoint:CGPointZero];
+ [path closePath];
+
+ pt.x = maxX - cornerRadius;
+ pt.y = 0;
+ [path moveToPoint:pt];
+ pt.y = maxY;
+ [path addLineToPoint:pt];
+ pt.x += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]];
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ break;
+
+ case MGCornersPositionTrailingVertical: // bottom of screen for a left/right split
+ pt.y = maxY;
+ [path moveToPoint:pt];
+ pt.y -= cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]];
+ pt.x += cornerRadius;
+ pt.y += cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ pt.x = maxX - cornerRadius;
+ pt.y = maxY;
+ [path moveToPoint:pt];
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]];
+ pt.y += cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ break;
+
+ case MGCornersPositionLeadingHorizontal: // left of screen for a top/bottom split
+ pt.x = 0;
+ pt.y = cornerRadius;
+ [path moveToPoint:pt];
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(270) clockwise:NO]];
+ pt.y += cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ pt.x = 0;
+ pt.y = maxY - cornerRadius;
+ [path moveToPoint:pt];
+ pt.y = maxY;
+ [path addLineToPoint:pt];
+ pt.x += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(180) endAngle:degreesToRadians(90) clockwise:YES]];
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ break;
+
+ case MGCornersPositionTrailingHorizontal: // right of screen for a top/bottom split
+ pt.y = cornerRadius;
+ [path moveToPoint:pt];
+ pt.y -= cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(270) endAngle:degreesToRadians(360) clockwise:NO]];
+ pt.x += cornerRadius;
+ pt.y += cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ pt.y = maxY - cornerRadius;
+ [path moveToPoint:pt];
+ pt.y += cornerRadius;
+ [path appendPath:[UIBezierPath bezierPathWithArcCenter:pt radius:cornerRadius startAngle:degreesToRadians(90) endAngle:0 clockwise:YES]];
+ pt.x += cornerRadius;
+ pt.y -= cornerRadius;
+ [path addLineToPoint:pt];
+ pt.x -= cornerRadius;
+ [path addLineToPoint:pt];
+ [path closePath];
+
+ break;
+
+ default:
+ break;
+ }
+
+ [self.cornerBackgroundColor set];
+ [path fill];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Accessors and properties
+
+
+- (void)setCornerRadius:(float)newRadius
+{
+ if (newRadius != cornerRadius) {
+ cornerRadius = newRadius;
+ [self setNeedsDisplay];
+ }
+}
+
+
+- (void)setSplitViewController:(MGSplitViewController *)theController
+{
+ if (theController != splitViewController) {
+ splitViewController = theController;
+ [self setNeedsDisplay];
+ }
+}
+
+
+- (void)setCornersPosition:(MGCornersPosition)posn
+{
+ if (cornersPosition != posn) {
+ cornersPosition = posn;
+ [self setNeedsDisplay];
+ }
+}
+
+
+- (void)setCornerBackgroundColor:(UIColor *)color
+{
+ if (color != cornerBackgroundColor) {
+ [cornerBackgroundColor release];
+ cornerBackgroundColor = [color retain];
+ [self setNeedsDisplay];
+ }
+}
+
+
+ at synthesize cornerRadius;
+ at synthesize splitViewController;
+ at synthesize cornersPosition;
+ at synthesize cornerBackgroundColor;
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.h
new file mode 100755
index 0000000..dee2a3a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.h
@@ -0,0 +1,22 @@
+//
+// MGSplitDividerView.h
+// MGSplitView
+//
+// Created by Matt Gemmell on 26/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import <UIKit/UIKit.h>
+
+ at class MGSplitViewController;
+ at interface MGSplitDividerView : UIView {
+ MGSplitViewController *splitViewController;
+ BOOL allowsDragging;
+}
+
+ at property (nonatomic, assign) MGSplitViewController *splitViewController; // weak ref.
+ at property (nonatomic, assign) BOOL allowsDragging;
+
+- (void)drawGripThumbInRect:(CGRect)rect;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.m
new file mode 100755
index 0000000..6305a0a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitDividerView.m
@@ -0,0 +1,216 @@
+//
+// MGSplitDividerView.m
+// MGSplitView
+//
+// Created by Matt Gemmell on 26/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import "MGSplitDividerView.h"
+#import "MGSplitViewController.h"
+
+
+ at implementation MGSplitDividerView
+
+
+#pragma mark -
+#pragma mark Setup and teardown
+
+
+- (id)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+ self.userInteractionEnabled = NO;
+ self.allowsDragging = NO;
+ self.contentMode = UIViewContentModeRedraw;
+ }
+ return self;
+}
+
+
+- (void)dealloc
+{
+ self.splitViewController = nil;
+ [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark Drawing
+
+
+- (void)drawRect:(CGRect)rect
+{
+ if (splitViewController.dividerStyle == MGSplitViewDividerStyleThin) {
+ [super drawRect:rect];
+
+ } else if (splitViewController.dividerStyle == MGSplitViewDividerStylePaneSplitter) {
+ // Draw gradient background.
+ CGRect bounds = self.bounds;
+ CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
+ CGFloat locations[2] = {0, 1};
+ CGFloat components[8] = { 0.988, 0.988, 0.988, 1.0, // light
+ 0.875, 0.875, 0.875, 1.0 };// dark
+ CGGradientRef gradient = CGGradientCreateWithColorComponents (rgb, components, locations, 2);
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGPoint start, end;
+ if (splitViewController.vertical) {
+ // Light left to dark right.
+ start = CGPointMake(CGRectGetMinX(bounds), CGRectGetMidY(bounds));
+ end = CGPointMake(CGRectGetMaxX(bounds), CGRectGetMidY(bounds));
+ } else {
+ // Light top to dark bottom.
+ start = CGPointMake(CGRectGetMidX(bounds), CGRectGetMinY(bounds));
+ end = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
+ }
+ CGContextDrawLinearGradient(context, gradient, start, end, 0);
+ CGColorSpaceRelease(rgb);
+ CGGradientRelease(gradient);
+
+ // Draw borders.
+ float borderThickness = 1.0;
+ [[UIColor colorWithWhite:0.7 alpha:1.0] set];
+ CGRect borderRect = bounds;
+ if (splitViewController.vertical) {
+ borderRect.size.width = borderThickness;
+ UIRectFill(borderRect);
+ borderRect.origin.x = CGRectGetMaxX(bounds) - borderThickness;
+ UIRectFill(borderRect);
+
+ } else {
+ borderRect.size.height = borderThickness;
+ UIRectFill(borderRect);
+ borderRect.origin.y = CGRectGetMaxY(bounds) - borderThickness;
+ UIRectFill(borderRect);
+ }
+
+ // Draw grip.
+ [self drawGripThumbInRect:bounds];
+ }
+}
+
+
+- (void)drawGripThumbInRect:(CGRect)rect
+{
+ float width = 9.0;
+ float height;
+ if (splitViewController.vertical) {
+ height = 30.0;
+ } else {
+ height = width;
+ width = 30.0;
+ }
+
+ // Draw grip in centred in rect.
+ CGRect gripRect = CGRectMake(0, 0, width, height);
+ gripRect.origin.x = ((rect.size.width - gripRect.size.width) / 2.0);
+ gripRect.origin.y = ((rect.size.height - gripRect.size.height) / 2.0);
+
+ float stripThickness = 1.0;
+ UIColor *stripColor = [UIColor colorWithWhite:0.35 alpha:1.0];
+ UIColor *lightColor = [UIColor colorWithWhite:1.0 alpha:1.0];
+ float space = 3.0;
+ if (splitViewController.vertical) {
+ gripRect.size.width = stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.x += stripThickness;
+ gripRect.origin.y += 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+ gripRect.origin.x -= stripThickness;
+ gripRect.origin.y -= 1;
+
+ gripRect.origin.x += space + stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.x += stripThickness;
+ gripRect.origin.y += 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+ gripRect.origin.x -= stripThickness;
+ gripRect.origin.y -= 1;
+
+ gripRect.origin.x += space + stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.x += stripThickness;
+ gripRect.origin.y += 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+
+ } else {
+ gripRect.size.height = stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.y += stripThickness;
+ gripRect.origin.x -= 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+ gripRect.origin.y -= stripThickness;
+ gripRect.origin.x += 1;
+
+ gripRect.origin.y += space + stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.y += stripThickness;
+ gripRect.origin.x -= 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+ gripRect.origin.y -= stripThickness;
+ gripRect.origin.x += 1;
+
+ gripRect.origin.y += space + stripThickness;
+ [stripColor set];
+ UIRectFill(gripRect);
+
+ gripRect.origin.y += stripThickness;
+ gripRect.origin.x -= 1;
+ [lightColor set];
+ UIRectFill(gripRect);
+ }
+}
+
+
+#pragma mark -
+#pragma mark Interaction
+
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ UITouch *touch = [touches anyObject];
+ if (touch) {
+ CGPoint lastPt = [touch previousLocationInView:self];
+ CGPoint pt = [touch locationInView:self];
+ float offset = (splitViewController.vertical) ? pt.x - lastPt.x : pt.y - lastPt.y;
+ if (!splitViewController.masterBeforeDetail) {
+ offset = -offset;
+ }
+ splitViewController.splitPosition = splitViewController.splitPosition + offset;
+ }
+}
+
+
+#pragma mark -
+#pragma mark Accessors and properties
+
+
+- (void)setAllowsDragging:(BOOL)flag
+{
+ if (flag != allowsDragging) {
+ allowsDragging = flag;
+ self.userInteractionEnabled = allowsDragging;
+ }
+}
+
+
+ at synthesize splitViewController;
+ at synthesize allowsDragging;
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.h b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.h
new file mode 100755
index 0000000..7fd16c9
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.h
@@ -0,0 +1,116 @@
+//
+// MGSplitViewController.h
+// MGSplitView
+//
+// Created by Matt Gemmell on 26/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef enum _MGSplitViewDividerStyle {
+ // These names have been chosen to be conceptually similar to those of NSSplitView on Mac OS X.
+ MGSplitViewDividerStyleThin = 0, // Thin divider, like UISplitViewController (default).
+ MGSplitViewDividerStylePaneSplitter = 1 // Thick divider, drawn with a grey gradient and a grab-strip.
+} MGSplitViewDividerStyle;
+
+ at class MGSplitDividerView;
+ at protocol MGSplitViewControllerDelegate;
+ at interface MGSplitViewController : UIViewController <UIPopoverControllerDelegate> {
+ BOOL _showsMasterInPortrait;
+ BOOL _showsMasterInLandscape;
+ float _splitWidth;
+ id _delegate;
+ BOOL _vertical;
+ BOOL _masterBeforeDetail;
+ NSMutableArray *_viewControllers;
+ UIBarButtonItem *_barButtonItem; // To be compliant with wacky UISplitViewController behaviour.
+ UIPopoverController *_hiddenPopoverController; // Popover used to hold the master view if it's not always visible.
+ MGSplitDividerView *_dividerView; // View that draws the divider between the master and detail views.
+ NSArray *_cornerViews; // Views to draw the inner rounded corners between master and detail views.
+ float _splitPosition;
+ BOOL _reconfigurePopup;
+ MGSplitViewDividerStyle _dividerStyle; // Meta-setting which configures several aspects of appearance and behaviour.
+}
+
+ at property (nonatomic, assign) IBOutlet id <MGSplitViewControllerDelegate> delegate;
+ at property (nonatomic, assign) BOOL showsMasterInPortrait; // applies to both portrait orientations (default NO)
+ at property (nonatomic, assign) BOOL showsMasterInLandscape; // applies to both landscape orientations (default YES)
+ at property (nonatomic, assign, getter=isVertical) BOOL vertical; // if NO, split is horizontal, i.e. master above detail (default YES)
+ at property (nonatomic, assign, getter=isMasterBeforeDetail) BOOL masterBeforeDetail; // if NO, master view is below/right of detail (default YES)
+ at property (nonatomic, assign) float splitPosition; // starting position of split in pixels, relative to top/left (depending on .isVertical setting) if masterBeforeDetail is YES, else relative to bottom/right.
+ at property (nonatomic, assign) float splitWidth; // width of split in pixels.
+ at property (nonatomic, assign) BOOL allowsDraggingDivider; // whether to let the user drag the divider to alter the split position (default NO).
+
+ at property (nonatomic, copy) NSArray *viewControllers; // array of UIViewControllers; master is at index 0, detail is at index 1.
+ at property (nonatomic, retain) IBOutlet UIViewController *masterViewController; // convenience.
+ at property (nonatomic, retain) IBOutlet UIViewController *detailViewController; // convenience.
+ at property (nonatomic, retain) MGSplitDividerView *dividerView; // the view which draws the divider/split between master and detail.
+ at property (nonatomic, assign) MGSplitViewDividerStyle dividerStyle; // style (and behaviour) of the divider between master and detail.
+
+ at property (nonatomic, readonly, getter=isLandscape) BOOL landscape; // returns YES if this view controller is in either of the two Landscape orientations, else NO.
+
+// Actions
+- (IBAction)toggleSplitOrientation:(id)sender; // toggles split axis between vertical (left/right; default) and horizontal (top/bottom).
+- (IBAction)toggleMasterBeforeDetail:(id)sender; // toggles position of master view relative to detail view.
+- (IBAction)toggleMasterView:(id)sender; // toggles display of the master view in the current orientation.
+- (IBAction)showMasterPopover:(id)sender; // shows the master view in a popover spawned from the provided barButtonItem, if it's currently hidden.
+- (void)notePopoverDismissed; // should rarely be needed, because you should not change the popover's delegate. If you must, then call this when it's dismissed.
+
+// Conveniences for you, because I care.
+- (BOOL)isShowingMaster;
+- (void)setSplitPosition:(float)posn animated:(BOOL)animate; // Allows for animation of splitPosition changes. The property's regular setter is not animated.
+/* Note: splitPosition is the width (in a left/right split, or height in a top/bottom split) of the master view.
+ It is relative to the appropriate side of the splitView, which can be any of the four sides depending on the values in isMasterBeforeDetail and isVertical:
+ isVertical = YES, isMasterBeforeDetail = YES: splitPosition is relative to the LEFT edge. (Default)
+ isVertical = YES, isMasterBeforeDetail = NO: splitPosition is relative to the RIGHT edge.
+ isVertical = NO, isMasterBeforeDetail = YES: splitPosition is relative to the TOP edge.
+ isVertical = NO, isMasterBeforeDetail = NO: splitPosition is relative to the BOTTOM edge.
+
+ This implementation was chosen so you don't need to recalculate equivalent splitPositions if the user toggles masterBeforeDetail themselves.
+ */
+- (void)setDividerStyle:(MGSplitViewDividerStyle)newStyle animated:(BOOL)animate; // Allows for animation of dividerStyle changes. The property's regular setter is not animated.
+- (NSArray *)cornerViews;
+/*
+ -cornerViews returns an NSArray of two MGSplitCornersView objects, used to draw the inner corners.
+ The first view is the "leading" corners (top edge of screen for left/right split, left edge of screen for top/bottom split).
+ The second view is the "trailing" corners (bottom edge of screen for left/right split, right edge of screen for top/bottom split).
+ Do NOT modify them, except to:
+ 1. Change their .cornerBackgroundColor
+ 2. Change their .cornerRadius
+ */
+
+ at end
+
+
+ at protocol MGSplitViewControllerDelegate
+
+ at optional
+
+// Called when a button should be added to a toolbar for a hidden view controller.
+- (void)splitViewController:(MGSplitViewController*)svc
+ willHideViewController:(UIViewController *)aViewController
+ withBarButtonItem:(UIBarButtonItem*)barButtonItem
+ forPopoverController: (UIPopoverController*)pc;
+
+// Called when the master view is shown again in the split view, invalidating the button and popover controller.
+- (void)splitViewController:(MGSplitViewController*)svc
+ willShowViewController:(UIViewController *)aViewController
+ invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem;
+
+// Called when the master view is shown in a popover, so the delegate can take action like hiding other popovers.
+- (void)splitViewController:(MGSplitViewController*)svc
+ popoverController:(UIPopoverController*)pc
+ willPresentViewController:(UIViewController *)aViewController;
+
+// Called when the split orientation will change (from vertical to horizontal, or vice versa).
+- (void)splitViewController:(MGSplitViewController*)svc willChangeSplitOrientationToVertical:(BOOL)isVertical;
+
+// Called when split position will change to the given pixel value (relative to left if split is vertical, or to top if horizontal).
+- (void)splitViewController:(MGSplitViewController*)svc willMoveSplitToPosition:(float)position;
+
+// Called before split position is changed to the given pixel value (relative to left if split is vertical, or to top if horizontal).
+// Note that viewSize is the current size of the entire split-view; i.e. the area enclosing the master, divider and detail views.
+- (float)splitViewController:(MGSplitViewController *)svc constrainSplitPosition:(float)proposedPosition splitViewSize:(CGSize)viewSize;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m
new file mode 100755
index 0000000..fb25d11
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MGSplitViewController/MGSplitViewController.m
@@ -0,0 +1,1133 @@
+//
+// MGSplitViewController.m
+// MGSplitView
+//
+// Created by Matt Gemmell on 26/07/2010.
+// Copyright 2010 Instinctive Code.
+//
+
+#import "MGSplitViewController.h"
+#import "MGSplitDividerView.h"
+#import "MGSplitCornersView.h"
+
+#define MG_DEFAULT_SPLIT_POSITION 320.0 // default width of master view in UISplitViewController.
+#define MG_DEFAULT_SPLIT_WIDTH 1.0 // default width of split-gutter in UISplitViewController.
+#define MG_DEFAULT_CORNER_RADIUS 5.0 // default corner-radius of overlapping split-inner corners on the master and detail views.
+#define MG_DEFAULT_CORNER_COLOR [UIColor blackColor] // default color of intruding inner corners (and divider background).
+
+#define MG_PANESPLITTER_CORNER_RADIUS 0.0 // corner-radius of split-inner corners for MGSplitViewDividerStylePaneSplitter style.
+#define MG_PANESPLITTER_SPLIT_WIDTH 25.0 // width of split-gutter for MGSplitViewDividerStylePaneSplitter style.
+
+#define MG_MIN_VIEW_WIDTH 200.0 // minimum width a view is allowed to become as a result of changing the splitPosition.
+
+#define MG_ANIMATION_CHANGE_SPLIT_ORIENTATION @"ChangeSplitOrientation" // Animation ID for internal use.
+#define MG_ANIMATION_CHANGE_SUBVIEWS_ORDER @"ChangeSubviewsOrder" // Animation ID for internal use.
+
+
+ at interface MGSplitViewController (MGPrivateMethods)
+
+- (void)setup;
+- (CGSize)splitViewSizeForOrientation:(UIInterfaceOrientation)theOrientation;
+- (void)layoutSubviews;
+- (void)layoutSubviewsWithAnimation:(BOOL)animate;
+- (void)layoutSubviewsForInterfaceOrientation:(UIInterfaceOrientation)theOrientation withAnimation:(BOOL)animate;
+- (BOOL)shouldShowMasterForInterfaceOrientation:(UIInterfaceOrientation)theOrientation;
+- (BOOL)shouldShowMaster;
+- (NSString *)nameOfInterfaceOrientation:(UIInterfaceOrientation)theOrientation;
+- (void)reconfigureForMasterInPopover:(BOOL)inPopover;
+
+ at end
+
+
+ at implementation MGSplitViewController
+
+
+#pragma mark -
+#pragma mark Orientation helpers
+
+
+- (NSString *)nameOfInterfaceOrientation:(UIInterfaceOrientation)theOrientation
+{
+ NSString *orientationName = nil;
+ switch (theOrientation) {
+ case UIInterfaceOrientationPortrait:
+ orientationName = @"Portrait"; // Home button at bottom
+ break;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ orientationName = @"Portrait (Upside Down)"; // Home button at top
+ break;
+ case UIInterfaceOrientationLandscapeLeft:
+ orientationName = @"Landscape (Left)"; // Home button on left
+ break;
+ case UIInterfaceOrientationLandscapeRight:
+ orientationName = @"Landscape (Right)"; // Home button on right
+ break;
+ default:
+ break;
+ }
+
+ return orientationName;
+}
+
+
+- (BOOL)isLandscape
+{
+ return UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
+}
+
+
+- (BOOL)shouldShowMasterForInterfaceOrientation:(UIInterfaceOrientation)theOrientation
+{
+ // Returns YES if master view should be shown directly embedded in the splitview, instead of hidden in a popover.
+ return ((UIInterfaceOrientationIsLandscape(theOrientation)) ? _showsMasterInLandscape : _showsMasterInPortrait);
+}
+
+
+- (BOOL)shouldShowMaster
+{
+ return [self shouldShowMasterForInterfaceOrientation:self.interfaceOrientation];
+}
+
+
+- (BOOL)isShowingMaster
+{
+ return [self shouldShowMaster] && self.masterViewController && self.masterViewController.view && ([self.masterViewController.view superview] == self.view);
+}
+
+
+#pragma mark -
+#pragma mark Setup and Teardown
+
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
+ [self setup];
+ }
+
+ return self;
+}
+
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+ if ((self = [super initWithCoder:aDecoder])) {
+ [self setup];
+ }
+
+ return self;
+}
+
+
+- (void)setup
+{
+ // Configure default behaviour.
+ _viewControllers = [[NSMutableArray alloc] initWithObjects:[NSNull null], [NSNull null], nil];
+ _splitWidth = MG_DEFAULT_SPLIT_WIDTH;
+ _showsMasterInPortrait = NO;
+ _showsMasterInLandscape = YES;
+ _reconfigurePopup = NO;
+ _vertical = YES;
+ _masterBeforeDetail = YES;
+ _splitPosition = MG_DEFAULT_SPLIT_POSITION;
+ CGRect divRect = self.view.bounds;
+ if ([self isVertical]) {
+ divRect.origin.y = _splitPosition;
+ divRect.size.height = _splitWidth;
+ } else {
+ divRect.origin.x = _splitPosition;
+ divRect.size.width = _splitWidth;
+ }
+ _dividerView = [[MGSplitDividerView alloc] initWithFrame:divRect];
+ _dividerView.splitViewController = self;
+ _dividerView.backgroundColor = MG_DEFAULT_CORNER_COLOR;
+ _dividerStyle = MGSplitViewDividerStyleThin;
+}
+
+
+- (void)dealloc
+{
+ _delegate = nil;
+ [self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
+ [_viewControllers release];
+ [_barButtonItem release];
+ [_hiddenPopoverController release];
+ [_dividerView release];
+ [_cornerViews release];
+
+ [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark View management
+
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return YES;
+}
+
+
+- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
+{
+ [self.masterViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [self.detailViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+}
+
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
+{
+ [self.masterViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+ [self.detailViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+}
+
+
+- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+ duration:(NSTimeInterval)duration
+{
+ [self.masterViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [self.detailViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+
+ // Hide popover.
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ // Re-tile views.
+ _reconfigurePopup = YES;
+ [self layoutSubviewsForInterfaceOrientation:toInterfaceOrientation withAnimation:YES];
+}
+
+
+- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
+{
+ [self.masterViewController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [self.detailViewController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+}
+
+
+- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
+{
+ [self.masterViewController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
+ [self.detailViewController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
+}
+
+
+- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration
+{
+ [self.masterViewController willAnimateSecondHalfOfRotationFromInterfaceOrientation:fromInterfaceOrientation duration:duration];
+ [self.detailViewController willAnimateSecondHalfOfRotationFromInterfaceOrientation:fromInterfaceOrientation duration:duration];
+}
+
+
+- (CGSize)splitViewSizeForOrientation:(UIInterfaceOrientation)theOrientation
+{
+ UIScreen *screen = [UIScreen mainScreen];
+ CGRect fullScreenRect = screen.bounds; // always implicitly in Portrait orientation.
+ CGRect appFrame = screen.applicationFrame;
+
+ // Find status bar height by checking which dimension of the applicationFrame is narrower than screen bounds.
+ // Little bit ugly looking, but it'll still work even if they change the status bar height in future.
+ float statusBarHeight = MAX((fullScreenRect.size.width - appFrame.size.width), (fullScreenRect.size.height - appFrame.size.height));
+
+ // Initially assume portrait orientation.
+ float width = fullScreenRect.size.width;
+ float height = fullScreenRect.size.height;
+
+ // Correct for orientation.
+ if (UIInterfaceOrientationIsLandscape(theOrientation)) {
+ width = height;
+ height = fullScreenRect.size.width;
+ }
+
+ // Account for status bar, which always subtracts from the height (since it's always at the top of the screen).
+ height -= statusBarHeight;
+
+ return CGSizeMake(width, height);
+}
+
+
+- (void)layoutSubviewsForInterfaceOrientation:(UIInterfaceOrientation)theOrientation withAnimation:(BOOL)animate
+{
+ if (_reconfigurePopup) {
+ [self reconfigureForMasterInPopover:![self shouldShowMasterForInterfaceOrientation:theOrientation]];
+ }
+
+ // Layout the master, detail and divider views appropriately, adding/removing subviews as needed.
+ // First obtain relevant geometry.
+ CGSize fullSize = [self splitViewSizeForOrientation:theOrientation];
+ float width = fullSize.width;
+ float height = fullSize.height;
+
+ if (NO) { // Just for debugging.
+ NSLog(@"Target orientation is %@, dimensions will be %.0f x %.0f",
+ [self nameOfInterfaceOrientation:theOrientation], width, height);
+ }
+
+ // Layout the master, divider and detail views.
+ CGRect newFrame = CGRectMake(0, 0, width, height);
+ UIViewController *controller;
+ UIView *theView;
+ BOOL shouldShowMaster = [self shouldShowMasterForInterfaceOrientation:theOrientation];
+ BOOL masterFirst = [self isMasterBeforeDetail];
+ if ([self isVertical]) {
+ // Master on left, detail on right (or vice versa).
+ CGRect masterRect, dividerRect, detailRect;
+ if (masterFirst) {
+ if (!shouldShowMaster) {
+ // Move off-screen.
+ newFrame.origin.x -= (_splitPosition + _splitWidth);
+ }
+
+ newFrame.size.width = _splitPosition;
+ masterRect = newFrame;
+
+ newFrame.origin.x += newFrame.size.width;
+ newFrame.size.width = _splitWidth;
+ dividerRect = newFrame;
+
+ newFrame.origin.x += newFrame.size.width;
+ newFrame.size.width = width - newFrame.origin.x;
+ detailRect = newFrame;
+
+ } else {
+ if (!shouldShowMaster) {
+ // Move off-screen.
+ newFrame.size.width += (_splitPosition + _splitWidth);
+ }
+
+ newFrame.size.width -= (_splitPosition + _splitWidth);
+ detailRect = newFrame;
+
+ newFrame.origin.x += newFrame.size.width;
+ newFrame.size.width = _splitWidth;
+ dividerRect = newFrame;
+
+ newFrame.origin.x += newFrame.size.width;
+ newFrame.size.width = _splitPosition;
+ masterRect = newFrame;
+ }
+
+ // Position master.
+ controller = self.masterViewController;
+ if (controller && [controller isKindOfClass:[UIViewController class]]) {
+ theView = controller.view;
+ if (theView) {
+ theView.frame = masterRect;
+ if (!theView.superview) {
+ [controller viewWillAppear:NO];
+ [self.view addSubview:theView];
+ [controller viewDidAppear:NO];
+ }
+ }
+ }
+
+ // Position divider.
+ theView = _dividerView;
+ theView.frame = dividerRect;
+ if (!theView.superview) {
+ [self.view addSubview:theView];
+ }
+
+ // Position detail.
+ controller = self.detailViewController;
+ if (controller && [controller isKindOfClass:[UIViewController class]]) {
+ theView = controller.view;
+ if (theView) {
+ theView.frame = detailRect;
+ if (!theView.superview) {
+ [self.view insertSubview:theView aboveSubview:self.masterViewController.view];
+ } else {
+ [self.view bringSubviewToFront:theView];
+ }
+ }
+ }
+
+ } else {
+ // Master above, detail below (or vice versa).
+ CGRect masterRect, dividerRect, detailRect;
+ if (masterFirst) {
+ if (!shouldShowMaster) {
+ // Move off-screen.
+ newFrame.origin.y -= (_splitPosition + _splitWidth);
+ }
+
+ newFrame.size.height = _splitPosition;
+ masterRect = newFrame;
+
+ newFrame.origin.y += newFrame.size.height;
+ newFrame.size.height = _splitWidth;
+ dividerRect = newFrame;
+
+ newFrame.origin.y += newFrame.size.height;
+ newFrame.size.height = height - newFrame.origin.y;
+ detailRect = newFrame;
+
+ } else {
+ if (!shouldShowMaster) {
+ // Move off-screen.
+ newFrame.size.height += (_splitPosition + _splitWidth);
+ }
+
+ newFrame.size.height -= (_splitPosition + _splitWidth);
+ detailRect = newFrame;
+
+ newFrame.origin.y += newFrame.size.height;
+ newFrame.size.height = _splitWidth;
+ dividerRect = newFrame;
+
+ newFrame.origin.y += newFrame.size.height;
+ newFrame.size.height = _splitPosition;
+ masterRect = newFrame;
+ }
+
+ // Position master.
+ controller = self.masterViewController;
+ if (controller && [controller isKindOfClass:[UIViewController class]]) {
+ theView = controller.view;
+ if (theView) {
+ theView.frame = masterRect;
+ if (!theView.superview) {
+ [controller viewWillAppear:NO];
+ [self.view addSubview:theView];
+ [controller viewDidAppear:NO];
+ }
+ }
+ }
+
+ // Position divider.
+ theView = _dividerView;
+ theView.frame = dividerRect;
+ if (!theView.superview) {
+ [self.view addSubview:theView];
+ }
+
+ // Position detail.
+ controller = self.detailViewController;
+ if (controller && [controller isKindOfClass:[UIViewController class]]) {
+ theView = controller.view;
+ if (theView) {
+ theView.frame = detailRect;
+ if (!theView.superview) {
+ [self.view insertSubview:theView aboveSubview:self.masterViewController.view];
+ } else {
+ [self.view bringSubviewToFront:theView];
+ }
+ }
+ }
+ }
+
+ // Create corner views if necessary.
+ MGSplitCornersView *leadingCorners; // top/left of screen in vertical/horizontal split.
+ MGSplitCornersView *trailingCorners; // bottom/right of screen in vertical/horizontal split.
+ if (!_cornerViews) {
+ CGRect cornerRect = CGRectMake(0, 0, 10, 10); // arbitrary, will be resized below.
+ leadingCorners = [[MGSplitCornersView alloc] initWithFrame:cornerRect];
+ leadingCorners.splitViewController = self;
+ leadingCorners.cornerBackgroundColor = MG_DEFAULT_CORNER_COLOR;
+ leadingCorners.cornerRadius = MG_DEFAULT_CORNER_RADIUS;
+ trailingCorners = [[MGSplitCornersView alloc] initWithFrame:cornerRect];
+ trailingCorners.splitViewController = self;
+ trailingCorners.cornerBackgroundColor = MG_DEFAULT_CORNER_COLOR;
+ trailingCorners.cornerRadius = MG_DEFAULT_CORNER_RADIUS;
+ _cornerViews = [[NSArray alloc] initWithObjects:leadingCorners, trailingCorners, nil];
+ [leadingCorners release];
+ [trailingCorners release];
+
+ } else if ([_cornerViews count] == 2) {
+ leadingCorners = [_cornerViews objectAtIndex:0];
+ trailingCorners = [_cornerViews objectAtIndex:1];
+ }
+
+ // Configure and layout the corner-views.
+ leadingCorners.cornersPosition = (_vertical) ? MGCornersPositionLeadingVertical : MGCornersPositionLeadingHorizontal;
+ trailingCorners.cornersPosition = (_vertical) ? MGCornersPositionTrailingVertical : MGCornersPositionTrailingHorizontal;
+ leadingCorners.autoresizingMask = (_vertical) ? UIViewAutoresizingFlexibleBottomMargin : UIViewAutoresizingFlexibleRightMargin;
+ trailingCorners.autoresizingMask = (_vertical) ? UIViewAutoresizingFlexibleTopMargin : UIViewAutoresizingFlexibleLeftMargin;
+
+ float x, y, cornersWidth, cornersHeight;
+ CGRect leadingRect, trailingRect;
+ float radius = leadingCorners.cornerRadius;
+ if (_vertical) { // left/right split
+ cornersWidth = (radius * 2.0) + _splitWidth;
+ cornersHeight = radius;
+ x = ((shouldShowMaster) ? ((masterFirst) ? _splitPosition : width - (_splitPosition + _splitWidth)) : (0 - _splitWidth)) - radius;
+ y = 0;
+ leadingRect = CGRectMake(x, y, cornersWidth, cornersHeight); // top corners
+ trailingRect = CGRectMake(x, (height - cornersHeight), cornersWidth, cornersHeight); // bottom corners
+
+ } else { // top/bottom split
+ x = 0;
+ y = ((shouldShowMaster) ? ((masterFirst) ? _splitPosition : height - (_splitPosition + _splitWidth)) : (0 - _splitWidth)) - radius;
+ cornersWidth = radius;
+ cornersHeight = (radius * 2.0) + _splitWidth;
+ leadingRect = CGRectMake(x, y, cornersWidth, cornersHeight); // left corners
+ trailingRect = CGRectMake((width - cornersWidth), y, cornersWidth, cornersHeight); // right corners
+ }
+
+ leadingCorners.frame = leadingRect;
+ trailingCorners.frame = trailingRect;
+
+ // Ensure corners are visible and frontmost.
+ if (!leadingCorners.superview) {
+ [self.view insertSubview:leadingCorners aboveSubview:self.detailViewController.view];
+ [self.view insertSubview:trailingCorners aboveSubview:self.detailViewController.view];
+ } else {
+ [self.view bringSubviewToFront:leadingCorners];
+ [self.view bringSubviewToFront:trailingCorners];
+ }
+}
+
+
+- (void)layoutSubviewsWithAnimation:(BOOL)animate
+{
+ [self layoutSubviewsForInterfaceOrientation:self.interfaceOrientation withAnimation:animate];
+}
+
+
+- (void)layoutSubviews
+{
+ [self layoutSubviewsForInterfaceOrientation:self.interfaceOrientation withAnimation:YES];
+}
+
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ if ([self isShowingMaster]) {
+ [self.masterViewController viewWillAppear:animated];
+ }
+ [self.detailViewController viewWillAppear:animated];
+
+ _reconfigurePopup = YES;
+ [self layoutSubviews];
+}
+
+
+- (void)viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+
+ if ([self isShowingMaster]) {
+ [self.masterViewController viewDidAppear:animated];
+ }
+ [self.detailViewController viewDidAppear:animated];
+}
+
+
+- (void)viewWillDisappear:(BOOL)animated
+{
+ [super viewWillDisappear:animated];
+
+ if ([self isShowingMaster]) {
+ [self.masterViewController viewWillDisappear:animated];
+ }
+ [self.detailViewController viewWillDisappear:animated];
+}
+
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+ [super viewDidDisappear:animated];
+
+ if ([self isShowingMaster]) {
+ [self.masterViewController viewDidDisappear:animated];
+ }
+ [self.detailViewController viewDidDisappear:animated];
+}
+
+
+#pragma mark -
+#pragma mark Popover handling
+
+
+- (void)reconfigureForMasterInPopover:(BOOL)inPopover
+{
+ _reconfigurePopup = NO;
+
+ if ((inPopover && _hiddenPopoverController) || (!inPopover && !_hiddenPopoverController) || !self.masterViewController) {
+ // Nothing to do.
+ return;
+ }
+
+ if (inPopover && !_hiddenPopoverController && !_barButtonItem) {
+ // Create and configure popover for our masterViewController.
+ [_hiddenPopoverController release];
+ _hiddenPopoverController = nil;
+ [self.masterViewController viewWillDisappear:NO];
+ _hiddenPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.masterViewController];
+ [self.masterViewController viewDidDisappear:NO];
+
+ // Create and configure _barButtonItem.
+ _barButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Master", nil)
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(showMasterPopover:)];
+
+ // Inform delegate of this state of affairs.
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willHideViewController:withBarButtonItem:forPopoverController:)]) {
+ [(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self
+ willHideViewController:self.masterViewController
+ withBarButtonItem:_barButtonItem
+ forPopoverController:_hiddenPopoverController];
+ }
+
+ } else if (!inPopover && _hiddenPopoverController && _barButtonItem) {
+ // I know this looks strange, but it fixes a bizarre issue with UIPopoverController leaving masterViewController's views in disarray.
+ [_hiddenPopoverController presentPopoverFromRect:CGRectZero inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
+
+ // Remove master from popover and destroy popover, if it exists.
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ [_hiddenPopoverController release];
+ _hiddenPopoverController = nil;
+
+ // Inform delegate that the _barButtonItem will become invalid.
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willShowViewController:invalidatingBarButtonItem:)]) {
+ [(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self
+ willShowViewController:self.masterViewController
+ invalidatingBarButtonItem:_barButtonItem];
+ }
+
+ // Destroy _barButtonItem.
+ [_barButtonItem release];
+ _barButtonItem = nil;
+
+ // Move master view.
+ UIView *masterView = self.masterViewController.view;
+ if (masterView && masterView.superview != self.view) {
+ [masterView removeFromSuperview];
+ }
+ }
+}
+
+
+- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
+{
+ [self reconfigureForMasterInPopover:NO];
+}
+
+
+- (void)notePopoverDismissed
+{
+ [self popoverControllerDidDismissPopover:_hiddenPopoverController];
+}
+
+
+#pragma mark -
+#pragma mark Animations
+
+
+- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
+{
+ if (([animationID isEqualToString:MG_ANIMATION_CHANGE_SPLIT_ORIENTATION] ||
+ [animationID isEqualToString:MG_ANIMATION_CHANGE_SUBVIEWS_ORDER])
+ && _cornerViews) {
+ for (UIView *corner in _cornerViews) {
+ corner.hidden = NO;
+ }
+ _dividerView.hidden = NO;
+ }
+}
+
+
+#pragma mark -
+#pragma mark IB Actions
+
+
+- (IBAction)toggleSplitOrientation:(id)sender
+{
+ BOOL showingMaster = [self isShowingMaster];
+ if (showingMaster) {
+ if (_cornerViews) {
+ for (UIView *corner in _cornerViews) {
+ corner.hidden = YES;
+ }
+ _dividerView.hidden = YES;
+ }
+ [UIView beginAnimations:MG_ANIMATION_CHANGE_SPLIT_ORIENTATION context:nil];
+ [UIView setAnimationDelegate:self];
+ [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
+ }
+ self.vertical = (!self.vertical);
+ if (showingMaster) {
+ [UIView commitAnimations];
+ }
+}
+
+
+- (IBAction)toggleMasterBeforeDetail:(id)sender
+{
+ BOOL showingMaster = [self isShowingMaster];
+ if (showingMaster) {
+ if (_cornerViews) {
+ for (UIView *corner in _cornerViews) {
+ corner.hidden = YES;
+ }
+ _dividerView.hidden = YES;
+ }
+ [UIView beginAnimations:MG_ANIMATION_CHANGE_SUBVIEWS_ORDER context:nil];
+ [UIView setAnimationDelegate:self];
+ [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
+ }
+ self.masterBeforeDetail = (!self.masterBeforeDetail);
+ if (showingMaster) {
+ [UIView commitAnimations];
+ }
+}
+
+
+- (IBAction)toggleMasterView:(id)sender
+{
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ if (![self isShowingMaster]) {
+ // We're about to show the master view. Ensure it's in place off-screen to be animated in.
+ _reconfigurePopup = YES;
+ [self reconfigureForMasterInPopover:NO];
+ [self layoutSubviews];
+ }
+
+ // This action functions on the current primary orientation; it is independent of the other primary orientation.
+ [UIView beginAnimations:@"toggleMaster" context:nil];
+ if (self.isLandscape) {
+ self.showsMasterInLandscape = !_showsMasterInLandscape;
+ } else {
+ self.showsMasterInPortrait = !_showsMasterInPortrait;
+ }
+ [UIView commitAnimations];
+}
+
+
+- (IBAction)showMasterPopover:(id) sender
+{
+ if (_hiddenPopoverController && !(_hiddenPopoverController.popoverVisible)) {
+ // Inform delegate.
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:popoverController:willPresentViewController:)]) {
+ [(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self
+ popoverController:_hiddenPopoverController
+ willPresentViewController:self.masterViewController];
+ }
+
+ // Show popover.
+ [_hiddenPopoverController presentPopoverFromBarButtonItem:_barButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Accessors and properties
+
+
+- (id)delegate
+{
+ return _delegate;
+}
+
+
+- (void)setDelegate:(id <MGSplitViewControllerDelegate>)newDelegate
+{
+ if (newDelegate != _delegate &&
+ (!newDelegate || [(NSObject *)newDelegate conformsToProtocol:@protocol(MGSplitViewControllerDelegate)])) {
+ _delegate = newDelegate;
+ }
+}
+
+
+- (BOOL)showsMasterInPortrait
+{
+ return _showsMasterInPortrait;
+}
+
+
+- (void)setShowsMasterInPortrait:(BOOL)flag
+{
+ if (flag != _showsMasterInPortrait) {
+ _showsMasterInPortrait = flag;
+
+ if (![self isLandscape]) { // i.e. if this will cause a visual change.
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ // Rearrange views.
+ _reconfigurePopup = YES;
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (BOOL)showsMasterInLandscape
+{
+ return _showsMasterInLandscape;
+}
+
+
+- (void)setShowsMasterInLandscape:(BOOL)flag
+{
+ if (flag != _showsMasterInLandscape) {
+ _showsMasterInLandscape = flag;
+
+ if ([self isLandscape]) { // i.e. if this will cause a visual change.
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ // Rearrange views.
+ _reconfigurePopup = YES;
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (BOOL)isVertical
+{
+ return _vertical;
+}
+
+
+- (void)setVertical:(BOOL)flag
+{
+ if (flag != _vertical) {
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ _vertical = flag;
+
+ // Inform delegate.
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willChangeSplitOrientationToVertical:)]) {
+ [_delegate splitViewController:self willChangeSplitOrientationToVertical:_vertical];
+ }
+
+ [self layoutSubviews];
+ }
+}
+
+
+- (BOOL)isMasterBeforeDetail
+{
+ return _masterBeforeDetail;
+}
+
+
+- (void)setMasterBeforeDetail:(BOOL)flag
+{
+ if (flag != _masterBeforeDetail) {
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ _masterBeforeDetail = flag;
+
+ if ([self isShowingMaster]) {
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (float)splitPosition
+{
+ return _splitPosition;
+}
+
+
+- (void)setSplitPosition:(float)posn
+{
+ // Check to see if delegate wishes to constrain the position.
+ float newPosn = posn;
+ BOOL constrained = NO;
+ CGSize fullSize = [self splitViewSizeForOrientation:self.interfaceOrientation];
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:constrainSplitPosition:splitViewSize:)]) {
+ newPosn = [_delegate splitViewController:self constrainSplitPosition:newPosn splitViewSize:fullSize];
+ constrained = YES; // implicitly trust delegate's response.
+
+ } else {
+ // Apply default constraints if delegate doesn't wish to participate.
+ float minPos = MG_MIN_VIEW_WIDTH;
+ float maxPos = ((_vertical) ? fullSize.width : fullSize.height) - (MG_MIN_VIEW_WIDTH + _splitWidth);
+ constrained = (newPosn != _splitPosition && newPosn >= minPos && newPosn <= maxPos);
+ }
+
+ if (constrained) {
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ _splitPosition = newPosn;
+
+ // Inform delegate.
+ if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willMoveSplitToPosition:)]) {
+ [_delegate splitViewController:self willMoveSplitToPosition:_splitPosition];
+ }
+
+ if ([self isShowingMaster]) {
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (void)setSplitPosition:(float)posn animated:(BOOL)animate
+{
+ BOOL shouldAnimate = (animate && [self isShowingMaster]);
+ if (shouldAnimate) {
+ [UIView beginAnimations:@"SplitPosition" context:nil];
+ }
+ [self setSplitPosition:posn];
+ if (shouldAnimate) {
+ [UIView commitAnimations];
+ }
+}
+
+
+- (float)splitWidth
+{
+ return _splitWidth;
+}
+
+
+- (void)setSplitWidth:(float)width
+{
+ if (width != _splitWidth && width >= 0) {
+ _splitWidth = width;
+ if ([self isShowingMaster]) {
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (NSArray *)viewControllers
+{
+ return [[_viewControllers copy] autorelease];
+}
+
+
+- (void)setViewControllers:(NSArray *)controllers
+{
+ if (controllers != _viewControllers) {
+ for (UIViewController *controller in _viewControllers) {
+ if ([controller isKindOfClass:[UIViewController class]]) {
+ [controller.view removeFromSuperview];
+ }
+ }
+ [_viewControllers release];
+ _viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
+ if (controllers && [controllers count] >= 2) {
+ self.masterViewController = [controllers objectAtIndex:0];
+ self.detailViewController = [controllers objectAtIndex:1];
+ } else {
+ NSLog(@"Error: %@ requires 2 view-controllers. (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
+ }
+
+ [self layoutSubviews];
+ }
+}
+
+
+- (UIViewController *)masterViewController
+{
+ if (_viewControllers && [_viewControllers count] > 0) {
+ NSObject *controller = [_viewControllers objectAtIndex:0];
+ if ([controller isKindOfClass:[UIViewController class]]) {
+ return [[controller retain] autorelease];
+ }
+ }
+
+ return nil;
+}
+
+
+- (void)setMasterViewController:(UIViewController *)master
+{
+ if (!_viewControllers) {
+ _viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
+ }
+
+ NSObject *newMaster = master;
+ if (!newMaster) {
+ newMaster = [NSNull null];
+ }
+
+ BOOL changed = YES;
+ if ([_viewControllers count] > 0) {
+ if ([_viewControllers objectAtIndex:0] == newMaster) {
+ changed = NO;
+ } else {
+ [_viewControllers replaceObjectAtIndex:0 withObject:newMaster];
+ }
+
+ } else {
+ [_viewControllers addObject:newMaster];
+ }
+
+ if (changed) {
+ [self layoutSubviews];
+ }
+}
+
+
+- (UIViewController *)detailViewController
+{
+ if (_viewControllers && [_viewControllers count] > 1) {
+ NSObject *controller = [_viewControllers objectAtIndex:1];
+ if ([controller isKindOfClass:[UIViewController class]]) {
+ return [[controller retain] autorelease];
+ }
+ }
+
+ return nil;
+}
+
+
+- (void)setDetailViewController:(UIViewController *)detail
+{
+ if (!_viewControllers) {
+ _viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
+ [_viewControllers addObject:[NSNull null]];
+ }
+
+ BOOL changed = YES;
+ if ([_viewControllers count] > 1) {
+ if ([_viewControllers objectAtIndex:1] == detail) {
+ changed = NO;
+ } else {
+ [_viewControllers replaceObjectAtIndex:1 withObject:detail];
+ }
+
+ } else {
+ [_viewControllers addObject:detail];
+ }
+
+ if (changed) {
+ [self layoutSubviews];
+ }
+}
+
+
+- (MGSplitDividerView *)dividerView
+{
+ return [[_dividerView retain] autorelease];
+}
+
+
+- (void)setDividerView:(MGSplitDividerView *)divider
+{
+ if (divider != _dividerView) {
+ [_dividerView removeFromSuperview];
+ [_dividerView release];
+ _dividerView = [divider retain];
+ _dividerView.splitViewController = self;
+ _dividerView.backgroundColor = MG_DEFAULT_CORNER_COLOR;
+ if ([self isShowingMaster]) {
+ [self layoutSubviews];
+ }
+ }
+}
+
+
+- (BOOL)allowsDraggingDivider
+{
+ if (_dividerView) {
+ return _dividerView.allowsDragging;
+ }
+
+ return NO;
+}
+
+
+- (void)setAllowsDraggingDivider:(BOOL)flag
+{
+ if (self.allowsDraggingDivider != flag && _dividerView) {
+ _dividerView.allowsDragging = flag;
+ }
+}
+
+
+- (MGSplitViewDividerStyle)dividerStyle
+{
+ return _dividerStyle;
+}
+
+
+- (void)setDividerStyle:(MGSplitViewDividerStyle)newStyle
+{
+ if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
+ [_hiddenPopoverController dismissPopoverAnimated:NO];
+ }
+
+ // We don't check to see if newStyle equals _dividerStyle, because it's a meta-setting.
+ // Aspects could have been changed since it was set.
+ _dividerStyle = newStyle;
+
+ // Reconfigure general appearance and behaviour.
+ float cornerRadius;
+ if (_dividerStyle == MGSplitViewDividerStyleThin) {
+ cornerRadius = MG_DEFAULT_CORNER_RADIUS;
+ _splitWidth = MG_DEFAULT_SPLIT_WIDTH;
+ self.allowsDraggingDivider = NO;
+
+ } else if (_dividerStyle == MGSplitViewDividerStylePaneSplitter) {
+ cornerRadius = MG_PANESPLITTER_CORNER_RADIUS;
+ _splitWidth = MG_PANESPLITTER_SPLIT_WIDTH;
+ self.allowsDraggingDivider = YES;
+ }
+
+ // Update divider and corners.
+ [_dividerView setNeedsDisplay];
+ if (_cornerViews) {
+ for (MGSplitCornersView *corner in _cornerViews) {
+ corner.cornerRadius = cornerRadius;
+ }
+ }
+
+ // Layout all views.
+ [self layoutSubviews];
+}
+
+
+- (void)setDividerStyle:(MGSplitViewDividerStyle)newStyle animated:(BOOL)animate
+{
+ BOOL shouldAnimate = (animate && [self isShowingMaster]);
+ if (shouldAnimate) {
+ [UIView beginAnimations:@"DividerStyle" context:nil];
+ }
+ [self setDividerStyle:newStyle];
+ if (shouldAnimate) {
+ [UIView commitAnimations];
+ }
+}
+
+
+- (NSArray *)cornerViews
+{
+ if (_cornerViews) {
+ return [[_cornerViews retain] autorelease];
+ }
+
+ return nil;
+}
+
+
+ at synthesize showsMasterInPortrait;
+ at synthesize showsMasterInLandscape;
+ at synthesize vertical;
+ at synthesize delegate;
+ at synthesize viewControllers;
+ at synthesize masterViewController;
+ at synthesize detailViewController;
+ at synthesize dividerView;
+ at synthesize splitPosition;
+ at synthesize splitWidth;
+ at synthesize allowsDraggingDivider;
+ at synthesize dividerStyle;
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.h b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.h
new file mode 100755
index 0000000..b70a079
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.h
@@ -0,0 +1,22 @@
+//
+// MNEValueTrackingSlider
+//
+// Copyright 2012 Michael Neuwert
+// "You can use the code in your own project and modify it as you like."
+// http://blog.neuwert-media.com/2012/04/customized-uislider-with-visual-value-tracking/
+//
+
+
+#import <Foundation/Foundation.h>
+
+ at class SliderValuePopupView;
+
+ at interface MNEValueTrackingSlider : UISlider {
+ SliderValuePopupView *valuePopupView;
+ NSString *textValue;
+}
+
+ at property (nonatomic, readonly) CGRect thumbRect;
+ at property (nonatomic, retain) NSString *textValue;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m
new file mode 100755
index 0000000..48e9894
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MNEValueTrackingSlider.m
@@ -0,0 +1,200 @@
+//
+// MNEValueTrackingSlider
+//
+// Copyright 2012 Michael Neuwert
+// "You can use the code in your own project and modify it as you like."
+// http://blog.neuwert-media.com/2012/04/customized-uislider-with-visual-value-tracking/
+//
+
+
+#import "MNEValueTrackingSlider.h"
+
+#pragma mark -
+#pragma mark Private UIView subclass rendering the popup showing slider value
+ at interface SliderValuePopupView : UIView
+ at property (nonatomic, retain) UIFont *font;
+ at property (nonatomic, copy) NSString *text;
+ at property (nonatomic) float arrowOffset;
+ at end
+
+ at implementation SliderValuePopupView
+
+ at synthesize font = _font;
+ at synthesize text = _text;
+ at synthesize arrowOffset = _arrowOffset;
+
+-(id) initWithFrame:(CGRect) frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ self.font = [UIFont boldSystemFontOfSize:18];
+ }
+ return self;
+}
+
+-(void) dealloc {
+ self.text = nil;
+ self.font = nil;
+ [super dealloc];
+}
+
+-(void) drawRect:(CGRect) rect {
+ // Create the path for the rounded rectangle
+ CGRect roundedRect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, floorf(self.bounds.size.height * 0.8));
+ UIBezierPath *roundedRectPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:6.0];
+ roundedRectPath.lineWidth = 2.0f;
+
+ // Create the arrow path
+ UIBezierPath *arrowPath = [UIBezierPath bezierPath];
+ /*
+ // Make sure the arrow offset is nice
+ if (-self.arrowOffset + 1 > CGRectGetMidX(self.bounds) / 2)
+ self.arrowOffset = -CGRectGetMidX(self.bounds) / 2 + 1;
+ if (self.arrowOffset > CGRectGetMidX(self.bounds) / 2)
+ self.arrowOffset = CGRectGetMidX(self.bounds) / 2 -1;
+ */
+
+ CGFloat midX = CGRectGetMidX(self.bounds) + self.arrowOffset;
+ CGPoint p0 = CGPointMake(midX, CGRectGetMaxY(self.bounds));
+ [arrowPath moveToPoint:p0];
+ [arrowPath addLineToPoint:CGPointMake((midX - 10.0), CGRectGetMaxY(roundedRect))];
+ [arrowPath addLineToPoint:CGPointMake((midX + 10.0), CGRectGetMaxY(roundedRect))];
+ [arrowPath closePath];
+
+ // Attach the arrow path to the rounded rect
+ [roundedRectPath appendPath:arrowPath];
+
+ // Color various sections
+ [[UIColor blackColor] setFill];
+ [roundedRectPath fill];
+ [[UIColor whiteColor] setStroke];
+ [roundedRectPath stroke];
+ [[UIColor whiteColor] setFill];
+ [arrowPath fill];
+
+ // Draw the text
+ if (self.text) {
+ [[UIColor lightYellowColor] set];
+ CGSize s = [_text sizeWithFont:self.font];
+ CGFloat yOffset = (roundedRect.size.height - s.height) / 2;
+ CGRect textRect = CGRectMake(roundedRect.origin.x, yOffset, roundedRect.size.width, s.height);
+
+ [_text drawInRect:textRect
+ withFont:self.font
+ lineBreakMode:UILineBreakModeWordWrap
+ alignment:UITextAlignmentCenter];
+ }
+}
+
+ at end
+
+#pragma mark -
+#pragma mark MNEValueTrackingSlider implementations
+ at implementation MNEValueTrackingSlider
+
+ at synthesize thumbRect, textValue;
+
+#pragma mark Private methods
+
+-(void) _constructSlider {
+ valuePopupView = [[SliderValuePopupView alloc] initWithFrame:CGRectZero];
+ valuePopupView.backgroundColor = [UIColor clearColor];
+ valuePopupView.alpha = 0.0;
+ [self addSubview:valuePopupView];
+}
+
+-(void) _fadePopupViewInAndOut:(BOOL)aFadeIn {
+ [UIView beginAnimations:nil context:NULL];
+ [UIView setAnimationDuration:0.25];
+ if (aFadeIn) {
+ valuePopupView.alpha = 1.0;
+ } else {
+ valuePopupView.alpha = 0.0;
+ }
+ [UIView commitAnimations];
+}
+
+-(void) _positionAndUpdatePopupView {
+ CGRect _thumbRect = self.thumbRect;
+ CGRect popupRect = CGRectOffset(_thumbRect, 0, -floorf(_thumbRect.size.height * 1.5));
+ // (-100, -15) determines the size of the the rect
+ popupRect = CGRectInset(popupRect, -100, -15);
+
+ // this prevents drawing the popup outside the slider view
+ if (popupRect.origin.x < -self.frame.origin.x+5)
+ popupRect.origin.x = -self.frame.origin.x+5;
+ else if (popupRect.origin.x > self.superview.frame.size.width - popupRect.size.width - self.frame.origin.x - 5)
+ popupRect.origin.x = self.superview.frame.size.width - popupRect.size.width - self.frame.origin.x - 5;
+ //else if (CGRectGetMaxX(popupRect) > CGRectGetMaxX(self.superview.bounds))
+ // popupRect.origin.x = CGRectGetMaxX(self.superview.bounds) - CGRectGetWidth(popupRect) - 1.0;
+
+ valuePopupView.arrowOffset = CGRectGetMidX(_thumbRect) - CGRectGetMidX(popupRect);
+
+ valuePopupView.frame = popupRect;
+ valuePopupView.text = self.textValue;
+ [valuePopupView setNeedsDisplay];
+}
+
+#pragma mark Memory management
+
+-(id) initWithFrame:(CGRect) frame {
+ self = [super initWithFrame:frame];
+ if (self) {
+ [self _constructSlider];
+ }
+ return self;
+}
+
+-(id) initWithCoder:(NSCoder *)aDecoder {
+ self = [super initWithCoder:aDecoder];
+ if (self) {
+ [self _constructSlider];
+ }
+ return self;
+}
+
+-(void) dealloc {
+ [valuePopupView release];
+ [textValue release];
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark UIControl touch event tracking
+-(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ // Fade in and update the popup view
+ CGPoint touchPoint = [touch locationInView:self];
+ // Check if the knob is touched. Only in this case show the popup-view
+ if(CGRectContainsPoint(CGRectInset(self.thumbRect, -14.0, -12.0), touchPoint)) {
+ [self _positionAndUpdatePopupView];
+ [self _fadePopupViewInAndOut:YES];
+ }
+ return [super beginTrackingWithTouch:touch withEvent:event];
+}
+
+-(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ // Update the popup view as slider knob is being moved
+ [self _positionAndUpdatePopupView];
+ return [super continueTrackingWithTouch:touch withEvent:event];
+}
+
+-(void) cancelTrackingWithEvent:(UIEvent *)event {
+ [super cancelTrackingWithEvent:event];
+}
+
+-(void) endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
+ // Fade out the popoup view
+ [self _fadePopupViewInAndOut:NO];
+ [super endTrackingWithTouch:touch withEvent:event];
+}
+
+#pragma mark -
+#pragma mark Custom property accessors
+-(CGRect) thumbRect {
+ CGRect trackRect = [self trackRectForBounds:self.bounds];
+ CGRect thumbR = [self thumbRectForBounds:self.bounds
+ trackRect:trackRect
+ value:self.value];
+ return thumbR;
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.h b/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.h
new file mode 100644
index 0000000..ebb4ae0
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.h
@@ -0,0 +1,55 @@
+// MXAudioPlayerFadeOperation.h
+//
+// Created by Andrew Mackenzie-Ross on 30/11/10.
+// mackross.net
+//
+
+#import <Foundation/Foundation.h>
+
+ at class AVAudioPlayer;
+ at interface MXAudioPlayerFadeOperation : NSOperation {
+ AVAudioPlayer *_audioPlayer;
+ NSTimeInterval _fadeDuration;
+ NSTimeInterval _delay;
+ float _finishVolume;
+ BOOL _pauseAfterFade;
+ BOOL _stopAfterFade;
+ BOOL _playBeforeFade;
+}
+
+// The AVAudioPlayer that the volume fade will be applied to.
+// Retained until the fade is completed.
+// Must be set with init method.
+ at property (nonatomic, retain, readonly) AVAudioPlayer *audioPlayer;
+
+// The duration of the volume fade.
+// Default value is 1.0
+ at property (nonatomic, assign) NSTimeInterval fadeDuration;
+
+// The delay before the volume fade begins.
+// Default value is 0.0
+ at property (nonatomic, assign) NSTimeInterval delay;
+
+// The volume that will be faded to.
+// Default value is 0.0
+ at property (nonatomic, assign) float finishVolume;
+
+// If YES, audio player will be sent a pause message when the fade has completed.
+// Default value is NO, however, if finishVolume is 0.0, default is YES
+ at property (nonatomic, assign) BOOL pauseAfterFade;
+
+// If YES, when the fade has completed the audio player will be sent a stop message.
+// Default value is NO.
+ at property (nonatomic, assign) BOOL stopAfterFade;
+
+// If YES, audio player will be sent a play message after the delay.
+// Default value is YES.
+ at property (nonatomic, assign) BOOL playBeforeFade;
+
+// Init Methods
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay;
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration;
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume;
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m b/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m
new file mode 100644
index 0000000..5c5783e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MXAudioPlayerFadeOperation.m
@@ -0,0 +1,133 @@
+// MXAudioPlayerFadeOperation.m
+//
+// Created by Andrew Mackenzie-Ross on 30/11/10.
+// mackross.net.
+//
+
+#import "MXAudioPlayerFadeOperation.h"
+#import <AVFoundation/AVFoundation.h>
+
+#define SKVolumeChangesPerSecond 15
+
+ at interface MXAudioPlayerFadeOperation ()
+ at property (nonatomic, retain, readwrite) AVAudioPlayer *audioPlayer;
+- (void)beginFadeOperation;
+- (void)finishFadeOperation;
+ at end
+
+ at implementation MXAudioPlayerFadeOperation
+#pragma mark -
+#pragma mark Properties
+ at synthesize audioPlayer = _audioPlayer;
+ at synthesize fadeDuration = _fadeDuration;
+ at synthesize finishVolume = _finishVolume;
+ at synthesize playBeforeFade = _playBeforeFade;
+ at synthesize pauseAfterFade = _pauseAfterFade;
+ at synthesize stopAfterFade = _stopAfterFade;
+ at synthesize delay = _delay;
+
+#pragma mark -
+#pragma mark Accessors
+- (AVAudioPlayer *)audioPlayer {
+ AVAudioPlayer *result;
+ @synchronized(self) {
+ result = [_audioPlayer retain];
+ }
+ return [result autorelease];
+}
+
+- (void)setAudioPlayer:(AVAudioPlayer *)anAudioPlayer {
+ @synchronized(self) {
+ if (_audioPlayer != anAudioPlayer) {
+ [_audioPlayer release];
+ _audioPlayer = [anAudioPlayer retain];
+ }
+ }
+}
+
+#pragma mark -
+#pragma mark NSOperation
+-(id) initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration withDelay:(NSTimeInterval)timeDelay {
+ if ((self = [super init])) {
+ self.audioPlayer = player;
+ [player prepareToPlay];
+ _fadeDuration = duration;
+ _finishVolume = volume;
+ _playBeforeFade = YES;
+ _stopAfterFade = NO;
+ _pauseAfterFade = (volume == 0.0) ? YES : NO;
+ _delay = timeDelay;
+ }
+ return self;
+}
+
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume overDuration:(NSTimeInterval)duration {
+ return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:duration withDelay:0.0];
+}
+
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player toVolume:(float)volume {
+ return [self initFadeWithAudioPlayer:player toVolume:volume overDuration:1.0];
+}
+
+- (id)initFadeWithAudioPlayer:(AVAudioPlayer*)player {
+ return [self initFadeWithAudioPlayer:player toVolume:0.0];
+}
+
+- (id) init {
+ ALog(@"Failed to init class (%@) with AVAudioPlayer instance, use initFadeWithAudioPlayer:",[self class]);
+ return nil;
+}
+
+- (void)main {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSThread sleepForTimeInterval:_delay];
+ if ([self.audioPlayer isKindOfClass:[AVAudioPlayer class]]) {
+ [self beginFadeOperation];
+ }
+ else {
+ ALog(@"AudioPlayerFadeOperation began with invalid AVAudioPlayer");
+ }
+
+ [pool release];
+}
+
+- (void)beginFadeOperation {
+ if (![self.audioPlayer isPlaying] && _playBeforeFade) [self.audioPlayer play];
+
+ if (_fadeDuration != 0.0) {
+
+ NSTimeInterval sleepInterval = (1.0 / SKVolumeChangesPerSecond);
+ NSTimeInterval startTime = [[NSDate date] timeIntervalSinceReferenceDate];
+ NSTimeInterval now = startTime;
+
+ float startVolume = [self.audioPlayer volume];
+
+ while (now < (startTime + _fadeDuration)) {
+ float ratioOfFadeCompleted = (now - startTime)/_fadeDuration;
+ float volume = (_finishVolume * ratioOfFadeCompleted) + (startVolume * (1-ratioOfFadeCompleted));
+ [self.audioPlayer setVolume:volume];
+ [NSThread sleepForTimeInterval:sleepInterval];
+ now = [[NSDate date] timeIntervalSinceReferenceDate];
+ }
+
+ [self.audioPlayer setVolume:_finishVolume];
+ [self finishFadeOperation];
+ }
+ else {
+ [self.audioPlayer setVolume:_finishVolume];
+ [self finishFadeOperation];
+ }
+}
+
+- (void)finishFadeOperation {
+ if ([self.audioPlayer isPlaying] && _pauseAfterFade) [self.audioPlayer pause];
+ if ([self.audioPlayer isPlaying] && _stopAfterFade) [self.audioPlayer stop];
+}
+
+- (void)dealloc {
+ releaseAndNil(_audioPlayer);
+ [super dealloc];
+}
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPad.xib b/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPad.xib
new file mode 100644
index 0000000..fc49897
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPad.xib
@@ -0,0 +1,719 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">294</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="976741091">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{1024, 768}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">background.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="867308721">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{383, 389}, {271, 244}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="917635782">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <double key="IBUITitleEdgeInsets.top">215</double>
+ <double key="IBUITitleEdgeInsets.bottom">0.0</double>
+ <double key="IBUITitleEdgeInsets.left">0.0</double>
+ <double key="IBUITitleEdgeInsets.right">0.0</double>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="918890028">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">2</int>
+ <bytes key="NSRGB">MC45OTYwNzg0OTEyIDAuODAwMDAwMDcxNSAwLjAzOTIxNTY4NzY2AA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="112471976">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">localplayButton~ipad.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="95106947">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{986, 19}, {18, 19}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <float key="IBUIAlpha">0.31690141558647156</float>
+ <int key="IBUITag">3</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">3</int>
+ <bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ <object class="IBUIButton" id="898948205">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">265</int>
+ <string key="NSFrame">{{940, 686}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">2</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">settingsButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="894101036">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 686}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">4</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">savesButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIImageView" id="1019880682">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{242, 43}, {540, 300}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">title~ipad.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="357438048">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{565, 686}, {89, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">5</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Missions</string>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ <object class="IBUIButton" id="719094980">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{383, 686}, {89, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">6</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Simple</string>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{1024, 768}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAAA</bytes>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="95106947"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">47</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="867308721"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">48</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="898948205"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">54</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="894101036"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">89</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="357438048"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">92</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="719094980"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">94</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="976741091"/>
+ <reference ref="867308721"/>
+ <reference ref="898948205"/>
+ <reference ref="894101036"/>
+ <reference ref="1019880682"/>
+ <reference ref="95106947"/>
+ <reference ref="357438048"/>
+ <reference ref="719094980"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">39</int>
+ <reference key="object" ref="867308721"/>
+ <reference key="parent" ref="191373211"/>
+ <string key="objectName">local</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">45</int>
+ <reference key="object" ref="95106947"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">52</int>
+ <reference key="object" ref="898948205"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">37</int>
+ <reference key="object" ref="976741091"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">88</int>
+ <reference key="object" ref="894101036"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">90</int>
+ <reference key="object" ref="1019880682"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">91</int>
+ <reference key="object" ref="357438048"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">93</int>
+ <reference key="object" ref="719094980"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>37.IBPluginDependency</string>
+ <string>39.IBPluginDependency</string>
+ <string>45.IBPluginDependency</string>
+ <string>45.IBViewBoundsToFrameTransform</string>
+ <string>52.IBPluginDependency</string>
+ <string>52.IBViewBoundsToFrameTransform</string>
+ <string>88.IBPluginDependency</string>
+ <string>88.IBViewBoundsToFrameTransform</string>
+ <string>90.IBPluginDependency</string>
+ <string>90.IBViewBoundsToFrameTransform</string>
+ <string>91.IBPluginDependency</string>
+ <string>91.IBViewBoundsToFrameTransform</string>
+ <string>93.IBPluginDependency</string>
+ <string>93.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MainMenuViewController</string>
+ <string>UIResponder</string>
+ <string>{{89, 260}, {1024, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABERsAAw6cAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABEaQAAxDsAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBoAAAxDsAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDbQAAw6qAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABD6gAAxDRAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDuYAAxDRAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">94</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MainMenuViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">switchViews:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">switchViews:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">switchViews:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MainMenuViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="864669175">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="864669175"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>background.png</string>
+ <string>localplayButton~ipad.png</string>
+ <string>savesButton.png</string>
+ <string>settingsButton.png</string>
+ <string>title~ipad.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{1024, 768}</string>
+ <string>{263, 244}</string>
+ <string>{64, 64}</string>
+ <string>{64, 64}</string>
+ <string>{540, 300}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPhone.xib b/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPhone.xib
new file mode 100644
index 0000000..dc78c9a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MainMenuViewController-iPhone.xib
@@ -0,0 +1,734 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="48"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">293</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="249993817">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ <int key="IBUIContentMode">4</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">background~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUIImageView" id="171108356">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">293</int>
+ <string key="NSFrame">{{105, 20}, {270, 150}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <int key="IBUIContentMode">4</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">title~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="124270424">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">289</int>
+ <string key="NSFrame">{{190, 200}, {100, 100}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="917635782">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="918890028">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="112471976">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">localplayButton~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="753723574">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{396, 236}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <int key="IBUITag">2</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">settingsButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="705508539">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{20, 236}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <int key="IBUITag">4</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">savesButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="818907840">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{20, 19}, {18, 19}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <float key="IBUIAlpha">0.5</float>
+ <int key="IBUITag">3</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">3</int>
+ <bool key="IBUIShowsTouchWhenHighlighted">YES</bool>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ <object class="IBUIButton" id="629390161">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{439, 13}, {29, 31}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">5</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">2</int>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ <object class="IBUIButton" id="274540289">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{439, 68}, {29, 31}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">6</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="917635782"/>
+ <int key="IBUIButtonType">2</int>
+ <reference key="IBUIHighlightedTitleColor" ref="918890028"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="112471976"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAAA</bytes>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="753723574"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">30</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="124270424"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">40</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="818907840"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">42</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="705508539"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">44</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="629390161"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">47</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">switchViews:</string>
+ <reference key="source" ref="274540289"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">49</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="249993817"/>
+ <reference ref="818907840"/>
+ <reference ref="171108356"/>
+ <reference ref="705508539"/>
+ <reference ref="753723574"/>
+ <reference ref="124270424"/>
+ <reference ref="629390161"/>
+ <reference ref="274540289"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="171108356"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">22</int>
+ <reference key="object" ref="249993817"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">41</int>
+ <reference key="object" ref="818907840"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">43</int>
+ <reference key="object" ref="705508539"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">24</int>
+ <reference key="object" ref="124270424"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">28</int>
+ <reference key="object" ref="753723574"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">46</int>
+ <reference key="object" ref="629390161"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">48</int>
+ <reference key="object" ref="274540289"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>22.IBPluginDependency</string>
+ <string>22.IBViewBoundsToFrameTransform</string>
+ <string>23.IBPluginDependency</string>
+ <string>23.IBViewBoundsToFrameTransform</string>
+ <string>24.IBPluginDependency</string>
+ <string>24.IBViewBoundsToFrameTransform</string>
+ <string>28.IBPluginDependency</string>
+ <string>28.IBViewBoundsToFrameTransform</string>
+ <string>41.IBPluginDependency</string>
+ <string>41.IBViewBoundsToFrameTransform</string>
+ <string>43.IBPluginDependency</string>
+ <string>43.IBViewBoundsToFrameTransform</string>
+ <string>46.IBPluginDependency</string>
+ <string>46.IBViewBoundsToFrameTransform</string>
+ <string>48.IBPluginDependency</string>
+ <string>48.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MainMenuViewController</string>
+ <string>UIResponder</string>
+ <string>{{517, 519}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw5UAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABCygAAwzcAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDPgAAw5UAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDxgAAw5iAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBcAAAwhAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw5iAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUPbgABBUAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABD3gAAwjwAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">49</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MainMenuViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">switchViews:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">switchViews:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">switchViews:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MainMenuViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="238583711">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="238583711"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>background~iphone.png</string>
+ <string>localplayButton~iphone.png</string>
+ <string>savesButton.png</string>
+ <string>settingsButton.png</string>
+ <string>title~iphone.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{480, 320}</string>
+ <string>{100, 100}</string>
+ <string>{64, 64}</string>
+ <string>{64, 64}</string>
+ <string>{270, 150}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MainMenuViewController.h b/project_files/HedgewarsMobile/Classes/MainMenuViewController.h
new file mode 100644
index 0000000..0016365
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MainMenuViewController.h
@@ -0,0 +1,48 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class GameConfigViewController;
+ at class SettingsContainerViewController;
+ at class AboutViewController;
+ at class SavedGamesViewController;
+ at class RestoreViewController;
+ at class MissionTrainingViewController;
+
+ at interface MainMenuViewController : UIViewController <UIAlertViewDelegate> {
+ GameConfigViewController *gameConfigViewController;
+ SettingsContainerViewController *settingsViewController;
+ AboutViewController *aboutViewController;
+ SavedGamesViewController *savedGamesViewController;
+ RestoreViewController *restoreViewController;
+ MissionTrainingViewController *missionsViewController;
+}
+
+ at property (nonatomic,retain) GameConfigViewController *gameConfigViewController;
+ at property (nonatomic,retain) SettingsContainerViewController *settingsViewController;
+ at property (nonatomic,retain) AboutViewController *aboutViewController;
+ at property (nonatomic,retain) SavedGamesViewController *savedGamesViewController;
+ at property (nonatomic,retain) RestoreViewController *restoreViewController;
+ at property (nonatomic,retain) MissionTrainingViewController *missionsViewController;
+
+-(IBAction) switchViews:(id)sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MainMenuViewController.m b/project_files/HedgewarsMobile/Classes/MainMenuViewController.m
new file mode 100644
index 0000000..863ee86
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MainMenuViewController.m
@@ -0,0 +1,244 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "MainMenuViewController.h"
+#import <QuartzCore/QuartzCore.h>
+#import "GameConfigViewController.h"
+#import "SettingsContainerViewController.h"
+#import "AboutViewController.h"
+#import "SavedGamesViewController.h"
+#import "RestoreViewController.h"
+#import "MissionTrainingViewController.h"
+#import "Appirater.h"
+#import "ServerProtocolNetwork.h"
+#import "GameInterfaceBridge.h"
+
+
+ at implementation MainMenuViewController
+ at synthesize gameConfigViewController, settingsViewController, aboutViewController, savedGamesViewController,
+ restoreViewController, missionsViewController;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+-(void) viewDidLoad {
+ self.view.frame = [[UIScreen mainScreen] safeBounds];
+ [super viewDidLoad];
+
+ // get the app's version
+ NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
+
+ // get the version number that we've been tracking
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ NSString *trackingVersion = [userDefaults stringForKey:@"HedgeVersion"];
+
+ if (trackingVersion == nil || [trackingVersion isEqualToString:version] == NO) {
+ // remove any reminder of previous games as saves are going to be wiped out
+ [userDefaults setObject:@"" forKey:@"savedGamePath"];
+ // update the tracking version with the new one
+ [userDefaults setObject:version forKey:@"HedgeVersion"];
+ [userDefaults synchronize];
+
+ [CreationChamber createFirstLaunch];
+ }
+
+ // prompt for restoring any previous game
+ NSString *saveString = [userDefaults objectForKey:@"savedGamePath"];
+ if (saveString != nil && [saveString isEqualToString:@""] == NO && [[userDefaults objectForKey:@"saveIsValid"] boolValue]) {
+ if (self.restoreViewController == nil) {
+ NSString *xibName = [@"RestoreViewController-" stringByAppendingString:(IS_IPAD() ? @"iPad" : @"iPhone")];
+ RestoreViewController *restored = [[RestoreViewController alloc] initWithNibName:xibName bundle:nil];
+ if ([restored respondsToSelector:@selector(setModalPresentationStyle:)])
+ restored.modalPresentationStyle = UIModalPresentationFormSheet;
+ self.restoreViewController = restored;
+ [restored release];
+ }
+ [self performSelector:@selector(presentModalViewController:animated:) withObject:self.restoreViewController afterDelay:0.25];
+ } else {
+ // let's not prompt for rating when app crashed >_>
+ [Appirater appLaunched];
+ }
+
+ /*
+ [ServerProtocolNetwork openServerConnection];
+ */
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [[AudioManagerController mainManager] playBackgroundMusic];
+ [super viewWillAppear:animated];
+}
+
+#pragma mark -
+-(IBAction) switchViews:(id) sender {
+ UIButton *button = (UIButton *)sender;
+ UIAlertView *alert;
+ NSString *xib = nil;
+ NSString *debugStr = nil;
+
+ [[AudioManagerController mainManager] playClickSound];
+ switch (button.tag) {
+ case 0:
+ if (nil == self.gameConfigViewController) {
+ xib = IS_IPAD() ? @"GameConfigViewController-iPad" : @"GameConfigViewController-iPhone";
+
+ GameConfigViewController *gcvc = [[GameConfigViewController alloc] initWithNibName:xib bundle:nil];
+ gcvc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
+ self.gameConfigViewController = gcvc;
+ [gcvc release];
+ }
+ [self presentModalViewController:self.gameConfigViewController animated:YES];
+ break;
+ case 2:
+ if (nil == self.settingsViewController) {
+ SettingsContainerViewController *svrc = [[SettingsContainerViewController alloc] initWithNibName:nil bundle:nil];
+ svrc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
+ self.settingsViewController = svrc;
+ [svrc release];
+ }
+ [self presentModalViewController:self.settingsViewController animated:YES];
+ break;
+ case 3:
+#ifdef DEBUG
+ if ([[NSFileManager defaultManager] fileExistsAtPath:DEBUG_FILE()])
+ debugStr = [[NSString alloc] initWithContentsOfFile:DEBUG_FILE()];
+ else
+ debugStr = [[NSString alloc] initWithString:@"Here be log"];
+ UITextView *scroll = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.width)];
+ scroll.text = debugStr;
+ [debugStr release];
+ scroll.editable = NO;
+ scroll.alpha = 0;
+
+ UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
+ [btn addTarget:scroll action:@selector(removeFromSuperview) forControlEvents:UIControlEventTouchUpInside];
+ [btn addTarget:btn action:@selector(removeFromSuperview) forControlEvents:UIControlEventTouchUpInside];
+ btn.frame = CGRectMake(self.view.frame.size.height-58, -6, 64, 64);
+ btn.backgroundColor = [UIColor blackColor];
+ btn.titleLabel.textColor = [UIColor whiteColor];
+ btn.titleLabel.textAlignment = UITextAlignmentCenter;
+ btn.titleLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
+ [btn setTitle:@"Close" forState:UIControlStateNormal];
+ btn.alpha = 0;
+ [btn.layer setCornerRadius:10.0f];
+ [btn.layer setMasksToBounds:YES];
+
+ [self.view addSubview:scroll];
+ [self.view addSubview:btn];
+
+ [UIView beginAnimations:@"fadein" context:NULL];
+ [UIView setAnimationDuration:0.25f];
+ btn.alpha = 1;
+ scroll.alpha = 1;
+ [UIView commitAnimations];
+ [scroll release];
+#else
+ debugStr = debugStr; // prevent compiler warning
+ if (nil == self.aboutViewController) {
+ AboutViewController *about = [[AboutViewController alloc] initWithNibName:@"AboutViewController" bundle:nil];
+ about.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
+ if ([about respondsToSelector:@selector(setModalPresentationStyle:)])
+ about.modalPresentationStyle = UIModalPresentationFormSheet;
+ self.aboutViewController = about;
+ [about release];
+ }
+ [self presentModalViewController:self.aboutViewController animated:YES];
+#endif
+ break;
+ case 4:
+ if (nil == self.savedGamesViewController) {
+ SavedGamesViewController *savedgames = [[SavedGamesViewController alloc] initWithNibName:@"SavedGamesViewController" bundle:nil];
+ savedgames.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
+ if ([savedgames respondsToSelector:@selector(setModalPresentationStyle:)])
+ savedgames.modalPresentationStyle = UIModalPresentationPageSheet;
+ self.savedGamesViewController = savedgames;
+ [savedgames release];
+ }
+ [self presentModalViewController:self.savedGamesViewController animated:YES];
+ break;
+ case 5:
+ if (nil == self.missionsViewController) {
+ xib = IS_IPAD() ? @"MissionTrainingViewController-iPad" : @"MissionTrainingViewController-iPhone";
+ MissionTrainingViewController *missions = [[MissionTrainingViewController alloc] initWithNibName:xib bundle:nil];
+ missions.modalTransitionStyle = IS_IPAD() ? UIModalTransitionStyleCoverVertical : UIModalTransitionStyleCrossDissolve;
+ if ([missions respondsToSelector:@selector(setModalPresentationStyle:)])
+ missions.modalPresentationStyle = UIModalPresentationPageSheet;
+ self.missionsViewController = missions;
+ [missions release];
+ }
+ [self presentModalViewController:self.missionsViewController animated:YES];
+ break;
+ case 6:
+ [GameInterfaceBridge registerCallingController:self];
+ [GameInterfaceBridge startSimpleGame];
+ break;
+ default:
+ alert = [[UIAlertView alloc] initWithTitle:@"Not Yet Implemented"
+ message:@"Sorry, this feature is not yet implemented"
+ delegate:nil
+ cancelButtonTitle:@"Well, don't worry"
+ otherButtonTitles:nil];
+ [alert show];
+ [alert release];
+ break;
+ }
+}
+
+#pragma mark -
+-(void) viewDidUnload {
+ self.gameConfigViewController = nil;
+ self.settingsViewController = nil;
+ self.aboutViewController = nil;
+ self.savedGamesViewController = nil;
+ self.restoreViewController = nil;
+ self.missionsViewController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) didReceiveMemoryWarning {
+ if (self.settingsViewController.view.superview == nil)
+ self.settingsViewController = nil;
+ if (self.gameConfigViewController.view.superview == nil)
+ self.gameConfigViewController = nil;
+ if (self.aboutViewController.view.superview == nil)
+ self.aboutViewController = nil;
+ if (self.savedGamesViewController.view.superview == nil)
+ self.savedGamesViewController = nil;
+ if (self.restoreViewController.view.superview == nil)
+ self.restoreViewController = nil;
+ if (self.missionsViewController.view.superview == nil)
+ self.missionsViewController = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) dealloc {
+ releaseAndNil(settingsViewController);
+ releaseAndNil(gameConfigViewController);
+ releaseAndNil(aboutViewController);
+ releaseAndNil(savedGamesViewController);
+ releaseAndNil(restoreViewController);
+ releaseAndNil(missionsViewController);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPad.xib b/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPad.xib
new file mode 100644
index 0000000..b6ed5da
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPad.xib
@@ -0,0 +1,744 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUISegmentedControl" id="88728219">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">261</int>
+ <string key="NSFrame">{{20, 166}, {280, 30}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBSegmentControlStyle">2</int>
+ <int key="IBNumberOfSegments">4</int>
+ <int key="IBSelectedSegmentIndex">1</int>
+ <object class="NSArray" key="IBSegmentTitles">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Random</string>
+ <string>Map</string>
+ <string>Maze</string>
+ <string>Mission</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentWidths">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentEnabledStates">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentContentOffsets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentImages">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSNull" id="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ </object>
+ <object class="NSColor" key="IBTintColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="IBUITableView" id="394383001">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 214}, {320, 554}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor" id="959670140">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIMultipleTouchEnabled">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <bool key="IBUIShowsHorizontalScrollIndicator">NO</bool>
+ <int key="IBUIIndicatorStyle">2</int>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ </object>
+ <object class="IBUIButton" id="426759828">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{32, 32}, {256, 128}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedTitleColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{320, 768}</string>
+ <reference key="NSSuperview"/>
+ <reference key="IBUIBackgroundColor" ref="959670140"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">segmentedControl</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="88728219"/>
+ </object>
+ <int key="connectionID">21</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">segmentedControlChanged:</string>
+ <reference key="source" ref="88728219"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="394383001"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">67</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="394383001"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">68</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="394383001"/>
+ </object>
+ <int key="connectionID">69</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">previewButton</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="426759828"/>
+ </object>
+ <int key="connectionID">128</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">mapButtonPressed:</string>
+ <reference key="source" ref="426759828"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">129</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="426759828"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">130</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="394383001"/>
+ <reference ref="88728219"/>
+ <reference ref="426759828"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">66</int>
+ <reference key="object" ref="394383001"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="88728219"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">127</int>
+ <reference key="object" ref="426759828"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>127.CustomClassName</string>
+ <string>127.IBPluginDependency</string>
+ <string>127.IBViewBoundsToFrameTransform</string>
+ <string>66.IBPluginDependency</string>
+ <string>66.IBViewBoundsToFrameTransform</string>
+ <string>7.IBPluginDependency</string>
+ <string>7.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MapConfigViewController</string>
+ <string>UIResponder</string>
+ <string>{{289, 181}, {320, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>MapPreviewButtonView</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUIAAABB0AAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABEMAAAxCmAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBoAAAw0IAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">130</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">mapButtonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentedControlChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderEndedChanging:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>MapPreviewButtonView</string>
+ <string>UISegmentedControl</string>
+ <string>ValueTrackingSliderView</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">maxLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewButton</string>
+ <string key="candidateClassName">MapPreviewButtonView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">segmentedControl</string>
+ <string key="candidateClassName">UISegmentedControl</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">slider</string>
+ <string key="candidateClassName">ValueTrackingSliderView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapPreviewButtonView</string>
+ <string key="superclassName">UIButton</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">delegate</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">delegate</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">delegate</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapPreviewButtonView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="823133985">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="823133985"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">ValueTrackingSliderView</string>
+ <string key="superclassName">UISlider</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MNEValueTrackingSlider.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="567455553">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="567455553"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISegmentedControl</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISlider</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPhone.xib b/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPhone.xib
new file mode 100644
index 0000000..ef2a428
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController-iPhone.xib
@@ -0,0 +1,885 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="574494641">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrameSize">{480, 276}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">background~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUISegmentedControl" id="88728219">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{9, 14}, {270, 30}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBSegmentControlStyle">2</int>
+ <int key="IBNumberOfSegments">4</int>
+ <int key="IBSelectedSegmentIndex">1</int>
+ <object class="NSArray" key="IBSegmentTitles">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Random</string>
+ <string>Map</string>
+ <string>Maze</string>
+ <string>Mission</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentWidths">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ <real value="0.0"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentEnabledStates">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ <boolean value="YES"/>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentContentOffsets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ <string>{0, 0}</string>
+ </object>
+ <object class="NSMutableArray" key="IBSegmentImages">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSNull" id="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ <reference ref="4"/>
+ </object>
+ <object class="NSColor" key="IBTintColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="IBUILabel" id="634417433">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{71, 196}, {145, 44}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">Loading...</string>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">17</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">2</int>
+ <bytes key="NSRGB">MC45NDExNzY1MzM3IDAuODE1Njg2MzQ1MSAwAA</bytes>
+ </object>
+ <nil key="IBUIHighlightedColor"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUIButton" id="326163764">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{16, 58}, {256, 128}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="437070330">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ <object class="IBUITableView" id="565214171">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{284, 0}, {196, 276}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIBouncesZoom">NO</bool>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ <object class="IBUISlider" id="938256702">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{52, 239}, {184, 23}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <float key="IBUIValue">0.05000000074505806</float>
+ <float key="IBUIMaxValue">0.05000000074505806</float>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 276}</string>
+ <reference key="NSSuperview"/>
+ <reference key="IBUIBackgroundColor" ref="437070330"/>
+ <object class="IBUISimulatedToolbarMetrics" key="IBUISimulatedBottomBarMetrics"/>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">previewButton</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="326163764"/>
+ </object>
+ <int key="connectionID">13</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">maxLabel</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="634417433"/>
+ </object>
+ <int key="connectionID">16</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">sliderChanged:</string>
+ <reference key="source" ref="938256702"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">19</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">sliderEndedChanging:</string>
+ <reference key="source" ref="938256702"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">20</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">segmentedControl</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="88728219"/>
+ </object>
+ <int key="connectionID">21</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">segmentedControlChanged:</string>
+ <reference key="source" ref="88728219"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="565214171"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">26</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="565214171"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">27</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="565214171"/>
+ </object>
+ <int key="connectionID">32</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="326163764"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">34</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">mapButtonPressed:</string>
+ <reference key="source" ref="326163764"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">37</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">slider</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="938256702"/>
+ </object>
+ <int key="connectionID">38</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="326163764"/>
+ <reference ref="565214171"/>
+ <reference ref="574494641"/>
+ <reference ref="88728219"/>
+ <reference ref="634417433"/>
+ <reference ref="938256702"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="88728219"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="326163764"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">25</int>
+ <reference key="object" ref="565214171"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="191373211"/>
+ <string key="objectName">Table View (Themes)</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">35</int>
+ <reference key="object" ref="574494641"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">11</int>
+ <reference key="object" ref="634417433"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="938256702"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>11.IBPluginDependency</string>
+ <string>11.IBViewBoundsToFrameTransform</string>
+ <string>25.IBPluginDependency</string>
+ <string>25.IBViewBoundsToFrameTransform</string>
+ <string>35.IBPluginDependency</string>
+ <string>35.IBViewBoundsToFrameTransform</string>
+ <string>7.IBPluginDependency</string>
+ <string>7.IBViewBoundsToFrameTransform</string>
+ <string>8.CustomClassName</string>
+ <string>8.IBPluginDependency</string>
+ <string>8.IBViewBoundsToFrameTransform</string>
+ <string>9.CustomClassName</string>
+ <string>9.IBPluginDependency</string>
+ <string>9.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MapConfigViewController</string>
+ <string>UIResponder</string>
+ <string>{{790, 298}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUKOAABDRAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDjgAAw4kAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAAAAAAAAw4kAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBUAAAwigAAA</bytes>
+ </object>
+ <string>MNEValueTrackingSlider</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABCWAAAw4IAAA</bytes>
+ </object>
+ <string>MapPreviewButtonView</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBgAAAwzgAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">38</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MNEValueTrackingSlider</string>
+ <string key="superclassName">UISlider</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MNEValueTrackingSlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapConfigViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>mapButtonPressed:</string>
+ <string>segmentedControlChanged:</string>
+ <string>sliderChanged:</string>
+ <string>sliderEndedChanging:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">mapButtonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">segmentedControlChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderChanged:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">sliderEndedChanging:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>MapPreviewButtonView</string>
+ <string>UISegmentedControl</string>
+ <string>MNEValueTrackingSlider</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>maxLabel</string>
+ <string>previewButton</string>
+ <string>segmentedControl</string>
+ <string>slider</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">maxLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewButton</string>
+ <string key="candidateClassName">MapPreviewButtonView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">segmentedControl</string>
+ <string key="candidateClassName">UISegmentedControl</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">slider</string>
+ <string key="candidateClassName">MNEValueTrackingSlider</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapConfigViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MapPreviewButtonView</string>
+ <string key="superclassName">UIButton</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">delegate</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">delegate</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">delegate</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MapPreviewButtonView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="67684033">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <reference key="sourceIdentifier" ref="67684033"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="67684033"/>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="567455553">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="567455553"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISegmentedControl</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISegmentedControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISlider</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISlider.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="NS.key.0">background~iphone.png</string>
+ <string key="NS.object.0">{480, 320}</string>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MapConfigViewController.h b/project_files/HedgewarsMobile/Classes/MapConfigViewController.h
new file mode 100644
index 0000000..1d9da3b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController.h
@@ -0,0 +1,85 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "MapPreviewButtonView.h"
+#import "MNEValueTrackingSlider.h"
+
+
+ at interface MapConfigViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, MapPreviewViewDelegate> {
+ NSInteger oldValue; // for the slider
+ NSInteger oldPage; // for the segmented control
+ BOOL busy; // for the preview button
+
+ // objects read (mostly) by parent view
+ NSInteger maxHogs;
+ NSString *seedCommand;
+ NSString *templateFilterCommand;
+ NSString *mapGenCommand;
+ NSString *mazeSizeCommand;
+ NSString *themeCommand;
+ NSString *staticMapCommand;
+ NSString *missionCommand;
+
+ // various widgets in the view
+ MapPreviewButtonView *previewButton;
+ UITableView *tableView;
+ UILabel *maxLabel;
+ UISegmentedControl *segmentedControl;
+ MNEValueTrackingSlider *slider;
+
+ // internal objects
+ NSIndexPath *lastIndexPath;
+ NSArray *dataSourceArray;
+}
+
+
+ at property (nonatomic,assign) NSInteger oldValue;
+ at property (nonatomic,assign) NSInteger oldPage;
+ at property (nonatomic,assign) BOOL busy;
+ at property (nonatomic,assign) NSInteger maxHogs;
+ at property (nonatomic,retain) NSString *seedCommand;
+ at property (nonatomic,retain) NSString *templateFilterCommand;
+ at property (nonatomic,retain) NSString *mapGenCommand;
+ at property (nonatomic,retain) NSString *mazeSizeCommand;
+ at property (nonatomic,retain) NSString *themeCommand;
+ at property (nonatomic,retain) NSString *staticMapCommand;
+ at property (nonatomic,retain) NSString *missionCommand;
+
+ at property (nonatomic,retain) IBOutlet MapPreviewButtonView *previewButton;
+ at property (nonatomic,retain) IBOutlet UITableView *tableView;
+ at property (nonatomic,retain) IBOutlet UILabel *maxLabel;
+ at property (nonatomic,retain) IBOutlet UISegmentedControl *segmentedControl;
+ at property (nonatomic,retain) IBOutlet MNEValueTrackingSlider *slider;
+
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+ at property (nonatomic,retain) NSArray *dataSourceArray;
+
+
+-(IBAction) mapButtonPressed:(id) sender;
+-(IBAction) sliderChanged:(id) sender;
+-(IBAction) sliderEndedChanging:(id) sender;
+-(IBAction) segmentedControlChanged:(id) sender;
+
+-(void) turnOnWidgets;
+-(void) turnOffWidgets;
+-(void) setMaxLabelText:(NSString *)str;
+-(void) updatePreview;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MapConfigViewController.m b/project_files/HedgewarsMobile/Classes/MapConfigViewController.m
new file mode 100644
index 0000000..6dd8103
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapConfigViewController.m
@@ -0,0 +1,503 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "MapConfigViewController.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+#define scIndex self.segmentedControl.selectedSegmentIndex
+#define isRandomness() (segmentedControl.selectedSegmentIndex == 0 || segmentedControl.selectedSegmentIndex == 2)
+
+ at implementation MapConfigViewController
+ at synthesize previewButton, maxHogs, seedCommand, templateFilterCommand, mapGenCommand, mazeSizeCommand, themeCommand, staticMapCommand,
+ missionCommand, tableView, maxLabel, segmentedControl, slider, lastIndexPath, dataSourceArray, busy,
+ oldPage, oldValue;
+
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(IBAction) mapButtonPressed:(id) sender {
+ [[AudioManagerController mainManager] playClickSound];
+ [self updatePreview];
+}
+
+-(void) updatePreview {
+ // don't generate a new preview while it's already generating one
+ if (self.busy)
+ return;
+
+ // generate a seed
+ CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+ NSString *seed = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuid);
+ CFRelease(uuid);
+ NSString *seedCmd = [[NSString alloc] initWithFormat:@"eseed {%@}", seed];
+ self.seedCommand = seedCmd;
+ [seedCmd release];
+
+ NSArray *source = [self.dataSourceArray objectAtIndex:scIndex];
+ if (isRandomness()) {
+ // prevent other events and add an activity while the preview is beign generated
+ [self turnOffWidgets];
+ [self.previewButton updatePreviewWithSeed:seed];
+ // the preview for static maps is loaded in didSelectRowAtIndexPath
+ }
+ [seed release];
+
+ // perform as if user clicked on an entry
+ NSIndexPath *theIndex = [NSIndexPath indexPathForRow:(random()%[source count]) inSection:0];
+ [self tableView:self.tableView didSelectRowAtIndexPath:theIndex];
+ if (IS_NOT_POWERFUL([HWUtils modelType]) == NO)
+ [self.tableView scrollToRowAtIndexPath:theIndex atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
+}
+
+-(void) turnOffWidgets {
+ busy = YES;
+ self.previewButton.alpha = 0.5f;
+ self.previewButton.enabled = NO;
+ self.maxLabel.text = NSLocalizedString(@"Loading...",@"");;
+ self.segmentedControl.enabled = NO;
+ self.slider.enabled = NO;
+}
+
+#pragma mark -
+#pragma mark MapPreviewButtonView delegate methods
+-(void) turnOnWidgets {
+ self.previewButton.alpha = 1.0f;
+ self.previewButton.enabled = YES;
+ self.segmentedControl.enabled = YES;
+ self.slider.enabled = YES;
+ self.busy = NO;
+}
+
+-(void) setMaxLabelText:(NSString *)str {
+ self.maxHogs = [str intValue];
+ self.maxLabel.text = [NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"Max Hogs:",@""),str];
+}
+
+-(NSDictionary *)getDataForEngine {
+ NSDictionary *dictForEngine = [NSDictionary dictionaryWithObjectsAndKeys:
+ self.seedCommand,@"seedCommand",
+ self.templateFilterCommand,@"templateFilterCommand",
+ self.mapGenCommand,@"mapGenCommand",
+ self.mazeSizeCommand,@"mazeSizeCommand",
+ nil];
+ return dictForEngine;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger) section {
+ return [[self.dataSourceArray objectAtIndex:scIndex] count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+ NSUInteger row = [indexPath row];
+
+ UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+
+ NSArray *source = [self.dataSourceArray objectAtIndex:scIndex];
+
+ NSString *labelString = [source objectAtIndex:row];
+ cell.textLabel.text = labelString;
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.textLabel.minimumFontSize = 7;
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ cell.textLabel.backgroundColor = [UIColor clearColor];
+
+ if (isRandomness()) {
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/icon.png",THEMES_DIRECTORY(),labelString]];
+ cell.imageView.image = image;
+ [image release];
+ } else
+ cell.imageView.image = nil;
+
+ if (row == [self.lastIndexPath row]) {
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ cell.accessoryView = checkbox;
+ [checkbox release];
+ } else
+ cell.accessoryView = nil;
+
+ cell.backgroundColor = [UIColor blackColorTransparent];
+ return cell;
+}
+
+// this set details for a static map (called by didSelectRowAtIndexPath)
+-(void) setDetailsForStaticMap:(NSInteger) index {
+ NSArray *source = [self.dataSourceArray objectAtIndex:scIndex];
+
+ NSString *fileCfg = [[NSString alloc] initWithFormat:@"%@/%@/map.cfg",
+ (scIndex == 1) ? MAPS_DIRECTORY() : MISSIONS_DIRECTORY(),[source objectAtIndex:index]];
+ NSString *contents = [[NSString alloc] initWithContentsOfFile:fileCfg encoding:NSUTF8StringEncoding error:NULL];
+ [fileCfg release];
+ NSArray *split = [contents componentsSeparatedByString:@"\n"];
+ [contents release];
+
+ // if the number is not set we keep 18 standard;
+ // sometimes it's not set but there are trailing characters, we get around them with the second equation
+ NSString *max;
+ if ([split count] > 1 && [[split objectAtIndex:1] intValue] > 0)
+ max = [split objectAtIndex:1];
+ else
+ max = @"18";
+ [self setMaxLabelText:max];
+
+ self.themeCommand = [NSString stringWithFormat:@"etheme %@", [split objectAtIndex:0]];
+ self.staticMapCommand = [NSString stringWithFormat:@"emap %@", [source objectAtIndex:index]];
+
+ if (scIndex != 3)
+ self.missionCommand = @"";
+ else
+ self.missionCommand = [NSString stringWithFormat:@"escript Missions/Maps/%@/map.lua",[source objectAtIndex:index]];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ NSArray *source = [self.dataSourceArray objectAtIndex:scIndex];
+ if (isRandomness()) {
+ // just change the theme, don't update preview
+ self.themeCommand = [NSString stringWithFormat:@"etheme %@", [source objectAtIndex:newRow]];
+ } else {
+ NSString *fileImage = [NSString stringWithFormat:@"%@/%@/preview.png",
+ (scIndex == 1) ? MAPS_DIRECTORY() : MISSIONS_DIRECTORY(),[source objectAtIndex:newRow]];
+ [self.previewButton updatePreviewWithFile:fileImage];
+ [self setDetailsForStaticMap:newRow];
+ }
+
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ newCell.accessoryView = checkbox;
+ [checkbox release];
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:self.lastIndexPath];
+ oldCell.accessoryView = nil;
+
+ self.lastIndexPath = indexPath;
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+#pragma mark -
+#pragma mark slider & segmentedControl & button
+// this updates the label and the command keys when the slider is moved, depending of the selection in segmentedControl
+// no methods are called by this routine and you can pass nil to it
+-(IBAction) sliderChanged:(id) sender {
+ NSString *labelText;
+ NSString *templateCommand;
+ NSString *mazeCommand;
+
+ switch ((int)(self.slider.value*100)) {
+ case 0:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"Wacky",@"");
+ } else {
+ labelText = NSLocalizedString(@"Large Floating Islands",@"");
+ }
+ templateCommand = @"e$template_filter 5";
+ mazeCommand = @"e$maze_size 5";
+ break;
+ case 1:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"Cavern",@"");
+ } else {
+ labelText = NSLocalizedString(@"Medium Floating Islands",@"");
+ }
+ templateCommand = @"e$template_filter 4";
+ mazeCommand = @"e$maze_size 4";
+ break;
+ case 2:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"Large",@"");
+ } else {
+ labelText = NSLocalizedString(@"Small Floating Islands",@"");
+ }
+ templateCommand = @"e$template_filter 1";
+ mazeCommand = @"e$maze_size 3";
+ break;
+ case 3:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"Medium",@"");
+ } else {
+ labelText = NSLocalizedString(@"Large Tunnels",@"");
+ }
+ templateCommand = @"e$template_filter 2";
+ mazeCommand = @"e$maze_size 2";
+ break;
+ case 4:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"Small",@"");
+ } else {
+ labelText = NSLocalizedString(@"Medium Tunnels",@"");
+ }
+ templateCommand = @"e$template_filter 3";
+ mazeCommand = @"e$maze_size 1";
+ break;
+ case 5:
+ if (self.segmentedControl.selectedSegmentIndex == 0) {
+ labelText = NSLocalizedString(@"All",@"");
+ } else {
+ labelText = NSLocalizedString(@"Small Tunnels",@"");
+ }
+ templateCommand = @"e$template_filter 0";
+ mazeCommand = @"e$maze_size 0";
+ break;
+ default:
+ labelText = nil;
+ templateCommand = nil;
+ mazeCommand = nil;
+ break;
+ }
+
+ self.slider.textValue = labelText;
+ self.templateFilterCommand = templateCommand;
+ self.mazeSizeCommand = mazeCommand;
+}
+
+// update preview (if not busy and if its value really changed) as soon as the user lifts its finger up
+-(IBAction) sliderEndedChanging:(id) sender {
+ int num = (int) (self.slider.value * 100);
+ if (oldValue != num) {
+ [self updatePreview];
+ oldValue = num;
+ }
+ [[AudioManagerController mainManager] playClickSound];
+}
+
+// perform actions based on the activated section, then call updatePreview to visually update the selection
+// and if necessary update the table with a slide animation
+-(IBAction) segmentedControlChanged:(id) sender {
+ NSString *mapgen, *staticmap, *mission;
+ NSInteger newPage = self.segmentedControl.selectedSegmentIndex;
+
+ [[AudioManagerController mainManager] playSelectSound];
+ switch (newPage) {
+ case 0: // Random
+ mapgen = @"e$mapgen 0";
+ staticmap = @"";
+ mission = @"";
+ [self sliderChanged:nil];
+ self.slider.enabled = YES;
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"fillsections" object:nil];
+ break;
+
+ case 1: // Map
+ mapgen = @"e$mapgen 0";
+ // dummy values, these are set by -updatePreview -> -didSelectRowAtIndexPath -> -setDetailsForStaticMap
+ staticmap = @"map Bamboo";
+ mission = @"";
+ self.slider.enabled = NO;
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"fillsections" object:nil];
+ break;
+
+ case 2: // Maze
+ mapgen = @"e$mapgen 1";
+ staticmap = @"";
+ mission = @"";
+ [self sliderChanged:nil];
+ self.slider.enabled = YES;
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"fillsections" object:nil];
+ break;
+
+ case 3: // Mission
+ mapgen = @"e$mapgen 0";
+ // dummy values, these are set by -updatePreview -> -didSelectRowAtIndexPath -> -setDetailsForStaticMap
+ staticmap = @"map Bamboo";
+ mission = @"";
+ self.slider.enabled = NO;
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"emptysections" object:nil];
+ break;
+
+ default:
+ mapgen = nil;
+ staticmap = nil;
+ mission = nil;
+ break;
+ }
+ self.mapGenCommand = mapgen;
+ self.staticMapCommand = staticmap;
+ self.missionCommand = mission;
+
+ [self.tableView reloadData];
+ [self updatePreview];
+ oldPage = newPage;
+}
+
+#pragma mark -
+#pragma mark view management
+-(NSArray *) dataSourceArray {
+ if (dataSourceArray == nil) {
+ NSString *model = [HWUtils modelType];
+
+ // only folders containing icon.png are a valid theme
+ NSArray *themeArrayFull = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:THEMES_DIRECTORY() error:NULL];
+ NSMutableArray *themeArray = [[NSMutableArray alloc] init];
+ for (NSString *themeName in themeArrayFull) {
+ NSString *checkPath = [[NSString alloc] initWithFormat:@"%@/%@/icon.png",THEMES_DIRECTORY(),themeName];
+ if ([[NSFileManager defaultManager] fileExistsAtPath:checkPath])
+ [themeArray addObject:themeName];
+ [checkPath release];
+ }
+
+ // remove images that are too big for certain devices without loading the whole image
+ NSArray *mapArrayFull = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:MAPS_DIRECTORY() error:NULL];
+ NSMutableArray *mapArray = [[NSMutableArray alloc] init];
+ for (NSString *str in mapArrayFull) {
+ CGSize imgSize = [UIImage imageSizeFromMetadataOf:[MAPS_DIRECTORY() stringByAppendingFormat:@"%@/map.png",str]];
+ if (IS_NOT_POWERFUL(model) && imgSize.height > 1024.0f)
+ continue;
+ if (IS_NOT_VERY_POWERFUL(model) && imgSize.height > 1280.0f)
+ continue;
+ [mapArray addObject:str];
+ }
+
+ NSArray *missionArrayFull = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:MISSIONS_DIRECTORY() error:NULL];
+ NSMutableArray *missionArray = [[NSMutableArray alloc] init];
+ for (NSString *str in missionArrayFull) {
+ CGSize imgSize = [UIImage imageSizeFromMetadataOf:[MISSIONS_DIRECTORY() stringByAppendingFormat:@"%@/map.png",str]];
+ if (IS_NOT_POWERFUL(model) && imgSize.height > 1024.0f)
+ continue;
+ if (IS_NOT_VERY_POWERFUL(model) && imgSize.height > 1280.0f)
+ continue;
+ [missionArray addObject:str];
+ }
+ NSArray *array = [[NSArray alloc] initWithObjects:themeArray,mapArray,themeArray,missionArray,nil];
+ [missionArray release];
+ [themeArray release];
+ [mapArray release];
+
+ self.dataSourceArray = array;
+ [array release];
+ }
+ return dataSourceArray;
+}
+
+-(void) viewDidLoad {
+ [super viewDidLoad];
+ srandom(time(NULL));
+
+ // initialize some "default" values
+ self.slider.value = 0.05f;
+ self.slider.enabled = NO;
+ self.oldValue = 5;
+ self.busy = NO;
+ self.oldPage = self.segmentedControl.selectedSegmentIndex;
+
+ self.templateFilterCommand = @"e$template_filter 0";
+ self.mazeSizeCommand = @"e$maze_size 0";
+ self.mapGenCommand = @"e$mapgen 0";
+ self.staticMapCommand = @"";
+ self.missionCommand = @"";
+
+ if (IS_IPAD()) {
+ [self.tableView setBackgroundColorForAnyTable:[UIColor darkBlueColorTransparent]];
+ self.tableView.layer.borderColor = [[UIColor darkYellowColor] CGColor];
+ self.tableView.layer.borderWidth = 2.7f;
+ self.tableView.layer.cornerRadius = 8;
+ self.tableView.contentInset = UIEdgeInsetsMake(10, 0, 10, 0);
+
+ UILabel *backLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 14, 300, 190) andTitle:nil withBorderWidth:2.3f];
+ backLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ [self.view insertSubview:backLabel belowSubview:self.segmentedControl];
+ [backLabel release];
+ }
+ self.tableView.separatorColor = [UIColor whiteColor];
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+}
+
+-(void) viewDidAppear:(BOOL) animated {
+ [self updatePreview];
+ [super viewDidAppear:animated];
+}
+
+-(void) viewDidUnload {
+ self.previewButton = nil;
+ self.seedCommand = nil;
+ self.templateFilterCommand = nil;
+ self.mapGenCommand = nil;
+ self.mazeSizeCommand = nil;
+ self.themeCommand = nil;
+ self.staticMapCommand = nil;
+ self.missionCommand = nil;
+
+ self.tableView = nil;
+ self.maxLabel = nil;
+ self.segmentedControl = nil;
+ self.slider = nil;
+
+ self.lastIndexPath = nil;
+ self.dataSourceArray = nil;
+
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) didReceiveMemoryWarning {
+ self.dataSourceArray = nil;
+ [super didReceiveMemoryWarning];
+
+ if (self.view.superview == nil) {
+ self.previewButton = nil;
+ self.tableView = nil;
+ self.maxLabel = nil;
+ self.slider = nil;
+ }
+
+ MSG_MEMCLEAN();
+}
+
+-(void) dealloc {
+ releaseAndNil(seedCommand);
+ releaseAndNil(templateFilterCommand);
+ releaseAndNil(mapGenCommand);
+ releaseAndNil(mazeSizeCommand);
+ releaseAndNil(themeCommand);
+ releaseAndNil(staticMapCommand);
+ releaseAndNil(missionCommand);
+
+ releaseAndNil(previewButton);
+ releaseAndNil(tableView);
+ releaseAndNil(maxLabel);
+ releaseAndNil(segmentedControl);
+ releaseAndNil(slider);
+
+ releaseAndNil(lastIndexPath);
+ releaseAndNil(dataSourceArray);
+
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h
new file mode 100644
index 0000000..1a8677d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.h
@@ -0,0 +1,47 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "SDL_net.h"
+
+
+ at protocol MapPreviewViewDelegate <NSObject>
+
+-(void) turnOnWidgets;
+-(void) setMaxLabelText:(NSString *)string;
+-(NSDictionary *)getDataForEngine;
+
+ at end
+
+ at interface MapPreviewButtonView : UIButton {
+ id<MapPreviewViewDelegate> delegate;
+ TCPsocket sd, csd;
+ NSInteger maxHogs;
+}
+
+ at property (nonatomic,assign) id<MapPreviewViewDelegate> delegate;
+
+-(void) setImageRounded:(UIImage *)image forState:(UIControlState) controlState;
+-(void) setImageRounded:(UIImage *)image;
+-(void) updatePreviewWithSeed:(NSString *)seed;
+-(void) updatePreviewWithFile:(NSString *)filePath;
+-(void) turnOnWidgets;
+-(NSDictionary *)getDataForEngine;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m
new file mode 100644
index 0000000..b9f24b1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MapPreviewButtonView.m
@@ -0,0 +1,222 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "MapPreviewButtonView.h"
+#import <pthread.h>
+#import <QuartzCore/QuartzCore.h>
+
+
+#define INDICATOR_TAG 7654
+
+ at implementation MapPreviewButtonView
+ at synthesize delegate;
+
+-(id) initWithFrame:(CGRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+ delegate = nil;
+ self.backgroundColor = [UIColor whiteColor];
+ self.layer.cornerRadius = 12;
+ }
+ return self;
+}
+
+-(void) dealloc {
+ self.delegate = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark image wrappers
+-(void) setImageRounded:(UIImage *)image forState:(UIControlState)controlState {
+ [self setImage:[image makeRoundCornersOfSize:CGSizeMake(12, 12)] forState:controlState];
+}
+
+-(void) setImageRounded:(UIImage *)image {
+ [self setImageRounded:image forState:UIControlStateNormal];
+}
+
+#pragma mark -
+#pragma mark preview
+-(int) sendToEngine:(NSString *)string {
+ unsigned char length = [string length];
+
+ SDLNet_TCP_Send(csd, &length, 1);
+ return SDLNet_TCP_Send(csd, [string UTF8String], length);
+}
+
+-(void) engineProtocol:(uint8_t *)unpackedMap {
+ IPaddress ip;
+ BOOL serverQuit = NO;
+ uint8_t packedMap[128*32];
+ int port = [HWUtils randomPort];
+
+ if (SDLNet_Init() < 0) {
+ DLog(@"SDLNet_Init: %s", SDLNet_GetError());
+ serverQuit = YES;
+ }
+
+ // Resolving the host using NULL make network interface to listen
+ if (SDLNet_ResolveHost(&ip, NULL, port) < 0) {
+ DLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+ serverQuit = YES;
+ }
+
+ // Open a connection with the IP provided (listen on the host's port)
+ if (!(sd = SDLNet_TCP_Open(&ip))) {
+ DLog(@"SDLNet_TCP_Open: %s %\n", SDLNet_GetError(), port);
+ serverQuit = YES;
+ }
+
+ // launch the preview here so that we're sure the tcp channel is open
+ pthread_t thread_id;
+ pthread_create(&thread_id, NULL, (void *(*)(void *))GenLandPreview, (void *)port);
+ pthread_detach(thread_id);
+
+ DLog(@"Waiting for a client on port %d", port);
+ while (!serverQuit) {
+ /* This check the sd if there is a pending connection.
+ * If there is one, accept that, and open a new socket for communicating */
+ csd = SDLNet_TCP_Accept(sd);
+ if (NULL != csd) {
+ DLog(@"Client found");
+
+ NSDictionary *dictForEngine = [self getDataForEngine];
+ [self sendToEngine:[dictForEngine objectForKey:@"seedCommand"]];
+ [self sendToEngine:[dictForEngine objectForKey:@"templateFilterCommand"]];
+ [self sendToEngine:[dictForEngine objectForKey:@"mapGenCommand"]];
+ [self sendToEngine:[dictForEngine objectForKey:@"mazeSizeCommand"]];
+ [self sendToEngine:@"!"];
+
+ memset(packedMap, 0, 128*32);
+ SDLNet_TCP_Recv(csd, packedMap, 128*32);
+ SDLNet_TCP_Recv(csd, &maxHogs, sizeof(uint8_t));
+
+ SDLNet_TCP_Close(csd);
+ serverQuit = YES;
+ }
+ }
+ [HWUtils freePort:port];
+ SDLNet_TCP_Close(sd);
+ SDLNet_Quit();
+
+ // spread the packed bits in an array of bytes (one pixel per element, 0= transparent 1= color)
+ int k = 0;
+ memset(unpackedMap, 255, 128*32*8); // 255 is white
+ for (int i = 0; i < 32*128; i++) {
+ for (int j = 7; j >= 0; j--) {
+ if (((packedMap[i] >> j) & 0x01) != 0)
+ unpackedMap[k] = 170; // level of gray [0-255]
+ k++;
+ }
+ }
+ return;
+}
+
+-(void) drawingThread {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ uint8_t unpackedMap[128*32*8];
+ [self engineProtocol:unpackedMap];
+
+ // http://developer.apple.com/mac/library/qa/qa2001/qa1037.html
+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
+ CGContextRef bitmapImage = CGBitmapContextCreate(unpackedMap, 256, 128, 8, 256, colorspace, kCGImageAlphaNone);
+ CGColorSpaceRelease(colorspace);
+
+ CGImageRef previewCGImage = CGBitmapContextCreateImage(bitmapImage);
+ CGContextRelease(bitmapImage);
+ UIImage *previewImage = [[UIImage alloc] initWithCGImage:previewCGImage];
+ CGImageRelease(previewCGImage);
+
+ // all these are performed on the main thread to prevent a leak
+ [self performSelectorOnMainThread:@selector(setImageRounded:)
+ withObject:previewImage
+ waitUntilDone:NO];
+ [previewImage release];
+ [self performSelectorOnMainThread:@selector(setLabelText:)
+ withObject:[NSString stringWithFormat:@"%d", maxHogs]
+ waitUntilDone:NO];
+ [self performSelectorOnMainThread:@selector(turnOnWidgets)
+ withObject:nil
+ waitUntilDone:NO];
+ [self performSelectorOnMainThread:@selector(removeIndicator)
+ withObject:nil
+ waitUntilDone:NO];
+
+ [pool release];
+}
+
+-(void) updatePreviewWithSeed:(NSString *)seed {
+ // remove the current preview and title
+ [self setImage:nil forState:UIControlStateNormal];
+ [self setTitle:nil forState:UIControlStateNormal];
+
+ // don't display preview on slower device, too slow and memory hog
+ if (IS_NOT_POWERFUL([HWUtils modelType])) {
+ [self setTitle:NSLocalizedString(@"Preview not available",@"") forState:UIControlStateNormal];
+ [self turnOnWidgets];
+ } else {
+ // add a very nice spinning wheel
+ UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc]
+ initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+ indicator.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
+ indicator.tag = INDICATOR_TAG;
+ [indicator startAnimating];
+ [self addSubview:indicator];
+ [indicator release];
+
+ // let's draw in a separate thread so the gui can work; at the end it restore other widgets
+ [NSThread detachNewThreadSelector:@selector(drawingThread) toTarget:self withObject:nil];
+ }
+}
+
+-(void) updatePreviewWithFile:(NSString *)filePath {
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath];
+ [self setImageRounded:image forState:UIControlStateNormal];
+ self.backgroundColor = [UIColor whiteColor];
+ self.layer.cornerRadius = 12;
+ [image release];
+}
+
+-(void) removeIndicator {
+ UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[self viewWithTag:INDICATOR_TAG];
+ if (indicator) {
+ [indicator stopAnimating];
+ [indicator removeFromSuperview];
+ }
+}
+
+#pragma mark -
+#pragma mark delegate
+-(void) turnOnWidgets {
+ if ([self.delegate respondsToSelector:@selector(turnOnWidgets)])
+ [self.delegate turnOnWidgets];
+}
+
+-(void) setLabelText:(NSString *)string {
+ if ([self.delegate respondsToSelector:@selector(setMaxLabelText:)])
+ [self.delegate setMaxLabelText:string];
+}
+
+-(NSDictionary *)getDataForEngine {
+ if ([self.delegate respondsToSelector:@selector(getDataForEngine)])
+ return [self.delegate getDataForEngine];
+ return nil;
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPad.xib b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPad.xib
new file mode 100644
index 0000000..9777cda
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPad.xib
@@ -0,0 +1,736 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="677142548">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">319</int>
+ <string key="NSFrameSize">{768, 768}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">mediumBackground~ipad.png</string>
+ </object>
+ </object>
+ <object class="IBUITableView" id="609221433">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{91, 86}, {585, 391}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUIIndicatorStyle">2</int>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ <object class="IBUIImageView" id="776434219">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">269</int>
+ <string key="NSFrame">{{227, 496}, {314, 260}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIButton" id="1038942684">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{20, 684}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="1000305902">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="76134506">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="181044244">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">backButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="1068873625">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">265</int>
+ <string key="NSFrame">{{606, 684}, {142, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">1</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="1000305902"/>
+ <reference key="IBUIHighlightedTitleColor" ref="76134506"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="181044244"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">startGameButton.png</string>
+ </object>
+ </object>
+ <object class="IBUILabel" id="12882009">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">306</int>
+ <string key="NSFrame">{{5, 6}, {757, 72}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <string key="IBUIText">Description here</string>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-BoldOblique</string>
+ <double key="NSSize">21</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAAA</bytes>
+ </object>
+ <reference key="IBUIHighlightedColor" ref="76134506"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUINumberOfLines">2</int>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ </object>
+ <string key="NSFrameSize">{768, 768}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="609221433"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="609221433"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">previewImage</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="776434219"/>
+ </object>
+ <int key="connectionID">13</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="609221433"/>
+ </object>
+ <int key="connectionID">14</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="1038942684"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">19</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="1068873625"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">20</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">descriptionLabel</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="12882009"/>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="776434219"/>
+ <reference ref="1038942684"/>
+ <reference ref="1068873625"/>
+ <reference ref="12882009"/>
+ <reference ref="609221433"/>
+ <reference ref="677142548"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="609221433"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="776434219"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">17</int>
+ <reference key="object" ref="1038942684"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">18</int>
+ <reference key="object" ref="1068873625"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">21</int>
+ <reference key="object" ref="12882009"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="677142548"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>10.IBPluginDependency</string>
+ <string>10.IBViewBoundsToFrameTransform</string>
+ <string>17.IBPluginDependency</string>
+ <string>17.IBViewBoundsToFrameTransform</string>
+ <string>18.IBPluginDependency</string>
+ <string>18.IBViewBoundsToFrameTransform</string>
+ <string>21.IBPluginDependency</string>
+ <string>21.IBViewBoundsToFrameTransform</string>
+ <string>23.IBPluginDependency</string>
+ <string>23.IBViewBoundsToFrameTransform</string>
+ <string>9.IBPluginDependency</string>
+ <string>9.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MissionTrainingViewController</string>
+ <string>UIResponder</string>
+ <string>{{139, 166}, {768, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDYwAAxD2AAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABBoAAAxC1AAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABEF4AAxC1AAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABCDAAAwowAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUOEAABDoAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABCtgAAw+2AAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">23</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MissionTrainingViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">buttonPressed:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">buttonPressed:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>descriptionLabel</string>
+ <string>previewImage</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>UIImageView</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>descriptionLabel</string>
+ <string>previewImage</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">descriptionLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewImage</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MissionTrainingViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="957394895">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <reference key="sourceIdentifier" ref="957394895"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="957394895"/>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="6906421">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="6906421"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>backButton.png</string>
+ <string>mediumBackground~ipad.png</string>
+ <string>startGameButton.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{64, 64}</string>
+ <string>{768, 768}</string>
+ <string>{142, 64}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPhone.xib b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPhone.xib
new file mode 100644
index 0000000..d9a292d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController-iPhone.xib
@@ -0,0 +1,682 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="474863980">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">smallerBackground~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUITableView" id="609221433">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{180, 0}, {300, 320}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <object class="NSColor" key="IBUIBackgroundColor" id="76134506">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUIIndicatorStyle">2</int>
+ <int key="IBUISeparatorStyle">1</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">22</float>
+ <float key="IBUISectionFooterHeight">22</float>
+ </object>
+ <object class="IBUIImageView" id="776434219">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{11, 19}, {157, 130}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIButton" id="1038942684">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{57, 245}, {64, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="1000305902">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <reference key="IBUIHighlightedTitleColor" ref="76134506"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="181044244">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">backButton.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="1068873625">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">292</int>
+ <string key="NSFrame">{{18, 164}, {142, 64}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">1</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="1000305902"/>
+ <reference key="IBUIHighlightedTitleColor" ref="76134506"/>
+ <object class="NSColor" key="IBUINormalTitleColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA</bytes>
+ </object>
+ <reference key="IBUINormalTitleShadowColor" ref="181044244"/>
+ <object class="NSCustomResource" key="IBUINormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">startGameButton.png</string>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="609221433"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="609221433"/>
+ <reference key="destination" ref="372490531"/>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">previewImage</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="776434219"/>
+ </object>
+ <int key="connectionID">13</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="609221433"/>
+ </object>
+ <int key="connectionID">14</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="1038942684"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">19</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="1068873625"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">20</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="609221433"/>
+ <reference ref="776434219"/>
+ <reference ref="1038942684"/>
+ <reference ref="1068873625"/>
+ <reference ref="474863980"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">9</int>
+ <reference key="object" ref="609221433"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="776434219"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">17</int>
+ <reference key="object" ref="1038942684"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">18</int>
+ <reference key="object" ref="1068873625"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="474863980"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>10.IBPluginDependency</string>
+ <string>10.IBViewBoundsToFrameTransform</string>
+ <string>17.IBPluginDependency</string>
+ <string>17.IBViewBoundsToFrameTransform</string>
+ <string>18.IBPluginDependency</string>
+ <string>18.IBViewBoundsToFrameTransform</string>
+ <string>23.IBPluginDependency</string>
+ <string>9.IBPluginDependency</string>
+ <string>9.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>MissionTrainingViewController</string>
+ <string>UIResponder</string>
+ <string>{{492, 751}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABAoAAAwwYAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABChAAAw5eAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABB2AAAw2cAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDUAAAw5UAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">23</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">MissionTrainingViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">buttonPressed:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">buttonPressed:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>descriptionLabel</string>
+ <string>previewImage</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UILabel</string>
+ <string>UIImageView</string>
+ <string>UITableView</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>descriptionLabel</string>
+ <string>previewImage</string>
+ <string>tableView</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">descriptionLabel</string>
+ <string key="candidateClassName">UILabel</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">previewImage</string>
+ <string key="candidateClassName">UIImageView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/MissionTrainingViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="249392476">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <reference key="sourceIdentifier" ref="249392476"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <reference key="sourceIdentifier" ref="249392476"/>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="6906421">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="6906421"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>backButton.png</string>
+ <string>smallerBackground~iphone.png</string>
+ <string>startGameButton.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{64, 64}</string>
+ <string>{480, 320}</string>
+ <string>{142, 64}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.h b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.h
new file mode 100644
index 0000000..c88977c
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.h
@@ -0,0 +1,41 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface MissionTrainingViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
+ NSArray *listOfMissions;
+ NSArray *listOfDescriptions;
+ NSString *missionName;
+ UIImageView *previewImage;
+ UITableView *tableView;
+ UILabel *descriptionLabel;
+}
+
+ at property (nonatomic, retain) NSArray *listOfMissions;
+ at property (nonatomic, retain) NSArray *listOfDescriptions;
+ at property (nonatomic, retain) NSString *missionName;
+ at property (nonatomic, retain) IBOutlet UIImageView *previewImage;
+ at property (nonatomic, retain) IBOutlet UITableView *tableView;
+ at property (nonatomic, retain) IBOutlet UILabel *descriptionLabel;
+
+-(IBAction) buttonPressed:(id) sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m
new file mode 100644
index 0000000..f03c750
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/MissionTrainingViewController.m
@@ -0,0 +1,199 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "MissionTrainingViewController.h"
+#import <QuartzCore/QuartzCore.h>
+#import "GameInterfaceBridge.h"
+
+
+ at implementation MissionTrainingViewController
+ at synthesize listOfMissions, listOfDescriptions, previewImage, tableView, descriptionLabel, missionName;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View management
+-(void) viewDidLoad {
+ self.previewImage.layer.borderColor = [[UIColor darkYellowColor] CGColor];
+ self.previewImage.layer.borderWidth = 3.8f;
+ self.previewImage.layer.cornerRadius = 14;
+
+ if (IS_IPAD()) {
+ [self.tableView setBackgroundColorForAnyTable:[UIColor darkBlueColorTransparent]];
+ self.tableView.layer.borderColor = [[UIColor darkYellowColor] CGColor];
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ } else {
+ [self.tableView setBackgroundColorForAnyTable:[UIColor blackColorTransparent]];
+ self.tableView.layer.borderColor = [[UIColor whiteColor] CGColor];
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
+ }
+ self.tableView.layer.borderWidth = 2.4f;
+ self.tableView.layer.cornerRadius = 8;
+ self.tableView.separatorColor = [UIColor whiteColor];
+
+ self.descriptionLabel.textColor = [UIColor lightYellowColor];
+ [super viewDidLoad];
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:random()%[self.listOfMissions count] inSection:0];
+ [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
+ [super viewWillAppear:animated];
+}
+
+-(IBAction) buttonPressed:(id) sender {
+ UIButton *button = (UIButton *)sender;
+
+ if (button.tag == 0) {
+ [[AudioManagerController mainManager] playBackSound];
+ [[self parentViewController] dismissModalViewControllerAnimated:YES];
+ } else {
+ [GameInterfaceBridge registerCallingController:self];
+ [GameInterfaceBridge startMissionGame:self.missionName];
+ }
+}
+
+#pragma mark -
+#pragma mark override setters/getters for better memory handling
+-(NSArray *)listOfMissions {
+ if (listOfMissions == nil)
+ self.listOfMissions = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TRAININGS_DIRECTORY() error:NULL];
+ return listOfMissions;
+}
+
+-(NSArray *)listOfDescriptions {
+ if (listOfDescriptions == nil) {
+ NSString *descLocation = [[NSString alloc] initWithFormat:@"%@/missions_en.txt",LOCALE_DIRECTORY()];
+ NSString *descComplete = [[NSString alloc] initWithContentsOfFile:descLocation encoding:NSUTF8StringEncoding error:NULL];
+ [descLocation release];
+ NSArray *descArray = [descComplete componentsSeparatedByString:@"\n"];
+ NSMutableArray *filteredArray = [[NSMutableArray alloc] initWithCapacity:[descArray count]/3];
+ [descComplete release];
+ // sanity check to avoid having missions and descriptions conflicts
+ for (NSUInteger i = 0; i < [self.listOfMissions count]; i++) {
+ NSString *desc = [[self.listOfMissions objectAtIndex:i] stringByDeletingPathExtension];
+ for (NSString *str in descArray)
+ if ([str hasPrefix:desc] && [str hasSuffix:@"\""]) {
+ NSArray *descriptionText = [str componentsSeparatedByString:@"\""];
+ [filteredArray insertObject:[descriptionText objectAtIndex:1] atIndex:i];
+ break;
+ }
+ }
+ self.listOfDescriptions = filteredArray;
+ [filteredArray release];
+ }
+ return listOfDescriptions;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.listOfMissions count];
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+ return (IS_IPAD()) ? self.tableView.rowHeight : 80;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"CellTr";
+ NSInteger row = [indexPath row];
+
+ UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:(IS_IPAD()) ? UITableViewCellStyleDefault : UITableViewCellStyleSubtitle
+ reuseIdentifier:CellIdentifier] autorelease];
+
+ cell.textLabel.text = [[[self.listOfMissions objectAtIndex:row] stringByDeletingPathExtension]
+ stringByReplacingOccurrencesOfString:@"_" withString:@" "];
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ //cell.textLabel.font = [UIFont fontWithName:@"Bradley Hand Bold" size:[UIFont labelFontSize]];
+ cell.textLabel.textAlignment = (IS_IPAD()) ? UITextAlignmentCenter : UITextAlignmentLeft;
+ cell.textLabel.backgroundColor = [UIColor clearColor];
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.detailTextLabel.text = (IS_IPAD()) ? nil : [self.listOfDescriptions objectAtIndex:row];
+ cell.detailTextLabel.textColor = [UIColor whiteColor];
+ cell.detailTextLabel.backgroundColor = [UIColor clearColor];
+ cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
+ cell.detailTextLabel.numberOfLines = ([cell.detailTextLabel.text length] % 40);
+ cell.detailTextLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
+
+ cell.backgroundColor = [UIColor blackColorTransparent];
+ return cell;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSInteger row = [indexPath row];
+
+ self.missionName = [[self.listOfMissions objectAtIndex:row] stringByDeletingPathExtension];
+ NSString *size = IS_IPAD() ? @"@2x" : @"";
+ NSString *filePath = [[NSString alloc] initWithFormat:@"%@/Missions/Training/%@%@.png",GRAPHICS_DIRECTORY(),self.missionName,size];
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:filePath];
+ [filePath release];
+ [self.previewImage setImage:img];
+ [img release];
+
+ self.descriptionLabel.text = [self.listOfDescriptions objectAtIndex:row];
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.previewImage = nil;
+ self.missionName = nil;
+ self.listOfMissions = nil;
+ self.listOfDescriptions = nil;
+ // if you nil this one it won't get updated anymore
+ //self.previewImage = nil;
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.listOfMissions = nil;
+ self.listOfDescriptions = nil;
+ self.previewImage = nil;
+ self.tableView = nil;
+ self.descriptionLabel = nil;
+ self.missionName = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(listOfMissions);
+ releaseAndNil(listOfDescriptions);
+ releaseAndNil(previewImage);
+ releaseAndNil(tableView);
+ releaseAndNil(descriptionLabel);
+ releaseAndNil(missionName);
+ [super dealloc];
+}
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/ObjcExports.h b/project_files/HedgewarsMobile/Classes/ObjcExports.h
new file mode 100644
index 0000000..b93b127
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.h
@@ -0,0 +1,27 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+void clearView(void);
+BOOL isApplePhone(void);
+
+void startLoadingIndicator(void);
+void stopLoadingIndicator(void);
+
+void saveBeganSynching(void);
+void saveFinishedSynching(void);
diff --git a/project_files/HedgewarsMobile/Classes/ObjcExports.m b/project_files/HedgewarsMobile/Classes/ObjcExports.m
new file mode 100644
index 0000000..d66c745
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m
@@ -0,0 +1,90 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "ObjcExports.h"
+
+#pragma mark -
+#pragma mark functions called by pascal code
+BOOL inline isApplePhone(void) {
+ return (IS_IPAD() == NO);
+}
+
+void startLoadingIndicator(void) {
+ // this is the first ojbc function called by engine, so we have to initialize some variables here
+
+ if ([HWUtils gameType] == gtSave) {
+ [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
+
+ /*
+ overlay_instance.view.backgroundColor = [UIColor blackColor];
+ overlay_instance.view.alpha = 0.75;
+ overlay_instance.view.userInteractionEnabled = NO;
+ */
+ }
+ /*
+ CGPoint center = overlay_instance.view.center;
+ CGPoint loaderCenter = ([HWUtils gameType] == gtSave) ? center : CGPointMake(center.x, center.y * 5/3);
+
+ overlay_instance.loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+ overlay_instance.loadingIndicator.hidesWhenStopped = YES;
+ overlay_instance.loadingIndicator.center = loaderCenter;
+ overlay_instance.loadingIndicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
+ UIViewAutoresizingFlexibleRightMargin |
+ UIViewAutoresizingFlexibleTopMargin |
+ UIViewAutoresizingFlexibleBottomMargin;
+ [overlay_instance.loadingIndicator startAnimating];
+ [overlay_instance.view addSubview:overlay_instance.loadingIndicator];
+ [overlay_instance.loadingIndicator release];
+ */
+}
+
+void stopLoadingIndicator(void) {
+ //HW_zoomSet(1.7);
+ if ([HWUtils gameType] != gtSave) {
+ //[overlay_instance.loadingIndicator stopAnimating];
+ //[overlay_instance.loadingIndicator removeFromSuperview];
+ [HWUtils setGameStatus:gsInGame];
+ }
+ // mark the savefile as valid, eg it's been loaded correctly
+ [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"saveIsValid"];
+ [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+void saveFinishedSynching(void) {
+ /*
+ [UIView beginAnimations:@"fading from save synch" context:NULL];
+ [UIView setAnimationDuration:1];
+ overlay_instance.view.backgroundColor = [UIColor clearColor];
+ overlay_instance.view.alpha = 1;
+ overlay_instance.view.userInteractionEnabled = YES;
+ [UIView commitAnimations];
+
+ [overlay_instance.loadingIndicator stopAnimating];
+ [overlay_instance.loadingIndicator performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
+ */
+
+ [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
+ [HWUtils setGameStatus:gsInGame];
+}
+
+
+// dummy function to prevent linkage fail
+int SDL_main(int argc, char **argv) {
+ return 0;
+}
diff --git a/project_files/HedgewarsMobile/Classes/PascalImports.h b/project_files/HedgewarsMobile/Classes/PascalImports.h
new file mode 100644
index 0000000..9cb60ab
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/PascalImports.h
@@ -0,0 +1,52 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef PASCALIMPORTS
+#define PASCALIMPORTS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* add C declarations below for all exported Pascal functions/procedure
+ * that you want to use in your non-Pascal code
+ */
+
+ void Game(const int argc, const char *argv[]);
+ void GenLandPreview(void);
+ void LoadLocaleWrapper(const char *filename);
+
+ void HW_versionInfo(int *protoNum, char **versionStr);
+ void *HW_getSDLWindow(void);
+ void HW_terminate(BOOL andCloseFrontend);
+
+ char *HW_getWeaponNameByIndex(int whichone);
+ //char *HW_getWeaponCaptionByIndex(int whichone);
+ //char *HW_getWeaponDescriptionByIndex(int whichone);
+ int HW_getNumberOfWeapons(void);
+ int HW_getMaxNumberOfHogs(void);
+ int HW_getMaxNumberOfTeams(void);
+
+ void HW_memoryWarningCallback(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/project_files/HedgewarsMobile/Classes/RestoreViewController-iPad.xib b/project_files/HedgewarsMobile/Classes/RestoreViewController-iPad.xib
new file mode 100644
index 0000000..2b2ed8d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/RestoreViewController-iPad.xib
@@ -0,0 +1,654 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="138553579">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">319</int>
+ <string key="NSFrameSize">{540, 640}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">smallerBackground~ipad.png</string>
+ </object>
+ </object>
+ <object class="IBUIButton" id="155385540">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">302</int>
+ <string key="NSFrame">{{84, 517}, {151, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="204967016">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Dismiss</string>
+ <object class="NSColor" key="IBUIHighlightedTitleColor" id="790402446">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleColor" id="829178890">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAuNTAxOTYwODE0AA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="644451038">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ <object class="IBUIButton" id="202794507">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">299</int>
+ <string key="NSFrame">{{308, 517}, {151, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">1</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="204967016"/>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Restore</string>
+ <reference key="IBUIHighlightedTitleColor" ref="790402446"/>
+ <reference key="IBUINormalTitleColor" ref="829178890"/>
+ <reference key="IBUINormalTitleShadowColor" ref="644451038"/>
+ </object>
+ <object class="IBUILabel" id="655269955">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">295</int>
+ <string key="NSFrame">{{216, 35}, {108, 29}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <string key="IBUIText">Hmm...</string>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">24</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">2</int>
+ <bytes key="NSRGB">MSAwLjc4MDM5MjIyOTYgMAA</bytes>
+ </object>
+ <reference key="IBUIHighlightedColor" ref="790402446"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUILabel" id="19933541">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">282</int>
+ <string key="NSFrame">{{80, 375}, {380, 96}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <string key="IBUIText">Would you like to restore it?</string>
+ <object class="NSFont" key="IBUIFont" id="276115526">
+ <string key="NSName">Helvetica</string>
+ <double key="NSSize">18</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC45MDE5NjA3OTAyIDAuOTAxOTYwNzkwMiAwLjkwMTk2MDc5MDIAA</bytes>
+ </object>
+ <reference key="IBUIHighlightedColor" ref="790402446"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUINumberOfLines">4</int>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUILabel" id="151967545">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">306</int>
+ <string key="NSFrame">{{80, 87}, {380, 96}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <string key="IBUIText">It appears you didn't complete your last game!</string>
+ <reference key="IBUIFont" ref="276115526"/>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC45MDE5NjA3OTAyIDAuOTAxOTYwNzkwMiAwLjkwMTk2MDc5MDIAA</bytes>
+ </object>
+ <reference key="IBUIHighlightedColor" ref="790402446"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUINumberOfLines">4</int>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUIImageView" id="129485928">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">301</int>
+ <string key="NSFrame">{{150, 191}, {240, 160}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">denied.png</string>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{540, 640}</string>
+ <reference key="NSSuperview"/>
+ <reference key="IBUIBackgroundColor" ref="790402446"/>
+ <int key="IBUIContentMode">4</int>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonReleased:</string>
+ <reference key="source" ref="155385540"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">21</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonReleased:</string>
+ <reference key="source" ref="202794507"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">22</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="155385540"/>
+ <reference ref="202794507"/>
+ <reference ref="655269955"/>
+ <reference ref="19933541"/>
+ <reference ref="151967545"/>
+ <reference ref="129485928"/>
+ <reference ref="138553579"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="155385540"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">16</int>
+ <reference key="object" ref="202794507"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">18</int>
+ <reference key="object" ref="655269955"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="19933541"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">20</int>
+ <reference key="object" ref="129485928"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="151967545"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">24</int>
+ <reference key="object" ref="138553579"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>15.IBPluginDependency</string>
+ <string>15.IBViewBoundsToFrameTransform</string>
+ <string>16.IBPluginDependency</string>
+ <string>16.IBViewBoundsToFrameTransform</string>
+ <string>18.IBPluginDependency</string>
+ <string>18.IBViewBoundsToFrameTransform</string>
+ <string>19.IBPluginDependency</string>
+ <string>19.IBViewBoundsToFrameTransform</string>
+ <string>20.IBPluginDependency</string>
+ <string>20.IBViewBoundsToFrameTransform</string>
+ <string>23.IBPluginDependency</string>
+ <string>23.IBViewBoundsToFrameTransform</string>
+ <string>24.IBPluginDependency</string>
+ <string>24.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>RestoreViewController</string>
+ <string>UIResponder</string>
+ <string>{{650, 289}, {540, 640}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDlIAAw2gAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABEAkAAw2gAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDXAAAw3UAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUKgAABDmYAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABDFgAAw8cAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">P4AAAL+AAABCoAAAw9uAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform"/>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">24</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">RestoreViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">buttonReleased:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">buttonReleased:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">buttonReleased:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/RestoreViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="749404015">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="749404015"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>denied.png</string>
+ <string>smallerBackground~ipad.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{240, 160}</string>
+ <string>{540, 640}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/RestoreViewController-iPhone.xib b/project_files/HedgewarsMobile/Classes/RestoreViewController-iPhone.xib
new file mode 100644
index 0000000..1616395
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/RestoreViewController-iPhone.xib
@@ -0,0 +1,620 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="372490531">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBProxyObject" id="975951072">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ <object class="IBUIView" id="191373211">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIImageView" id="396922791">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">319</int>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">smallerBackground~iphone.png</string>
+ </object>
+ </object>
+ <object class="IBUIImageView" id="508553704">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">300</int>
+ <string key="NSFrame">{{20, 20}, {240, 160}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSCustomResource" key="IBUIImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">denied.png</string>
+ </object>
+ </object>
+ <object class="IBUILabel" id="531154203">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">315</int>
+ <string key="NSFrame">{{310, 32}, {108, 29}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">Hmm...</string>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">24</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">2</int>
+ <bytes key="NSRGB">MSAwLjgyNzQ1MTA1MDMgMAA</bytes>
+ </object>
+ <object class="NSColor" key="IBUIHighlightedColor" id="790402446">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUILabel" id="785455561">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">307</int>
+ <string key="NSFrame">{{268, 74}, {192, 96}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <int key="IBUIContentMode">7</int>
+ <bool key="IBUIUserInteractionEnabled">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <string key="IBUIText">It appears you didn't complete your last game! Would you like to restore it?</string>
+ <object class="NSFont" key="IBUIFont">
+ <string key="NSName">Helvetica</string>
+ <double key="NSSize">18</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <object class="NSColor" key="IBUITextColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MC45MDE5NjA3OTAyIDAuOTAxOTYwNzkwMiAwLjkwMTk2MDc5MDIAA</bytes>
+ </object>
+ <reference key="IBUIHighlightedColor" ref="790402446"/>
+ <int key="IBUIBaselineAdjustment">1</int>
+ <float key="IBUIMinimumFontSize">10</float>
+ <int key="IBUINumberOfLines">4</int>
+ <int key="IBUITextAlignment">1</int>
+ </object>
+ <object class="IBUIButton" id="472385208">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">302</int>
+ <string key="NSFrame">{{53, 229}, {151, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <object class="NSFont" key="IBUIFont" id="204967016">
+ <string key="NSName">Helvetica-Bold</string>
+ <double key="NSSize">15</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Dismiss</string>
+ <reference key="IBUIHighlightedTitleColor" ref="790402446"/>
+ <object class="NSColor" key="IBUINormalTitleColor" id="734262812">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAuNTAxOTYwODE0AA</bytes>
+ </object>
+ <object class="NSColor" key="IBUINormalTitleShadowColor" id="644451038">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ <object class="IBUIButton" id="923913762">
+ <reference key="NSNextResponder" ref="191373211"/>
+ <int key="NSvFlags">299</int>
+ <string key="NSFrame">{{277, 229}, {151, 37}}</string>
+ <reference key="NSSuperview" ref="191373211"/>
+ <bool key="IBUIOpaque">NO</bool>
+ <int key="IBUITag">1</int>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <int key="IBUIContentHorizontalAlignment">0</int>
+ <int key="IBUIContentVerticalAlignment">0</int>
+ <reference key="IBUIFont" ref="204967016"/>
+ <int key="IBUIButtonType">1</int>
+ <string key="IBUINormalTitle">Restore</string>
+ <reference key="IBUIHighlightedTitleColor" ref="790402446"/>
+ <reference key="IBUINormalTitleColor" ref="734262812"/>
+ <reference key="IBUINormalTitleShadowColor" ref="644451038"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{480, 320}</string>
+ <reference key="NSSuperview"/>
+ <reference key="IBUIBackgroundColor" ref="790402446"/>
+ <int key="IBUIContentMode">4</int>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="372490531"/>
+ <reference key="destination" ref="191373211"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonReleased:</string>
+ <reference key="source" ref="923913762"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">11</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonReleased:</string>
+ <reference key="source" ref="472385208"/>
+ <reference key="destination" ref="372490531"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">12</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">1</int>
+ <reference key="object" ref="191373211"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="508553704"/>
+ <reference ref="923913762"/>
+ <reference ref="785455561"/>
+ <reference ref="531154203"/>
+ <reference ref="472385208"/>
+ <reference ref="396922791"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="372490531"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="975951072"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="508553704"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6</int>
+ <reference key="object" ref="531154203"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="785455561"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="472385208"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">10</int>
+ <reference key="object" ref="923913762"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="396922791"/>
+ <reference key="parent" ref="191373211"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>1.IBEditorWindowLastContentRect</string>
+ <string>1.IBPluginDependency</string>
+ <string>10.IBPluginDependency</string>
+ <string>10.IBViewBoundsToFrameTransform</string>
+ <string>15.IBPluginDependency</string>
+ <string>15.IBViewBoundsToFrameTransform</string>
+ <string>5.IBPluginDependency</string>
+ <string>5.IBViewBoundsToFrameTransform</string>
+ <string>6.IBPluginDependency</string>
+ <string>6.IBViewBoundsToFrameTransform</string>
+ <string>7.IBPluginDependency</string>
+ <string>7.IBViewBoundsToFrameTransform</string>
+ <string>8.IBPluginDependency</string>
+ <string>8.IBViewBoundsToFrameTransform</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>RestoreViewController</string>
+ <string>UIResponder</string>
+ <string>{{206, 423}, {480, 320}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUOKgABDZQAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform"/>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUGgAABBoAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUObAABCAAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUOGAABClAAAA</bytes>
+ </object>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <object class="NSAffineTransform">
+ <bytes key="NSTransformStruct">AUJUAABDZQAAA</bytes>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">15</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">RestoreViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">buttonReleased:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">buttonReleased:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">buttonReleased:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/RestoreViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="749404015">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIButton</string>
+ <string key="superclassName">UIControl</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIButton.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIControl</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIControl.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIImageView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIImageView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UILabel</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UILabel.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="749404015"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3000" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <object class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>denied.png</string>
+ <string>smallerBackground~iphone.png</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>{240, 160}</string>
+ <string>{480, 320}</string>
+ </object>
+ </object>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/RestoreViewController.h b/project_files/HedgewarsMobile/Classes/RestoreViewController.h
new file mode 100644
index 0000000..ccef147
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/RestoreViewController.h
@@ -0,0 +1,29 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface RestoreViewController : UIViewController {
+
+}
+
+-(IBAction) buttonReleased:(id) sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/RestoreViewController.m b/project_files/HedgewarsMobile/Classes/RestoreViewController.m
new file mode 100644
index 0000000..687199a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/RestoreViewController.m
@@ -0,0 +1,62 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "RestoreViewController.h"
+#import "GameInterfaceBridge.h"
+
+ at implementation RestoreViewController
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(IBAction) buttonReleased:(id) sender {
+ UIButton *theButton = (UIButton *)sender;
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+
+ if (theButton.tag != 0) {
+ [[AudioManagerController mainManager] playClickSound];
+ [GameInterfaceBridge registerCallingController:self.parentViewController];
+ [GameInterfaceBridge startSaveGame:[[NSUserDefaults standardUserDefaults] objectForKey:@"savedGamePath"]];
+ } else {
+ [[AudioManagerController mainManager] playBackSound];
+ [defaults setObject:@"" forKey:@"savedGamePath"];
+ [defaults synchronize];
+ }
+ [self.parentViewController dismissModalViewControllerAnimated:YES];
+}
+
+-(void) viewDidLoad {
+ [super viewDidLoad];
+}
+
+-(void) didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ [super dealloc];
+}
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SavedGamesViewController.h b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.h
new file mode 100644
index 0000000..f198075
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.h
@@ -0,0 +1,36 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface SavedGamesViewController : UIViewController <UITableViewDelegate, UITableViewDataSource,
+ EditableCellViewDelegate, UIActionSheetDelegate> {
+ UITableView *tableView;
+ NSMutableArray *listOfSavegames;
+ NSInteger numberOfItems;
+}
+
+ at property (nonatomic,retain) IBOutlet UITableView *tableView;
+ at property (nonatomic,retain) NSMutableArray *listOfSavegames;
+ at property (assign) NSInteger numberOfItems;
+
+-(IBAction) buttonPressed:(id) sender;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SavedGamesViewController.m b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.m
new file mode 100644
index 0000000..eb32538
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.m
@@ -0,0 +1,235 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SavedGamesViewController.h"
+#import "GameInterfaceBridge.h"
+
+
+ at implementation SavedGamesViewController
+ at synthesize tableView, listOfSavegames, numberOfItems;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(void) updateTable {
+ NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:SAVES_DIRECTORY() error:NULL];
+ NSMutableArray *array = [[NSMutableArray alloc] initWithArray:contentsOfDir copyItems:YES];
+ self.listOfSavegames = array;
+ [array release];
+ self.numberOfItems = [self.listOfSavegames count];
+
+ [self.tableView reloadData];
+}
+
+-(void) viewDidLoad {
+ [self.tableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+
+ NSString *imgName = (IS_IPAD()) ? @"mediumBackground~ipad.png" : @"smallerBackground~iphone.png";
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgName];
+ UIImageView *background = [[UIImageView alloc] initWithImage:img];
+ [img release];
+ background.frame = self.view.frame;
+ background.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view insertSubview:background atIndex:0];
+ [background release];
+
+ if (self.listOfSavegames == nil)
+ [self updateTable];
+ [super viewDidLoad];
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [self updateTable];
+ [super viewWillAppear:animated];
+}
+
+#pragma mark -
+#pragma mark button functions
+-(IBAction) buttonPressed:(id) sender {
+ UIButton *button = (UIButton *)sender;
+
+ if (button.tag == 0) {
+ [[AudioManagerController mainManager] playBackSound];
+ [self.tableView setEditing:NO animated:YES];
+ [[self parentViewController] dismissModalViewControllerAnimated:YES];
+ } else {
+ NSString *titleStr, *cancelStr, *confirmStr;
+ titleStr = NSLocalizedString(@"Are you reeeeeally sure?", @"");
+ cancelStr = NSLocalizedString(@"Well, maybe not...", @"");
+ confirmStr = NSLocalizedString(@"Of course!", @"");
+
+ UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:titleStr
+ delegate:self
+ cancelButtonTitle:cancelStr
+ destructiveButtonTitle:confirmStr
+ otherButtonTitles:nil];
+
+ if (IS_IPAD())
+ [actionSheet showFromBarButtonItem:(UIBarButtonItem *)sender animated:YES];
+ else
+ [actionSheet showInView:self.view];
+ [actionSheet release];
+ }
+}
+
+-(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex {
+ if ([actionSheet cancelButtonIndex] != buttonIndex) {
+ // remove all files and recreate the directory
+ [[NSFileManager defaultManager] removeItemAtPath:SAVES_DIRECTORY() error:NULL];
+ [[NSFileManager defaultManager] createDirectoryAtPath:SAVES_DIRECTORY() withIntermediateDirectories:NO attributes:nil error:NULL];
+
+ // update the table and the cached list
+ NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:self.numberOfItems];
+ for (int i = 0; i < self.numberOfItems; i++)
+ [array addObject:[NSIndexPath indexPathForRow:i inSection:0]];
+ self.numberOfItems = 0;
+ [self.tableView deleteRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationTop];
+ [self.listOfSavegames removeAllObjects];
+
+ [array release];
+ }
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return self.numberOfItems;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ if (self.listOfSavegames == nil)
+ [self updateTable];
+ EditableCellView *editableCell = (EditableCellView *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (editableCell == nil) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ editableCell.delegate = self;
+ }
+ editableCell.respectEditing = YES;
+ editableCell.textField.text = [[self.listOfSavegames objectAtIndex:[indexPath row]] stringByDeletingPathExtension];
+ editableCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+
+ return (UITableViewCell *)editableCell;
+}
+
+-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger) section {
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 60)];
+ footer.backgroundColor = [UIColor clearColor];
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width*60/100, 60)];
+ label.center = CGPointMake(self.tableView.frame.size.width/2, 30);
+ label.textAlignment = UITextAlignmentCenter;
+ label.font = [UIFont italicSystemFontOfSize:16];
+ label.textColor = [UIColor lightGrayColor];
+ label.numberOfLines = 5;
+ label.text = NSLocalizedString(@"Press to resume playing or swipe to delete the save file.",@"");
+
+ label.backgroundColor = [UIColor clearColor];
+ [footer addSubview:label];
+ [label release];
+ return [footer autorelease];
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+ return 60;
+}
+
+-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ [(EditableCellView *)[self.tableView cellForRowAtIndexPath:indexPath] save:nil];
+ self.numberOfItems--;
+ [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
+
+ NSString *saveName = [self.listOfSavegames objectAtIndex:[indexPath row]];
+ NSString *filePath = [NSString stringWithFormat:@"%@/%@",SAVES_DIRECTORY(),saveName];
+ [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
+ [self.listOfSavegames removeObject:saveName];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
+ if (self.listOfSavegames == nil)
+ [self updateTable];
+
+ // duplicate the entry
+ [(EditableCellView *)[self.tableView cellForRowAtIndexPath:indexPath] save:nil];
+
+ NSString *currentSaveName = [self.listOfSavegames objectAtIndex:[indexPath row]];
+ NSString *currentFilePath = [[NSString alloc] initWithFormat:@"%@/%@",SAVES_DIRECTORY(),currentSaveName];
+ NSString *newSaveName = [[NSString alloc] initWithFormat:@"[%@] %@",NSLocalizedString(@"Backup",@""),currentSaveName];
+ NSString *newFilePath = [[NSString alloc] initWithFormat:@"%@/%@",SAVES_DIRECTORY(),newSaveName];
+
+ [self.listOfSavegames addObject:newSaveName];
+ [newSaveName release];
+ [[NSFileManager defaultManager] copyItemAtPath:currentFilePath toPath:newFilePath error:nil];
+ [newFilePath release];
+
+ self.numberOfItems++;
+ [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
+
+ [GameInterfaceBridge registerCallingController:self];
+ [GameInterfaceBridge startSaveGame:currentFilePath];
+ [currentFilePath release];
+}
+
+#pragma mark -
+#pragma mark editableCellView delegate
+// rename old file if names differ
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue {
+ if (self.listOfSavegames == nil)
+ [self updateTable];
+ NSString *oldFilePath = [NSString stringWithFormat:@"%@/%@",SAVES_DIRECTORY(),[self.listOfSavegames objectAtIndex:tagValue]];
+ NSString *newFilePath = [NSString stringWithFormat:@"%@/%@.hws",SAVES_DIRECTORY(),textString];
+
+ if ([oldFilePath isEqualToString:newFilePath] == NO) {
+ [[NSFileManager defaultManager] moveItemAtPath:oldFilePath toPath:newFilePath error:nil];
+ [self.listOfSavegames replaceObjectAtIndex:tagValue withObject:[textString stringByAppendingString:@".hws"]];
+ }
+
+}
+
+#pragma mark -
+#pragma mark Memory Management
+-(void) didReceiveMemoryWarning {
+ self.listOfSavegames = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.tableView = nil;
+ self.listOfSavegames = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(tableView);
+ releaseAndNil(listOfSavegames);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SavedGamesViewController.xib b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.xib
new file mode 100644
index 0000000..1c65b61
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SavedGamesViewController.xib
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="7.10">
+ <data>
+ <int key="IBDocument.SystemTarget">1056</int>
+ <string key="IBDocument.SystemVersion">10K549</string>
+ <string key="IBDocument.InterfaceBuilderVersion">823</string>
+ <string key="IBDocument.AppKitVersion">1038.36</string>
+ <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string key="NS.object.0">132</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="7"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys" id="0">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBProxyObject" id="606714003">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ <object class="IBUIView" id="766721923">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">292</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIToolbar" id="832454237">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">290</int>
+ <string key="NSFrameSize">{768, 44}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <int key="IBUITag">458912</int>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableArray" key="IBUIItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIBarButtonItem" id="422926197">
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUIToolbar" ref="832454237"/>
+ <int key="IBUISystemItemIdentifier">0</int>
+ </object>
+ <object class="IBUIBarButtonItem" id="881124109">
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <reference key="IBUIToolbar" ref="832454237"/>
+ <int key="IBUISystemItemIdentifier">5</int>
+ </object>
+ <object class="IBUIBarButtonItem" id="882246004">
+ <int key="IBUITag">1</int>
+ <string key="IBUITitle">Clear All</string>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <int key="IBUIStyle">1</int>
+ <reference key="IBUIToolbar" ref="832454237"/>
+ </object>
+ </object>
+ </object>
+ <object class="IBUITableView" id="399289716">
+ <reference key="NSNextResponder" ref="766721923"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{0, 44}, {768, 724}}</string>
+ <reference key="NSSuperview" ref="766721923"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwAA</bytes>
+ </object>
+ <bool key="IBUIClipsSubviews">YES</bool>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ <bool key="IBUIAlwaysBounceVertical">YES</bool>
+ <int key="IBUIStyle">1</int>
+ <int key="IBUISeparatorStyle">2</int>
+ <int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
+ <bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
+ <float key="IBUIRowHeight">44</float>
+ <float key="IBUISectionHeaderHeight">10</float>
+ <float key="IBUISectionFooterHeight">10</float>
+ </object>
+ </object>
+ <string key="NSFrameSize">{768, 768}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <object class="IBUISimulatedOrientationMetrics" key="IBUISimulatedOrientationMetrics">
+ <int key="interfaceOrientation">3</int>
+ </object>
+ <string key="targetRuntimeIdentifier">IBIPadFramework</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">view</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="766721923"/>
+ </object>
+ <int key="connectionID">3</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="422926197"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">6</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">dataSource</string>
+ <reference key="source" ref="399289716"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">8</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="399289716"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">9</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">tableView</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="399289716"/>
+ </object>
+ <int key="connectionID">10</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">buttonPressed:</string>
+ <reference key="source" ref="882246004"/>
+ <reference key="destination" ref="841351856"/>
+ </object>
+ <int key="connectionID">17</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <reference key="object" ref="0"/>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="606714003"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="766721923"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="832454237"/>
+ <reference ref="399289716"/>
+ </object>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">4</int>
+ <reference key="object" ref="832454237"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="422926197"/>
+ <reference ref="881124109"/>
+ <reference ref="882246004"/>
+ </object>
+ <reference key="parent" ref="766721923"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="422926197"/>
+ <reference key="parent" ref="832454237"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">7</int>
+ <reference key="object" ref="399289716"/>
+ <reference key="parent" ref="766721923"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">13</int>
+ <reference key="object" ref="881124109"/>
+ <reference key="parent" ref="832454237"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">15</int>
+ <reference key="object" ref="882246004"/>
+ <reference key="parent" ref="832454237"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>13.IBPluginDependency</string>
+ <string>15.IBPluginDependency</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>4.IBPluginDependency</string>
+ <string>5.IBPluginDependency</string>
+ <string>7.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>SavedGamesViewController</string>
+ <string>UIResponder</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>{{467, 276}, {768, 768}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference key="dict.sortedKeys" ref="0"/>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">17</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">SavedGamesViewController</string>
+ <string key="superclassName">UIViewController</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">buttonPressed:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">buttonPressed:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">buttonPressed:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">tableView</string>
+ <string key="NS.object.0">UITableView</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">tableView</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">tableView</string>
+ <string key="candidateClassName">UITableView</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/SavedGamesViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/ExtraCategories.h</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSError.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSFileManager.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueCoding.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyValueObserving.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSKeyedArchiver.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSObject.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSRunLoop.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSThread.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURL.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">Foundation.framework/Headers/NSURLConnection.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CAAnimation.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">QuartzCore.framework/Headers/CALayer.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIAccessibility.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINibLoading.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="786211723">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIResponder.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarButtonItem</string>
+ <string key="superclassName">UIBarItem</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarButtonItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIBarItem</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIBarItem.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIResponder</string>
+ <string key="superclassName">NSObject</string>
+ <reference key="sourceIdentifier" ref="786211723"/>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIScrollView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIScrollView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchBar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchBar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UISearchDisplayController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISearchDisplayController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UITableView</string>
+ <string key="superclassName">UIScrollView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITableView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIToolbar</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIToolbar.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPrintFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITextField.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIView</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIView.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UINavigationController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIPopoverController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UISplitViewController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UITabBarController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">UIViewController</string>
+ <string key="superclassName">UIResponder</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBFrameworkSource</string>
+ <string key="minorKey">UIKit.framework/Headers/UIViewController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBIPadFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
+ <integer value="1056" key="NS.object.0"/>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
+ <integer value="3100" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../Hedgewars.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <string key="IBCocoaTouchPluginVersion">132</string>
+ </data>
+</archive>
diff --git a/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.h b/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.h
new file mode 100644
index 0000000..5b71709
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.h
@@ -0,0 +1,32 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class SingleSchemeViewController;
+
+ at interface SchemeSettingsViewController : UITableViewController {
+ NSMutableArray *listOfSchemes;
+ SingleSchemeViewController *childController;
+}
+
+ at property (nonatomic, retain) NSMutableArray *listOfSchemes;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.m b/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.m
new file mode 100644
index 0000000..3f445e1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SchemeSettingsViewController.m
@@ -0,0 +1,176 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SchemeSettingsViewController.h"
+#import "SingleSchemeViewController.h"
+
+
+ at implementation SchemeSettingsViewController
+ at synthesize listOfSchemes;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Edit",@"")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(toggleEdit:)];
+ self.navigationItem.rightBarButtonItem = editButton;
+ [editButton release];
+
+ self.navigationItem.title = @"List of schemes";
+}
+
+-(void) viewWillAppear:(BOOL) animated {
+ [super viewWillAppear:animated];
+
+ NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:SCHEMES_DIRECTORY() error:NULL];
+ NSMutableArray *array = [[NSMutableArray alloc] initWithArray:contentsOfDir copyItems:YES];
+ self.listOfSchemes = array;
+ [array release];
+
+ [self.tableView reloadData];
+}
+
+// modifies the navigation bar to add the "Add" and "Done" buttons
+-(void) toggleEdit:(id) sender {
+ BOOL isEditing = self.tableView.editing;
+ [self.tableView setEditing:!isEditing animated:YES];
+
+ if (isEditing) {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Edit",@"from the scheme panel")];
+ [self.navigationItem.rightBarButtonItem setStyle: UIBarButtonItemStyleBordered];
+ self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;
+ } else {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Done",@"from the scheme panel")];
+ [self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
+ UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Add",@"from the scheme panel")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(addScheme:)];
+ self.navigationItem.leftBarButtonItem = addButton;
+ [addButton release];
+ }
+}
+
+-(void) addScheme:(id) sender {
+ NSString *fileName = [[NSString alloc] initWithFormat:@"Scheme %u.plist", [self.listOfSchemes count]];
+
+ [CreationChamber createSchemeNamed:[fileName stringByDeletingPathExtension]];
+
+ [self.listOfSchemes addObject:fileName];
+
+ // order the array alphabetically, so schemes will keep their position
+ [self.listOfSchemes sortUsingSelector:@selector(compare:)];
+ [self.tableView reloadData];
+
+ NSInteger index = [self.listOfSchemes indexOfObject:fileName];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
+ [fileName release];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.listOfSchemes count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ NSUInteger row = [indexPath row];
+ NSString *rowString = [[self.listOfSchemes objectAtIndex:row] stringByDeletingPathExtension];
+ cell.textLabel.text = rowString;
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+
+ return cell;
+}
+
+// delete the row and the file
+-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSUInteger row = [indexPath row];
+
+ NSString *schemeFile = [[NSString alloc] initWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),[self.listOfSchemes objectAtIndex:row]];
+ [[NSFileManager defaultManager] removeItemAtPath:schemeFile error:NULL];
+ [schemeFile release];
+
+ [self.listOfSchemes removeObjectAtIndex:row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (childController == nil) {
+ childController = [[SingleSchemeViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ }
+
+ NSInteger row = [indexPath row];
+ NSString *selectedSchemeFile = [self.listOfSchemes objectAtIndex:row];
+
+ // this must be set so childController can load the correct plist
+ childController.schemeName = [selectedSchemeFile stringByDeletingPathExtension];
+ [childController.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+
+ [self.navigationController pushViewController:childController animated:YES];
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ if (childController.view.superview == nil )
+ childController = nil;
+ MSG_MEMCLEAN();
+}
+
+-(void) viewDidUnload {
+ self.listOfSchemes = nil;
+ childController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(listOfSchemes);
+ releaseAndNil(childController);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.h b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.h
new file mode 100644
index 0000000..3097b41
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.h
@@ -0,0 +1,57 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface SchemeWeaponConfigViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
+ NSArray *listOfSchemes;
+ NSArray *listOfWeapons;
+ NSArray *listOfScripts;
+
+ NSIndexPath *lastIndexPath_sc;
+ NSIndexPath *lastIndexPath_we;
+ NSIndexPath *lastIndexPath_lu;
+
+ NSString *selectedScheme;
+ NSString *selectedWeapon;
+ NSString *selectedScript;
+ NSString *scriptCommand;
+
+ UISegmentedControl *topControl;
+ BOOL sectionsHidden;
+}
+
+ at property (nonatomic,retain) NSArray *listOfSchemes;
+ at property (nonatomic,retain) NSArray *listOfWeapons;
+ at property (nonatomic,retain) NSArray *listOfScripts;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath_sc;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath_we;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath_lu;
+ at property (nonatomic,retain) NSString *selectedScheme;
+ at property (nonatomic,retain) NSString *selectedWeapon;
+ at property (nonatomic,retain) NSString *selectedScript;
+ at property (nonatomic,retain) NSString *scriptCommand;
+ at property (nonatomic,retain) UISegmentedControl *topControl;
+ at property (nonatomic,assign) BOOL sectionsHidden;
+
+-(void) fillSections;
+-(void) emptySections;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m
new file mode 100644
index 0000000..1ef09a7
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m
@@ -0,0 +1,436 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SchemeWeaponConfigViewController.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+#define LABEL_TAG 57423
+#define TABLE_TAG 45657
+
+ at implementation SchemeWeaponConfigViewController
+ at synthesize listOfSchemes, listOfWeapons, listOfScripts, lastIndexPath_sc, lastIndexPath_we, lastIndexPath_lu,
+ selectedScheme, selectedWeapon, selectedScript, scriptCommand, topControl, sectionsHidden;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark custom setters/getters
+-(NSString *)selectedScheme {
+ if (selectedScheme == nil)
+ self.selectedScheme = @"Default.plist";
+ return selectedScheme;
+}
+
+-(NSString *)selectedWeapon {
+ if (selectedWeapon == nil)
+ self.selectedWeapon = @"Default.plist";
+ return selectedWeapon;
+}
+
+-(NSString *)selectedScript {
+ if (selectedScript == nil)
+ self.selectedScript = @"Normal.plist";
+ return selectedScript;
+}
+
+-(NSString *)scriptCommand {
+ if (scriptCommand == nil)
+ self.scriptCommand = @"";
+ return scriptCommand;
+}
+
+-(NSArray *)listOfSchemes {
+ if (listOfSchemes == nil)
+ self.listOfSchemes = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:SCHEMES_DIRECTORY() error:NULL];
+ return listOfSchemes;
+}
+
+-(NSArray *)listOfWeapons {
+ if (listOfWeapons == nil)
+ self.listOfWeapons = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:WEAPONS_DIRECTORY() error:NULL];
+ return listOfWeapons;
+}
+
+-(NSArray *)listOfScripts {
+ if (listOfScripts == nil)
+ self.listOfScripts = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:SCRIPTS_DIRECTORY() error:NULL]
+ filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF ENDSWITH '.lua'"]];
+ return listOfScripts;
+}
+
+-(UISegmentedControl *)topControl {
+ if (topControl == nil) {
+ NSArray *array = [[NSArray alloc] initWithObjects:
+ NSLocalizedString(@"Scheme",@""),
+ NSLocalizedString(@"Weapon",@""),
+ NSLocalizedString(@"Style",@""),nil];
+ UISegmentedControl *controller = [[UISegmentedControl alloc] initWithItems:array];
+ [array release];
+ controller.segmentedControlStyle = UISegmentedControlStyleBar;
+ controller.tintColor = [UIColor lightGrayColor];
+ controller.selectedSegmentIndex = 0;
+ self.topControl = controller;
+ [controller release];
+ }
+ return topControl;
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ self.sectionsHidden = NO;
+
+ NSInteger topOffset = IS_IPAD() ? 45 : 0;
+ NSInteger bottomOffset = IS_IPAD() ? 3 : 0;
+ UITableView *aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0,
+ topOffset,
+ self.view.frame.size.width,
+ self.view.frame.size.height - topOffset - bottomOffset)
+ style:UITableViewStyleGrouped];
+ aTableView.delegate = self;
+ aTableView.dataSource = self;
+ if (IS_IPAD()) {
+ [aTableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+ UILabel *background = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
+ andTitle:nil
+ withBorderWidth:2.7f];
+ background.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view insertSubview:background atIndex:0];
+ [background release];
+
+ self.topControl.frame = CGRectMake(0, 4, self.view.frame.size.width * 80/100, 30);
+ self.topControl.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ self.topControl.center = CGPointMake(self.view.frame.size.width/2, 24);
+ [self.topControl addTarget:aTableView action:@selector(reloadData) forControlEvents:UIControlEventValueChanged];
+ [self.view addSubview:self.topControl];
+ } else {
+ UIImage *backgroundImage = [[UIImage alloc] initWithContentsOfFile:@"background~iphone.png"];
+ UIImageView *background = [[UIImageView alloc] initWithImage:backgroundImage];
+ [backgroundImage release];
+ [self.view addSubview:background];
+ [background release];
+ [aTableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+ }
+
+ aTableView.tag = TABLE_TAG;
+ aTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
+ aTableView.separatorColor = [UIColor whiteColor];
+ aTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ aTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:aTableView];
+ [aTableView release];
+
+ [super viewDidLoad];
+
+ // display or hide the lists, driven by MapConfigViewController
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(fillSections)
+ name:@"fillsections"
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(emptySections)
+ name:@"emptysections"
+ object:nil];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)aTableView {
+ return (self.sectionsHidden ? 0 : 1);
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (self.topControl.selectedSegmentIndex == 0)
+ return [self.listOfSchemes count];
+ else if (self.topControl.selectedSegmentIndex == 1)
+ return [self.listOfWeapons count];
+ else
+ return [self.listOfScripts count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+ NSInteger index = self.topControl.selectedSegmentIndex;
+ NSInteger row = [indexPath row];
+
+ UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
+
+ cell.accessoryView = nil;
+ if (0 == index) {
+ cell.textLabel.text = [[self.listOfSchemes objectAtIndex:row] stringByDeletingPathExtension];
+ NSString *str = [NSString stringWithFormat:@"%@/%@",SCHEMES_DIRECTORY(),[self.listOfSchemes objectAtIndex:row]];
+ NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:str];
+ cell.detailTextLabel.text = [dict objectForKey:@"description"];
+ [dict release];
+ if ([[self.listOfSchemes objectAtIndex:row] isEqualToString:self.selectedScheme]) {
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ cell.accessoryView = checkbox;
+ [checkbox release];
+ self.lastIndexPath_sc = indexPath;
+ }
+ } else if (1 == index) {
+ cell.textLabel.text = [[self.listOfWeapons objectAtIndex:row] stringByDeletingPathExtension];
+ NSString *str = [NSString stringWithFormat:@"%@/%@",WEAPONS_DIRECTORY(),[self.listOfWeapons objectAtIndex:row]];
+ NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:str];
+ cell.detailTextLabel.text = [dict objectForKey:@"description"];
+ [dict release];
+ if ([[self.listOfWeapons objectAtIndex:row] isEqualToString:self.selectedWeapon]) {
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ cell.accessoryView = checkbox;
+ [checkbox release];
+ self.lastIndexPath_we = indexPath;
+ }
+ } else {
+ cell.textLabel.text = [[[self.listOfScripts objectAtIndex:row] stringByDeletingPathExtension]
+ stringByReplacingOccurrencesOfString:@"_" withString:@" "];
+ //cell.detailTextLabel.text = ;
+ if ([[self.listOfScripts objectAtIndex:row] isEqualToString:self.selectedScript]) {
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ cell.accessoryView = checkbox;
+ [checkbox release];
+ self.lastIndexPath_lu = indexPath;
+ }
+ }
+
+ cell.backgroundColor = [UIColor blackColorTransparent];
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ cell.detailTextLabel.textColor = [UIColor whiteColor];
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
+ return cell;
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForHeaderInSection:(NSInteger) section {
+ return IS_IPAD() ? 0 : 50;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger) section {
+ if (IS_IPAD())
+ return nil;
+ UIView *theView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 30)];
+ theView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+ self.topControl.frame = CGRectMake(0, 0, self.view.frame.size.width * 80/100, 30);
+ self.topControl.center = CGPointMake(self.view.frame.size.width/2, 24);
+ [self.topControl addTarget:aTableView action:@selector(reloadData) forControlEvents:UIControlEventValueChanged];
+ [theView addSubview:self.topControl];
+ return [theView autorelease];
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForFooterInSection:(NSInteger) section {
+ return 40;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForFooterInSection:(NSInteger) section {
+ NSInteger height = 40;
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width, height)];
+ footer.backgroundColor = [UIColor clearColor];
+ footer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*80/100, height)];
+ label.center = CGPointMake(aTableView.frame.size.width/2, height/2);
+ label.textAlignment = UITextAlignmentCenter;
+ label.font = [UIFont italicSystemFontOfSize:12];
+ label.textColor = [UIColor whiteColor];
+ label.numberOfLines = 2;
+ label.backgroundColor = [UIColor clearColor];
+ label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+
+ label.text = NSLocalizedString(@"Setting a Style might force a particular Scheme or Weapon configuration.",@"");
+
+ [footer addSubview:label];
+ [label release];
+ return [footer autorelease];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSIndexPath *lastIndexPath;
+ NSInteger index = self.topControl.selectedSegmentIndex;
+ if (index == 0)
+ lastIndexPath = self.lastIndexPath_sc;
+ else if (index == 1)
+ lastIndexPath = self.lastIndexPath_we;
+ else
+ lastIndexPath = self.lastIndexPath_lu;
+
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ //TODO: this code works only for a single section table
+ UITableViewCell *newCell = [aTableView cellForRowAtIndexPath:indexPath];
+ UIImageView *checkbox = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"checkbox.png"]];
+ newCell.accessoryView = checkbox;
+ [checkbox release];
+ UITableViewCell *oldCell = [aTableView cellForRowAtIndexPath:lastIndexPath];
+ oldCell.accessoryView = nil;
+
+ if (index == 0) {
+ self.lastIndexPath_sc = indexPath;
+ self.selectedScheme = [self.listOfSchemes objectAtIndex:newRow];
+
+ // also set weaponset when selecting scheme, if set
+ NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
+ if ([[settings objectForKey:@"sync_ws"] boolValue]) {
+ for (NSString *str in self.listOfWeapons) {
+ if ([str isEqualToString:self.selectedScheme]) {
+ int row = [self.listOfSchemes indexOfObject:str];
+ self.selectedWeapon = str;
+ self.lastIndexPath_we = [NSIndexPath indexPathForRow:row inSection:1];
+ break;
+ }
+ }
+ }
+ } else if (index == 1) {
+ self.lastIndexPath_we = indexPath;
+ self.selectedWeapon = [self.listOfWeapons objectAtIndex:newRow];
+ } else {
+ self.lastIndexPath_lu = indexPath;
+ self.selectedScript = [self.listOfScripts objectAtIndex:newRow];
+
+ // some styles disable or force the choice of a particular scheme/weaponset
+ NSString *path = [[NSString alloc] initWithFormat:@"%@/%@.cfg",SCRIPTS_DIRECTORY(),[self.selectedScript stringByDeletingPathExtension]];
+ NSString *configFile = [[NSString alloc] initWithContentsOfFile:path];
+ [path release];
+ NSArray *scriptOptions = [configFile componentsSeparatedByString:@"\n"];
+ [configFile release];
+
+ self.scriptCommand = [NSString stringWithFormat:@"escript Scripts/Multiplayer/%@",self.selectedScript];
+ NSString *scheme = [scriptOptions objectAtIndex:0];
+ if ([scheme isEqualToString:@"locked"]) {
+ self.selectedScheme = @"Default.plist";
+ [self.topControl setEnabled:NO forSegmentAtIndex:0];
+ } else {
+ self.selectedScheme = [NSString stringWithFormat:@"%@.plist",scheme];
+ [self.topControl setEnabled:YES forSegmentAtIndex:0];
+ }
+
+ NSString *weapon = [scriptOptions objectAtIndex:1];
+ if ([weapon isEqualToString:@"locked"]) {
+ self.selectedWeapon = @"Default.plist";
+ [self.topControl setEnabled:NO forSegmentAtIndex:1];
+ } else {
+ self.selectedWeapon = [NSString stringWithFormat:@"%@.plist",weapon];
+ [self.topControl setEnabled:YES forSegmentAtIndex:1];
+ }
+ }
+
+ [aTableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+#pragma mark -
+#pragma mark called by an NSNotification to empty or fill the sections completely
+-(void) fillSections {
+ if (self.sectionsHidden == YES) {
+ self.sectionsHidden = NO;
+ NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 1)];
+ UITableView *aTableView = (UITableView *)[self.view viewWithTag:TABLE_TAG];
+ [aTableView insertSections:sections withRowAnimation:UITableViewRowAnimationFade];
+ aTableView.scrollEnabled = YES;
+ [[self.view viewWithTag:LABEL_TAG] removeFromSuperview];
+ }
+}
+
+-(void) emptySections {
+ if (self.sectionsHidden == NO) {
+ self.sectionsHidden = YES;
+ NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 1)];
+ UITableView *aTableView = (UITableView *)[self.view viewWithTag:TABLE_TAG];
+ [aTableView deleteSections:sections withRowAnimation:UITableViewRowAnimationFade];
+ aTableView.scrollEnabled = NO;
+
+ CGRect frame = CGRectMake(0, 0, self.view.frame.size.width * 80/100, 60);
+ UILabel *theLabel = [[UILabel alloc] initWithFrame:frame
+ andTitle:NSLocalizedString(@"Missions don't need further configuration",@"")];
+ theLabel.center = CGPointMake(self.view.frame.size.width/2, self.view.frame.size.height/2);
+ theLabel.numberOfLines = 2;
+ theLabel.tag = LABEL_TAG;
+ theLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth |
+ UIViewAutoresizingFlexibleTopMargin |
+ UIViewAutoresizingFlexibleBottomMargin;
+
+ [self.view addSubview:theLabel];
+ [theLabel release];
+ }
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ if ([HWUtils isGameLaunched]) {
+ self.lastIndexPath_sc = nil;
+ self.lastIndexPath_we = nil;
+ self.lastIndexPath_lu = nil;
+ self.selectedScheme = nil;
+ self.selectedWeapon = nil;
+ self.selectedScript = nil;
+ self.scriptCommand = nil;
+ self.topControl = nil;
+ }
+ self.listOfSchemes = nil;
+ self.listOfWeapons = nil;
+ self.listOfScripts = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ self.listOfSchemes = nil;
+ self.listOfWeapons = nil;
+ self.listOfScripts = nil;
+ self.lastIndexPath_sc = nil;
+ self.lastIndexPath_we = nil;
+ self.lastIndexPath_lu = nil;
+ self.selectedScheme = nil;
+ self.selectedWeapon = nil;
+ self.selectedScript = nil;
+ self.scriptCommand = nil;
+ self.topControl = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(listOfSchemes);
+ releaseAndNil(listOfWeapons);
+ releaseAndNil(listOfScripts);
+ releaseAndNil(lastIndexPath_sc);
+ releaseAndNil(lastIndexPath_we);
+ releaseAndNil(lastIndexPath_lu);
+ releaseAndNil(selectedScheme);
+ releaseAndNil(selectedWeapon);
+ releaseAndNil(selectedScript);
+ releaseAndNil(scriptCommand);
+ releaseAndNil(topControl);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h
new file mode 100644
index 0000000..fa4c437
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.h
@@ -0,0 +1,40 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+#import "SDL_net.h"
+
+
+ at interface ServerProtocolNetwork : NSObject {
+ NSInteger serverPort;
+ NSString *serverAddress;
+ TCPsocket ssd;
+}
+
+ at property (assign) TCPsocket ssd;
+ at property (assign) NSInteger serverPort;
+ at property (nonatomic,retain) NSString *serverAddress;
+
+-(id) init;
+-(id) init:(NSInteger) onPort withAddress:(NSString *)address;
+-(id) initOnPort:(NSInteger) port;
+-(id) initToAddress:(NSString *)address;
++(id) openServerConnection;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m
new file mode 100644
index 0000000..326257b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/ServerProtocolNetwork.m
@@ -0,0 +1,212 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "ServerProtocolNetwork.h"
+#import "hwconsts.h"
+
+#define BUFFER_SIZE 256
+
+static ServerProtocolNetwork *serverConnection;
+
+ at implementation ServerProtocolNetwork
+ at synthesize serverPort, serverAddress, ssd;
+
+#pragma mark -
+#pragma mark init and class methods
+-(id) init:(NSInteger) onPort withAddress:(NSString *)address {
+ if ((self = [super init])) {
+ self.serverPort = onPort;
+ self.serverAddress = address;
+ }
+ serverConnection = self;
+ return self;
+}
+
+-(id) init {
+ return [self init:NETGAME_DEFAULT_PORT withAddress:@"netserver.hedgewars.org"];
+}
+
+-(id) initOnPort:(NSInteger) port {
+ return [self init:port withAddress:@"netserver.hedgewars.org"];
+}
+
+-(id) initToAddress:(NSString *)address {
+ return [self init:NETGAME_DEFAULT_PORT withAddress:address];
+}
+
+-(void) dealloc {
+ releaseAndNil(serverAddress);
+ serverConnection = nil;
+ [super dealloc];
+}
+
++(id) openServerConnection {
+ id connection = [[self alloc] init];
+ [NSThread detachNewThreadSelector:@selector(serverProtocol)
+ toTarget:connection
+ withObject:nil];
+ [connection retain]; // retain count here is +2
+ return connection;
+}
+
+#pragma mark -
+#pragma mark Communication layer
+-(int) sendToServer:(NSString *)command {
+ NSString *message = [[NSString alloc] initWithFormat:@"%@\n\n",command];
+ int result = SDLNet_TCP_Send(self.ssd, [message UTF8String], [message length]);
+ [message release];
+ return result;
+}
+
+-(int) sendToServer:(NSString *)command withArgument:(NSString *)argument {
+ NSString *message = [[NSString alloc] initWithFormat:@"%@\n%@\n\n",command,argument];
+ int result = SDLNet_TCP_Send(self.ssd, [message UTF8String], [message length]);
+ [message release];
+ return result;
+}
+
+-(void) serverProtocol {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ IPaddress ip;
+ BOOL clientQuit = NO;
+ char *buffer = (char *)malloc(sizeof(char)*BUFFER_SIZE);
+ int dim = BUFFER_SIZE;
+ uint8_t msgSize;
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+
+ if (SDLNet_Init() < 0) {
+ DLog(@"SDLNet_Init: %s", SDLNet_GetError());
+ clientQuit = YES;
+ }
+
+ // Resolving the host using NULL make network interface to listen
+ if (SDLNet_ResolveHost(&ip, [self.serverAddress UTF8String] , self.serverPort) < 0 && !clientQuit) {
+ DLog(@"SDLNet_ResolveHost: %s", SDLNet_GetError());
+ clientQuit = YES;
+ }
+
+ // Open a connection with the IP provided (listen on the host's port)
+ if (!(self.ssd = SDLNet_TCP_Open(&ip)) && !clientQuit) {
+ DLog(@"SDLNet_TCP_Open: %s %d", SDLNet_GetError(), self.serverPort);
+ clientQuit = YES;
+ }
+
+ DLog(@"Found server on port %d", self.serverPort);
+ while (!clientQuit) {
+ int index = 0;
+ BOOL exitBufferLoop = NO;
+ memset(buffer, '\0', dim);
+
+ while (exitBufferLoop != YES) {
+ msgSize = SDLNet_TCP_Recv(self.ssd, &buffer[index], 2);
+
+ // exit in case of error
+ if (msgSize <= 0) {
+ DLog(@"SDLNet_TCP_Recv: %s", SDLNet_GetError());
+ clientQuit = YES;
+ break;
+ }
+
+ // update index position and check for End-Of-Message
+ index += msgSize;
+ if (strncmp(&buffer[index-2], "\n\n", 2) == 0) {
+ exitBufferLoop = YES;
+ }
+
+ // if message is too big allocate new space
+ if (index >= dim) {
+ dim += BUFFER_SIZE;
+ buffer = (char *)realloc(buffer, dim);
+ if (buffer == NULL) {
+ clientQuit = YES;
+ break;
+ }
+ }
+ }
+
+ NSString *bufferedMessage = [[NSString alloc] initWithBytes:buffer length:index-2 encoding:NSASCIIStringEncoding];
+ NSArray *listOfCommands = [bufferedMessage componentsSeparatedByString:@"\n"];
+ [bufferedMessage release];
+ NSString *command = [listOfCommands objectAtIndex:0];
+ DLog(@"size = %d, %@", index-2, listOfCommands);
+ if ([command isEqualToString:@"PING"]) {
+ if ([listOfCommands count] > 1)
+ [self sendToServer:@"PONG" withArgument:[listOfCommands objectAtIndex:1]];
+ else
+ [self sendToServer:@"PONG"];
+ DLog(@"PONG");
+ }
+ else if ([command isEqualToString:@"NICK"]) {
+ //what is this for?
+ }
+ else if ([command isEqualToString:@"PROTO"]) {
+ //what is this for?
+ }
+ else if ([command isEqualToString:@"ROOM"]) {
+ //TODO: stub
+ }
+ else if ([command isEqualToString:@"LOBBY:LEFT"]) {
+ //TODO: stub
+ }
+ else if ([command isEqualToString:@"LOBBY:JOINED"]) {
+ //TODO: stub
+ }
+ else if ([command isEqualToString:@"ASKPASSWORD"]) {
+ NSString *pwd = [defaults objectForKey:@"password"];
+ [self sendToServer:@"PASSWORD" withArgument:pwd];
+ }
+ else if ([command isEqualToString:@"CONNECTED"]) {
+ int netProto;
+ char *versionStr;
+ HW_versionInfo(&netProto, &versionStr);
+ NSString *nick = [defaults objectForKey:@"username"];
+ [self sendToServer:@"NICK" withArgument:nick];
+ [self sendToServer:@"PROTO" withArgument:[NSString stringWithFormat:@"%d",netProto]];
+ }
+ else if ([command isEqualToString:@"SERVER_MESSAGE"]) {
+ DLog(@"%@", [listOfCommands objectAtIndex:1]);
+ }
+ else if ([command isEqualToString:@"WARNING"]) {
+ if ([listOfCommands count] > 1)
+ DLog(@"Server warning - %@", [listOfCommands objectAtIndex:1]);
+ else
+ DLog(@"Server warning - unknown");
+ }
+ else if ([command isEqualToString:@"ERROR"]) {
+ DLog(@"Server error - %@", [listOfCommands objectAtIndex:1]);
+ }
+ else if ([command isEqualToString:@"BYE"]) {
+ //TODO: handle "Reconnected too fast"
+ DLog(@"Server disconnected, reason: %@", [listOfCommands objectAtIndex:1]);
+ clientQuit = YES;
+ }
+ else {
+ DLog(@"Unknown/Unsupported message received: %@", command);
+ }
+ }
+ DLog(@"Server closed connection, ending thread");
+
+ free(buffer);
+ SDLNet_TCP_Close(self.ssd);
+ SDLNet_Quit();
+
+ [pool release];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.h b/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.h
new file mode 100644
index 0000000..10da723
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.h
@@ -0,0 +1,48 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class GeneralSettingsViewController;
+ at class TeamSettingsViewController;
+ at class WeaponSettingsViewController;
+ at class SchemeSettingsViewController;
+ at class SupportViewController;
+
+ at interface SettingsBaseViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITabBarControllerDelegate> {
+ UIViewController *targetController;
+ NSArray *controllerNames;
+ NSIndexPath *lastIndexPath;
+ UITabBarController *tabController;
+ GeneralSettingsViewController *generalSettingsViewController;
+ TeamSettingsViewController *teamSettingsViewController;
+ WeaponSettingsViewController *weaponSettingsViewController;
+ SchemeSettingsViewController *schemeSettingsViewController;
+ SupportViewController *supportViewController;
+}
+
+ at property (nonatomic, retain) UIViewController *targetController;
+ at property (nonatomic, retain) NSArray *controllerNames;
+ at property (nonatomic, retain) NSIndexPath *lastIndexPath;
+ at property (nonatomic, retain) UITabBarController *tabController;
+
+-(void) dismissSplitView;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m b/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m
new file mode 100644
index 0000000..f483172
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SettingsBaseViewController.m
@@ -0,0 +1,308 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SettingsBaseViewController.h"
+#import "GeneralSettingsViewController.h"
+#import "TeamSettingsViewController.h"
+#import "WeaponSettingsViewController.h"
+#import "SchemeSettingsViewController.h"
+#import "SupportViewController.h"
+
+
+ at implementation SettingsBaseViewController
+ at synthesize tabController, targetController, controllerNames, lastIndexPath;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ // the list of available controllers
+ NSArray *array = [[NSArray alloc] initWithObjects:NSLocalizedString(@"General",@""),
+ NSLocalizedString(@"Teams",@""),
+ NSLocalizedString(@"Weapons",@""),
+ NSLocalizedString(@"Schemes",@""),
+ NSLocalizedString(@"Support",@""),
+ nil];
+ self.controllerNames = array;
+ [array release];
+
+ UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+ target:self
+ action:@selector(dismissSplitView)];
+ if (IS_IPAD()) {
+ // this class gets loaded twice, we tell the difference by looking at targetController
+ if (self.targetController != nil) {
+ UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
+ tableView.delegate = self;
+ tableView.dataSource = self;
+ [tableView reloadData];
+ [self.view addSubview:tableView];
+ [self tableView:tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
+ [tableView release];
+ self.navigationItem.leftBarButtonItem = doneButton;
+ }
+ } else {
+ // this class just loads all controllers and set up tabbar and navigation controllers
+ NSMutableArray *tabBarNavigationControllers = [[NSMutableArray alloc] initWithCapacity:5];
+ UINavigationController *navController = nil;
+
+ if (nil == generalSettingsViewController) {
+ generalSettingsViewController = [[GeneralSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ generalSettingsViewController.tabBarItem.title = [self.controllerNames objectAtIndex:0];
+ generalSettingsViewController.tabBarItem.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/TargetBee.png",GRAPHICS_DIRECTORY()]];
+ navController = [[UINavigationController alloc] initWithRootViewController:generalSettingsViewController];
+ generalSettingsViewController.navigationItem.backBarButtonItem = doneButton;
+ generalSettingsViewController.navigationItem.leftBarButtonItem = doneButton;
+ [generalSettingsViewController release];
+ [tabBarNavigationControllers addObject:navController];
+ releaseAndNil(navController);
+ }
+ if (nil == teamSettingsViewController) {
+ teamSettingsViewController = [[TeamSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ teamSettingsViewController.tabBarItem.title = [self.controllerNames objectAtIndex:1];
+ teamSettingsViewController.tabBarItem.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/Egg.png",GRAPHICS_DIRECTORY()]];
+ navController = [[UINavigationController alloc] initWithRootViewController:teamSettingsViewController];
+ teamSettingsViewController.navigationItem.backBarButtonItem = doneButton;
+ teamSettingsViewController.navigationItem.leftBarButtonItem = doneButton;
+ [tabBarNavigationControllers addObject:navController];
+ releaseAndNil(navController);
+ }
+ if (nil == weaponSettingsViewController) {
+ weaponSettingsViewController = [[WeaponSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ weaponSettingsViewController.tabBarItem.title = [self.controllerNames objectAtIndex:2];
+ weaponSettingsViewController.tabBarItem.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/cheese.png",GRAPHICS_DIRECTORY()]];
+ navController = [[UINavigationController alloc] initWithRootViewController:weaponSettingsViewController];
+ weaponSettingsViewController.navigationItem.backBarButtonItem = doneButton;
+ weaponSettingsViewController.navigationItem.leftBarButtonItem = doneButton;
+ [tabBarNavigationControllers addObject:navController];
+ releaseAndNil(navController);
+ }
+ if (nil == schemeSettingsViewController) {
+ schemeSettingsViewController = [[SchemeSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ schemeSettingsViewController.tabBarItem.title = [self.controllerNames objectAtIndex:3];
+ schemeSettingsViewController.tabBarItem.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/Targetp.png",GRAPHICS_DIRECTORY()]];
+ navController = [[UINavigationController alloc] initWithRootViewController:schemeSettingsViewController];
+ schemeSettingsViewController.navigationItem.backBarButtonItem = doneButton;
+ schemeSettingsViewController.navigationItem.leftBarButtonItem = doneButton;
+ [tabBarNavigationControllers addObject:navController];
+ releaseAndNil(navController);
+ }
+ if (nil == supportViewController) {
+ supportViewController = [[SupportViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ supportViewController.tabBarItem.title = [self.controllerNames objectAtIndex:4];
+ supportViewController.tabBarItem.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/Seduction.png",GRAPHICS_DIRECTORY()]];
+ navController = [[UINavigationController alloc] initWithRootViewController:supportViewController];
+ supportViewController.navigationItem.backBarButtonItem = doneButton;
+ supportViewController.navigationItem.leftBarButtonItem = doneButton;
+ [tabBarNavigationControllers addObject:navController];
+ releaseAndNil(navController);
+ }
+
+ self.tabController = [[UITabBarController alloc] init];
+ self.tabController.viewControllers = tabBarNavigationControllers;
+ self.tabController.delegate = self;
+
+ [self.view addSubview:self.tabController.view];
+ }
+ [doneButton release];
+ [super viewDidLoad];
+}
+
+-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
+ [viewController viewWillAppear:NO];
+}
+
+-(void) dismissSplitView {
+ [[AudioManagerController mainManager] playBackSound];
+ [[[HedgewarsAppDelegate sharedAppDelegate] mainViewController] dismissModalViewControllerAnimated:YES];
+}
+
+-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ if (IS_IPAD() == NO)
+ return;
+
+ if (self.targetController != nil) {
+ CGRect screenRect = [[UIScreen mainScreen] safeBounds];
+ self.view.frame = CGRectMake(0, 0, 320, screenRect.size.height);
+ }
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.controllerNames count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+
+ NSString *iconStr = nil;
+ switch ([indexPath row]) {
+ case 0:
+ iconStr = [NSString stringWithFormat:@"%@/TargetBee.png",GRAPHICS_DIRECTORY()];
+ break;
+ case 1:
+ iconStr = [NSString stringWithFormat:@"%@/Egg.png",GRAPHICS_DIRECTORY()];
+ break;
+ case 2:
+ iconStr = [NSString stringWithFormat:@"%@/cheese.png",GRAPHICS_DIRECTORY()];
+ break;
+ case 3:
+ iconStr = [NSString stringWithFormat:@"%@/Target.png",GRAPHICS_DIRECTORY()];
+ break;
+ case 4:
+ iconStr = [NSString stringWithFormat:@"%@/Seduction.png",GRAPHICS_DIRECTORY()];
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ cell.textLabel.text = [controllerNames objectAtIndex:[indexPath row]];
+ UIImage *icon = [[UIImage alloc] initWithContentsOfFile:iconStr];
+ cell.imageView.image = icon;
+ [icon release];
+
+ return cell;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+ UIViewController *nextController = nil;
+
+ if (newRow != oldRow) {
+ [tableView deselectRowAtIndexPath:lastIndexPath animated:YES];
+ [targetController.navigationController popToRootViewControllerAnimated:NO];
+
+ switch (newRow) {
+ case 0:
+ if (nil == generalSettingsViewController)
+ generalSettingsViewController = [[GeneralSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ nextController = generalSettingsViewController;
+ break;
+ case 1:
+ if (nil == teamSettingsViewController)
+ teamSettingsViewController = [[TeamSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ nextController = teamSettingsViewController;
+ break;
+ case 2:
+ if (nil == weaponSettingsViewController)
+ weaponSettingsViewController = [[WeaponSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ nextController = weaponSettingsViewController;
+ break;
+ case 3:
+ if (nil == schemeSettingsViewController)
+ schemeSettingsViewController = [[SchemeSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ nextController = schemeSettingsViewController;
+ break;
+ case 4:
+ if (nil == supportViewController)
+ supportViewController = [[SupportViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ nextController = supportViewController;
+ break;
+ }
+
+ self.lastIndexPath = indexPath;
+ [tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+
+ nextController.navigationItem.hidesBackButton = YES;
+ [nextController viewWillAppear:NO];
+ [targetController.navigationController pushViewController:nextController animated:NO];
+ [[AudioManagerController mainManager] playClickSound];
+ }
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ if (generalSettingsViewController.view.superview == nil)
+ generalSettingsViewController = nil;
+ if (teamSettingsViewController.view.superview == nil)
+ teamSettingsViewController = nil;
+ if (weaponSettingsViewController.view.superview == nil)
+ weaponSettingsViewController = nil;
+ if (schemeSettingsViewController.view.superview == nil)
+ schemeSettingsViewController = nil;
+ if (supportViewController.view.superview == nil)
+ supportViewController = nil;
+ if (tabController.view.superview == nil)
+ tabController = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.controllerNames = nil;
+ self.lastIndexPath = nil;
+ self.targetController = nil;
+ self.tabController = nil;
+ generalSettingsViewController = nil;
+ teamSettingsViewController = nil;
+ weaponSettingsViewController = nil;
+ schemeSettingsViewController = nil;
+ supportViewController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(targetController);
+ releaseAndNil(controllerNames);
+ releaseAndNil(lastIndexPath);
+ releaseAndNil(tabController);
+ releaseAndNil(generalSettingsViewController);
+ releaseAndNil(teamSettingsViewController);
+ releaseAndNil(weaponSettingsViewController);
+ releaseAndNil(schemeSettingsViewController);
+ releaseAndNil(supportViewController);
+ [super dealloc];
+}
+
+
+-(void) viewWillDisappear:(BOOL)animated {
+ // this will send -viewWillDisappear: only the active view
+ [self.tabController viewWillDisappear:animated];
+ // let's send that to every page, even though only GeneralSettingsViewController needs it
+ [generalSettingsViewController viewWillDisappear:animated];
+ [teamSettingsViewController viewWillDisappear:animated];
+ [weaponSettingsViewController viewWillDisappear:animated];
+ [schemeSettingsViewController viewWillDisappear:animated];
+ [supportViewController viewWillDisappear:animated];
+ [super viewWillDisappear:animated];
+}
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.h b/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.h
new file mode 100644
index 0000000..24eab16
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.h
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class SettingsBaseViewController;
+ at class MGSplitViewController;
+
+ at interface SettingsContainerViewController : UIViewController {
+ SettingsBaseViewController *baseController;
+ MGSplitViewController *splitViewRootController;
+}
+
+ at property (nonatomic,retain) SettingsBaseViewController *baseController;
+ at property (nonatomic,retain) MGSplitViewController *splitViewRootController;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.m b/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.m
new file mode 100644
index 0000000..279f9ef
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SettingsContainerViewController.m
@@ -0,0 +1,142 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SettingsContainerViewController.h"
+#import "SettingsBaseViewController.h"
+#import "MGSplitViewController.h"
+
+
+ at implementation SettingsContainerViewController
+ at synthesize baseController, splitViewRootController;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(void) viewDidLoad {
+ CGRect screenRect = [[UIScreen mainScreen] safeBounds];
+ self.view.frame = screenRect;
+
+ if (IS_IPAD()) {
+ // the contents on the right of the splitview, setting targetController to nil to avoid creating the table
+ SettingsBaseViewController *rightController = [[SettingsBaseViewController alloc] init];
+ rightController.targetController = nil;
+ UINavigationController *rightNavController = [[UINavigationController alloc] initWithRootViewController:rightController];
+ [rightController release];
+
+ // the contens on the left of the splitview, setting targetController that will receive push/pop actions
+ SettingsBaseViewController *leftController = [[SettingsBaseViewController alloc] init];
+ leftController.targetController = rightNavController.topViewController;
+ UINavigationController *leftNavController = [[UINavigationController alloc] initWithRootViewController:leftController];
+ [leftController release];
+
+ self.splitViewRootController = [[MGSplitViewController alloc] init];
+ self.splitViewRootController.delegate = nil;
+ self.splitViewRootController.view.frame = screenRect;
+ self.splitViewRootController.viewControllers = [NSArray arrayWithObjects: leftNavController, rightNavController, nil];
+ self.splitViewRootController.showsMasterInPortrait = YES;
+ [leftNavController release];
+ [rightNavController release];
+
+ // add view to main controller
+ [self.view addSubview:self.splitViewRootController.view];
+ } else {
+ if (nil == self.baseController) {
+ SettingsBaseViewController *sbvc = [[SettingsBaseViewController alloc] init];
+ self.baseController = sbvc;
+ [sbvc release];
+ }
+ self.baseController.targetController = nil;
+ self.baseController.view.frame = screenRect;
+
+ [self.view addSubview:self.baseController.view];
+ }
+
+ [super viewDidLoad];
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ if (self.baseController.view.superview == nil)
+ self.baseController = nil;
+ if (self.splitViewRootController.view.superview == nil)
+ self.splitViewRootController = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.baseController = nil;
+ self.splitViewRootController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(baseController);
+ releaseAndNil(splitViewRootController);
+ [super dealloc];
+}
+
+
+#pragma mark -
+#pragma mark view event management propagation
+// every time we add a uiviewcontroller programmatically we need to take care of propgating such messages
+// see http://davidebenini.it/2009/01/03/viewwillappear-not-being-called-inside-a-uinavigationcontroller/
+-(void) viewWillAppear:(BOOL)animated {
+ [self.splitViewRootController.detailViewController viewWillAppear:animated];
+ [self.baseController viewWillAppear:animated];
+ [super viewWillAppear:animated];
+}
+
+-(void) viewWillDisappear:(BOOL)animated {
+ [self.splitViewRootController.detailViewController viewWillDisappear:animated];
+ [self.baseController viewWillDisappear:animated];
+ [super viewWillDisappear:animated];
+}
+
+-(void) viewDidAppear:(BOOL)animated {
+ [self.splitViewRootController.detailViewController viewDidAppear:animated];
+ [self.baseController viewDidAppear:animated];
+ [super viewDidAppear:animated];
+}
+
+-(void) viewDidDisappear:(BOOL)animated {
+ [self.splitViewRootController.detailViewController viewDidDisappear:animated];
+ [self.baseController viewDidDisappear:animated];
+ [super viewDidDisappear:animated];
+}
+
+-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ [self.splitViewRootController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [self.baseController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+}
+
+-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ [self.splitViewRootController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ [self.baseController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
+}
+
+-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [self.splitViewRootController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+ [self.baseController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.h b/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.h
new file mode 100644
index 0000000..e362463
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.h
@@ -0,0 +1,35 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface SingleSchemeViewController : UITableViewController <EditableCellViewDelegate> {
+ NSString *schemeName;
+ NSMutableDictionary *schemeDictionary;
+ NSArray *basicSettingList;
+ NSArray *gameModifierArray;
+}
+
+ at property (nonatomic, retain) NSString *schemeName;
+ at property (nonatomic, retain) NSMutableDictionary *schemeDictionary;
+ at property (nonatomic, retain) NSArray *basicSettingList;
+ at property (nonatomic, retain) NSArray *gameModifierArray;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m b/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m
new file mode 100644
index 0000000..63c7195
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m
@@ -0,0 +1,373 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SingleSchemeViewController.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+#define LABEL_TAG 12345
+#define SLIDER_TAG 54321
+#define SWITCH_TAG 67890
+
+#define checkValueString(detailString,labelSting,sliderRef); \
+ if ([labelSting isEqualToString:@"Turn Time"] && (NSInteger) sliderRef.value == 100) \
+ detailString = @"â"; \
+ else if ([labelSting isEqualToString:@"Water Rise Amount"] && (NSInteger) sliderRef.value == 100) \
+ detailString = NSLocalizedString(@"Nvr",@"Short for 'Never'"); \
+ else if ([labelSting isEqualToString:@"Crate Drop Turns"] && (NSInteger) sliderRef.value == 0) \
+ detailString = NSLocalizedString(@"Nvr",@"Short for 'Never'"); \
+ else if ([labelSting isEqualToString:@"Mines Time"] && (NSInteger) sliderRef.value == -1) \
+ detailString = NSLocalizedString(@"Rnd",@"Short for 'Random'"); \
+ else \
+ detailString = [NSString stringWithFormat:@"%d",(NSInteger) sliderRef.value];
+
+
+ at implementation SingleSchemeViewController
+ at synthesize schemeName, schemeDictionary, basicSettingList, gameModifierArray;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ // title, description, image name (+btn)
+ NSArray *mods = [[NSArray alloc] initWithContentsOfFile:GAMEMODS_FILE()];
+ self.gameModifierArray = mods;
+ [mods release];
+
+ // title, image name (+icon), default value, max value, min value
+ NSArray *basicSettings = [[NSArray alloc] initWithContentsOfFile:BASICFLAGS_FILE()];
+ self.basicSettingList = basicSettings;
+ [basicSettings release];
+
+ self.title = NSLocalizedString(@"Edit scheme preferences",@"");
+}
+
+// load from file
+-(void) viewWillAppear:(BOOL) animated {
+ [super viewWillAppear:animated];
+
+ NSString *schemeFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.schemeName];
+ NSMutableDictionary *scheme = [[NSMutableDictionary alloc] initWithContentsOfFile:schemeFile];
+ [schemeFile release];
+ self.schemeDictionary = scheme;
+ [scheme release];
+
+ [self.tableView reloadData];
+}
+
+// save to file
+-(void) viewWillDisappear:(BOOL) animated {
+ [super viewWillDisappear:animated];
+
+ NSString *schemeFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.schemeName];
+ [self.schemeDictionary writeToFile:schemeFile atomically:YES];
+ [schemeFile release];
+}
+
+// force a redraw of the game mod section to reposition the slider
+-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ if (IS_IPAD() == NO)
+ return;
+ [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
+}
+
+#pragma mark -
+#pragma mark editableCellView delegate
+// set the new value
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue {
+ if (tagValue == 0) {
+ // delete old file
+ [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.schemeName] error:NULL];
+ // update filename
+ self.schemeName = textString;
+ // save new file
+ [self.schemeDictionary writeToFile:[NSString stringWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.schemeName] atomically:YES];
+ } else {
+ [self.schemeDictionary setObject:textString forKey:@"description"];
+ }
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 3;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ switch (section) {
+ case 0:
+ return 2;
+ break;
+ case 1:
+ return [[self.schemeDictionary objectForKey:@"basic"] count];
+ break;
+ case 2:
+ return [[self.schemeDictionary objectForKey:@"gamemod"] count];
+ default:
+ break;
+ }
+ return 0;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ static NSString *CellIdentifier1 = @"Cell1";
+ static NSString *CellIdentifier2 = @"Cell2";
+
+ UITableViewCell *cell = nil;
+ EditableCellView *editableCell = nil;
+ NSInteger row = [indexPath row];
+
+ switch ([indexPath section]) {
+ case 0:
+ editableCell = (EditableCellView *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (editableCell == nil) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault
+ reuseIdentifier:CellIdentifier0] autorelease];
+ editableCell.delegate = self;
+ }
+ editableCell.tag = row;
+ editableCell.selectionStyle = UITableViewCellSelectionStyleNone;
+ editableCell.imageView.image = nil;
+ editableCell.detailTextLabel.text = nil;
+
+ if (row == 0) {
+ editableCell.textField.text = self.schemeName;
+ editableCell.textField.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ } else {
+ editableCell.minimumCharacters = 0;
+ editableCell.textField.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
+ editableCell.textField.text = [self.schemeDictionary objectForKey:@"description"];
+ editableCell.textField.placeholder = NSLocalizedString(@"You can add a description if you wish",@"");
+ }
+ cell = editableCell;
+ break;
+ case 1:
+ cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier1];
+ NSDictionary *detail = [self.basicSettingList objectAtIndex:row];
+ // need to offset this section (see format in CommodityFunctions.m and above)
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
+ reuseIdentifier:CellIdentifier1] autorelease];
+
+ UISlider *slider = [[UISlider alloc] init];
+ [slider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
+ [cell.contentView addSubview:slider];
+ [slider release];
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 7, 200, 30)];
+ label.tag = LABEL_TAG;
+ label.backgroundColor = [UIColor clearColor];
+ label.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ [cell.contentView addSubview:label];
+ [label release];
+ }
+
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/icon%@.png",ICONS_DIRECTORY(),
+ [[self.basicSettingList objectAtIndex:row] objectForKey:@"image"]]];
+ cell.imageView.image = img;
+ [img release];
+
+ UILabel *cellLabel = (UILabel *)[cell.contentView viewWithTag:LABEL_TAG];
+ cellLabel.text = [[self.basicSettingList objectAtIndex:row] objectForKey:@"title"];
+ cellLabel.adjustsFontSizeToFitWidth = YES;
+
+ // can't use the viewWithTag method because row is dynamic
+ UISlider *cellSlider = nil;
+ for (UIView *oneView in cell.contentView.subviews) {
+ if ([oneView isMemberOfClass:[UISlider class]]) {
+ cellSlider = (UISlider *)oneView;
+ break;
+ }
+ }
+ cellSlider.tag = SLIDER_TAG + row;
+ cellSlider.maximumValue = [[detail objectForKey:@"max"] floatValue];
+ cellSlider.minimumValue = [[detail objectForKey:@"min"] floatValue];
+ cellSlider.value = [[[self.schemeDictionary objectForKey:@"basic"] objectAtIndex:row] floatValue];
+ // redraw the slider here
+ NSInteger hOffset = 260;
+ NSInteger vOffset = 12;
+ NSInteger sliderLength = 150;
+ if (IS_IPAD()) {
+ hOffset = 310;
+ sliderLength = 230;
+ if (IS_ON_PORTRAIT()) {
+ hOffset = 50;
+ vOffset = 40;
+ sliderLength = 285;
+ }
+ }
+ cellSlider.frame = CGRectMake(hOffset, vOffset, sliderLength, 23);
+
+ NSString *prestring = nil;
+ checkValueString(prestring,cellLabel.text,cellSlider);
+
+ // forced to use this weird format otherwise the label disappears when size of the text is bigger than the original
+ while ([prestring length] <= 4)
+ prestring = [NSString stringWithFormat:@" %@",prestring];
+ cell.detailTextLabel.text = prestring;
+
+ cell.selectionStyle = UITableViewCellSelectionStyleBlue;
+ break;
+ case 2:
+ cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier2];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
+ reuseIdentifier:CellIdentifier2] autorelease];
+ UISwitch *onOff = [[UISwitch alloc] init];
+ [onOff addTarget:self action:@selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
+ cell.accessoryView = onOff;
+ [onOff release];
+ }
+
+ UISwitch *switcher = (UISwitch *)cell.accessoryView;
+ switcher.tag = SWITCH_TAG + row;
+ [switcher setOn:[[[self.schemeDictionary objectForKey:@"gamemod"] objectAtIndex:row] boolValue] animated:NO];
+
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/btn%@.png",ICONS_DIRECTORY(),
+ [[self.gameModifierArray objectAtIndex:row] objectForKey:@"image"]]];
+ cell.imageView.image = image;
+ [image release];
+ cell.imageView.layer.cornerRadius = 6.0f;
+ cell.imageView.layer.masksToBounds = YES;
+ cell.textLabel.text = [[self.gameModifierArray objectAtIndex:row] objectForKey:@"title"];
+ cell.detailTextLabel.text = [[self.gameModifierArray objectAtIndex:row] objectForKey:@"description"];
+ cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
+ cell.detailTextLabel.minimumFontSize = 6;
+
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ }
+
+ return cell;
+}
+
+-(void) toggleSwitch:(id) sender {
+ UISwitch *theSwitch = (UISwitch *)sender;
+ NSMutableArray *array = [self.schemeDictionary objectForKey:@"gamemod"];
+ [array replaceObjectAtIndex:theSwitch.tag-SWITCH_TAG withObject:[NSNumber numberWithBool:theSwitch.on]];
+}
+
+-(void) sliderChanged:(id) sender {
+ // the slider that changed is sent as object
+ UISlider *theSlider = (UISlider *)sender;
+ // create the indexPath of the row of the slider
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:theSlider.tag-SLIDER_TAG inSection:1];
+ // get its cell
+ UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+ // grab the associated labels
+ UILabel *detailLabel = (UILabel *)cell.detailTextLabel;
+ UILabel *cellLabel = (UILabel *)[cell.contentView viewWithTag:LABEL_TAG];
+ // modify it
+
+ checkValueString(detailLabel.text,cellLabel.text,theSlider);
+
+ // save changes in the main array
+ NSMutableArray *array = [self.schemeDictionary objectForKey:@"basic"];
+ [array replaceObjectAtIndex:theSlider.tag-SLIDER_TAG withObject:[NSNumber numberWithInt:(NSInteger) theSlider.value]];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath];
+ EditableCellView *editableCell = nil;
+ UISlider *cellSlider = nil;
+
+ switch ([indexPath section]) {
+ case 0:
+ editableCell = (EditableCellView *)cell;
+ [editableCell replyKeyboard];
+ break;
+ case 1:
+ cellSlider = (UISlider *)[cell.contentView viewWithTag:[indexPath row]+SLIDER_TAG];
+ [cellSlider setValue:[[[self.basicSettingList objectAtIndex:[indexPath row]] objectForKey:@"default"] floatValue] animated:YES];
+ [self sliderChanged:cellSlider];
+ //cell.detailTextLabel.text = [[[self.basicSettingList objectAtIndex:[indexPath row]] objectForKey:@"default"] stringValue];
+ break;
+ case 2:
+ /*sw = (UISwitch *)cell.accessoryView;
+ [sw setOn:!sw.on animated:YES];
+ [self toggleSwitch:sw];*/
+ break;
+ default:
+ break;
+ }
+
+ [aTableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+-(NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
+ NSString *sectionTitle = nil;
+ switch (section) {
+ case 0:
+ sectionTitle = NSLocalizedString(@"Scheme Name", @"");
+ break;
+ case 1:
+ sectionTitle = NSLocalizedString(@"Game Settings", @"");
+ break;
+ case 2:
+ sectionTitle = NSLocalizedString(@"Game Modifiers", @"");
+ break;
+ default:
+ DLog(@"nope");
+ break;
+ }
+ return sectionTitle;
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+ if ([indexPath section] == 0)
+ return aTableView.rowHeight;
+ else if ([indexPath section] == 1)
+ return IS_ON_PORTRAIT() ? 72 : aTableView.rowHeight;
+ else
+ return 56;
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ self.basicSettingList = nil;
+ self.gameModifierArray = nil;
+}
+
+-(void) viewDidUnload {
+ self.schemeName = nil;
+ self.schemeDictionary = nil;
+ self.basicSettingList = nil;
+ self.gameModifierArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(schemeName);
+ releaseAndNil(schemeDictionary);
+ releaseAndNil(basicSettingList);
+ releaseAndNil(gameModifierArray);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SingleTeamViewController.h b/project_files/HedgewarsMobile/Classes/SingleTeamViewController.h
new file mode 100644
index 0000000..9a90e2b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleTeamViewController.h
@@ -0,0 +1,57 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class HogHatViewController;
+ at class GravesViewController;
+ at class VoicesViewController;
+ at class FortsViewController;
+ at class FlagsViewController;
+ at class LevelViewController;
+
+ at interface SingleTeamViewController : UITableViewController <EditableCellViewDelegate> {
+ NSMutableDictionary *teamDictionary;
+
+ NSString *teamName;
+ UIImage *normalHogSprite;
+
+ NSArray *secondaryItems;
+ NSArray *moreSecondaryItems;
+ BOOL isWriteNeeded;
+
+ HogHatViewController *hogHatViewController;
+ GravesViewController *gravesViewController;
+ VoicesViewController *voicesViewController;
+ FortsViewController *fortsViewController;
+ FlagsViewController *flagsViewController;
+ LevelViewController *levelViewController;
+}
+
+ at property (nonatomic,retain) NSMutableDictionary *teamDictionary;
+ at property (nonatomic,retain) NSString *teamName;
+ at property (nonatomic,retain) UIImage *normalHogSprite;
+ at property (nonatomic,retain) NSArray *secondaryItems;
+ at property (nonatomic,retain) NSArray *moreSecondaryItems;
+
+-(void) writeFile;
+-(void) setWriteNeeded;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SingleTeamViewController.m b/project_files/HedgewarsMobile/Classes/SingleTeamViewController.m
new file mode 100644
index 0000000..562cade
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleTeamViewController.m
@@ -0,0 +1,412 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SingleTeamViewController.h"
+#import <QuartzCore/QuartzCore.h>
+#import "HogHatViewController.h"
+#import "GravesViewController.h"
+#import "VoicesViewController.h"
+#import "FortsViewController.h"
+#import "FlagsViewController.h"
+#import "LevelViewController.h"
+
+
+#define TEAMNAME_TAG 78789
+
+ at implementation SingleTeamViewController
+ at synthesize teamDictionary, normalHogSprite, secondaryItems, moreSecondaryItems, teamName;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark editableCellViewDelegate methods
+// set the new value
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue {
+ if (TEAMNAME_TAG == tagValue) {
+ // delete old file
+ [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@.plist",TEAMS_DIRECTORY(),self.teamName] error:NULL];
+ // update filename
+ self.teamName = textString;
+ // save new file
+ [self writeFile];
+ } else {
+ // replace the old value with the new one
+ NSMutableDictionary *hog = [[teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:tagValue];
+ [hog setObject:textString forKey:@"hogname"];
+ isWriteNeeded = YES;
+ }
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ // labels for the entries
+ NSArray *array = [[NSArray alloc] initWithObjects:
+ NSLocalizedString(@"Grave",@""),
+ NSLocalizedString(@"Voice",@""),
+ NSLocalizedString(@"Fort",@""),
+ NSLocalizedString(@"Flag",@""),
+ NSLocalizedString(@"Level",@""),nil];
+ self.secondaryItems = array;
+ [array release];
+
+ // labels for the subtitles
+ NSArray *moreArray = [[NSArray alloc] initWithObjects:
+ NSLocalizedString(@"Mark the death of your fallen warriors",@""),
+ NSLocalizedString(@"Pick a slang your hogs will speak",@""),
+ NSLocalizedString(@"Select the team invincible fortress (only valid for fort games)",@""),
+ NSLocalizedString(@"Choose a charismatic symbol for your team",@""),
+ NSLocalizedString(@"Opt for controlling the team or let the AI lead",@""),nil];
+ self.moreSecondaryItems = moreArray;
+ [moreArray release];
+
+ // load the base hog image, drawing will occure in cellForRow...
+ NSString *normalHogFile = [[NSString alloc] initWithFormat:@"%@/basehat-hedgehog.png",[[NSBundle mainBundle] resourcePath]];
+ UIImage *hogSprite = [[UIImage alloc] initWithContentsOfFile:normalHogFile];
+ [normalHogFile release];
+ self.normalHogSprite = hogSprite;
+ [hogSprite release];
+
+ // listen if any childController modifies the plist and write it if needed
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setWriteNeeded) name:@"setWriteNeedTeams" object:nil];
+ isWriteNeeded = NO;
+
+ self.title = NSLocalizedString(@"Edit team settings",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ // load data about the team and write if there has been a change from other childControllers
+ if (isWriteNeeded)
+ [self writeFile];
+
+ NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",TEAMS_DIRECTORY(),self.teamName];
+ NSMutableDictionary *teamDict = [[NSMutableDictionary alloc] initWithContentsOfFile:teamFile];
+ self.teamDictionary = teamDict;
+ [teamDict release];
+ [teamFile release];
+
+ [self.tableView reloadData];
+}
+
+// write on file if there has been a change
+-(void) viewWillDisappear:(BOOL)animated {
+ [super viewWillDisappear:animated];
+
+ if (isWriteNeeded)
+ [self writeFile];
+}
+
+#pragma mark -
+// needed by other classes to warn about a user change
+-(void) setWriteNeeded {
+ isWriteNeeded = YES;
+}
+
+-(void) writeFile {
+ NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",TEAMS_DIRECTORY(),self.teamName];
+ [self.teamDictionary writeToFile:teamFile atomically:YES];
+ [teamFile release];
+
+ //DLog(@"%@",teamDictionary);
+ isWriteNeeded = NO;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 3;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ NSInteger rows = 0;
+ switch (section) {
+ case 0: // team name
+ rows = 1;
+ break;
+ case 1: // team members
+ rows = HW_getMaxNumberOfHogs();
+ break;
+ case 2: // team details
+ rows = [self.secondaryItems count];
+ break;
+ default:
+ break;
+ }
+ return rows;
+}
+
+-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
+ NSString *sectionTitle = nil;
+ switch (section) {
+ case 0:
+ sectionTitle = NSLocalizedString(@"Team Name", @"");
+ break;
+ case 1:
+ sectionTitle = NSLocalizedString(@"Names and Hats", @"");
+ break;
+ case 2:
+ sectionTitle = NSLocalizedString(@"Team Preferences", @"");
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ return sectionTitle;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ static NSString *CellIdentifier1 = @"Cell1";
+ static NSString *CellIdentifier2 = @"Cell2";
+
+ NSArray *hogArray;
+ UITableViewCell *cell = nil;
+ EditableCellView *editableCell = nil;
+ NSInteger row = [indexPath row];
+ UIImage *accessoryImage;
+
+ switch ([indexPath section]) {
+ case 0:
+ editableCell = (EditableCellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (editableCell == nil) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault
+ reuseIdentifier:CellIdentifier0] autorelease];
+ editableCell.delegate = self;
+ editableCell.tag = TEAMNAME_TAG;
+ }
+
+ editableCell.imageView.image = nil;
+ editableCell.accessoryType = UITableViewCellAccessoryNone;
+ editableCell.textField.text = self.teamName;
+
+ cell = editableCell;
+ break;
+ case 1:
+ editableCell = (EditableCellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
+ if (editableCell == nil) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault
+ reuseIdentifier:CellIdentifier1] autorelease];
+ editableCell.delegate = self;
+ editableCell.tag = [indexPath row];
+ }
+
+ hogArray = [self.teamDictionary objectForKey:@"hedgehogs"];
+
+ // draw the hat on top of the hog
+ NSString *hatFile = [[NSString alloc] initWithFormat:@"%@/%@.png", HATS_DIRECTORY(), [[hogArray objectAtIndex:row] objectForKey:@"hat"]];
+ UIImage *hatSprite = [[UIImage alloc] initWithContentsOfFile: hatFile andCutAt:CGRectMake(0, 0, 32, 32)];
+ [hatFile release];
+ editableCell.imageView.image = [self.normalHogSprite mergeWith:hatSprite atPoint:CGPointMake(0, 5)];
+ [hatSprite release];
+
+ editableCell.textField.text = [[hogArray objectAtIndex:row] objectForKey:@"hogname"];
+ editableCell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
+
+ cell = editableCell;
+ break;
+ case 2:
+ cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
+ reuseIdentifier:CellIdentifier2] autorelease];
+ }
+
+ cell.textLabel.text = [self.secondaryItems objectAtIndex:row];
+ cell.detailTextLabel.text = [self.moreSecondaryItems objectAtIndex:row];
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+ switch (row) {
+ case 0: // grave
+ accessoryImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png",
+ GRAVES_DIRECTORY(),[teamDictionary objectForKey:@"grave"]]
+ andCutAt:CGRectMake(0,0,32,32)];
+ cell.imageView.image = accessoryImage;
+ [accessoryImage release];
+ break;
+ case 1: // voice
+ accessoryImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/HellishBomb.png",
+ GRAPHICS_DIRECTORY()]];
+ cell.imageView.image = accessoryImage;
+ [accessoryImage release];
+ break;
+ case 2: // fort
+ accessoryImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@-icon.png",
+ FORTS_DIRECTORY(),[teamDictionary objectForKey:@"fort"]]];
+ cell.imageView.image = accessoryImage;
+ [accessoryImage release];
+ break;
+ case 3: // flags
+ accessoryImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png",
+ FLAGS_DIRECTORY(),[teamDictionary objectForKey:@"flag"]]];
+ cell.imageView.image = [accessoryImage scaleToSize:CGSizeMake(26, 18)];
+ [accessoryImage release];
+ cell.imageView.layer.borderWidth = 1;
+ cell.imageView.layer.borderColor = [[UIColor blackColor] CGColor];
+ break;
+ case 4: // level
+ accessoryImage = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/bot%d.png",
+ [[NSBundle mainBundle] resourcePath],
+ [[[[teamDictionary objectForKey:@"hedgehogs"]
+ objectAtIndex:0] objectForKey:@"level"]
+ intValue]]];
+ cell.imageView.image = accessoryImage;
+ [accessoryImage release];
+ break;
+ default:
+ cell.imageView.image = nil;
+ break;
+ }
+ break;
+ }
+
+ return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSInteger row = [indexPath row];
+ NSInteger section = [indexPath section];
+
+ if (2 == section) {
+ switch (row) {
+ case 0: // grave
+ if (nil == gravesViewController)
+ gravesViewController = [[GravesViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ [gravesViewController setTeamDictionary:teamDictionary];
+ [self.navigationController pushViewController:gravesViewController animated:YES];
+ break;
+ case 1: // voice
+ if (nil == voicesViewController)
+ voicesViewController = [[VoicesViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ [voicesViewController setTeamDictionary:teamDictionary];
+ [self.navigationController pushViewController:voicesViewController animated:YES];
+ break;
+ case 2: // fort
+ if (nil == fortsViewController)
+ fortsViewController = [[FortsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ [fortsViewController setTeamDictionary:teamDictionary];
+ [self.navigationController pushViewController:fortsViewController animated:YES];
+ break;
+ case 3: // flag
+ if (nil == flagsViewController)
+ flagsViewController = [[FlagsViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ [flagsViewController setTeamDictionary:teamDictionary];
+ [self.navigationController pushViewController:flagsViewController animated:YES];
+ break;
+ case 4: // level
+ if (nil == levelViewController)
+ levelViewController = [[LevelViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ [levelViewController setTeamDictionary:teamDictionary];
+ [self.navigationController pushViewController:levelViewController animated:YES];
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ } else {
+ EditableCellView *cell = (EditableCellView *)[aTableView cellForRowAtIndexPath:indexPath];
+ [cell replyKeyboard];
+ [aTableView deselectRowAtIndexPath:indexPath animated:NO];
+ }
+
+}
+
+// action to perform when you want to change a hog hat
+-(void) tableView:(UITableView *)aTableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
+ if (nil == hogHatViewController)
+ hogHatViewController = [[HogHatViewController alloc] initWithStyle:UITableViewStyleGrouped];
+
+ // cache the dictionary file of the team, so that other controllers can modify it
+ hogHatViewController.teamDictionary = self.teamDictionary;
+ hogHatViewController.selectedHog = [indexPath row];
+
+ // if we are editing the field undo any change before proceeding
+ EditableCellView *cell = (EditableCellView *)[aTableView cellForRowAtIndexPath:indexPath];
+ [cell cancel:nil];
+
+ [self.navigationController pushViewController:hogHatViewController animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ if (hogHatViewController.view.superview == nil)
+ hogHatViewController = nil;
+ if (gravesViewController.view.superview == nil)
+ gravesViewController = nil;
+ if (voicesViewController.view.superview == nil)
+ voicesViewController = nil;
+ if (fortsViewController.view.superview == nil)
+ fortsViewController = nil;
+ if (flagsViewController.view.superview == nil)
+ flagsViewController = nil;
+ if (levelViewController.view.superview == nil)
+ levelViewController = nil;
+ MSG_MEMCLEAN();
+}
+
+-(void) viewDidUnload {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ self.teamDictionary = nil;
+ self.teamName = nil;
+ self.normalHogSprite = nil;
+ self.secondaryItems = nil;
+ self.moreSecondaryItems = nil;
+ hogHatViewController = nil;
+ gravesViewController = nil;
+ voicesViewController = nil;
+ flagsViewController = nil;
+ fortsViewController = nil;
+ levelViewController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(teamDictionary);
+ releaseAndNil(teamName);
+ releaseAndNil(normalHogSprite);
+ releaseAndNil(secondaryItems);
+ releaseAndNil(moreSecondaryItems);
+ releaseAndNil(hogHatViewController);
+ releaseAndNil(gravesViewController);
+ releaseAndNil(fortsViewController);
+ releaseAndNil(voicesViewController);
+ releaseAndNil(flagsViewController);
+ releaseAndNil(levelViewController);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.h b/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.h
new file mode 100644
index 0000000..cc8f09d
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.h
@@ -0,0 +1,42 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "WeaponCellView.h"
+
+
+ at interface SingleWeaponViewController : UITableViewController <EditableCellViewDelegate, WeaponButtonControllerDelegate> {
+ NSString *weaponName;
+ NSString *description;
+
+ UIImage *ammoStoreImage;
+
+ char *quantity;
+ char *probability;
+ char *delay;
+ char *crateness;
+}
+
+ at property (nonatomic,retain) NSString *weaponName;
+ at property (nonatomic,retain) NSString *description;
+ at property (nonatomic,retain) UIImage *ammoStoreImage;
+
+-(void) saveAmmos;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.m b/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.m
new file mode 100644
index 0000000..7cdc7be
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SingleWeaponViewController.m
@@ -0,0 +1,272 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SingleWeaponViewController.h"
+
+
+ at implementation SingleWeaponViewController
+ at synthesize weaponName, description, ammoStoreImage;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ NSString *trFilePath = [NSString stringWithFormat:@"%@/%@.txt",LOCALE_DIRECTORY(),[[NSLocale preferredLanguages] objectAtIndex:0]];
+ // fill the data structure that we are going to read
+ LoadLocaleWrapper([trFilePath UTF8String]);
+
+ quantity = (char *)malloc(sizeof(char)*(HW_getNumberOfWeapons()+1));
+ probability = (char *)malloc(sizeof(char)*(HW_getNumberOfWeapons()+1));
+ delay = (char *)malloc(sizeof(char)*(HW_getNumberOfWeapons()+1));
+ crateness = (char *)malloc(sizeof(char)*(HW_getNumberOfWeapons()+1));
+
+ NSString *str = [NSString stringWithFormat:@"%@/AmmoMenu/Ammos.png",GRAPHICS_DIRECTORY()];
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:str];
+ self.ammoStoreImage = img;
+ [img release];
+
+ self.title = NSLocalizedString(@"Edit weapons preferences",@"");
+}
+
+-(void) viewWillAppear:(BOOL) animated {
+ [super viewWillAppear:animated];
+
+ NSString *ammoFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",WEAPONS_DIRECTORY(),self.weaponName];
+ NSDictionary *weapon = [[NSDictionary alloc] initWithContentsOfFile:ammoFile];
+ [ammoFile release];
+
+ self.description = [weapon objectForKey:@"description"];
+ const char *tmp1 = [[weapon objectForKey:@"ammostore_initialqt"] UTF8String];
+ const char *tmp2 = [[weapon objectForKey:@"ammostore_probability"] UTF8String];
+ const char *tmp3 = [[weapon objectForKey:@"ammostore_delay"] UTF8String];
+ const char *tmp4 = [[weapon objectForKey:@"ammostore_crate"] UTF8String];
+ [weapon release];
+
+ // if the new weaponset is diffrent from the older we need to update it replacing
+ // the missing ammos with 0 quantity
+ int oldlen = strlen(tmp1);
+ for (int i = 0; i < oldlen; i++) {
+ quantity[i] = tmp1[i];
+ probability[i] = tmp2[i];
+ delay[i] = tmp3[i];
+ crateness[i] = tmp4[i];
+ }
+ for (int i = oldlen; i < HW_getNumberOfWeapons(); i++) {
+ quantity[i] = '0';
+ probability[i] = '0';
+ delay[i] = '0';
+ crateness[i] = '0';
+ }
+
+ [self.tableView reloadData];
+}
+
+-(void) viewWillDisappear:(BOOL) animated {
+ [super viewWillDisappear:animated];
+ [self saveAmmos];
+}
+
+-(void) saveAmmos {
+ quantity[HW_getNumberOfWeapons()] = '\0';
+ probability[HW_getNumberOfWeapons()] = '\0';
+ delay[HW_getNumberOfWeapons()] = '\0';
+ crateness[HW_getNumberOfWeapons()] = '\0';
+
+ NSString *quantityStr = [NSString stringWithUTF8String:quantity];
+ NSString *probabilityStr = [NSString stringWithUTF8String:probability];
+ NSString *delayStr = [NSString stringWithUTF8String:delay];
+ NSString *cratenessStr = [NSString stringWithUTF8String:crateness];
+
+ NSDictionary *weapon = [[NSDictionary alloc] initWithObjectsAndKeys:
+ quantityStr,@"ammostore_initialqt",
+ probabilityStr,@"ammostore_probability",
+ delayStr,@"ammostore_delay",
+ cratenessStr,@"ammostore_crate",
+ self.description,@"description",
+ nil];
+
+ NSString *ammoFile = [[NSString alloc] initWithFormat:@"%@/%@.plist",WEAPONS_DIRECTORY(),self.weaponName];
+ [weapon writeToFile:ammoFile atomically:YES];
+ [ammoFile release];
+ [weapon release];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 2;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (section == 0)
+ return 2;
+ else
+ return HW_getNumberOfWeapons();
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ static NSString *CellIdentifier1 = @"Cell1";
+ NSInteger row = [indexPath row];
+ UITableViewCell *cell = nil;
+
+ if (0 == [indexPath section]) {
+ EditableCellView *editableCell = (EditableCellView *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (editableCell == nil) {
+ editableCell = [[[EditableCellView alloc] initWithStyle:UITableViewCellStyleDefault
+ reuseIdentifier:CellIdentifier0] autorelease];
+ editableCell.delegate = self;
+ }
+ editableCell.tag = row;
+ editableCell.selectionStyle = UITableViewCellSelectionStyleNone;
+ editableCell.imageView.image = nil;
+ editableCell.detailTextLabel.text = nil;
+
+ if (row == 0) {
+ editableCell.textField.text = self.weaponName;
+ editableCell.textField.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ } else {
+ editableCell.minimumCharacters = 0;
+ editableCell.textField.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];
+ editableCell.textField.text = self.description;
+ editableCell.textField.placeholder = NSLocalizedString(@"You can add a description if you wish",@"");
+ }
+ cell = editableCell;
+ } else {
+ WeaponCellView *weaponCell = (WeaponCellView *)[aTableView dequeueReusableCellWithIdentifier:CellIdentifier1];
+ if (weaponCell == nil) {
+ weaponCell = [[[WeaponCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
+ weaponCell.delegate = self;
+ }
+
+ CGFloat theScale = [[UIScreen mainScreen] safeScale];
+ int size = 32 * theScale;
+ int corners = 8 * theScale;
+ int x = ((row*size)/(int)(self.ammoStoreImage.size.height * theScale))*size;
+ int y = (row*size)%(int)(self.ammoStoreImage.size.height * theScale);
+
+ UIImage *img = [[self.ammoStoreImage cutAt:CGRectMake(x, y, size, size)] makeRoundCornersOfSize:CGSizeMake(corners, corners)];
+ weaponCell.weaponIcon.image = img;
+ weaponCell.weaponName.text = [NSString stringWithUTF8String:HW_getWeaponNameByIndex(row)];
+ weaponCell.tag = row;
+
+ [weaponCell.initialSli setValue:[[NSString stringWithFormat:@"%c",quantity[row]] intValue] animated:NO];
+ [weaponCell.probabilitySli setValue:[[NSString stringWithFormat:@"%c", probability[row]] intValue] animated:NO];
+ [weaponCell.delaySli setValue:[[NSString stringWithFormat:@"%c", delay[row]] intValue] animated:NO];
+ [weaponCell.crateSli setValue:[[NSString stringWithFormat:@"%c", crateness[row]] intValue] animated:NO];
+ cell = weaponCell;
+ }
+
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+ return cell;
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (0 == [indexPath section])
+ return aTableView.rowHeight;
+ else
+ return IS_ON_PORTRAIT() ? 208 : 120;
+}
+
+-(NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
+ NSString *sectionTitle = nil;
+ switch (section) {
+ case 0:
+ sectionTitle = NSLocalizedString(@"Weaponset Name", @"");
+ break;
+ case 1:
+ sectionTitle = NSLocalizedString(@"Weapon Ammuntions", @"");
+ break;
+ default:
+ DLog(@"nope");
+ break;
+ }
+ return sectionTitle;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (0 == [indexPath section]) {
+ EditableCellView *editableCell = (EditableCellView *)[aTableView cellForRowAtIndexPath:indexPath];
+ [editableCell replyKeyboard];
+ }
+}
+
+#pragma mark -
+#pragma mark editableCellView delegate
+// set the new value
+-(void) saveTextFieldValue:(NSString *)textString withTag:(NSInteger) tagValue {
+ if (tagValue == 0) {
+ // delete old file
+ [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@.plist",WEAPONS_DIRECTORY(),self.weaponName] error:NULL];
+ // update filename
+ self.weaponName = textString;
+ // save new file
+ [self saveAmmos];
+ } else {
+ self.description = textString;
+ }
+}
+
+#pragma mark -
+#pragma mark WeaponButtonControllerDelegate
+-(void) updateValues:(NSArray *)withArray atIndex:(NSInteger) index {
+ quantity[index] = [[NSString stringWithFormat:@"%d",[[withArray objectAtIndex:0] intValue]] characterAtIndex:0];
+ probability[index] = [[NSString stringWithFormat:@"%d",[[withArray objectAtIndex:1] intValue]] characterAtIndex:0];
+ delay[index] = [[NSString stringWithFormat:@"%d",[[withArray objectAtIndex:2] intValue]] characterAtIndex:0];
+ crateness[index] = [[NSString stringWithFormat:@"%d",[[withArray objectAtIndex:3] intValue]] characterAtIndex:0];
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ free(quantity); quantity = NULL;
+ free(probability); probability = NULL;
+ free(delay); delay = NULL;
+ free(crateness); crateness = NULL;
+ [super viewDidUnload];
+ self.description = nil;
+ self.weaponName = nil;
+ self.ammoStoreImage = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(weaponName);
+ releaseAndNil(description);
+ releaseAndNil(ammoStoreImage);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/SquareButtonView.h b/project_files/HedgewarsMobile/Classes/SquareButtonView.h
new file mode 100644
index 0000000..e17950e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SquareButtonView.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface SquareButtonView : UIButton {
+ NSMutableDictionary *ownerDictionary;
+ NSUInteger colorIndex;
+ NSUInteger selectedColor;
+ NSArray *colorArray;
+}
+
+ at property (nonatomic,retain) NSMutableDictionary *ownerDictionary;
+ at property (nonatomic,retain) NSArray *colorArray;
+ at property (nonatomic,assign) NSUInteger selectedColor;
+ at property (nonatomic,assign) NSUInteger colorIndex;
+
+-(void) nextColor;
+-(void) selectColor:(NSUInteger) color;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SquareButtonView.m b/project_files/HedgewarsMobile/Classes/SquareButtonView.m
new file mode 100644
index 0000000..b1811d9
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SquareButtonView.m
@@ -0,0 +1,80 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SquareButtonView.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+ at implementation SquareButtonView
+ at synthesize ownerDictionary, colorIndex, selectedColor, colorArray;
+
+-(id) initWithFrame:(CGRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+ self.colorIndex = 0;
+ self.selectedColor = 0;
+
+ self.colorArray = [HWUtils teamColors];
+
+ // set the color to the first available one
+ [self nextColor];
+
+ // this makes the button round and nice with a border
+ [self.layer setCornerRadius:7.0f];
+ [self.layer setMasksToBounds:YES];
+ [self.layer setBorderWidth:2];
+ [self.layer setBorderColor:[[UIColor darkYellowColor] CGColor]];
+
+ // this changes the color at button press
+ [self addTarget:self action:@selector(nextColor) forControlEvents:UIControlEventTouchUpInside];
+ }
+ return self;
+}
+
+-(void) nextColor {
+ self.colorIndex++;
+
+ if (self.colorIndex >= [self.colorArray count])
+ self.colorIndex = 0;
+
+ NSNumber *colorNumber = [self.colorArray objectAtIndex:colorIndex];
+ [self.ownerDictionary setObject:colorNumber forKey:@"color"];
+ NSUInteger color = [colorNumber unsignedIntValue];
+ [self selectColor:color];
+}
+
+-(void) selectColor:(NSUInteger) color {
+ if (color != self.selectedColor) {
+ self.selectedColor = color;
+ self.colorIndex = [self.colorArray indexOfObject:[NSNumber numberWithUnsignedInt:color]];
+
+ self.backgroundColor = [UIColor colorWithRed:((color & 0x00FF0000) >> 16)/255.0f
+ green:((color & 0x0000FF00) >> 8)/255.0f
+ blue: (color & 0x000000FF)/255.0f
+ alpha:1.0f];
+ }
+}
+
+-(void) dealloc {
+ releaseAndNil(ownerDictionary);
+ releaseAndNil(colorArray);
+ [super dealloc];
+}
+
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/StatsPageViewController.h b/project_files/HedgewarsMobile/Classes/StatsPageViewController.h
new file mode 100644
index 0000000..42cc7dc
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/StatsPageViewController.h
@@ -0,0 +1,29 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface StatsPageViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
+ NSArray *statsArray;
+}
+
+ at property (nonatomic,retain) NSArray *statsArray;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/StatsPageViewController.m b/project_files/HedgewarsMobile/Classes/StatsPageViewController.m
new file mode 100644
index 0000000..ff7f569
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/StatsPageViewController.m
@@ -0,0 +1,183 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "StatsPageViewController.h"
+
+
+ at implementation StatsPageViewController
+ at synthesize statsArray;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+-(void) viewDidLoad {
+ UITableView *aTableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
+ [aTableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+
+ NSString *imgName = (IS_IPAD()) ? @"mediumBackground~ipad.png" : @"smallerBackground~iphone.png";
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgName];
+ UIImageView *background = [[UIImageView alloc] initWithImage:img];
+ [img release];
+ background.frame = self.view.frame;
+ background.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view insertSubview:background atIndex:0];
+ [background release];
+
+ aTableView.separatorColor = [UIColor darkYellowColor];
+ aTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ aTableView.delegate = self;
+ aTableView.dataSource = self;
+
+ [self.view addSubview:aTableView];
+ [aTableView release];
+
+ [super viewDidLoad];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 3;
+}
+
+-(NSInteger) tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
+ if (section == 0)
+ return 1;
+ else if (section == 1)
+ return [[self.statsArray objectAtIndex:0] count];
+ else
+ return [self.statsArray count] - 2;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ NSInteger section = [indexPath section];
+ NSInteger row = [indexPath row];
+ NSString *imgName = @"";
+ NSString *imgPath = ICONS_DIRECTORY();
+
+ UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier0] autorelease];
+
+ if (section == 0) { // winning team
+ imgName = @"star";
+ imgPath = [[NSBundle mainBundle] resourcePath];
+ cell.textLabel.text = [self.statsArray objectAtIndex:1];
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ } else if (section == 1) { // teams ranking
+ // color, # kills, teamname
+ NSArray *info = [[[self.statsArray objectAtIndex:0] objectAtIndex:row] componentsSeparatedByString:@" "];
+ NSUInteger color = [[info objectAtIndex:0] intValue];
+ cell.textLabel.textColor = [UIColor colorWithRed:((color >> 16) & 0xFF)/255.0f
+ green:((color >> 8) & 0xFF)/255.0f
+ blue:(color & 0xFF)/255.0f
+ alpha:1.0f];
+ cell.textLabel.text = [NSString stringWithFormat:@"%d. %@ (%@ kills)", row+1, [info objectAtIndex:2], [info objectAtIndex:1]];
+ imgName = [NSString stringWithFormat:@"StatsMedal%d",row+1];
+ } else if (section == 2) { // general info
+ imgName = @"iconDamage";
+ cell.textLabel.text = [self.statsArray objectAtIndex:row + 2];
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ }
+
+ NSString *imgString = [[NSString alloc] initWithFormat:@"%@/%@.png",imgPath,imgName];
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgString];
+ [imgString release];
+ UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
+ cell.imageView.image = img;
+ [img release];
+ cell.accessoryView = imgView;
+ [imgView release];
+
+ cell.textLabel.textAlignment = UITextAlignmentCenter;
+ cell.textLabel.adjustsFontSizeToFitWidth = YES;
+ cell.backgroundColor = [UIColor blackColor];
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+
+ return cell;
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForHeaderInSection:(NSInteger)section {
+ return 160;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section {
+ if (section == 0) {
+ UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width, 160)];
+ header.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:@"smallerTitle.png"];
+ UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
+ [img release];
+ imgView.center = CGPointMake(aTableView.frame.size.width/2, 160/2);
+ imgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ [header addSubview:imgView];
+ [imgView release];
+
+ return [header autorelease];
+ } else
+ return nil;
+}
+
+-(CGFloat) tableView:(UITableView *)aTableView heightForFooterInSection:(NSInteger)section {
+ return aTableView.rowHeight + 30;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForFooterInSection:(NSInteger)section {
+ if (section == 2) {
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width * 70 / 100, aTableView.rowHeight)];
+ footer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 17, self.view.frame.size.width * 70 / 100, aTableView.rowHeight)
+ andTitle:NSLocalizedString(@"Done",@"")];
+ button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ [button addTarget:self action:@selector(dismissView) forControlEvents:UIControlEventTouchUpInside];
+ [footer addSubview:button];
+ [button release];
+
+ return [footer autorelease];
+ } else
+ return nil;
+}
+
+#pragma mark -
+#pragma mark button delegate
+-(void) dismissView {
+ [[AudioManagerController mainManager] playClickSound];
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+ self.statsArray = nil;
+}
+
+-(void) dealloc {
+ releaseAndNil(statsArray);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/SupportViewController.h b/project_files/HedgewarsMobile/Classes/SupportViewController.h
new file mode 100644
index 0000000..af10c20
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SupportViewController.h
@@ -0,0 +1,29 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at interface SupportViewController : UITableViewController {
+ NSArray *waysToSupport;
+}
+
+ at property (nonatomic, retain) NSArray *waysToSupport;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/SupportViewController.m b/project_files/HedgewarsMobile/Classes/SupportViewController.m
new file mode 100644
index 0000000..d732d20
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/SupportViewController.m
@@ -0,0 +1,190 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "SupportViewController.h"
+
+
+ at implementation SupportViewController
+ at synthesize waysToSupport;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ NSArray *array = [[NSArray alloc] initWithObjects:
+ NSLocalizedString(@"Leave a positive review on iTunes!",@""),
+ NSLocalizedString(@"Join us on Facebook",@""),
+ NSLocalizedString(@"Follow us on Twitter",@""),
+ NSLocalizedString(@"Visit our website",@""),
+ NSLocalizedString(@"Chat with the devs in IRC",@""),
+ nil];
+ self.waysToSupport = array;
+ [array release];
+
+ self.navigationItem.title = @"â¥";
+ self.tableView.rowHeight = 50;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 2;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (section == 0)
+ return 1;
+ else
+ return [self.waysToSupport count] - 1;
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+ NSInteger row = [indexPath row];
+ NSInteger section = [indexPath section];
+ NSString *imgName = @"";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+
+ NSString *rowString = [self.waysToSupport objectAtIndex:(row + section)];
+ cell.textLabel.text = rowString;
+
+ if (section == 0) {
+ imgName = @"star";
+ cell.textLabel.textAlignment = UITextAlignmentCenter;
+ cell.imageView.image = nil;
+ } else {
+ cell.textLabel.textAlignment = UITextAlignmentLeft;
+ switch (row) {
+ case 0:
+ imgName = @"fb";
+ break;
+ case 1:
+ imgName = @"tw";
+ break;
+ case 2:
+ imgName = @"hedgehog";
+ break;
+ case 3:
+ imgName = @"irc";
+ break;
+ default:
+ DLog(@"No way");
+ break;
+ }
+ }
+
+ NSString *imgString = [[NSString alloc] initWithFormat:@"%@/%@.png",[[NSBundle mainBundle] resourcePath],imgName];
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:imgString];
+ [imgString release];
+ cell.imageView.image = img;
+ if (section == 0) {
+ UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
+ cell.accessoryView = imgView;
+ [imgView release];
+ }
+ [img release];
+
+ return cell;
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSString *urlString = nil;
+ if ([indexPath section] == 0)
+ urlString = @"http://itunes.apple.com/us/app/hedgewars/id391234866?affC=QQABAAAAHgAFasEiWjVwUGZOc3k1VGctQkRJazlacXhUclpBTVpiU2xteVdfUQ%3D%3D#&mt=8";
+ else
+ switch ([indexPath row]) {
+ case 0:
+ urlString = @"http://www.facebook.com/Hedgewars";
+ break;
+ case 1:
+ urlString = @"http://twitter.com/hedgewars";
+ break;
+ case 2:
+ urlString = @"http://www.hedgewars.org";
+ break;
+ case 3:
+ urlString = @"http://webchat.freenode.net/?channels=hedgewars";
+ break;
+ default:
+ DLog(@"No way");
+ break;
+ }
+ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
+}
+
+-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger) section {
+ if (section == 1) {
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 240)];
+ footer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ UIImage *img = [[UIImage alloc] initWithContentsOfFile:@"surprise.png"];
+ UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
+ [img release];
+ imgView.center = CGPointMake(self.tableView.frame.size.width/2, 120);
+ imgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ [footer addSubview:imgView];
+ [imgView release];
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 20)];
+ label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+ label.textAlignment = UITextAlignmentCenter;
+ label.text = @" ⥠THANK YOU ⥠";
+ label.backgroundColor = [UIColor clearColor];
+ label.center = CGPointMake(self.tableView.frame.size.width/2, 250);
+ [footer addSubview:label];
+ [label release];
+
+ return [footer autorelease];
+ } else
+ return nil;
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+ // image height + label height
+ return 265;
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.waysToSupport = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(waysToSupport);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.h b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.h
new file mode 100644
index 0000000..f925280
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.h
@@ -0,0 +1,42 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "HoldTableViewCell.h"
+
+
+ at interface TeamConfigViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,HoldTableViewCellDelegate> {
+ UITableView *tableView;
+
+ NSInteger selectedTeamsCount;
+ NSInteger allTeamsCount;
+
+ NSMutableArray *listOfSelectedTeams;
+ NSMutableArray *listOfAllTeams;
+ NSArray *cachedContentsOfDir;
+}
+
+ at property (nonatomic,retain) UITableView *tableView;
+ at property (nonatomic,assign) NSInteger selectedTeamsCount;
+ at property (nonatomic,assign) NSInteger allTeamsCount;
+ at property (nonatomic,retain) NSMutableArray *listOfAllTeams;
+ at property (nonatomic,retain) NSMutableArray *listOfSelectedTeams;
+ at property (nonatomic,retain) NSArray *cachedContentsOfDir;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m
new file mode 100644
index 0000000..d241f01
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m
@@ -0,0 +1,303 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "TeamConfigViewController.h"
+#import <QuartzCore/QuartzCore.h>
+#import "SquareButtonView.h"
+
+
+ at implementation TeamConfigViewController
+ at synthesize tableView, selectedTeamsCount, allTeamsCount, listOfAllTeams, listOfSelectedTeams, cachedContentsOfDir;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ UITableView *aTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
+ style:UITableViewStyleGrouped];
+ aTableView.delegate = self;
+ aTableView.dataSource = self;
+ if (IS_IPAD()) {
+ [aTableView setBackgroundColorForAnyTable:[UIColor darkBlueColorTransparent]];
+ aTableView.layer.borderColor = [[UIColor darkYellowColor] CGColor];
+ aTableView.layer.borderWidth = 2.7f;
+ aTableView.layer.cornerRadius = 8;
+ aTableView.contentInset = UIEdgeInsetsMake(10, 0, 10, 0);
+ } else {
+ UIImage *backgroundImage = [[UIImage alloc] initWithContentsOfFile:@"background~iphone.png"];
+ UIImageView *background = [[UIImageView alloc] initWithImage:backgroundImage];
+ [backgroundImage release];
+ [self.view addSubview:background];
+ [background release];
+ [aTableView setBackgroundColorForAnyTable:[UIColor clearColor]];
+ }
+
+ aTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
+ aTableView.separatorColor = [UIColor whiteColor];
+ aTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+ aTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.tableView = aTableView;
+ [aTableView release];
+
+ [self.view addSubview:self.tableView];
+ [super viewDidLoad];
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TEAMS_DIRECTORY() error:NULL];
+ if ([self.cachedContentsOfDir isEqualToArray:contentsOfDir] == NO) {
+ self.cachedContentsOfDir = contentsOfDir;
+ NSArray *colors = [HWUtils teamColors];
+ NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:[contentsOfDir count]];
+ for (NSUInteger i = 0; i < [contentsOfDir count]; i++) {
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+ [contentsOfDir objectAtIndex:i],@"team",
+ [NSNumber numberWithInt:4],@"number",
+ [colors objectAtIndex:i%[colors count]],@"color",nil];
+ [array addObject:dict];
+ [dict release];
+ }
+ self.listOfAllTeams = array;
+ [array release];
+
+ NSMutableArray *emptyArray = [[NSMutableArray alloc] initWithObjects:nil];
+ self.listOfSelectedTeams = emptyArray;
+ [emptyArray release];
+
+ self.selectedTeamsCount = [self.listOfSelectedTeams count];
+ self.allTeamsCount = [self.listOfAllTeams count];
+ [self.tableView reloadData];
+ }
+
+ [super viewWillAppear:animated];
+}
+
+-(NSInteger) filterNumberOfHogs:(NSInteger) hogs {
+ NSInteger numberOfHogs;
+ if (hogs <= HW_getMaxNumberOfHogs() && hogs >= 1)
+ numberOfHogs = hogs;
+ else {
+ if (hogs > HW_getMaxNumberOfHogs())
+ numberOfHogs = 1;
+ else
+ numberOfHogs = HW_getMaxNumberOfHogs();
+ }
+ return numberOfHogs;
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 2;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return (section == 0 ? self.selectedTeamsCount : self.allTeamsCount);
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier0 = @"Cell0";
+ static NSString *CellIdentifier1 = @"Cell1";
+ NSInteger section = [indexPath section];
+ UITableViewCell *cell;
+
+ if (section == 0) {
+ cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier0];
+ if (cell == nil) {
+ cell = [[[HoldTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier0] autorelease];
+
+ SquareButtonView *squareButton = [[SquareButtonView alloc] initWithFrame:CGRectMake(0, 0, 36, 36)];
+ cell.accessoryView = squareButton;
+ [squareButton release];
+ }
+
+ NSMutableDictionary *selectedRow = [listOfSelectedTeams objectAtIndex:[indexPath row]];
+ cell.textLabel.text = [[selectedRow objectForKey:@"team"] stringByDeletingPathExtension];
+ cell.textLabel.backgroundColor = [UIColor clearColor];
+
+ SquareButtonView *squareButton = (SquareButtonView *)cell.accessoryView;
+ [squareButton selectColor:[[selectedRow objectForKey:@"color"] intValue]];
+ NSNumber *hogNumber = [selectedRow objectForKey:@"number"];
+ [squareButton setTitle:[hogNumber stringValue] forState:UIControlStateNormal];
+ squareButton.ownerDictionary = selectedRow;
+
+ cell.imageView.image = [UIImage drawHogsRepeated:[hogNumber intValue]];
+ ((HoldTableViewCell *)cell).delegate = self;
+ } else {
+ cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier1];
+ if (cell == nil)
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
+
+ cell.textLabel.text = [[[self.listOfAllTeams objectAtIndex:[indexPath row]] objectForKey:@"team"] stringByDeletingPathExtension];
+ cell.textLabel.backgroundColor = [UIColor clearColor];
+
+ NSString *teamPath = [NSString stringWithFormat:@"%@/%@.plist",TEAMS_DIRECTORY(),cell.textLabel.text];
+ NSDictionary *firstHog = [[[NSDictionary dictionaryWithContentsOfFile:teamPath] objectForKey:@"hedgehogs"] objectAtIndex:0];
+ if ([[firstHog objectForKey:@"level"] intValue] != 0) {
+ NSString *imgString = [[NSString alloc] initWithFormat:@"%@/robotBadge.png",[[NSBundle mainBundle] resourcePath]];
+ UIImage *sprite = [[UIImage alloc] initWithContentsOfFile:imgString];
+ [imgString release];
+ UIImageView *spriteView = [[UIImageView alloc] initWithImage:sprite];
+ [sprite release];
+
+ cell.accessoryView = spriteView;
+ [spriteView release];
+ } else
+ cell.accessoryView = nil;
+ }
+
+ cell.textLabel.textColor = [UIColor lightYellowColor];
+ cell.backgroundColor = [UIColor blackColorTransparent];
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+
+ return cell;
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
+ return 45.0;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForHeaderInSection:(NSInteger)section {
+ CGRect frame = CGRectMake(0, 0, self.view.frame.size.width * 70/100, 30);
+ NSString *text = (section == 0) ? NSLocalizedString(@"Playing Teams",@"") : NSLocalizedString(@"Available Teams",@"");
+ UILabel *theLabel = [[UILabel alloc] initWithFrame:frame andTitle:text];
+ theLabel.center = CGPointMake(self.view.frame.size.width/2, 20);
+ theLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+
+ UIView *theView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width, 30)];
+ theView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+ [theView addSubview:theLabel];
+ [theLabel release];
+ return [theView autorelease];
+}
+
+-(CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
+ return IS_IPAD() ? 40 : 20;
+}
+
+-(UIView *)tableView:(UITableView *)aTableView viewForFooterInSection:(NSInteger) section {
+ NSInteger height = IS_IPAD() ? 40 : 20;
+ UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width, height)];
+ footer.backgroundColor = [UIColor clearColor];
+ footer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, aTableView.frame.size.width*80/100, height)];
+ label.center = CGPointMake(aTableView.frame.size.width/2, height/2);
+ label.textAlignment = UITextAlignmentCenter;
+ label.font = [UIFont italicSystemFontOfSize:12];
+ label.textColor = [UIColor whiteColor];
+ label.numberOfLines = 2;
+ label.backgroundColor = [UIColor clearColor];
+ label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
+
+ if (section == 0)
+ label.text = NSLocalizedString(@"Tap to add hogs or change color, touch and hold to remove a team.",@"");
+ else
+ label.text = NSLocalizedString(@"The robot badge indicates an AI-controlled team.",@"");
+
+ [footer addSubview:label];
+ [label release];
+ return [footer autorelease];
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSUInteger row = [indexPath row];
+ NSUInteger section = [indexPath section];
+
+ if (section == 1 && [self.listOfAllTeams count] > row) {
+ [self.listOfSelectedTeams addObject:[self.listOfAllTeams objectAtIndex:row]];
+ [self.listOfAllTeams removeObjectAtIndex:row];
+
+ NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:selectedTeamsCount inSection:0];
+ allTeamsCount--;
+ selectedTeamsCount++;
+ [aTableView beginUpdates];
+ [aTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationRight];
+ [aTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
+ [aTableView endUpdates];
+ }
+ if (section == 0 && [self.listOfSelectedTeams count] > row) {
+ NSMutableDictionary *selectedRow = [self.listOfSelectedTeams objectAtIndex:row];
+ UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath];
+ SquareButtonView *squareButton = (SquareButtonView *)cell.accessoryView;
+
+ NSInteger increaseNumber = [[selectedRow objectForKey:@"number"] intValue] + 1;
+ NSNumber *newNumber = [NSNumber numberWithInt:[self filterNumberOfHogs:increaseNumber]];
+ [squareButton setTitle:[newNumber stringValue] forState:UIControlStateNormal];
+ [selectedRow setObject:newNumber forKey:@"number"];
+
+ cell.imageView.image = [UIImage drawHogsRepeated:[newNumber intValue]];
+ }
+}
+
+-(void) holdAction:(NSString *)content onTable:(UITableView *)aTableView {
+ NSUInteger row;
+ for (row = 0; row < [self.listOfSelectedTeams count]; row++) {
+ NSDictionary *dict = [self.listOfSelectedTeams objectAtIndex:row];
+ if ([content isEqualToString:[[dict objectForKey:@"team"] stringByDeletingPathExtension]])
+ break;
+ }
+
+ [self.listOfAllTeams addObject:[self.listOfSelectedTeams objectAtIndex:row]];
+ [self.listOfSelectedTeams removeObjectAtIndex:row];
+
+ [aTableView beginUpdates];
+ [aTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:row inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
+ [aTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:allTeamsCount inSection:1]] withRowAnimation:UITableViewRowAnimationLeft];
+ self.allTeamsCount++;
+ self.selectedTeamsCount--;
+ [aTableView endUpdates];
+}
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ self.cachedContentsOfDir = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ self.tableView = nil;
+ self.listOfAllTeams = nil;
+ self.listOfSelectedTeams = nil;
+ self.cachedContentsOfDir = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(tableView);
+ releaseAndNil(listOfAllTeams);
+ releaseAndNil(listOfSelectedTeams);
+ releaseAndNil(cachedContentsOfDir);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.h b/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.h
new file mode 100644
index 0000000..342ec85
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.h
@@ -0,0 +1,32 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class SingleTeamViewController;
+
+ at interface TeamSettingsViewController : UITableViewController {
+ NSMutableArray *listOfTeams;
+ SingleTeamViewController *childController;
+}
+
+ at property (nonatomic, retain) NSMutableArray *listOfTeams;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.m b/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.m
new file mode 100644
index 0000000..fb887a1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/TeamSettingsViewController.m
@@ -0,0 +1,181 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "TeamSettingsViewController.h"
+#import "SingleTeamViewController.h"
+
+
+ at implementation TeamSettingsViewController
+ at synthesize listOfTeams;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+// add an edit button
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Edit",@"")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(toggleEdit:)];
+ self.navigationItem.rightBarButtonItem = editButton;
+ [editButton release];
+
+ self.navigationItem.title = @"List of teams";
+}
+
+// load the list of teams in the teams directory
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:TEAMS_DIRECTORY() error:NULL];
+ NSMutableArray *array = [[NSMutableArray alloc] initWithArray:contentsOfDir copyItems:YES];
+ self.listOfTeams = array;
+ [array release];
+
+ [self.tableView reloadData];
+}
+
+// modifies the navigation bar to add the "Add" and "Done" buttons
+-(void) toggleEdit:(id) sender {
+ BOOL isEditing = self.tableView.editing;
+ [self.tableView setEditing:!isEditing animated:YES];
+
+ if (isEditing) {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Edit",@"from the team panel")];
+ [self.navigationItem.rightBarButtonItem setStyle: UIBarButtonItemStyleBordered];
+ self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;
+ } else {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Done",@"from the team panel")];
+ [self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
+ UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Add",@"from the team panel")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(addTeam:)];
+ self.navigationItem.leftBarButtonItem = addButton;
+ [addButton release];
+ }
+}
+
+// add a team file with default values and updates the table
+-(void) addTeam:(id) sender {
+ NSString *fileName = [[NSString alloc] initWithFormat:@"Default Team %u.plist", [self.listOfTeams count]];
+
+ [CreationChamber createTeamNamed:[fileName stringByDeletingPathExtension]];
+
+ [self.listOfTeams addObject:fileName];
+
+ // order the array alphabetically, so teams will keep their position
+ [self.listOfTeams sortUsingSelector:@selector(compare:)];
+ [self.tableView reloadData];
+
+ NSInteger index = [self.listOfTeams indexOfObject:fileName];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
+ [fileName release];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.listOfTeams count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ NSUInteger row = [indexPath row];
+ NSString *rowString = [[self.listOfTeams objectAtIndex:row] stringByDeletingPathExtension];
+ cell.textLabel.text = rowString;
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+
+ return cell;
+}
+
+// delete the row and the file
+-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSUInteger row = [indexPath row];
+
+ NSString *teamFile = [[NSString alloc] initWithFormat:@"%@/%@",TEAMS_DIRECTORY(),[self.listOfTeams objectAtIndex:row]];
+ [[NSFileManager defaultManager] removeItemAtPath:teamFile error:NULL];
+ [teamFile release];
+
+ [self.listOfTeams removeObjectAtIndex:row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (childController == nil) {
+ childController = [[SingleTeamViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ }
+
+ NSInteger row = [indexPath row];
+ NSString *selectedTeamFile = [listOfTeams objectAtIndex:row];
+
+ // this must be set so childController can load the correct plist
+ childController.teamName = [selectedTeamFile stringByDeletingPathExtension];
+ [childController.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+
+ [self.navigationController pushViewController:childController animated:YES];
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ // Releases the view if it doesn't have a superview.
+ [super didReceiveMemoryWarning];
+ // Relinquish ownership any cached data, images, etc that aren't in use.
+ if (childController.view.superview == nil )
+ childController = nil;
+}
+
+-(void) viewDidUnload {
+ self.listOfTeams = nil;
+ childController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(listOfTeams);
+ releaseAndNil(childController);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/UIImageExtra.h b/project_files/HedgewarsMobile/Classes/UIImageExtra.h
new file mode 100644
index 0000000..8922f5a
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/UIImageExtra.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <Foundation/Foundation.h>
+
+
+ at interface UIImage (extra)
+
++(UIImage *)whiteImage:(CGSize) ofSize;
++(UIImage *)drawHogsRepeated:(NSInteger) manyTimes;
++(CGSize) imageSizeFromMetadataOf:(NSString *)aFileName;
+
+-(UIImage *)scaleToSize:(CGSize) size;
+-(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint;
+-(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect;
+-(UIImage *)cutAt:(CGRect) rect;
+-(UIImage *)convertToGrayScale;
+-(UIImage *)convertToNegative;
+-(UIImage *)maskImageWith:(UIImage *)maskImage;
+-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/UIImageExtra.m b/project_files/HedgewarsMobile/Classes/UIImageExtra.m
new file mode 100644
index 0000000..f7b0091
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/UIImageExtra.m
@@ -0,0 +1,344 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "UIImageExtra.h"
+
+
+ at implementation UIImage (extra)
+
+-(UIImage *)scaleToSize:(CGSize) size {
+ // Create a bitmap graphics context; this will also set it as the current context
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 4 * size.width, colorSpace, kCGImageAlphaPremultipliedFirst);
+
+ // draw the image inside the context
+ CGFloat screenScale = [[UIScreen mainScreen] safeScale];
+ CGContextDrawImage(context, CGRectMake(0, 0, size.width*screenScale, size.height*screenScale), self.CGImage);
+
+ // Create bitmap image info from pixel data in current context
+ CGImageRef imageRef = CGBitmapContextCreateImage(context);
+
+ // Create a new UIImage object
+ UIImage *resultImage;
+ if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
+ resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp];
+ else
+ resultImage = [UIImage imageWithCGImage:imageRef];
+
+ // Release colorspace, context and bitmap information
+ CGColorSpaceRelease(colorSpace);
+ CGContextRelease(context);
+ CFRelease(imageRef);
+
+ return resultImage;
+}
+
+-(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint {
+ if (secondImage == nil) {
+ DLog(@"Warning, secondImage == nil");
+ return self;
+ }
+ CGFloat screenScale = [[UIScreen mainScreen] safeScale];
+ int w = self.size.width * screenScale;
+ int h = self.size.height * screenScale;
+ int yOffset = self.size.height - secondImage.size.height + secondImagePoint.y;
+
+ if (w == 0 || h == 0) {
+ DLog(@"Cannot have 0 dimesions");
+ return self;
+ }
+
+ // Create a bitmap graphics context; this will also set it as the current context
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, w, h+yOffset, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
+
+ // draw the two images in the current context
+ CGContextDrawImage(context, CGRectMake(0, 0, self.size.width*screenScale, self.size.height*screenScale), [self CGImage]);
+ CGContextDrawImage(context, CGRectMake(secondImagePoint.x*screenScale, secondImagePoint.y*screenScale, secondImage.size.width*screenScale, secondImage.size.height*screenScale), [secondImage CGImage]);
+
+ // Create bitmap image info from pixel data in current context
+ CGImageRef imageRef = CGBitmapContextCreateImage(context);
+
+ // Create a new UIImage object
+ UIImage *resultImage;
+ if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
+ resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp];
+ else
+ resultImage = [UIImage imageWithCGImage:imageRef];
+
+ // Release colorspace, context and bitmap information
+ CGColorSpaceRelease(colorSpace);
+ CGContextRelease(context);
+ CFRelease(imageRef);
+
+ return resultImage;
+}
+
+-(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect {
+ // load image from path
+ UIImage *image = [[UIImage alloc] initWithContentsOfFile: path];
+
+ if (nil != image) {
+ // get its CGImage representation with a give size
+ CGImageRef cgImage = CGImageCreateWithImageInRect([image CGImage], rect);
+
+ // clean memory
+ [image release];
+
+ // create a UIImage from the CGImage (memory must be allocated already)
+ UIImage *sprite = [self initWithCGImage:cgImage];
+
+ // clean memory
+ CGImageRelease(cgImage);
+
+ // return resulting image
+ return sprite;
+ } else {
+ DLog(@"error - image == nil");
+ return nil;
+ }
+}
+
+-(UIImage *)cutAt:(CGRect) rect {
+ CGImageRef cgImage = CGImageCreateWithImageInRect([self CGImage], rect);
+
+ UIImage *res = [UIImage imageWithCGImage:cgImage];
+ CGImageRelease(cgImage);
+
+ return res;
+}
+
+-(UIImage *)convertToGrayScale {
+ // Create image rectangle with current image width/height
+ CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
+
+ // Grayscale color space
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ // Create bitmap content with current image size and grayscale colorspace
+ CGContextRef context = CGBitmapContextCreate(nil, self.size.width, self.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
+
+ // Draw image into current context, with specified rectangle
+ // using previously defined context (with grayscale colorspace)
+ CGContextDrawImage(context, imageRect, [self CGImage]);
+
+ // Create bitmap image info from pixel data in current context
+ CGImageRef imageRef = CGBitmapContextCreateImage(context);
+
+ // Create a new UIImage object
+ UIImage *newImage = [UIImage imageWithCGImage:imageRef];
+
+ // Release colorspace, context and bitmap information
+ CFRelease(imageRef);
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ // Return the new grayscale image
+ return newImage;
+}
+
+// by http://iphonedevelopertips.com/cocoa/how-to-mask-an-image.html turned into a category by koda
+-(UIImage*) maskImageWith:(UIImage *)maskImage {
+ // prepare the reference image
+ CGImageRef maskRef = [maskImage CGImage];
+
+ // create the mask using parameters of the mask reference
+ CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
+ CGImageGetHeight(maskRef),
+ CGImageGetBitsPerComponent(maskRef),
+ CGImageGetBitsPerPixel(maskRef),
+ CGImageGetBytesPerRow(maskRef),
+ CGImageGetDataProvider(maskRef), NULL, false);
+
+ // create an image in the current context
+ CGImageRef masked = CGImageCreateWithMask([self CGImage], mask);
+ CGImageRelease(mask);
+
+ UIImage* retImage = [UIImage imageWithCGImage:masked];
+ CGImageRelease(masked);
+
+ return retImage;
+}
+
+// by http://blog.sallarp.com/iphone-uiimage-round-corners/ turned into a category by koda
+void addRoundedRectToPath(CGContextRef context, CGRect rect, CGFloat ovalWidth, CGFloat ovalHeight) {
+ CGFloat fw, fh;
+ if (ovalWidth == 0 || ovalHeight == 0) {
+ CGContextAddRect(context, rect);
+ return;
+ }
+ CGContextSaveGState(context);
+ CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
+ CGContextScaleCTM (context, ovalWidth, ovalHeight);
+ fw = CGRectGetWidth (rect) / ovalWidth;
+ fh = CGRectGetHeight (rect) / ovalHeight;
+ CGContextMoveToPoint(context, fw, fh/2);
+ CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
+ CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
+ CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
+ CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
+ CGContextClosePath(context);
+ CGContextRestoreGState(context);
+}
+
+-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh {
+ CGFloat cornerWidth = sizewh.width;
+ CGFloat cornerHeight = sizewh.height;
+ CGFloat screenScale = [[UIScreen mainScreen] safeScale];
+ CGFloat w = self.size.width * screenScale;
+ CGFloat h = self.size.height * screenScale;
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
+
+ CGContextBeginPath(context);
+ CGRect rect = CGRectMake(0, 0, w, h);
+ addRoundedRectToPath(context, rect, cornerWidth, cornerHeight);
+ CGContextClosePath(context);
+ CGContextClip(context);
+
+ CGContextDrawImage(context, CGRectMake(0, 0, w, h), [self CGImage]);
+
+ CGImageRef imageMasked = CGBitmapContextCreateImage(context);
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ UIImage *resultImage;
+ if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
+ resultImage = [UIImage imageWithCGImage:imageMasked scale:screenScale orientation:UIImageOrientationUp];
+ else
+ resultImage = [UIImage imageWithCGImage:imageMasked];
+ CGImageRelease(imageMasked);
+
+ return resultImage;
+}
+
+// by http://www.sixtemia.com/journal/2010/06/23/uiimage-negative-color-effect/
+-(UIImage *)convertToNegative {
+ UIGraphicsBeginImageContext(self.size);
+ CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
+ [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
+ CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeDifference);
+ CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(),[UIColor whiteColor].CGColor);
+ CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, self.size.width, self.size.height));
+ // create an image from the current contex (not thread safe)
+ UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return result;
+}
+
++(UIImage *)whiteImage:(CGSize) ofSize {
+ CGFloat w = ofSize.width;
+ CGFloat h = ofSize.height;
+ DLog(@"w: %f, h: %f", w, h);
+
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
+
+ CGContextBeginPath(context);
+ CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
+ CGContextFillRect(context,CGRectMake(0,0,ofSize.width,ofSize.height));
+
+ CGImageRef image = CGBitmapContextCreateImage(context);
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ UIImage *bkgImg = [UIImage imageWithCGImage:image];
+ CGImageRelease(image);
+ return bkgImg;
+}
+
++(UIImage *)drawHogsRepeated:(NSInteger) manyTimes {
+ NSString *imgString = [[NSString alloc] initWithFormat:@"%@/hedgehog.png",[[NSBundle mainBundle] resourcePath]];
+ UIImage *hogSprite = [[UIImage alloc] initWithContentsOfFile:imgString];
+ [imgString release];
+ CGFloat screenScale = [[UIScreen mainScreen] safeScale];
+ int w = hogSprite.size.width * screenScale;
+ int h = hogSprite.size.height * screenScale;
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(NULL, w * 3, h, 8, 4 * w * 3, colorSpace, kCGImageAlphaPremultipliedFirst);
+
+ // draw the two images in the current context
+ for (int i = 0; i < manyTimes; i++)
+ CGContextDrawImage(context, CGRectMake(i*8*screenScale, 0, w, h), [hogSprite CGImage]);
+ [hogSprite release];
+
+ // Create bitmap image info from pixel data in current context
+ CGImageRef imageRef = CGBitmapContextCreateImage(context);
+
+ // Create a new UIImage object
+ UIImage *resultImage;
+ if ([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)])
+ resultImage = [UIImage imageWithCGImage:imageRef scale:screenScale orientation:UIImageOrientationUp];
+ else
+ resultImage = [UIImage imageWithCGImage:imageRef];
+
+ // Release colorspace, context and bitmap information
+ CGColorSpaceRelease(colorSpace);
+ CGContextRelease(context);
+ CFRelease(imageRef);
+
+ return resultImage;
+}
+
+// this routine checks for the PNG size without loading it in memory
+// https://github.com/steipete/PSFramework/blob/master/PSFramework%20Version%200.3/PhotoshopFramework/PSMetaDataFunctions.m
++(CGSize) imageSizeFromMetadataOf:(NSString *)aFileName {
+ // File Name to C String.
+ const char *fileName = [aFileName UTF8String];
+ // source file
+ FILE *infile = fopen(fileName, "rb");
+ if (infile == NULL) {
+ DLog(@"Can't open the file: %@", aFileName);
+ return CGSizeZero;
+ }
+
+ // Bytes Buffer.
+ unsigned char buffer[30];
+ // Grab Only First Bytes.
+ fread(buffer, 1, 30, infile);
+ // Close File.
+ fclose(infile);
+
+ // PNG Signature.
+ unsigned char png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+ // Compare File signature.
+ if ((int)(memcmp(&buffer[0], &png_signature[0], 8))) {
+ DLog(@"The file (%@) is not a PNG file", aFileName);
+ return CGSizeZero;
+ }
+
+ // Calc Sizes. Isolate only four bytes of each size (width, height).
+ int width[4];
+ int height[4];
+ for (int d = 16; d < (16 + 4); d++) {
+ width[d-16] = buffer[d];
+ height[d-16] = buffer[d+4];
+ }
+
+ // Convert bytes to Long (Integer)
+ long resultWidth = (width[0] << (int)24) | (width[1] << (int)16) | (width[2] << (int)8) | width[3];
+ long resultHeight = (height[0] << (int)24) | (height[1] << (int)16) | (height[2] << (int)8) | height[3];
+
+ // Return Size.
+ return CGSizeMake(resultWidth,resultHeight);
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/VoicesViewController.h b/project_files/HedgewarsMobile/Classes/VoicesViewController.h
new file mode 100644
index 0000000..c8b89e3
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/VoicesViewController.h
@@ -0,0 +1,38 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+#import "SDL_mixer.h"
+
+
+ at interface VoicesViewController : UITableViewController {
+ NSMutableDictionary *teamDictionary;
+
+ NSArray *voiceArray;
+ NSIndexPath *lastIndexPath;
+
+ Mix_Chunk *voiceBeingPlayed;
+ int lastChannel;
+}
+
+ at property (nonatomic,retain) NSMutableDictionary *teamDictionary;
+ at property (nonatomic,retain) NSArray *voiceArray;
+ at property (nonatomic,retain) NSIndexPath *lastIndexPath;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/VoicesViewController.m b/project_files/HedgewarsMobile/Classes/VoicesViewController.m
new file mode 100644
index 0000000..323b624
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/VoicesViewController.m
@@ -0,0 +1,175 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "VoicesViewController.h"
+
+
+ at implementation VoicesViewController
+ at synthesize teamDictionary, voiceArray, lastIndexPath;
+
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+ srandom(time(NULL));
+
+ voiceBeingPlayed = NULL;
+
+ // load all the voices names and store them into voiceArray
+ // it's here and not in viewWillAppear because user cannot add/remove them
+ NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:VOICES_DIRECTORY() error:NULL];
+ self.voiceArray = array;
+
+ self.title = NSLocalizedString(@"Set hedgehog voices",@"");
+}
+
+-(void) viewWillAppear:(BOOL)animated {
+ [super viewWillAppear:animated];
+
+ // this moves the tableview to the top
+ [self.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+}
+
+-(void) viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ Mix_OpenAudio(44100, 0x8010, 1, 1024);
+}
+
+-(void) viewDidDisappear:(BOOL)animated {
+ [super viewDidDisappear:animated];
+ if(voiceBeingPlayed != NULL) {
+ Mix_HaltChannel(lastChannel);
+ Mix_FreeChunk(voiceBeingPlayed);
+ voiceBeingPlayed = NULL;
+ }
+ Mix_CloseAudio();
+}
+
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.voiceArray count];
+}
+
+// Customize the appearance of table view cells.
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ NSString *voice = [[voiceArray objectAtIndex:[indexPath row]] stringByDeletingPathExtension];
+ cell.textLabel.text = voice;
+
+ if ([voice isEqualToString:[teamDictionary objectForKey:@"voicepack"]]) {
+ cell.accessoryType = UITableViewCellAccessoryCheckmark;
+ self.lastIndexPath = indexPath;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ }
+
+ return cell;
+}
+
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ int newRow = [indexPath row];
+ int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
+
+ if (newRow != oldRow) {
+ [teamDictionary setObject:[voiceArray objectAtIndex:newRow] forKey:@"voicepack"];
+
+ // tell our boss to write this new stuff on disk
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"setWriteNeedTeams" object:nil];
+ [self.tableView reloadData];
+
+ self.lastIndexPath = indexPath;
+ [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone];
+ }
+ [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
+
+ // stop any sound before playing another one
+ if (voiceBeingPlayed != NULL) {
+ Mix_HaltChannel(lastChannel);
+ Mix_FreeChunk(voiceBeingPlayed);
+ voiceBeingPlayed = NULL;
+ }
+
+ NSString *voiceDir = [[NSString alloc] initWithFormat:@"%@/%@/",VOICES_DIRECTORY(),[voiceArray objectAtIndex:newRow]];
+ NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:voiceDir error:NULL];
+
+ int index = random() % [array count];
+
+ voiceBeingPlayed = Mix_LoadWAV([[voiceDir stringByAppendingString:[array objectAtIndex:index]] UTF8String]);
+ [voiceDir release];
+ lastChannel = Mix_PlayChannel(-1, voiceBeingPlayed, 0);
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void) didReceiveMemoryWarning {
+ if (voiceBeingPlayed != NULL) {
+ Mix_HaltChannel(lastChannel);
+ Mix_FreeChunk(voiceBeingPlayed);
+ voiceBeingPlayed = NULL;
+ }
+ self.lastIndexPath = nil;
+ MSG_MEMCLEAN();
+ [super didReceiveMemoryWarning];
+}
+
+-(void) viewDidUnload {
+ if (voiceBeingPlayed != NULL) {
+ Mix_HaltChannel(lastChannel);
+ Mix_FreeChunk(voiceBeingPlayed);
+ voiceBeingPlayed = NULL;
+ }
+ self.lastIndexPath = nil;
+ self.teamDictionary = nil;
+ self.voiceArray = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+-(void) dealloc {
+ releaseAndNil(voiceArray);
+ releaseAndNil(teamDictionary);
+ releaseAndNil(lastIndexPath);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Classes/WeaponCellView.h b/project_files/HedgewarsMobile/Classes/WeaponCellView.h
new file mode 100644
index 0000000..d3c5f4e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/WeaponCellView.h
@@ -0,0 +1,75 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at protocol WeaponButtonControllerDelegate <NSObject>
+
+-(void) updateValues:(NSArray *)withArray atIndex:(NSInteger) index;
+
+ at end
+
+ at interface WeaponCellView : UITableViewCell {
+ id<WeaponButtonControllerDelegate> delegate;
+ UILabel *weaponName;
+ UIImageView *weaponIcon;
+
+ UISlider *initialSli;
+ UISlider *probabilitySli;
+ UISlider *delaySli;
+ UISlider *crateSli;
+
+ at private
+ UIImageView *initialImg;
+ UIImageView *probabilityImg;
+ UIImageView *delayImg;
+ UIImageView *crateImg;
+
+ UILabel *initialLab;
+ UILabel *probabilityLab;
+ UILabel *delayLab;
+ UILabel *crateLab;
+
+ UILabel *helpLabel;
+}
+
+ at property (nonatomic,assign) id<WeaponButtonControllerDelegate> delegate;
+
+ at property (nonatomic,retain) UILabel *weaponName;
+ at property (nonatomic,retain) UIImageView *weaponIcon;
+
+ at property (nonatomic,retain) UISlider *initialSli;
+ at property (nonatomic,retain) UISlider *probabilitySli;
+ at property (nonatomic,retain) UISlider *delaySli;
+ at property (nonatomic,retain) UISlider *crateSli;
+
+ at property (nonatomic,retain) UIImageView *initialImg;
+ at property (nonatomic,retain) UIImageView *probabilityImg;
+ at property (nonatomic,retain) UIImageView *delayImg;
+ at property (nonatomic,retain) UIImageView *crateImg;
+
+ at property (nonatomic,retain) UILabel *initialLab;
+ at property (nonatomic,retain) UILabel *probabilityLab;
+ at property (nonatomic,retain) UILabel *delayLab;
+ at property (nonatomic,retain) UILabel *crateLab;
+
+ at property (nonatomic,retain) UILabel *helpLabel;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/WeaponCellView.m b/project_files/HedgewarsMobile/Classes/WeaponCellView.m
new file mode 100644
index 0000000..bec9fd6
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/WeaponCellView.m
@@ -0,0 +1,269 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "WeaponCellView.h"
+
+
+ at implementation WeaponCellView
+ at synthesize delegate, weaponName, weaponIcon, initialSli, probabilitySli, delaySli, crateSli, helpLabel,
+ initialImg, probabilityImg, delayImg, crateImg, initialLab, probabilityLab, delayLab, crateLab;
+
+-(id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
+ if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
+ delegate = nil;
+
+ weaponName = [[UILabel alloc] init];
+ weaponName.backgroundColor = [UIColor clearColor];
+ weaponName.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];
+ weaponIcon = [[UIImageView alloc] init];
+
+ initialSli = [[UISlider alloc] init];
+ [initialSli addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
+ [initialSli addTarget:self action:@selector(startDragging:) forControlEvents:UIControlEventTouchDown];
+ [initialSli addTarget:self action:@selector(stopDragging:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
+ initialSli.maximumValue = 9;
+ initialSli.minimumValue = 0;
+ initialSli.tag = 100;
+
+ probabilitySli = [[UISlider alloc] init];
+ [probabilitySli addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
+ [probabilitySli addTarget:self action:@selector(startDragging:) forControlEvents:UIControlEventTouchDown];
+ [probabilitySli addTarget:self action:@selector(stopDragging:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
+ probabilitySli.maximumValue = 9;
+ probabilitySli.minimumValue = 0;
+ probabilitySli.tag = 200;
+
+ delaySli = [[UISlider alloc] init];
+ [delaySli addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
+ [delaySli addTarget:self action:@selector(startDragging:) forControlEvents:UIControlEventTouchDown];
+ [delaySli addTarget:self action:@selector(stopDragging:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
+ delaySli.maximumValue = 9;
+ delaySli.minimumValue = 0;
+ delaySli.tag = 300;
+
+ crateSli = [[UISlider alloc] init];
+ [crateSli addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
+ [crateSli addTarget:self action:@selector(startDragging:) forControlEvents:UIControlEventTouchDown];
+ [crateSli addTarget:self action:@selector(stopDragging:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
+ crateSli.maximumValue = 9;
+ crateSli.minimumValue = 0;
+ crateSli.tag = 400;
+
+ NSString *imgAmmoStr = [[NSString alloc] initWithFormat:@"%@/ammopic.png",ICONS_DIRECTORY()];
+ initialImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:imgAmmoStr]];
+ [imgAmmoStr release];
+ NSString *imgDamageStr = [[NSString alloc] initWithFormat:@"%@/iconDamage.png",ICONS_DIRECTORY()];
+ probabilityImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:imgDamageStr]];
+ [imgDamageStr release];
+ NSString *imgTimeStr = [[NSString alloc] initWithFormat:@"%@/iconTime.png",ICONS_DIRECTORY()];
+ delayImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:imgTimeStr]];
+ [imgTimeStr release];
+ NSString *imgBoxStr = [[NSString alloc] initWithFormat:@"%@/iconBox.png",ICONS_DIRECTORY()];
+ crateImg = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:imgBoxStr]];
+ [imgBoxStr release];
+
+ initialLab = [[UILabel alloc] init];
+ initialLab.backgroundColor = [UIColor clearColor];
+ initialLab.textColor = [UIColor grayColor];
+ initialLab.textAlignment = UITextAlignmentCenter;
+
+ probabilityLab = [[UILabel alloc] init];
+ probabilityLab.backgroundColor = [UIColor clearColor];
+ probabilityLab.textColor = [UIColor grayColor];
+ probabilityLab.textAlignment = UITextAlignmentCenter;
+
+ delayLab = [[UILabel alloc] init];
+ delayLab.backgroundColor = [UIColor clearColor];
+ delayLab.textColor = [UIColor grayColor];
+ delayLab.textAlignment = UITextAlignmentCenter;
+
+ crateLab = [[UILabel alloc] init];
+ crateLab.backgroundColor = [UIColor clearColor];
+ crateLab.textColor = [UIColor grayColor];
+ crateLab.textAlignment = UITextAlignmentCenter;
+
+ helpLabel = [[UILabel alloc] init];
+ helpLabel.backgroundColor = [UIColor clearColor];
+ helpLabel.textColor = [UIColor darkGrayColor];
+ helpLabel.textAlignment = UITextAlignmentRight;
+ helpLabel.font = [UIFont italicSystemFontOfSize:[UIFont systemFontSize]];
+ helpLabel.adjustsFontSizeToFitWidth = YES;
+
+ [self.contentView addSubview:weaponName];
+ [self.contentView addSubview:weaponIcon];
+
+ [self.contentView addSubview:initialSli];
+ [self.contentView addSubview:probabilitySli];
+ [self.contentView addSubview:delaySli];
+ [self.contentView addSubview:crateSli];
+
+ [self.contentView addSubview:initialImg];
+ [self.contentView addSubview:probabilityImg];
+ [self.contentView addSubview:delayImg];
+ [self.contentView addSubview:crateImg];
+
+ [self.contentView addSubview:initialLab];
+ [self.contentView addSubview:probabilityLab];
+ [self.contentView addSubview:delayLab];
+ [self.contentView addSubview:crateLab];
+
+ [self.contentView addSubview:helpLabel];
+ }
+ return self;
+}
+
+-(void) layoutSubviews {
+ [super layoutSubviews];
+
+ CGFloat hOffset = 80;
+ CGFloat hOffsetWhenLandscape = 234;
+ CGFloat vOffset = 40;
+ CGFloat vOffsetWhenPortrait = 0;
+ CGFloat helpLabelOffset = 0;
+ CGFloat helpLabelLength = 0;
+ CGFloat sliderLength = 150;
+
+ if (IS_IPAD()) {
+ if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) {
+ sliderLength = 190;
+ hOffsetWhenLandscape = 0;
+ vOffsetWhenPortrait = 80;
+ hOffset = 120;
+ helpLabelOffset = -35;
+ helpLabelLength = 200;
+ } else {
+ hOffset = 145;
+ helpLabelOffset = 35;
+ helpLabelLength = 350;
+ }
+ } else {
+ helpLabelLength = 250;
+ hOffset = 67;
+ }
+
+ weaponIcon.frame = CGRectMake(5, 5, 32, 32);
+ weaponName.frame = CGRectMake(45, 8, 200, 25);
+
+ helpLabel.frame = CGRectMake(200 + helpLabelOffset, 11, helpLabelLength, 20);
+
+ // second line
+ initialImg.frame = CGRectMake(hOffset - 60, vOffset, 32, 32);
+ initialLab.frame = CGRectMake(hOffset - 23, vOffset, 20, 32);
+ initialLab.text = ((int)initialSli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)initialSli.value];
+ initialSli.frame = CGRectMake(hOffset, vOffset, sliderLength, 32);
+
+ probabilityImg.frame = CGRectMake(hOffset + hOffsetWhenLandscape - 60, vOffset + vOffsetWhenPortrait, 32, 32);
+ probabilityLab.frame = CGRectMake(hOffset + hOffsetWhenLandscape - 23, vOffset + vOffsetWhenPortrait, 20, 32);
+ probabilityLab.text = ((int)probabilitySli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)probabilitySli.value];
+ probabilitySli.frame = CGRectMake(hOffset + hOffsetWhenLandscape, vOffset + vOffsetWhenPortrait, sliderLength, 32);
+
+ // third line
+ delayImg.frame = CGRectMake(hOffset - 60, vOffset + 40, 32, 32);
+ delayLab.frame = CGRectMake(hOffset - 23, vOffset + 40, 20, 32);
+ delayLab.text = ((int)delaySli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)delaySli.value];
+ delaySli.frame = CGRectMake(hOffset, vOffset + 40, sliderLength, 32);
+
+ crateImg.frame = CGRectMake(hOffset + hOffsetWhenLandscape - 60, vOffset + 40 + vOffsetWhenPortrait, 32, 32);
+ crateLab.frame = CGRectMake(hOffset + hOffsetWhenLandscape - 23, vOffset + 40 + vOffsetWhenPortrait, 20, 32);
+ crateLab.text = ((int)crateSli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)crateSli.value];
+ crateSli.frame = CGRectMake(hOffset + hOffsetWhenLandscape, vOffset + 40 + vOffsetWhenPortrait, sliderLength, 32);
+}
+
+/*
+-(void) setSelected:(BOOL)selected animated:(BOOL)animated {
+ [super setSelected:selected animated:animated];
+ // Configure the view for the selected state
+}
+*/
+
+-(void) valueChanged:(id) sender {
+ if (self.delegate != nil) {
+ initialLab.text = ((int)initialSli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)initialSli.value];
+ probabilityLab.text = ((int)probabilitySli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)probabilitySli.value];
+ delayLab.text = ((int)delaySli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)delaySli.value];
+ crateLab.text = ((int)crateSli.value == 9) ? @"â" : [NSString stringWithFormat:@"%d",(int)crateSli.value];
+
+ [delegate updateValues:[NSArray arrayWithObjects:
+ [NSNumber numberWithInt:(int)initialSli.value],
+ [NSNumber numberWithInt:(int)probabilitySli.value],
+ [NSNumber numberWithInt:(int)delaySli.value],
+ [NSNumber numberWithInt:(int)crateSli.value], nil]
+ atIndex:self.tag];
+ } else
+ DLog(@"error - delegate = nil!");
+}
+
+-(void) startDragging:(id) sender {
+ UISlider *slider = (UISlider *)sender;
+ NSString *str = nil;
+
+ switch (slider.tag) {
+ case 100:
+ str = NSLocalizedString(@"Initial quantity",@"ammo selection");
+ break;
+ case 200:
+ if (IS_ON_PORTRAIT())
+ str = NSLocalizedString(@"Probability in crates",@"ammo selection");
+ else
+ str = NSLocalizedString(@"Presence probability in crates",@"ammo selection");
+ break;
+ case 300:
+ if (IS_ON_PORTRAIT())
+ str = NSLocalizedString(@"Weapon delay",@"ammo selection");
+ else
+ str = NSLocalizedString(@"Turns before this weapon becomes usable",@"ammo selection");
+ break;
+ case 400:
+ if (IS_ON_PORTRAIT())
+ str = NSLocalizedString(@"Quantity per crate",@"ammo selection");
+ else
+ str = NSLocalizedString(@"Quantity you will find in a crate",@"ammo selection");
+ break;
+ default:
+ DLog(@"Nope");
+ break;
+ }
+ self.helpLabel.text = str;
+}
+
+-(void) stopDragging:(id) sender {
+ self.helpLabel.text = @"";
+}
+
+-(void) dealloc {
+ self.delegate = nil;
+ releaseAndNil(weaponName);
+ releaseAndNil(weaponIcon);
+ releaseAndNil(initialSli);
+ releaseAndNil(probabilitySli);
+ releaseAndNil(delaySli);
+ releaseAndNil(crateSli);
+ releaseAndNil(initialImg);
+ releaseAndNil(probabilityImg);
+ releaseAndNil(delayImg);
+ releaseAndNil(crateImg);
+ releaseAndNil(initialLab);
+ releaseAndNil(probabilityLab);
+ releaseAndNil(delayLab);
+ releaseAndNil(crateLab);
+ releaseAndNil(helpLabel);
+ [super dealloc];
+}
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.h b/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.h
new file mode 100644
index 0000000..eb48847
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.h
@@ -0,0 +1,32 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import <UIKit/UIKit.h>
+
+
+ at class SingleWeaponViewController;
+
+ at interface WeaponSettingsViewController : UITableViewController {
+ NSMutableArray *listOfWeapons;
+ SingleWeaponViewController *childController;
+}
+
+ at property (nonatomic, retain) NSMutableArray *listOfWeapons;
+
+ at end
diff --git a/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.m b/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.m
new file mode 100644
index 0000000..0d611de
--- /dev/null
+++ b/project_files/HedgewarsMobile/Classes/WeaponSettingsViewController.m
@@ -0,0 +1,175 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2012 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#import "WeaponSettingsViewController.h"
+#import "SingleWeaponViewController.h"
+
+
+ at implementation WeaponSettingsViewController
+ at synthesize listOfWeapons;
+
+-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return rotationManager(interfaceOrientation);
+}
+
+#pragma mark -
+#pragma mark View lifecycle
+-(void) viewDidLoad {
+ [super viewDidLoad];
+
+ UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Edit",@"")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(toggleEdit:)];
+ self.navigationItem.rightBarButtonItem = editButton;
+ [editButton release];
+
+ self.navigationItem.title = @"List of weapons";
+}
+
+-(void) viewWillAppear:(BOOL) animated {
+ [super viewWillAppear:animated];
+
+ NSArray *contentsOfDir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:WEAPONS_DIRECTORY() error:NULL];
+ NSMutableArray *array = [[NSMutableArray alloc] initWithArray:contentsOfDir copyItems:YES];
+ self.listOfWeapons = array;
+ [array release];
+
+ [self.tableView reloadData];
+}
+
+// modifies the navigation bar to add the "Add" and "Done" buttons
+-(void) toggleEdit:(id) sender {
+ BOOL isEditing = self.tableView.editing;
+ [self.tableView setEditing:!isEditing animated:YES];
+
+ if (isEditing) {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Edit",@"from the scheme panel")];
+ [self.navigationItem.rightBarButtonItem setStyle: UIBarButtonItemStyleBordered];
+ self.navigationItem.leftBarButtonItem = self.navigationItem.backBarButtonItem;
+ } else {
+ [self.navigationItem.rightBarButtonItem setTitle:NSLocalizedString(@"Done",@"from the scheme panel")];
+ [self.navigationItem.rightBarButtonItem setStyle:UIBarButtonItemStyleDone];
+ UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Add",@"from the scheme panel")
+ style:UIBarButtonItemStyleBordered
+ target:self
+ action:@selector(addWeapon:)];
+ self.navigationItem.leftBarButtonItem = addButton;
+ [addButton release];
+ }
+}
+
+-(void) addWeapon:(id) sender {
+ NSString *fileName = [[NSString alloc] initWithFormat:@"Weapon %u.plist", [self.listOfWeapons count]];
+
+ [CreationChamber createWeaponNamed:[fileName stringByDeletingPathExtension]];
+
+ [self.listOfWeapons addObject:fileName];
+
+ // order the array alphabetically, so schemes will keep their position
+ [self.listOfWeapons sortUsingSelector:@selector(compare:)];
+ [self.tableView reloadData];
+
+ NSInteger index = [self.listOfWeapons indexOfObject:fileName];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
+ [fileName release];
+}
+
+#pragma mark -
+#pragma mark Table view data source
+-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
+ return 1;
+}
+
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ return [self.listOfWeapons count];
+}
+
+-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+ }
+
+ NSUInteger row = [indexPath row];
+ NSString *rowString = [[self.listOfWeapons objectAtIndex:row] stringByDeletingPathExtension];
+ cell.textLabel.text = rowString;
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
+
+ return cell;
+}
+
+// delete the row and the file
+-(void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ NSUInteger row = [indexPath row];
+
+ NSString *schemeFile = [[NSString alloc] initWithFormat:@"%@/%@",WEAPONS_DIRECTORY(),[self.listOfWeapons objectAtIndex:row]];
+ [[NSFileManager defaultManager] removeItemAtPath:schemeFile error:NULL];
+ [schemeFile release];
+
+ [self.listOfWeapons removeObjectAtIndex:row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+}
+
+#pragma mark -
+#pragma mark Table view delegate
+-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (childController == nil) {
+ childController = [[SingleWeaponViewController alloc] initWithStyle:UITableViewStyleGrouped];
+ }
+
+ NSInteger row = [indexPath row];
+ NSString *selectedWeaponFile = [self.listOfWeapons objectAtIndex:row];
+
+ // this must be set so childController can load the correct plist
+ childController.weaponName = [selectedWeaponFile stringByDeletingPathExtension];
+ [childController.tableView setContentOffset:CGPointMake(0,0) animated:NO];
+
+ [self.navigationController pushViewController:childController animated:YES];
+ [tableView deselectRowAtIndexPath:indexPath animated:YES];
+}
+
+
+#pragma mark -
+#pragma mark Memory management
+-(void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ if (childController.view.superview == nil )
+ childController = nil;
+}
+
+-(void) viewDidUnload {
+ self.listOfWeapons = nil;
+ childController = nil;
+ MSG_DIDUNLOAD();
+ [super viewDidUnload];
+}
+
+
+-(void) dealloc {
+ releaseAndNil(listOfWeapons);
+ releaseAndNil(childController);
+ [super dealloc];
+}
+
+
+ at end
+
diff --git a/project_files/HedgewarsMobile/Entitlements-Development.plist b/project_files/HedgewarsMobile/Entitlements-Development.plist
new file mode 100644
index 0000000..42cfb9c
--- /dev/null
+++ b/project_files/HedgewarsMobile/Entitlements-Development.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>get-task-allow</key>
+ <true/>
+</dict>
+</plist>
diff --git a/project_files/HedgewarsMobile/Entitlements-Distribution.plist b/project_files/HedgewarsMobile/Entitlements-Distribution.plist
new file mode 100644
index 0000000..ce373e1
--- /dev/null
+++ b/project_files/HedgewarsMobile/Entitlements-Distribution.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>get-task-allow</key>
+ <false/>
+</dict>
+</plist>
diff --git a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.mode1v3 b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.mode1v3
new file mode 100644
index 0000000..2385b98
--- /dev/null
+++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.mode1v3
@@ -0,0 +1,1602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ActivePerspectiveName</key>
+ <string>Project</string>
+ <key>AllowedModules</key>
+ <array>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Name</key>
+ <string>Groups and Files Outline View</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Name</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCTaskListModule</string>
+ <key>Name</key>
+ <string>Task List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Name</key>
+ <string>File and Smart Group Detail Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Name</key>
+ <string>Detailed Build Results Viewer</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Name</key>
+ <string>Project Batch Find Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Name</key>
+ <string>Project Format Conflicts List</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Name</key>
+ <string>Bookmarks Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Name</key>
+ <string>Class Browser</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Name</key>
+ <string>Source Code Control Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXDebugBreakpointsModule</string>
+ <key>Name</key>
+ <string>Debug Breakpoints Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCDockableInspector</string>
+ <key>Name</key>
+ <string>Inspector</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>PBXOpenQuicklyModule</string>
+ <key>Name</key>
+ <string>Open Quickly Tool</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Name</key>
+ <string>Debugger</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>1</string>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Name</key>
+ <string>Debug Console</string>
+ </dict>
+ <dict>
+ <key>BundleLoadPath</key>
+ <string></string>
+ <key>MaxInstances</key>
+ <string>n</string>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Name</key>
+ <string>Snapshots Tool</string>
+ </dict>
+ </array>
+ <key>BundlePath</key>
+ <string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources</string>
+ <key>Description</key>
+ <string>DefaultDescriptionKey</string>
+ <key>DockingSystemVisible</key>
+ <false/>
+ <key>Extension</key>
+ <string>mode1v3</string>
+ <key>FavBarConfig</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>61798847114AA42600BA94A9</string>
+ <key>XCBarModuleItemNames</key>
+ <dict/>
+ <key>XCBarModuleItems</key>
+ <array/>
+ </dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>com.apple.perspectives.project.mode1v3</string>
+ <key>MajorVersion</key>
+ <integer>33</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Default</string>
+ <key>Notifications</key>
+ <array/>
+ <key>OpenEditors</key>
+ <array/>
+ <key>PerspectiveWidths</key>
+ <array>
+ <integer>-1</integer>
+ <integer>-1</integer>
+ </array>
+ <key>Perspectives</key>
+ <array>
+ <dict>
+ <key>ChosenToolbarItems</key>
+ <array>
+ <string>active-platform-popup</string>
+ <string>active-buildstyle-popup</string>
+ <string>active-target-popup</string>
+ <string>active-architecture-popup</string>
+ <string>NSToolbarFlexibleSpaceItem</string>
+ <string>debugger-enable-breakpoints</string>
+ <string>buildOrClean</string>
+ <string>build-and-go</string>
+ <string>com.apple.ide.PBXToolbarStopButton</string>
+ </array>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProjectWithEditor</string>
+ <key>Identifier</key>
+ <string>perspective.project</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>248</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>080E96DDFE201D6D7F000001</string>
+ <string>61A118481168371400359010</string>
+ <string>29B97317FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>1</integer>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {248, 558}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <true/>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {265, 576}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>248</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>156 479 801 617 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>265pt</string>
+ </dict>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20306471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SDLh.pas</string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20406471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SDLh.pas</string>
+ <key>_historyCapacity</key>
+ <integer>0</integer>
+ <key>bookmark</key>
+ <string>61C3266E117A15C8001E70B1</string>
+ <key>history</key>
+ <array>
+ <string>6179889D114AA5BD00BA94A9</string>
+ <string>61799342114B297000BA94A9</string>
+ <string>61799343114B297000BA94A9</string>
+ <string>6179937111501D7800BA94A9</string>
+ <string>6179937411501D7800BA94A9</string>
+ <string>6179937511501D7800BA94A9</string>
+ <string>6179938511501FFA00BA94A9</string>
+ <string>6179943111502CEA00BA94A9</string>
+ <string>611FD81F1155111700C2203D</string>
+ <string>611FD8201155111700C2203D</string>
+ <string>611FD95811551C3700C2203D</string>
+ <string>611FD96611551E8000C2203D</string>
+ <string>611FDB6C1155C0B300C2203D</string>
+ <string>611FDB6D1155C0B300C2203D</string>
+ <string>611FDBF71155D39400C2203D</string>
+ <string>61E2F0811156B170002D33C1</string>
+ <string>618AFC07115BE92A003D411B</string>
+ <string>61CE23E7115E49560098C467</string>
+ <string>61CE23FF115E4B290098C467</string>
+ <string>61CE251F115E75A70098C467</string>
+ <string>61CCBE60116135FF00833FE8</string>
+ <string>61CCBF1E116162CA00833FE8</string>
+ <string>61CCBF451161637F00833FE8</string>
+ <string>61CCBF461161637F00833FE8</string>
+ <string>61CCBF471161637F00833FE8</string>
+ <string>61CCBF7B1161657400833FE8</string>
+ <string>61CCBF7C1161657400833FE8</string>
+ <string>61CCBF7E1161657400833FE8</string>
+ <string>61CCBF7F1161657400833FE8</string>
+ <string>61CCBFD11161833800833FE8</string>
+ <string>61CCBFD21161833800833FE8</string>
+ <string>61CCBFD31161833800833FE8</string>
+ <string>61CCBFD41161833800833FE8</string>
+ <string>61CCBFD51161833800833FE8</string>
+ <string>61CCBFD71161833800833FE8</string>
+ <string>61CCBFD91161833800833FE8</string>
+ <string>61CCBFDA1161833800833FE8</string>
+ <string>61CCBFDB1161833800833FE8</string>
+ <string>61CCBFDC1161833800833FE8</string>
+ <string>61697B9E1163478A00CCDF37</string>
+ <string>612D5C451165535400C6D842</string>
+ <string>612D616B1165536300C6D842</string>
+ <string>61430D3D1165551600E2C62D</string>
+ <string>615F1316116561BE002444F2</string>
+ <string>615F134D11656569002444F2</string>
+ <string>615F198C1166A71E002444F2</string>
+ <string>615F198E1166A71E002444F2</string>
+ <string>61CEDB60116ACBBB0067BAFC</string>
+ <string>611B0AC6116B6E8B00112153</string>
+ <string>611B0C42116BAF3A00112153</string>
+ <string>61056377116C0393003C420C</string>
+ <string>610563DF116C15E5003C420C</string>
+ <string>61513435116C1B07001F16D1</string>
+ <string>61513436116C1B07001F16D1</string>
+ <string>6151348C116C2954001F16D1</string>
+ <string>6151348D116C2954001F16D1</string>
+ <string>6151348E116C2954001F16D1</string>
+ <string>6151348F116C2954001F16D1</string>
+ <string>61FE2AE4116D658700F76CDC</string>
+ <string>619C51C6116E42850049FD84</string>
+ <string>619C51CB116E42850049FD84</string>
+ <string>619C51E0116E45820049FD84</string>
+ <string>619C523D116E56330049FD84</string>
+ <string>619C523F116E56330049FD84</string>
+ <string>619C5241116E56330049FD84</string>
+ <string>619C5243116E56330049FD84</string>
+ <string>619C5245116E56330049FD84</string>
+ <string>619C5247116E56330049FD84</string>
+ <string>619C5249116E56330049FD84</string>
+ <string>619C524B116E56330049FD84</string>
+ <string>619C524D116E56330049FD84</string>
+ <string>619C524F116E56330049FD84</string>
+ <string>619C5251116E56330049FD84</string>
+ <string>619C5253116E56330049FD84</string>
+ <string>619C5255116E56330049FD84</string>
+ <string>619C5257116E56330049FD84</string>
+ <string>619C5259116E56330049FD84</string>
+ <string>619C525B116E56330049FD84</string>
+ <string>619C525D116E56330049FD84</string>
+ <string>619C525F116E56330049FD84</string>
+ <string>619C5261116E56330049FD84</string>
+ <string>619C5263116E56330049FD84</string>
+ <string>619C5265116E56330049FD84</string>
+ <string>619C5267116E56330049FD84</string>
+ <string>619C5269116E56330049FD84</string>
+ <string>619C526B116E56330049FD84</string>
+ <string>619C526D116E56330049FD84</string>
+ <string>619C526F116E56330049FD84</string>
+ <string>619C5271116E56330049FD84</string>
+ <string>619C5273116E56330049FD84</string>
+ <string>619C5275116E56330049FD84</string>
+ <string>619C5277116E56330049FD84</string>
+ <string>619C5279116E56330049FD84</string>
+ <string>619C527B116E56330049FD84</string>
+ <string>619C527D116E56330049FD84</string>
+ <string>619C527F116E56330049FD84</string>
+ <string>619C5281116E56330049FD84</string>
+ <string>619C5283116E56330049FD84</string>
+ <string>619C5285116E56330049FD84</string>
+ <string>619C5287116E56330049FD84</string>
+ <string>619C5289116E56330049FD84</string>
+ <string>619C528B116E56330049FD84</string>
+ <string>619C528D116E56330049FD84</string>
+ <string>619C528F116E56330049FD84</string>
+ <string>619C5291116E56330049FD84</string>
+ <string>619C5293116E56330049FD84</string>
+ <string>619C5295116E56330049FD84</string>
+ <string>619C5297116E56330049FD84</string>
+ <string>619C5299116E56330049FD84</string>
+ <string>619C529B116E56330049FD84</string>
+ <string>619C529D116E56330049FD84</string>
+ <string>619C529F116E56330049FD84</string>
+ <string>619C52A1116E56330049FD84</string>
+ <string>619C52A3116E56330049FD84</string>
+ <string>619C52A5116E56330049FD84</string>
+ <string>619C52A7116E56330049FD84</string>
+ <string>619C52A9116E56330049FD84</string>
+ <string>619C52AB116E56330049FD84</string>
+ <string>619C52AD116E56330049FD84</string>
+ <string>619C52AF116E56330049FD84</string>
+ <string>619C52B1116E56330049FD84</string>
+ <string>619C52B7116E56330049FD84</string>
+ <string>619C52B9116E56330049FD84</string>
+ <string>619C52BB116E56330049FD84</string>
+ <string>619C52BD116E56330049FD84</string>
+ <string>619C52BF116E56330049FD84</string>
+ <string>619C52C1116E56330049FD84</string>
+ <string>619C5859116E73B00049FD84</string>
+ <string>619C585B116E73B00049FD84</string>
+ <string>619C585D116E73B00049FD84</string>
+ <string>619C585F116E73B00049FD84</string>
+ <string>619C5861116E73B00049FD84</string>
+ <string>619C5863116E73B00049FD84</string>
+ <string>619C5865116E73B00049FD84</string>
+ <string>619C5867116E73B00049FD84</string>
+ <string>619C5869116E73B00049FD84</string>
+ <string>619C586B116E73B00049FD84</string>
+ <string>619C586D116E73B00049FD84</string>
+ <string>619C586F116E73B00049FD84</string>
+ <string>619C5871116E73B00049FD84</string>
+ <string>619C5873116E73B00049FD84</string>
+ <string>619C5875116E73B00049FD84</string>
+ <string>619C5877116E73B00049FD84</string>
+ <string>619C5879116E73B00049FD84</string>
+ <string>619C587B116E73B00049FD84</string>
+ <string>619C587D116E73B00049FD84</string>
+ <string>619C587F116E73B00049FD84</string>
+ <string>619C5880116E73B00049FD84</string>
+ <string>619C5882116E73B00049FD84</string>
+ <string>619C5883116E73B00049FD84</string>
+ <string>619C5885116E73B00049FD84</string>
+ <string>619C5887116E73B00049FD84</string>
+ <string>619C5888116E73B00049FD84</string>
+ <string>619C5889116E73B00049FD84</string>
+ <string>619C588B116E73B00049FD84</string>
+ <string>619C588C116E73B00049FD84</string>
+ <string>619C588D116E73B00049FD84</string>
+ <string>619C588F116E73B00049FD84</string>
+ <string>619C5890116E73B00049FD84</string>
+ <string>619C5892116E73B00049FD84</string>
+ <string>619C58B2116E76080049FD84</string>
+ <string>6196317D116E89DF00C47CEE</string>
+ <string>61F8E0D6116E98A900108149</string>
+ <string>6157F7BA116F3B2D005E4A26</string>
+ <string>6188FE60116F77AF004F3690</string>
+ <string>617E1DB5116FEE5B002EF3D8</string>
+ <string>617B27B71171617A004A76A2</string>
+ <string>617B27B81171617A004A76A2</string>
+ <string>617B27B91171617A004A76A2</string>
+ <string>617B280E117164FC004A76A2</string>
+ <string>61D96559117180D9001EB3B4</string>
+ <string>61D96591117182B1001EB3B4</string>
+ <string>618BE56511750F6B00F22556</string>
+ <string>618BE599117512E400F22556</string>
+ <string>618BE59A117512E400F22556</string>
+ <string>618BE5FE11751F1C00F22556</string>
+ <string>618BE6C2117528B200F22556</string>
+ <string>618BE6C3117528B200F22556</string>
+ <string>618BE6E81175298700F22556</string>
+ <string>618BE70111752C5200F22556</string>
+ <string>618BE70311752C5200F22556</string>
+ <string>618BE70511752C5200F22556</string>
+ <string>618BE70711752C5200F22556</string>
+ <string>618BE72C11752D7900F22556</string>
+ <string>61F6AB931177BE470013254C</string>
+ <string>61BD54C411789A020038D495</string>
+ <string>614A80ED1178BB9B00552546</string>
+ <string>614A81041178BCC500552546</string>
+ <string>6184DE201178F4BD00AF6EFA</string>
+ <string>6184DF001179666500AF6EFA</string>
+ <string>6184DF10117967DC00AF6EFA</string>
+ <string>6184DF4411796A9200AF6EFA</string>
+ <string>6184DF4511796A9200AF6EFA</string>
+ <string>6184DF9A1179752300AF6EFA</string>
+ <string>6184DFE111797D2500AF6EFA</string>
+ <string>61C325231179A314001E70B1</string>
+ <string>61C325681179A3A0001E70B1</string>
+ <string>61C325691179A3A0001E70B1</string>
+ <string>61C325DD1179A993001E70B1</string>
+ <string>61C326361179B0A5001E70B1</string>
+ <string>61C3266D117A15C8001E70B1</string>
+ <string>615F147F11659AC5002444F2</string>
+ </array>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {531, 222}}</string>
+ <key>RubberWindowFrame</key>
+ <string>156 479 801 617 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>222pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B20506471E060097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 227}, {531, 349}}</string>
+ <key>RubberWindowFrame</key>
+ <string>156 479 801 617 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>349pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>531pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCModuleDock</string>
+ <string>PBXNavigatorGroup</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>61C326631179EA92001E70B1</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>61C326641179EA92001E70B1</string>
+ <string>1CE0B20306471E060097A5F4</string>
+ <string>1CE0B20506471E060097A5F4</string>
+ </array>
+ <key>ToolbarConfigUserDefaultsMinorVersion</key>
+ <string>2</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.defaultV3</string>
+ </dict>
+ <dict>
+ <key>ControllerClassBaseName</key>
+ <string></string>
+ <key>IconName</key>
+ <string>WindowOfProject</string>
+ <key>Identifier</key>
+ <string>perspective.morph</string>
+ <key>IsVertical</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C37FBAC04509CD000000102</string>
+ <string>1C37FAAC04509CD000000102</string>
+ <string>1C08E77C0454961000C914BD</string>
+ <string>1C37FABC05509CD000000102</string>
+ <string>1C37FABC05539CD112110102</string>
+ <string>E2644B35053B69B200211256</string>
+ <string>1C37FABC04509CD000100104</string>
+ <string>1CC0EA4004350EF90044410B</string>
+ <string>1CC0EA4004350EF90041110B</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>yes</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>186</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>29B97314FDCFA39411CA2CEA</string>
+ <string>1C37FABC05509CD000000102</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {186, 337}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <integer>1</integer>
+ <key>XCSharingToken</key>
+ <string>com.apple.Xcode.GFSharingToken</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {203, 355}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>186</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>373 269 690 397 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Morph</string>
+ <key>PreferredWidth</key>
+ <integer>300</integer>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCModuleDock</string>
+ <string>PBXSmartGroupTreeModule</string>
+ </array>
+ <key>TableOfContents</key>
+ <array>
+ <string>11E0B1FE06471DED0097A5F4</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.default.shortV3</string>
+ </dict>
+ </array>
+ <key>PerspectivesBarVisible</key>
+ <false/>
+ <key>ShelfIsVisible</key>
+ <false/>
+ <key>SourceDescription</key>
+ <string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TimeStamp</key>
+ <real>0.0</real>
+ <key>ToolbarConfigUserDefaultsMinorVersion</key>
+ <string>2</string>
+ <key>ToolbarDisplayMode</key>
+ <integer>1</integer>
+ <key>ToolbarIsVisible</key>
+ <true/>
+ <key>ToolbarSizeMode</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Perspectives</string>
+ <key>UpdateMessage</key>
+ <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+ <key>WindowJustification</key>
+ <integer>5</integer>
+ <key>WindowOrderList</key>
+ <array>
+ <string>61798848114AA42600BA94A9</string>
+ <string>/Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/HedgewarsMobile.xcodeproj</string>
+ </array>
+ <key>WindowString</key>
+ <string>156 479 801 617 0 0 1920 1178 </string>
+ <key>WindowToolsV3</key>
+ <array>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.build</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528F0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string></string>
+ <key>StatusBarVisibility</key>
+ <true/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {605, 307}}</string>
+ <key>RubberWindowFrame</key>
+ <string>1146 372 605 638 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>307pt</string>
+ </dict>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>XCMainBuildResultsModuleGUID</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Build Results</string>
+ <key>XCBuildResultsTrigger_Collapse</key>
+ <integer>1021</integer>
+ <key>XCBuildResultsTrigger_Open</key>
+ <integer>1011</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 312}, {605, 285}}</string>
+ <key>RubberWindowFrame</key>
+ <string>1146 372 605 638 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXBuildResultsModule</string>
+ <key>Proportion</key>
+ <string>285pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>597pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Build Results</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBuildResultsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>61798848114AA42600BA94A9</string>
+ <string>61C326651179EA92001E70B1</string>
+ <string>1CD0528F0623707200166675</string>
+ <string>XCMainBuildResultsModuleGUID</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.buildV3</string>
+ <key>WindowContentMinSize</key>
+ <string>486 300</string>
+ <key>WindowString</key>
+ <string>1146 372 605 638 0 0 1920 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>61798848114AA42600BA94A9</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debugger</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>Debugger</key>
+ <dict>
+ <key>HorizontalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {412, 253}}</string>
+ <string>{{412, 0}, {411, 253}}</string>
+ </array>
+ </dict>
+ <key>VerticalSplitView</key>
+ <dict>
+ <key>_collapsingFrameDimension</key>
+ <real>0.0</real>
+ <key>_indexOfCollapsedView</key>
+ <integer>0</integer>
+ <key>_percentageOfCollapsedView</key>
+ <real>0.0</real>
+ <key>isCollapsed</key>
+ <string>yes</string>
+ <key>sizes</key>
+ <array>
+ <string>{{0, 0}, {823, 253}}</string>
+ <string>{{0, 253}, {823, 225}}</string>
+ </array>
+ </dict>
+ </dict>
+ <key>LauncherConfigVersion</key>
+ <string>8</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C162984064C10D400B95A72</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debug - GLUTExamples (Underwater)</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>DebugConsoleVisible</key>
+ <string>None</string>
+ <key>DebugConsoleWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>DebugSTDIOWindowFrame</key>
+ <string>{{200, 200}, {500, 300}}</string>
+ <key>Frame</key>
+ <string>{{0, 0}, {823, 478}}</string>
+ <key>PBXDebugSessionStackFrameViewKey</key>
+ <dict>
+ <key>DebugVariablesTableConfiguration</key>
+ <array>
+ <string>Name</string>
+ <real>120</real>
+ <string>Value</string>
+ <real>85</real>
+ <string>Summary</string>
+ <real>94</real>
+ <string>Type</string>
+ <real>84</real>
+ </array>
+ <key>Frame</key>
+ <string>{{412, 0}, {411, 253}}</string>
+ <key>RubberWindowFrame</key>
+ <string>558 215 823 519 0 0 1920 1178 </string>
+ </dict>
+ <key>RubberWindowFrame</key>
+ <string>558 215 823 519 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugSessionModule</string>
+ <key>Proportion</key>
+ <string>478pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>478pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugSessionModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <string>61C325291179A314001E70B1</string>
+ <string>1C162984064C10D400B95A72</string>
+ <string>61C3252A1179A314001E70B1</string>
+ <string>61C3252B1179A314001E70B1</string>
+ <string>61C3252C1179A314001E70B1</string>
+ <string>61C3252D1179A314001E70B1</string>
+ <string>61C3252E1179A314001E70B1</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugV3</string>
+ <key>WindowString</key>
+ <string>558 215 823 519 0 0 1920 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>1CD10A99069EF8BA00B06720</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.find</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CDD528C0622207200134675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528D0623707200166675</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {781, 167}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>781pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD0528E0623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Project Find</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{8, 0}, {773, 254}}</string>
+ <key>RubberWindowFrame</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXProjectFindModule</string>
+ <key>Proportion</key>
+ <string>50%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>428pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Find</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXProjectFindModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <string>1C530D58069F1CE1000CFCEE</string>
+ <string>1C530D59069F1CE1000CFCEE</string>
+ <string>1CDD528C0622207200134675</string>
+ <string>1C530D5A069F1CE1000CFCEE</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CD0528E0623707200166675</string>
+ </array>
+ <key>WindowString</key>
+ <string>62 385 781 470 0 0 1440 878 </string>
+ <key>WindowToolGUID</key>
+ <string>1C530D57069F1CE1000CFCEE</string>
+ <key>WindowToolIsVisible</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>MENUSEPARATOR</string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.debuggerConsole</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAAC065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Debugger Console</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {750, 328}}</string>
+ <key>RubberWindowFrame</key>
+ <string>20 809 750 369 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXDebugCLIModule</string>
+ <key>Proportion</key>
+ <string>328pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>328pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debugger Console</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXDebugCLIModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAAD065D492600B07095</string>
+ <string>61C325CC1179A8F9001E70B1</string>
+ <string>1C78EAAC065D492600B07095</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.consoleV3</string>
+ <key>WindowString</key>
+ <string>20 809 750 369 0 0 1920 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>1C78EAAD065D492600B07095</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.snapshots</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCSnapshotModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Snapshots</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCSnapshotModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <string>Yes</string>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.snapshots</string>
+ <key>WindowString</key>
+ <string>315 824 300 550 0 0 1440 878 </string>
+ <key>WindowToolIsVisible</key>
+ <string>Yes</string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.scm</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB2065D492600B07095</string>
+ <key>PBXProjectModuleLabel</key>
+ <string><No Editor></string>
+ <key>PBXSplitModuleInNavigatorKey</key>
+ <dict>
+ <key>Split0</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1C78EAB3065D492600B07095</string>
+ </dict>
+ <key>SplitCount</key>
+ <string>1</string>
+ </dict>
+ <key>StatusBarVisibility</key>
+ <integer>1</integer>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {452, 0}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>0pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CD052920623707200166675</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>SCM</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ConsoleFrame</key>
+ <string>{{0, 259}, {452, 0}}</string>
+ <key>Frame</key>
+ <string>{{0, 7}, {452, 259}}</string>
+ <key>RubberWindowFrame</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ <key>TableConfiguration</key>
+ <array>
+ <string>Status</string>
+ <real>30</real>
+ <string>FileName</string>
+ <real>199</real>
+ <string>Path</string>
+ <real>197.0950012207031</real>
+ </array>
+ <key>TableFrame</key>
+ <string>{{0, 0}, {452, 250}}</string>
+ </dict>
+ <key>Module</key>
+ <string>PBXCVSModule</string>
+ <key>Proportion</key>
+ <string>262pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>266pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>SCM</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXCVSModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C78EAB4065D492600B07095</string>
+ <string>1C78EAB5065D492600B07095</string>
+ <string>1C78EAB2065D492600B07095</string>
+ <string>1CD052920623707200166675</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.scm</string>
+ <key>WindowString</key>
+ <string>743 379 452 308 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.breakpoints</string>
+ <key>IsVertical</key>
+ <false/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXBottomSmartGroupGIDs</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ </array>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Files</string>
+ <key>PBXProjectStructureProvided</key>
+ <string>no</string>
+ <key>PBXSmartGroupTreeModuleColumnData</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+ <array>
+ <real>168</real>
+ </array>
+ <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+ <array>
+ <string>MainColumn</string>
+ </array>
+ </dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+ <dict>
+ <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+ <array>
+ <string>1C77FABC04509CD000000102</string>
+ <string>1C3E0DCA080725EA00A55177</string>
+ <string>1C3E0DCA080725EA00A55177</string>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+ <array>
+ <array>
+ <integer>0</integer>
+ </array>
+ </array>
+ <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+ <string>{{0, 0}, {168, 350}}</string>
+ </dict>
+ <key>PBXTopSmartGroupGIDs</key>
+ <array/>
+ <key>XCIncludePerspectivesSwitch</key>
+ <false/>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{0, 0}, {185, 368}}</string>
+ <key>GroupTreeTableConfiguration</key>
+ <array>
+ <string>MainColumn</string>
+ <real>168</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>264 599 744 409 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXSmartGroupTreeModule</string>
+ <key>Proportion</key>
+ <string>185pt</string>
+ </dict>
+ <dict>
+ <key>BecomeActive</key>
+ <true/>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA1AED706398EBD00589147</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Detail</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{{190, 0}, {554, 368}}</string>
+ <key>RubberWindowFrame</key>
+ <string>264 599 744 409 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>XCDetailModule</string>
+ <key>Proportion</key>
+ <string>554pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>368pt</string>
+ </dict>
+ </array>
+ <key>MajorVersion</key>
+ <integer>3</integer>
+ <key>MinorVersion</key>
+ <integer>0</integer>
+ <key>Name</key>
+ <string>Breakpoints</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXSmartGroupTreeModule</string>
+ <string>XCDetailModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <true/>
+ <key>TableOfContents</key>
+ <array>
+ <string>6184DE581178F75B00AF6EFA</string>
+ <string>6184DE591178F75B00AF6EFA</string>
+ <string>1CE0B1FE06471DED0097A5F4</string>
+ <string>1CA1AED706398EBD00589147</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.breakpointsV3</string>
+ <key>WindowString</key>
+ <string>264 599 744 409 0 0 1920 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>6184DE581178F75B00AF6EFA</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.debugAnimator</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXNavigatorGroup</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Debug Visualizer</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXNavigatorGroup</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>1</integer>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.debugAnimatorV3</string>
+ <key>WindowString</key>
+ <string>100 100 700 500 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.bookmarks</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>PBXBookmarksModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Bookmarks</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXBookmarksModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowString</key>
+ <string>538 42 401 187 0 0 1280 1002 </string>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.projectFormatConflicts</string>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>Module</key>
+ <string>XCProjectFormatConflictsModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Project Format Conflicts</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCProjectFormatConflictsModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <integer>0</integer>
+ <key>WindowContentMinSize</key>
+ <string>450 300</string>
+ <key>WindowString</key>
+ <string>50 850 472 307 0 0 1440 877</string>
+ </dict>
+ <dict>
+ <key>FirstTimeWindowDisplayed</key>
+ <false/>
+ <key>Identifier</key>
+ <string>windowTool.classBrowser</string>
+ <key>IsVertical</key>
+ <true/>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>ContentConfiguration</key>
+ <dict>
+ <key>OptionsSetName</key>
+ <string>Hierarchy, all classes</string>
+ <key>PBXProjectModuleGUID</key>
+ <string>1CA6456E063B45B4001379D8</string>
+ <key>PBXProjectModuleLabel</key>
+ <string>Class Browser - NSObject</string>
+ </dict>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>ClassesFrame</key>
+ <string>{{0, 0}, {378, 96}}</string>
+ <key>ClassesTreeTableConfiguration</key>
+ <array>
+ <string>PBXClassNameColumnIdentifier</string>
+ <real>208</real>
+ <string>PBXClassBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>Frame</key>
+ <string>{{0, 0}, {630, 332}}</string>
+ <key>MembersFrame</key>
+ <string>{{0, 101}, {378, 231}}</string>
+ <key>MembersTreeTableConfiguration</key>
+ <array>
+ <string>PBXMemberTypeIconColumnIdentifier</string>
+ <real>22</real>
+ <string>PBXMemberNameColumnIdentifier</string>
+ <real>216</real>
+ <string>PBXMemberTypeColumnIdentifier</string>
+ <real>101</real>
+ <string>PBXMemberBookColumnIdentifier</string>
+ <real>22</real>
+ </array>
+ <key>RubberWindowFrame</key>
+ <string>503 565 630 352 0 0 1920 1178 </string>
+ </dict>
+ <key>Module</key>
+ <string>PBXClassBrowserModule</string>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>332pt</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Class Browser</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>PBXClassBrowserModule</string>
+ </array>
+ <key>StatusbarIsVisible</key>
+ <false/>
+ <key>TableOfContents</key>
+ <array>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <string>61A1195A1168457500359010</string>
+ <string>1CA6456E063B45B4001379D8</string>
+ </array>
+ <key>ToolbarConfiguration</key>
+ <string>xcode.toolbar.config.classbrowser</string>
+ <key>WindowString</key>
+ <string>503 565 630 352 0 0 1920 1178 </string>
+ <key>WindowToolGUID</key>
+ <string>1C0AD2AF069F1E9B00FABCE6</string>
+ <key>WindowToolIsVisible</key>
+ <false/>
+ </dict>
+ <dict>
+ <key>Identifier</key>
+ <string>windowTool.refactoring</string>
+ <key>IncludeInToolsMenu</key>
+ <integer>0</integer>
+ <key>Layout</key>
+ <array>
+ <dict>
+ <key>Dock</key>
+ <array>
+ <dict>
+ <key>BecomeActive</key>
+ <integer>1</integer>
+ <key>GeometryConfiguration</key>
+ <dict>
+ <key>Frame</key>
+ <string>{0, 0}, {500, 335}</string>
+ <key>RubberWindowFrame</key>
+ <string>{0, 0}, {500, 335}</string>
+ </dict>
+ <key>Module</key>
+ <string>XCRefactoringModule</string>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Proportion</key>
+ <string>100%</string>
+ </dict>
+ </array>
+ <key>Name</key>
+ <string>Refactoring</string>
+ <key>ServiceClasses</key>
+ <array>
+ <string>XCRefactoringModule</string>
+ </array>
+ <key>WindowString</key>
+ <string>200 200 500 356 0 0 1920 1200 </string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.pbxuser b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.pbxuser
new file mode 100644
index 0000000..b2c63ff
--- /dev/null
+++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/default.pbxuser
@@ -0,0 +1,3241 @@
+// !$*UTF8*$!
+{
+ 1D6058900D05DD3D006BFB54 /* HedgewarsMobile */ = {
+ activeExec = 0;
+ executables = (
+ 617987D7114AA2CD00BA94A9 /* HedgewarsMobile */,
+ );
+ };
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ activeBuildConfigurationName = Debug;
+ activeExecutable = 617987D7114AA2CD00BA94A9 /* HedgewarsMobile */;
+ activeSDKPreference = iphonesimulator3.2;
+ activeTarget = 1D6058900D05DD3D006BFB54 /* HedgewarsMobile */;
+ addToTargets = (
+ 61C3251C1179A300001E70B1 /* openalbridge */,
+ );
+ breakpoints = (
+ );
+ codeSenseManager = 617987E0114AA2EB00BA94A9 /* Code sense */;
+ executables = (
+ 617987D7114AA2CD00BA94A9 /* HedgewarsMobile */,
+ );
+ ignoreBreakpointsInProjectsDict = {
+ SDL_mixer = Ignored;
+ SDL_net = Ignored;
+ };
+ perUserDictionary = {
+ "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 20,
+ 198,
+ 20,
+ 99,
+ 99,
+ 29,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXBreakpointsDataSource_ActionID,
+ PBXBreakpointsDataSource_TypeID,
+ PBXBreakpointsDataSource_BreakpointID,
+ PBXBreakpointsDataSource_UseID,
+ PBXBreakpointsDataSource_LocationID,
+ PBXBreakpointsDataSource_ConditionID,
+ PBXBreakpointsDataSource_IgnoreCountID,
+ PBXBreakpointsDataSource_ContinueID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 22,
+ 300,
+ 184,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXExecutablesDataSource_ActiveFlagID,
+ PBXExecutablesDataSource_NameID,
+ PBXExecutablesDataSource_CommentsID,
+ );
+ };
+ PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 292,
+ 20,
+ 48,
+ 43,
+ 43,
+ 20,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ PBXFileDataSource_Target_ColumnID,
+ );
+ };
+ PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+ PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+ PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+ PBXFileTableDataSourceColumnWidthsKey = (
+ 20,
+ 252,
+ 60,
+ 20,
+ 48,
+ 43,
+ 43,
+ );
+ PBXFileTableDataSourceColumnsKey = (
+ PBXFileDataSource_FiletypeID,
+ PBXFileDataSource_Filename_ColumnID,
+ PBXTargetDataSource_PrimaryAttribute,
+ PBXFileDataSource_Built_ColumnID,
+ PBXFileDataSource_ObjectSize_ColumnID,
+ PBXFileDataSource_Errors_ColumnID,
+ PBXFileDataSource_Warnings_ColumnID,
+ );
+ };
+ PBXPerProjectTemplateStateSaveDate = 293202553;
+ PBXWorkspaceStateSaveDate = 293202553;
+ };
+ perUserProjectItems = {
+ 61056377116C0393003C420C /* PBXBookmark */ = 61056377116C0393003C420C /* PBXBookmark */;
+ 610563DF116C15E5003C420C /* PBXTextBookmark */ = 610563DF116C15E5003C420C /* PBXTextBookmark */;
+ 611B0AC6116B6E8B00112153 /* PBXTextBookmark */ = 611B0AC6116B6E8B00112153 /* PBXTextBookmark */;
+ 611B0C42116BAF3A00112153 /* PBXTextBookmark */ = 611B0C42116BAF3A00112153 /* PBXTextBookmark */;
+ 611FD81F1155111700C2203D /* PBXTextBookmark */ = 611FD81F1155111700C2203D /* PBXTextBookmark */;
+ 611FD8201155111700C2203D /* PBXTextBookmark */ = 611FD8201155111700C2203D /* PBXTextBookmark */;
+ 611FD95811551C3700C2203D /* PBXBookmark */ = 611FD95811551C3700C2203D /* PBXBookmark */;
+ 611FD96611551E8000C2203D /* PBXBookmark */ = 611FD96611551E8000C2203D /* PBXBookmark */;
+ 611FDB6C1155C0B300C2203D /* PBXBookmark */ = 611FDB6C1155C0B300C2203D /* PBXBookmark */;
+ 611FDB6D1155C0B300C2203D /* PBXBookmark */ = 611FDB6D1155C0B300C2203D /* PBXBookmark */;
+ 611FDBF71155D39400C2203D /* PBXTextBookmark */ = 611FDBF71155D39400C2203D /* PBXTextBookmark */;
+ 612D5C451165535400C6D842 /* PBXTextBookmark */ = 612D5C451165535400C6D842 /* PBXTextBookmark */;
+ 612D616B1165536300C6D842 /* PBXTextBookmark */ = 612D616B1165536300C6D842 /* PBXTextBookmark */;
+ 61430D3D1165551600E2C62D /* PBXTextBookmark */ = 61430D3D1165551600E2C62D /* PBXTextBookmark */;
+ 614A80ED1178BB9B00552546 /* PBXTextBookmark */ = 614A80ED1178BB9B00552546 /* PBXTextBookmark */;
+ 614A81041178BCC500552546 /* PBXTextBookmark */ = 614A81041178BCC500552546 /* PBXTextBookmark */;
+ 61513435116C1B07001F16D1 /* PBXTextBookmark */ = 61513435116C1B07001F16D1 /* PBXTextBookmark */;
+ 61513436116C1B07001F16D1 /* PBXTextBookmark */ = 61513436116C1B07001F16D1 /* PBXTextBookmark */;
+ 6151348C116C2954001F16D1 /* PBXBookmark */ = 6151348C116C2954001F16D1 /* PBXBookmark */;
+ 6151348D116C2954001F16D1 /* PBXBookmark */ = 6151348D116C2954001F16D1 /* PBXBookmark */;
+ 6151348E116C2954001F16D1 /* PBXBookmark */ = 6151348E116C2954001F16D1 /* PBXBookmark */;
+ 6151348F116C2954001F16D1 /* PlistBookmark */ = 6151348F116C2954001F16D1 /* PlistBookmark */;
+ 6157F7BA116F3B2D005E4A26 /* PBXTextBookmark */ = 6157F7BA116F3B2D005E4A26 /* PBXTextBookmark */;
+ 615F1316116561BE002444F2 /* PBXTextBookmark */ = 615F1316116561BE002444F2 /* PBXTextBookmark */;
+ 615F134D11656569002444F2 /* PBXTextBookmark */ = 615F134D11656569002444F2 /* PBXTextBookmark */;
+ 615F147F11659AC5002444F2 /* PBXTextBookmark */ = 615F147F11659AC5002444F2 /* PBXTextBookmark */;
+ 615F198C1166A71E002444F2 /* PBXBookmark */ = 615F198C1166A71E002444F2 /* PBXBookmark */;
+ 615F198E1166A71E002444F2 /* PBXTextBookmark */ = 615F198E1166A71E002444F2 /* PBXTextBookmark */;
+ 61697B9E1163478A00CCDF37 /* PBXTextBookmark */ = 61697B9E1163478A00CCDF37 /* PBXTextBookmark */;
+ 6179889D114AA5BD00BA94A9 /* PBXTextBookmark */ = 6179889D114AA5BD00BA94A9 /* PBXTextBookmark */;
+ 61799342114B297000BA94A9 /* PBXBookmark */ = 61799342114B297000BA94A9 /* PBXBookmark */;
+ 61799343114B297000BA94A9 /* PBXBookmark */ = 61799343114B297000BA94A9 /* PBXBookmark */;
+ 6179937111501D7800BA94A9 /* PBXBookmark */ = 6179937111501D7800BA94A9 /* PBXBookmark */;
+ 6179937411501D7800BA94A9 /* PBXBookmark */ = 6179937411501D7800BA94A9 /* PBXBookmark */;
+ 6179937511501D7800BA94A9 /* PBXBookmark */ = 6179937511501D7800BA94A9 /* PBXBookmark */;
+ 6179938511501FFA00BA94A9 /* PBXBookmark */ = 6179938511501FFA00BA94A9 /* PBXBookmark */;
+ 6179943111502CEA00BA94A9 /* PBXBookmark */ = 6179943111502CEA00BA94A9 /* PBXBookmark */;
+ 617B27B71171617A004A76A2 /* PBXTextBookmark */ = 617B27B71171617A004A76A2 /* PBXTextBookmark */;
+ 617B27B81171617A004A76A2 /* PBXTextBookmark */ = 617B27B81171617A004A76A2 /* PBXTextBookmark */;
+ 617B27B91171617A004A76A2 /* PBXTextBookmark */ = 617B27B91171617A004A76A2 /* PBXTextBookmark */;
+ 617B280E117164FC004A76A2 /* PBXTextBookmark */ = 617B280E117164FC004A76A2 /* PBXTextBookmark */;
+ 617E1DB5116FEE5B002EF3D8 /* PBXTextBookmark */ = 617E1DB5116FEE5B002EF3D8 /* PBXTextBookmark */;
+ 6184DE201178F4BD00AF6EFA /* PBXTextBookmark */ = 6184DE201178F4BD00AF6EFA /* PBXTextBookmark */;
+ 6184DF001179666500AF6EFA /* PBXTextBookmark */ = 6184DF001179666500AF6EFA /* PBXTextBookmark */;
+ 6184DF10117967DC00AF6EFA /* PBXTextBookmark */ = 6184DF10117967DC00AF6EFA /* PBXTextBookmark */;
+ 6184DF4411796A9200AF6EFA /* PBXTextBookmark */ = 6184DF4411796A9200AF6EFA /* PBXTextBookmark */;
+ 6184DF4511796A9200AF6EFA /* PBXTextBookmark */ = 6184DF4511796A9200AF6EFA /* PBXTextBookmark */;
+ 6184DF9A1179752300AF6EFA /* PBXTextBookmark */ = 6184DF9A1179752300AF6EFA /* PBXTextBookmark */;
+ 6184DFE111797D2500AF6EFA /* PBXTextBookmark */ = 6184DFE111797D2500AF6EFA /* PBXTextBookmark */;
+ 6188FE60116F77AF004F3690 /* PBXTextBookmark */ = 6188FE60116F77AF004F3690 /* PBXTextBookmark */;
+ 618AFC07115BE92A003D411B /* PBXBookmark */ = 618AFC07115BE92A003D411B /* PBXBookmark */;
+ 618BE56511750F6B00F22556 /* PBXTextBookmark */ = 618BE56511750F6B00F22556 /* PBXTextBookmark */;
+ 618BE599117512E400F22556 /* PBXTextBookmark */ = 618BE599117512E400F22556 /* PBXTextBookmark */;
+ 618BE59A117512E400F22556 /* PBXTextBookmark */ = 618BE59A117512E400F22556 /* PBXTextBookmark */;
+ 618BE5FE11751F1C00F22556 /* PBXTextBookmark */ = 618BE5FE11751F1C00F22556 /* PBXTextBookmark */;
+ 618BE6C2117528B200F22556 /* PBXTextBookmark */ = 618BE6C2117528B200F22556 /* PBXTextBookmark */;
+ 618BE6C3117528B200F22556 /* PBXTextBookmark */ = 618BE6C3117528B200F22556 /* PBXTextBookmark */;
+ 618BE6E81175298700F22556 /* PBXTextBookmark */ = 618BE6E81175298700F22556 /* PBXTextBookmark */;
+ 618BE70111752C5200F22556 /* PBXTextBookmark */ = 618BE70111752C5200F22556 /* PBXTextBookmark */;
+ 618BE70311752C5200F22556 /* PBXTextBookmark */ = 618BE70311752C5200F22556 /* PBXTextBookmark */;
+ 618BE70511752C5200F22556 /* PBXTextBookmark */ = 618BE70511752C5200F22556 /* PBXTextBookmark */;
+ 618BE70711752C5200F22556 /* PBXTextBookmark */ = 618BE70711752C5200F22556 /* PBXTextBookmark */;
+ 618BE72C11752D7900F22556 /* PBXTextBookmark */ = 618BE72C11752D7900F22556 /* PBXTextBookmark */;
+ 6196317D116E89DF00C47CEE /* PBXTextBookmark */ = 6196317D116E89DF00C47CEE /* PBXTextBookmark */;
+ 619C51C6116E42850049FD84 /* PBXTextBookmark */ = 619C51C6116E42850049FD84 /* PBXTextBookmark */;
+ 619C51CB116E42850049FD84 /* PBXTextBookmark */ = 619C51CB116E42850049FD84 /* PBXTextBookmark */;
+ 619C51E0116E45820049FD84 /* PBXTextBookmark */ = 619C51E0116E45820049FD84 /* PBXTextBookmark */;
+ 619C523D116E56330049FD84 /* PBXBookmark */ = 619C523D116E56330049FD84 /* PBXBookmark */;
+ 619C523F116E56330049FD84 /* PBXBookmark */ = 619C523F116E56330049FD84 /* PBXBookmark */;
+ 619C5241116E56330049FD84 /* PBXBookmark */ = 619C5241116E56330049FD84 /* PBXBookmark */;
+ 619C5243116E56330049FD84 /* PBXBookmark */ = 619C5243116E56330049FD84 /* PBXBookmark */;
+ 619C5245116E56330049FD84 /* PBXBookmark */ = 619C5245116E56330049FD84 /* PBXBookmark */;
+ 619C5247116E56330049FD84 /* PBXBookmark */ = 619C5247116E56330049FD84 /* PBXBookmark */;
+ 619C5249116E56330049FD84 /* PBXBookmark */ = 619C5249116E56330049FD84 /* PBXBookmark */;
+ 619C524B116E56330049FD84 /* PBXBookmark */ = 619C524B116E56330049FD84 /* PBXBookmark */;
+ 619C524D116E56330049FD84 /* PBXBookmark */ = 619C524D116E56330049FD84 /* PBXBookmark */;
+ 619C524F116E56330049FD84 /* PBXBookmark */ = 619C524F116E56330049FD84 /* PBXBookmark */;
+ 619C5251116E56330049FD84 /* PBXBookmark */ = 619C5251116E56330049FD84 /* PBXBookmark */;
+ 619C5253116E56330049FD84 /* PBXBookmark */ = 619C5253116E56330049FD84 /* PBXBookmark */;
+ 619C5255116E56330049FD84 /* PBXBookmark */ = 619C5255116E56330049FD84 /* PBXBookmark */;
+ 619C5257116E56330049FD84 /* PBXBookmark */ = 619C5257116E56330049FD84 /* PBXBookmark */;
+ 619C5259116E56330049FD84 /* PBXBookmark */ = 619C5259116E56330049FD84 /* PBXBookmark */;
+ 619C525B116E56330049FD84 /* PBXBookmark */ = 619C525B116E56330049FD84 /* PBXBookmark */;
+ 619C525D116E56330049FD84 /* PBXBookmark */ = 619C525D116E56330049FD84 /* PBXBookmark */;
+ 619C525F116E56330049FD84 /* PBXBookmark */ = 619C525F116E56330049FD84 /* PBXBookmark */;
+ 619C5261116E56330049FD84 /* PBXBookmark */ = 619C5261116E56330049FD84 /* PBXBookmark */;
+ 619C5263116E56330049FD84 /* PBXBookmark */ = 619C5263116E56330049FD84 /* PBXBookmark */;
+ 619C5265116E56330049FD84 /* PBXBookmark */ = 619C5265116E56330049FD84 /* PBXBookmark */;
+ 619C5267116E56330049FD84 /* PBXBookmark */ = 619C5267116E56330049FD84 /* PBXBookmark */;
+ 619C5269116E56330049FD84 /* PBXBookmark */ = 619C5269116E56330049FD84 /* PBXBookmark */;
+ 619C526B116E56330049FD84 /* PBXBookmark */ = 619C526B116E56330049FD84 /* PBXBookmark */;
+ 619C526D116E56330049FD84 /* PBXBookmark */ = 619C526D116E56330049FD84 /* PBXBookmark */;
+ 619C526F116E56330049FD84 /* PBXBookmark */ = 619C526F116E56330049FD84 /* PBXBookmark */;
+ 619C5271116E56330049FD84 /* PBXBookmark */ = 619C5271116E56330049FD84 /* PBXBookmark */;
+ 619C5273116E56330049FD84 /* PBXBookmark */ = 619C5273116E56330049FD84 /* PBXBookmark */;
+ 619C5275116E56330049FD84 /* PBXBookmark */ = 619C5275116E56330049FD84 /* PBXBookmark */;
+ 619C5277116E56330049FD84 /* PBXBookmark */ = 619C5277116E56330049FD84 /* PBXBookmark */;
+ 619C5279116E56330049FD84 /* PBXBookmark */ = 619C5279116E56330049FD84 /* PBXBookmark */;
+ 619C527B116E56330049FD84 /* PBXBookmark */ = 619C527B116E56330049FD84 /* PBXBookmark */;
+ 619C527D116E56330049FD84 /* PBXBookmark */ = 619C527D116E56330049FD84 /* PBXBookmark */;
+ 619C527F116E56330049FD84 /* PBXBookmark */ = 619C527F116E56330049FD84 /* PBXBookmark */;
+ 619C5281116E56330049FD84 /* PBXBookmark */ = 619C5281116E56330049FD84 /* PBXBookmark */;
+ 619C5283116E56330049FD84 /* PBXBookmark */ = 619C5283116E56330049FD84 /* PBXBookmark */;
+ 619C5285116E56330049FD84 /* PBXBookmark */ = 619C5285116E56330049FD84 /* PBXBookmark */;
+ 619C5287116E56330049FD84 /* PBXBookmark */ = 619C5287116E56330049FD84 /* PBXBookmark */;
+ 619C5289116E56330049FD84 /* PBXBookmark */ = 619C5289116E56330049FD84 /* PBXBookmark */;
+ 619C528B116E56330049FD84 /* PBXBookmark */ = 619C528B116E56330049FD84 /* PBXBookmark */;
+ 619C528D116E56330049FD84 /* PBXBookmark */ = 619C528D116E56330049FD84 /* PBXBookmark */;
+ 619C528F116E56330049FD84 /* PBXBookmark */ = 619C528F116E56330049FD84 /* PBXBookmark */;
+ 619C5291116E56330049FD84 /* PBXBookmark */ = 619C5291116E56330049FD84 /* PBXBookmark */;
+ 619C5293116E56330049FD84 /* PBXBookmark */ = 619C5293116E56330049FD84 /* PBXBookmark */;
+ 619C5295116E56330049FD84 /* PBXBookmark */ = 619C5295116E56330049FD84 /* PBXBookmark */;
+ 619C5297116E56330049FD84 /* PBXBookmark */ = 619C5297116E56330049FD84 /* PBXBookmark */;
+ 619C5299116E56330049FD84 /* PBXBookmark */ = 619C5299116E56330049FD84 /* PBXBookmark */;
+ 619C529B116E56330049FD84 /* PBXBookmark */ = 619C529B116E56330049FD84 /* PBXBookmark */;
+ 619C529D116E56330049FD84 /* PBXBookmark */ = 619C529D116E56330049FD84 /* PBXBookmark */;
+ 619C529F116E56330049FD84 /* PBXBookmark */ = 619C529F116E56330049FD84 /* PBXBookmark */;
+ 619C52A1116E56330049FD84 /* PBXBookmark */ = 619C52A1116E56330049FD84 /* PBXBookmark */;
+ 619C52A3116E56330049FD84 /* PBXBookmark */ = 619C52A3116E56330049FD84 /* PBXBookmark */;
+ 619C52A5116E56330049FD84 /* PBXBookmark */ = 619C52A5116E56330049FD84 /* PBXBookmark */;
+ 619C52A7116E56330049FD84 /* PBXBookmark */ = 619C52A7116E56330049FD84 /* PBXBookmark */;
+ 619C52A9116E56330049FD84 /* PBXBookmark */ = 619C52A9116E56330049FD84 /* PBXBookmark */;
+ 619C52AB116E56330049FD84 /* PBXBookmark */ = 619C52AB116E56330049FD84 /* PBXBookmark */;
+ 619C52AD116E56330049FD84 /* PBXBookmark */ = 619C52AD116E56330049FD84 /* PBXBookmark */;
+ 619C52AF116E56330049FD84 /* PBXBookmark */ = 619C52AF116E56330049FD84 /* PBXBookmark */;
+ 619C52B1116E56330049FD84 /* PBXBookmark */ = 619C52B1116E56330049FD84 /* PBXBookmark */;
+ 619C52B7116E56330049FD84 /* PBXBookmark */ = 619C52B7116E56330049FD84 /* PBXBookmark */;
+ 619C52B9116E56330049FD84 /* PBXBookmark */ = 619C52B9116E56330049FD84 /* PBXBookmark */;
+ 619C52BB116E56330049FD84 /* PBXBookmark */ = 619C52BB116E56330049FD84 /* PBXBookmark */;
+ 619C52BD116E56330049FD84 /* PBXBookmark */ = 619C52BD116E56330049FD84 /* PBXBookmark */;
+ 619C52BF116E56330049FD84 /* PBXBookmark */ = 619C52BF116E56330049FD84 /* PBXBookmark */;
+ 619C52C1116E56330049FD84 /* PBXBookmark */ = 619C52C1116E56330049FD84 /* PBXBookmark */;
+ 619C5859116E73B00049FD84 /* PBXBookmark */ = 619C5859116E73B00049FD84 /* PBXBookmark */;
+ 619C585B116E73B00049FD84 /* PBXBookmark */ = 619C585B116E73B00049FD84 /* PBXBookmark */;
+ 619C585D116E73B00049FD84 /* PBXBookmark */ = 619C585D116E73B00049FD84 /* PBXBookmark */;
+ 619C585F116E73B00049FD84 /* PBXBookmark */ = 619C585F116E73B00049FD84 /* PBXBookmark */;
+ 619C5861116E73B00049FD84 /* PBXBookmark */ = 619C5861116E73B00049FD84 /* PBXBookmark */;
+ 619C5863116E73B00049FD84 /* PBXBookmark */ = 619C5863116E73B00049FD84 /* PBXBookmark */;
+ 619C5865116E73B00049FD84 /* PBXBookmark */ = 619C5865116E73B00049FD84 /* PBXBookmark */;
+ 619C5867116E73B00049FD84 /* PBXBookmark */ = 619C5867116E73B00049FD84 /* PBXBookmark */;
+ 619C5869116E73B00049FD84 /* PBXBookmark */ = 619C5869116E73B00049FD84 /* PBXBookmark */;
+ 619C586B116E73B00049FD84 /* PBXBookmark */ = 619C586B116E73B00049FD84 /* PBXBookmark */;
+ 619C586D116E73B00049FD84 /* PBXBookmark */ = 619C586D116E73B00049FD84 /* PBXBookmark */;
+ 619C586F116E73B00049FD84 /* PBXBookmark */ = 619C586F116E73B00049FD84 /* PBXBookmark */;
+ 619C5871116E73B00049FD84 /* PBXBookmark */ = 619C5871116E73B00049FD84 /* PBXBookmark */;
+ 619C5873116E73B00049FD84 /* PBXBookmark */ = 619C5873116E73B00049FD84 /* PBXBookmark */;
+ 619C5875116E73B00049FD84 /* PBXBookmark */ = 619C5875116E73B00049FD84 /* PBXBookmark */;
+ 619C5877116E73B00049FD84 /* PBXBookmark */ = 619C5877116E73B00049FD84 /* PBXBookmark */;
+ 619C5879116E73B00049FD84 /* PBXBookmark */ = 619C5879116E73B00049FD84 /* PBXBookmark */;
+ 619C587B116E73B00049FD84 /* PBXBookmark */ = 619C587B116E73B00049FD84 /* PBXBookmark */;
+ 619C587D116E73B00049FD84 /* PBXBookmark */ = 619C587D116E73B00049FD84 /* PBXBookmark */;
+ 619C587F116E73B00049FD84 /* PBXBookmark */ = 619C587F116E73B00049FD84 /* PBXBookmark */;
+ 619C5880116E73B00049FD84 /* PBXBookmark */ = 619C5880116E73B00049FD84 /* PBXBookmark */;
+ 619C5882116E73B00049FD84 /* PBXBookmark */ = 619C5882116E73B00049FD84 /* PBXBookmark */;
+ 619C5883116E73B00049FD84 /* PBXBookmark */ = 619C5883116E73B00049FD84 /* PBXBookmark */;
+ 619C5885116E73B00049FD84 /* PBXBookmark */ = 619C5885116E73B00049FD84 /* PBXBookmark */;
+ 619C5887116E73B00049FD84 /* PBXBookmark */ = 619C5887116E73B00049FD84 /* PBXBookmark */;
+ 619C5888116E73B00049FD84 /* PBXBookmark */ = 619C5888116E73B00049FD84 /* PBXBookmark */;
+ 619C5889116E73B00049FD84 /* PBXBookmark */ = 619C5889116E73B00049FD84 /* PBXBookmark */;
+ 619C588B116E73B00049FD84 /* PBXBookmark */ = 619C588B116E73B00049FD84 /* PBXBookmark */;
+ 619C588C116E73B00049FD84 /* PBXBookmark */ = 619C588C116E73B00049FD84 /* PBXBookmark */;
+ 619C588D116E73B00049FD84 /* PBXBookmark */ = 619C588D116E73B00049FD84 /* PBXBookmark */;
+ 619C588F116E73B00049FD84 /* PBXBookmark */ = 619C588F116E73B00049FD84 /* PBXBookmark */;
+ 619C5890116E73B00049FD84 /* PBXBookmark */ = 619C5890116E73B00049FD84 /* PBXBookmark */;
+ 619C5892116E73B00049FD84 /* PBXBookmark */ = 619C5892116E73B00049FD84 /* PBXBookmark */;
+ 619C58B2116E76080049FD84 /* PBXBookmark */ = 619C58B2116E76080049FD84 /* PBXBookmark */;
+ 61BD54C411789A020038D495 /* PBXTextBookmark */ = 61BD54C411789A020038D495 /* PBXTextBookmark */;
+ 61C325231179A314001E70B1 /* PBXTextBookmark */ = 61C325231179A314001E70B1 /* PBXTextBookmark */;
+ 61C325681179A3A0001E70B1 /* PBXTextBookmark */ = 61C325681179A3A0001E70B1 /* PBXTextBookmark */;
+ 61C325691179A3A0001E70B1 /* PBXTextBookmark */ = 61C325691179A3A0001E70B1 /* PBXTextBookmark */;
+ 61C325DD1179A993001E70B1 /* PBXTextBookmark */ = 61C325DD1179A993001E70B1 /* PBXTextBookmark */;
+ 61C326361179B0A5001E70B1 /* PBXTextBookmark */ = 61C326361179B0A5001E70B1 /* PBXTextBookmark */;
+ 61C3266D117A15C8001E70B1 /* PBXTextBookmark */ = 61C3266D117A15C8001E70B1 /* PBXTextBookmark */;
+ 61C3266E117A15C8001E70B1 /* PBXTextBookmark */ = 61C3266E117A15C8001E70B1 /* PBXTextBookmark */;
+ 61CCBE60116135FF00833FE8 /* PBXTextBookmark */ = 61CCBE60116135FF00833FE8 /* PBXTextBookmark */;
+ 61CCBF1E116162CA00833FE8 /* PBXTextBookmark */ = 61CCBF1E116162CA00833FE8 /* PBXTextBookmark */;
+ 61CCBF451161637F00833FE8 /* PBXTextBookmark */ = 61CCBF451161637F00833FE8 /* PBXTextBookmark */;
+ 61CCBF461161637F00833FE8 /* PBXTextBookmark */ = 61CCBF461161637F00833FE8 /* PBXTextBookmark */;
+ 61CCBF471161637F00833FE8 /* PBXTextBookmark */ = 61CCBF471161637F00833FE8 /* PBXTextBookmark */;
+ 61CCBF7B1161657400833FE8 /* PBXTextBookmark */ = 61CCBF7B1161657400833FE8 /* PBXTextBookmark */;
+ 61CCBF7C1161657400833FE8 /* PBXTextBookmark */ = 61CCBF7C1161657400833FE8 /* PBXTextBookmark */;
+ 61CCBF7E1161657400833FE8 /* PBXTextBookmark */ = 61CCBF7E1161657400833FE8 /* PBXTextBookmark */;
+ 61CCBF7F1161657400833FE8 /* PBXTextBookmark */ = 61CCBF7F1161657400833FE8 /* PBXTextBookmark */;
+ 61CCBFD11161833800833FE8 /* PBXTextBookmark */ = 61CCBFD11161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD21161833800833FE8 /* PBXTextBookmark */ = 61CCBFD21161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD31161833800833FE8 /* PBXTextBookmark */ = 61CCBFD31161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD41161833800833FE8 /* PBXTextBookmark */ = 61CCBFD41161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD51161833800833FE8 /* PBXTextBookmark */ = 61CCBFD51161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD71161833800833FE8 /* PBXTextBookmark */ = 61CCBFD71161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFD91161833800833FE8 /* PBXTextBookmark */ = 61CCBFD91161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFDA1161833800833FE8 /* PBXTextBookmark */ = 61CCBFDA1161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFDB1161833800833FE8 /* PBXTextBookmark */ = 61CCBFDB1161833800833FE8 /* PBXTextBookmark */;
+ 61CCBFDC1161833800833FE8 /* PBXTextBookmark */ = 61CCBFDC1161833800833FE8 /* PBXTextBookmark */;
+ 61CE23E7115E49560098C467 /* PBXTextBookmark */ = 61CE23E7115E49560098C467 /* PBXTextBookmark */;
+ 61CE23FF115E4B290098C467 /* PBXBookmark */ = 61CE23FF115E4B290098C467 /* PBXBookmark */;
+ 61CE251F115E75A70098C467 /* PBXBookmark */ = 61CE251F115E75A70098C467 /* PBXBookmark */;
+ 61CEDB60116ACBBB0067BAFC /* PBXTextBookmark */ = 61CEDB60116ACBBB0067BAFC /* PBXTextBookmark */;
+ 61D96559117180D9001EB3B4 /* PBXTextBookmark */ = 61D96559117180D9001EB3B4 /* PBXTextBookmark */;
+ 61D96591117182B1001EB3B4 /* PBXTextBookmark */ = 61D96591117182B1001EB3B4 /* PBXTextBookmark */;
+ 61E2F0811156B170002D33C1 /* PBXTextBookmark */ = 61E2F0811156B170002D33C1 /* PBXTextBookmark */;
+ 61F6AB931177BE470013254C /* PBXTextBookmark */ = 61F6AB931177BE470013254C /* PBXTextBookmark */;
+ 61F8E0D6116E98A900108149 /* PBXTextBookmark */ = 61F8E0D6116E98A900108149 /* PBXTextBookmark */;
+ 61FE2AE4116D658700F76CDC /* PBXTextBookmark */ = 61FE2AE4116D658700F76CDC /* PBXTextBookmark */;
+ };
+ sourceControlManager = 617987DF114AA2EB00BA94A9 /* Source Control */;
+ userBuildSettings = {
+ };
+ };
+ 32CA4F630368D1EE00C91783 /* HedgewarsMobile_Prefix.pch */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {698, 204}}";
+ sepNavSelRange = "{181, 0}";
+ sepNavVisRange = "{0, 225}";
+ };
+ };
+ 61056377116C0393003C420C /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 6122CD00116BECCA002648E9 /* Default-Landscape.png */;
+ };
+ 610563DF116C15E5003C420C /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 610563E0116C15E5003C420C /* SDL_renderer_gles.c */;
+ name = "SDL_renderer_gles.c: 341";
+ rLen = 0;
+ rLoc = 11314;
+ rType = 0;
+ vrLen = 357;
+ vrLoc = 11160;
+ };
+ 610563E0116C15E5003C420C /* SDL_renderer_gles.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = SDL_renderer_gles.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL/src/video/SDL_renderer_gles.c";
+ sourceTree = "<absolute>";
+ };
+ 611B0A9F116B626E00112153 /* GeneralSettingsViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 639}}";
+ sepNavSelRange = "{288, 18}";
+ sepNavVisRange = "{0, 825}";
+ };
+ };
+ 611B0AA0116B626E00112153 /* GeneralSettingsViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 5187}}";
+ sepNavSelRange = "{511, 0}";
+ sepNavVisRange = "{0, 1843}";
+ sepNavWindowFrame = "{{413, 349}, {1058, 792}}";
+ };
+ };
+ 611B0AC6116B6E8B00112153 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11ABF1168D8B600359010 /* SplitViewRootController.h */;
+ name = "SplitViewRootController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 3;
+ vrLoc = 0;
+ };
+ 611B0C42116BAF3A00112153 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 611B0AA0116B626E00112153 /* GeneralSettingsViewController.m */;
+ name = "GeneralSettingsViewController.m: 249";
+ rLen = 0;
+ rLoc = 10620;
+ rType = 0;
+ vrLen = 75;
+ vrLoc = 631;
+ };
+ 611FD81F1155111700C2203D /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798858114AA48A00BA94A9 /* IMG_png.c */;
+ name = "IMG_png.c: 69";
+ rLen = 0;
+ rLoc = 2544;
+ rType = 0;
+ vrLen = 162;
+ vrLoc = 2505;
+ };
+ 611FD8201155111700C2203D /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798859114AA48A00BA94A9 /* IMG.c */;
+ name = "IMG.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 295;
+ vrLoc = 1032;
+ };
+ 611FD95811551C3700C2203D /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A25114ADD2600BA94A9 /* Default.png */;
+ };
+ 611FD96611551E8000C2203D /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A27114ADD2600BA94A9 /* networkButton.png */;
+ };
+ 611FDB6C1155C0B300C2203D /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 611FD9C81155A1F200C2203D /* Background.png */;
+ };
+ 611FDB6D1155C0B300C2203D /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 611FD9D11155A41000C2203D /* Multiplayer.png */;
+ };
+ 611FDBF71155D39400C2203D /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987E1114AA34C00BA94A9 /* CCHandlers.inc */;
+ name = "CCHandlers.inc: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 201;
+ vrLoc = 686;
+ };
+ 612D5C451165535400C6D842 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FE114AA34C00BA94A9 /* uKeys.pas */;
+ name = "uKeys.pas: 106";
+ rLen = 0;
+ rLoc = 2597;
+ rType = 0;
+ vrLen = 94;
+ vrLoc = 2933;
+ };
+ 612D616B1165536300C6D842 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987E7114AA34C00BA94A9 /* hwengine.pas */;
+ name = "hwengine.pas: 21";
+ rLen = 0;
+ rLoc = 806;
+ rType = 0;
+ vrLen = 33;
+ vrLoc = 791;
+ };
+ 61430D3D1165551600E2C62D /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798867114AA4AA00BA94A9 /* SDL_uikitwindow.h */;
+ name = "SDL_uikitwindow.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 3;
+ vrLoc = 0;
+ };
+ 614A80ED1178BB9B00552546 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987EC114AA34C00BA94A9 /* PascalExports.pas */;
+ name = "PascalExports.pas: 133";
+ rLen = 0;
+ rLoc = 2198;
+ rType = 0;
+ vrLen = 368;
+ vrLoc = 1805;
+ };
+ 614A81041178BCC500552546 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798888114AA4E600BA94A9 /* GameSetup.m */;
+ name = "GameSetup.m: 356";
+ rLen = 0;
+ rLoc = 13178;
+ rType = 0;
+ vrLen = 674;
+ vrLoc = 11543;
+ };
+ 614A818B1178C72A00552546 /* uMisc.s */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.asm;
+ name = uMisc.s;
+ path = "/Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/build/HedgewarsMobile.build/Debug-iphonesimulator/HedgewarsMobile.build/DerivedSources-normal/i386/uMisc.s";
+ sourceTree = "<absolute>";
+ };
+ 61513435116C1B07001F16D1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987EB114AA34C00BA94A9 /* options.inc */;
+ name = "options.inc: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 320;
+ vrLoc = 0;
+ };
+ 61513436116C1B07001F16D1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179880B114AA34C00BA94A9 /* uStore.pas */;
+ name = "uStore.pas: 1122";
+ rLen = 0;
+ rLoc = 37059;
+ rType = 0;
+ vrLen = 87;
+ vrLoc = 37021;
+ };
+ 6151348C116C2954001F16D1 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A26114ADD2600BA94A9 /* Icon.png */;
+ };
+ 6151348D116C2954001F16D1 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 6151347D116C2803001F16D1 /* Icon-iPad.png */;
+ };
+ 6151348E116C2954001F16D1 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A2B114ADD2600BA94A9 /* title.png */;
+ };
+ 6151348F116C2954001F16D1 /* PlistBookmark */ = {
+ isa = PlistBookmark;
+ fRef = 8D1107310486CEB800E47090 /* Info.plist */;
+ fallbackIsa = PBXBookmark;
+ isK = 0;
+ kPath = (
+ );
+ name = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Info.plist;
+ rLen = 0;
+ rLoc = 9223372036854775808;
+ };
+ 6157F7BA116F3B2D005E4A26 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11ADF1168DC6E00359010 /* SingleTeamViewController.h */;
+ name = "SingleTeamViewController.h: 19";
+ rLen = 0;
+ rLoc = 631;
+ rType = 0;
+ vrLen = 213;
+ vrLoc = 337;
+ };
+ 615F1316116561BE002444F2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798863114AA4AA00BA94A9 /* SDL_uikitappdelegate.h */;
+ name = "SDL_uikitappdelegate.h: 40";
+ rLen = 0;
+ rLoc = 1384;
+ rType = 0;
+ vrLen = 331;
+ vrLoc = 1260;
+ };
+ 615F134D11656569002444F2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798887114AA4E600BA94A9 /* GameSetup.h */;
+ name = "GameSetup.h: 13";
+ rLen = 0;
+ rLoc = 254;
+ rType = 0;
+ vrLen = 135;
+ vrLoc = 169;
+ };
+ 615F147F11659AC5002444F2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987ED114AA34C00BA94A9 /* SDLh.pas */;
+ name = "SDLh.pas: 488";
+ rLen = 0;
+ rLoc = 13681;
+ rType = 0;
+ vrLen = 150;
+ vrLoc = 12762;
+ };
+ 615F198C1166A71E002444F2 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 611FD9CF1155A40700C2203D /* NetworkPlay.png */;
+ };
+ 615F198E1166A71E002444F2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179885A114AA48A00BA94A9 /* PascalImports.h */;
+ name = "PascalImports.h: 17";
+ rLen = 0;
+ rLoc = 246;
+ rType = 0;
+ vrLen = 52;
+ vrLoc = 139;
+ };
+ 61697B9E1163478A00CCDF37 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798803114AA34C00BA94A9 /* uLandTexture.pas */;
+ name = "uLandTexture.pas: 107";
+ rLen = 0;
+ rLoc = 3388;
+ rType = 0;
+ vrLen = 250;
+ vrLoc = 3;
+ };
+ 617987D7114AA2CD00BA94A9 /* HedgewarsMobile */ = {
+ isa = PBXExecutable;
+ activeArgIndices = (
+ );
+ argumentStrings = (
+ );
+ autoAttachOnCrash = 1;
+ breakpointsEnabled = 1;
+ configStateDict = {
+ };
+ customDataFormattersEnabled = 1;
+ dataTipCustomDataFormattersEnabled = 1;
+ dataTipShowTypeColumn = 1;
+ dataTipSortType = 0;
+ debuggerPlugin = GDBDebugging;
+ disassemblyDisplayState = 0;
+ dylibVariantSuffix = "";
+ enableDebugStr = 1;
+ environmentEntries = (
+ {
+ active = NO;
+ name = NSZombieEnabled;
+ value = YES;
+ },
+ );
+ executableSystemSymbolLevel = 0;
+ executableUserSymbolLevel = 0;
+ libgmallocEnabled = 0;
+ name = HedgewarsMobile;
+ savedGlobals = {
+ };
+ showTypeColumn = 1;
+ sourceDirectories = (
+ );
+ variableFormatDictionary = {
+ $cs = 1;
+ $ds = 1;
+ $eax = 1;
+ $ebp = 1;
+ $ebx = 1;
+ $ecx = 1;
+ $edi = 1;
+ $edx = 1;
+ $eflags = 1;
+ $eip = 1;
+ $es = 1;
+ $esi = 1;
+ $esp = 1;
+ $fs = 1;
+ $gs = 1;
+ $ss = 1;
+ };
+ };
+ 617987DF114AA2EB00BA94A9 /* Source Control */ = {
+ isa = PBXSourceControlManager;
+ fallbackIsa = XCSourceControlManager;
+ isSCMEnabled = 0;
+ scmConfiguration = {
+ repositoryNamesForRoots = {
+ "" = "";
+ };
+ };
+ };
+ 617987E0114AA2EB00BA94A9 /* Code sense */ = {
+ isa = PBXCodeSenseManager;
+ indexTemplatePath = "";
+ };
+ 617987E1114AA34C00BA94A9 /* CCHandlers.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {735, 10088}}";
+ sepNavSelRange = "{17156, 0}";
+ sepNavVisRange = "{16604, 999}";
+ sepNavWindowFrame = "{{406, 184}, {794, 632}}";
+ };
+ };
+ 617987E4114AA34C00BA94A9 /* GSHandlers.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {572, 39507}}";
+ sepNavSelRange = "{23048, 0}";
+ sepNavVisRange = "{22940, 148}";
+ sepNavWindowFrame = "{{429, 163}, {794, 632}}";
+ };
+ };
+ 617987E7114AA34C00BA94A9 /* hwengine.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {838, 7774}}";
+ sepNavSelRange = "{7090, 0}";
+ sepNavVisRange = "{6695, 1053}";
+ sepNavWindowFrame = "{{421, 176}, {897, 692}}";
+ };
+ };
+ 617987E9114AA34C00BA94A9 /* hwLibrary.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {677, 329}}";
+ sepNavSelRange = "{344, 7}";
+ sepNavVisRange = "{0, 691}";
+ sepNavWindowFrame = "{{15, 481}, {897, 692}}";
+ };
+ };
+ 617987EB114AA34C00BA94A9 /* options.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {509, 507}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 320}";
+ sepNavWindowFrame = "{{864, 517}, {921, 605}}";
+ };
+ };
+ 617987EC114AA34C00BA94A9 /* PascalExports.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {474, 1872}}";
+ sepNavSelRange = "{2198, 0}";
+ sepNavVisRange = "{1805, 368}";
+ sepNavWindowFrame = "{{238, 238}, {803, 674}}";
+ };
+ };
+ 617987ED114AA34C00BA94A9 /* SDLh.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {488, 12480}}";
+ sepNavSelRange = "{13681, 0}";
+ sepNavVisRange = "{12570, 605}";
+ sepNavWindowFrame = "{{15, 455}, {927, 718}}";
+ };
+ };
+ 617987F0114AA34C00BA94A9 /* SinTable.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {532, 13936}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 49}";
+ };
+ };
+ 617987F1114AA34C00BA94A9 /* uAI.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 4862}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1860}";
+ sepNavWindowFrame = "{{15, 206}, {938, 967}}";
+ };
+ };
+ 617987F2114AA34C00BA94A9 /* uAIActions.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 2847}}";
+ sepNavSelRange = "{878, 0}";
+ sepNavVisRange = "{0, 2061}";
+ sepNavWindowFrame = "{{38, 185}, {938, 967}}";
+ };
+ };
+ 617987F3114AA34C00BA94A9 /* uAIAmmoTests.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1174, 8190}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{18811, 1378}";
+ sepNavWindowFrame = "{{61, 164}, {938, 967}}";
+ };
+ };
+ 617987F4114AA34C00BA94A9 /* uAIMisc.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {719, 6279}}";
+ sepNavSelRange = "{6716, 0}";
+ sepNavVisRange = "{2094, 49}";
+ sepNavWindowFrame = "{{84, 143}, {938, 967}}";
+ };
+ };
+ 617987F5114AA34C00BA94A9 /* uAmmos.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {868, 4966}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1559}";
+ sepNavWindowFrame = "{{38, 434}, {927, 718}}";
+ };
+ };
+ 617987F6114AA34C00BA94A9 /* uChat.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 3848}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1960}";
+ sepNavWindowFrame = "{{15, 206}, {938, 967}}";
+ };
+ };
+ 617987F7114AA34C00BA94A9 /* uCollisions.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {532, 4238}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{111, 3}";
+ sepNavWindowFrame = "{{38, 185}, {938, 967}}";
+ };
+ };
+ 617987F8114AA34C00BA94A9 /* uConsole.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 4407}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 2119}";
+ sepNavWindowFrame = "{{61, 164}, {938, 967}}";
+ };
+ };
+ 617987F9114AA34C00BA94A9 /* uConsts.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 25077}}";
+ sepNavSelRange = "{10318, 0}";
+ sepNavVisRange = "{9634, 1948}";
+ sepNavWindowFrame = "{{162, 164}, {938, 967}}";
+ };
+ };
+ 617987FA114AA34C00BA94A9 /* uFloat.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {532, 4797}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 49}";
+ sepNavWindowFrame = "{{84, 143}, {938, 967}}";
+ };
+ };
+ 617987FB114AA34C00BA94A9 /* uGame.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {621, 1040}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{49, 62}";
+ sepNavWindowFrame = "{{15, 455}, {927, 718}}";
+ };
+ };
+ 617987FC114AA34C00BA94A9 /* uGears.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {768, 30953}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{258, 58}";
+ sepNavWindowFrame = "{{61, 413}, {927, 718}}";
+ };
+ };
+ 617987FD114AA34C00BA94A9 /* uIO.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 4810}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 1848}";
+ sepNavWindowFrame = "{{15, 206}, {938, 967}}";
+ };
+ };
+ 617987FE114AA34C00BA94A9 /* uKeys.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {862, 7111}}";
+ sepNavSelRange = "{14805, 0}";
+ sepNavVisRange = "{14913, 585}";
+ sepNavWindowFrame = "{{270, 164}, {921, 605}}";
+ };
+ };
+ 617987FF114AA34C00BA94A9 /* uLand.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1734, 16068}}";
+ sepNavSelRange = "{25370, 0}";
+ sepNavVisRange = "{25434, 209}";
+ sepNavWindowFrame = "{{287, 275}, {803, 674}}";
+ };
+ };
+ 61798800114AA34C00BA94A9 /* uLandGraphics.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 7241}}";
+ sepNavSelRange = "{204, 0}";
+ sepNavVisRange = "{5200, 1985}";
+ sepNavWindowFrame = "{{61, 457}, {803, 674}}";
+ };
+ };
+ 61798801114AA34C00BA94A9 /* uLandObjects.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {744, 6812}}";
+ sepNavSelRange = "{1189, 0}";
+ sepNavVisRange = "{114, 1541}";
+ sepNavWindowFrame = "{{84, 436}, {803, 674}}";
+ };
+ };
+ 61798802114AA34C00BA94A9 /* uLandTemplates.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {544, 26650}}";
+ sepNavSelRange = "{1407, 0}";
+ sepNavVisRange = "{1225, 366}";
+ sepNavWindowFrame = "{{38, 185}, {938, 967}}";
+ };
+ };
+ 61798803114AA34C00BA94A9 /* uLandTexture.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {845, 1638}}";
+ sepNavSelRange = "{3388, 0}";
+ sepNavVisRange = "{3, 250}";
+ sepNavWindowFrame = "{{400, 151}, {938, 967}}";
+ };
+ };
+ 61798804114AA34C00BA94A9 /* uLocale.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 1846}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 2884}";
+ sepNavWindowFrame = "{{61, 164}, {938, 967}}";
+ };
+ };
+ 61798805114AA34C00BA94A9 /* uMisc.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1034, 10127}}";
+ sepNavSelRange = "{16907, 0}";
+ sepNavVisRange = "{15663, 1986}";
+ sepNavWindowFrame = "{{84, 143}, {938, 967}}";
+ };
+ };
+ 61798806114AA34C00BA94A9 /* uRandom.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 1235}}";
+ sepNavSelRange = "{1113, 0}";
+ sepNavVisRange = "{0, 1817}";
+ sepNavWindowFrame = "{{15, 206}, {938, 967}}";
+ };
+ };
+ 61798807114AA34C00BA94A9 /* uScript.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {607, 11297}}";
+ sepNavSelRange = "{1143, 0}";
+ sepNavVisRange = "{1004, 219}";
+ sepNavWindowFrame = "{{38, 185}, {938, 967}}";
+ };
+ };
+ 61798808114AA34C00BA94A9 /* uSHA.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 2028}}";
+ sepNavSelRange = "{1408, 0}";
+ sepNavVisRange = "{0, 1914}";
+ sepNavWindowFrame = "{{749, 211}, {938, 967}}";
+ };
+ };
+ 61798809114AA34C00BA94A9 /* uSound.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {544, 3302}}";
+ sepNavSelRange = "{1282, 0}";
+ sepNavVisRange = "{1229, 128}";
+ sepNavWindowFrame = "{{61, 164}, {938, 967}}";
+ };
+ };
+ 6179880A114AA34C00BA94A9 /* uStats.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 3042}}";
+ sepNavSelRange = "{905, 0}";
+ sepNavVisRange = "{0, 2007}";
+ sepNavWindowFrame = "{{84, 143}, {938, 967}}";
+ };
+ };
+ 6179880B114AA34C00BA94A9 /* uStore.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1090, 19552}}";
+ sepNavSelRange = "{13527, 0}";
+ sepNavVisRange = "{13229, 2030}";
+ sepNavWindowFrame = "{{38, 478}, {803, 674}}";
+ };
+ };
+ 6179880C114AA34C00BA94A9 /* uTeams.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {775, 6617}}";
+ sepNavSelRange = "{932, 0}";
+ sepNavVisRange = "{831, 110}";
+ sepNavWindowFrame = "{{15, 206}, {938, 967}}";
+ };
+ };
+ 6179880E114AA34C00BA94A9 /* uVisualGears.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1321, 11063}}";
+ sepNavSelRange = "{873, 0}";
+ sepNavVisRange = "{0, 2081}";
+ sepNavWindowFrame = "{{38, 185}, {938, 967}}";
+ };
+ };
+ 6179880F114AA34C00BA94A9 /* uWorld.pas */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {901, 13247}}";
+ sepNavSelRange = "{1635, 0}";
+ sepNavVisRange = "{3460, 1435}";
+ sepNavWindowFrame = "{{158, 270}, {960, 678}}";
+ };
+ };
+ 61798852114AA44900BA94A9 /* config.inc */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 871}";
+ sepNavWindowFrame = "{{753, -247}, {1058, 792}}";
+ };
+ };
+ 61798856114AA48A00BA94A9 /* CGPointUtils.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {474, 572}}";
+ sepNavSelRange = "{423, 0}";
+ sepNavVisRange = "{139, 468}";
+ sepNavWindowFrame = "{{107, 411}, {960, 678}}";
+ };
+ };
+ 61798857114AA48A00BA94A9 /* CGPointUtils.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {472, 247}}";
+ sepNavSelRange = "{152, 29}";
+ sepNavVisRange = "{144, 38}";
+ sepNavWindowFrame = "{{61, 339}, {1058, 792}}";
+ };
+ };
+ 61798858114AA48A00BA94A9 /* IMG_png.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1524, 6266}}";
+ sepNavSelRange = "{2544, 0}";
+ sepNavVisRange = "{2505, 162}";
+ };
+ };
+ 61798859114AA48A00BA94A9 /* IMG.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {786, 1820}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 776}";
+ };
+ };
+ 6179885A114AA48A00BA94A9 /* PascalImports.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {744, 754}}";
+ sepNavSelRange = "{899, 0}";
+ sepNavVisRange = "{191, 766}";
+ sepNavWindowFrame = "{{685, 352}, {803, 674}}";
+ };
+ };
+ 6179885B114AA48A00BA94A9 /* SDL_image.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {516, 1196}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{899, 1}";
+ };
+ };
+ 61798863114AA4AA00BA94A9 /* SDL_uikitappdelegate.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {744, 715}}";
+ sepNavSelRange = "{1425, 0}";
+ sepNavVisRange = "{551, 1256}";
+ sepNavWindowFrame = "{{471, 203}, {803, 674}}";
+ };
+ };
+ 61798864114AA4AA00BA94A9 /* SDL_uikitappdelegate.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {873, 2002}}";
+ sepNavSelRange = "{3865, 188}";
+ sepNavVisRange = "{3583, 1566}";
+ sepNavWindowFrame = "{{29, 241}, {803, 674}}";
+ };
+ };
+ 61798867114AA4AA00BA94A9 /* SDL_uikitwindow.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {532, 572}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 3}";
+ };
+ };
+ 61798868114AA4AA00BA94A9 /* SDL_uikitwindow.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {735, 1677}}";
+ sepNavSelRange = "{1723, 0}";
+ sepNavVisRange = "{0, 1306}";
+ sepNavWindowFrame = "{{880, 321}, {794, 632}}";
+ };
+ };
+ 6179886E114AA4D000BA94A9 /* MainMenuViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{172, 0}";
+ sepNavVisRange = "{0, 480}";
+ sepNavWindowFrame = "{{852, 335}, {775, 623}}";
+ };
+ };
+ 6179886F114AA4D000BA94A9 /* MainMenuViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 2210}}";
+ sepNavSelRange = "{192, 20}";
+ sepNavVisRange = "{0, 1468}";
+ sepNavWindowFrame = "{{682, 125}, {1058, 792}}";
+ };
+ };
+ 61798887114AA4E600BA94A9 /* GameSetup.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1020, 742}}";
+ sepNavSelRange = "{254, 0}";
+ sepNavVisRange = "{0, 746}";
+ sepNavWindowFrame = "{{761, 205}, {897, 692}}";
+ };
+ };
+ 61798888114AA4E600BA94A9 /* GameSetup.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1384, 5044}}";
+ sepNavSelRange = "{2276, 0}";
+ sepNavVisRange = "{1347, 2987}";
+ sepNavWindowFrame = "{{93, 224}, {1079, 870}}";
+ };
+ };
+ 6179889D114AA5BD00BA94A9 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798852114AA44900BA94A9 /* config.inc */;
+ name = "config.inc: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 874;
+ vrLoc = 0;
+ };
+ 61798A1F114ADD2600BA94A9 /* backgroundCenter.png */ = {
+ uiCtxt = {
+ sepNavWindowFrame = "{{38, 360}, {1058, 792}}";
+ };
+ };
+ 61798A26114ADD2600BA94A9 /* Icon.png */ = {
+ uiCtxt = {
+ sepNavWindowFrame = "{{38, 360}, {1058, 792}}";
+ };
+ };
+ 6179928B114AE0C800BA94A9 /* UpdateDataFolder */ = {
+ activeExec = 0;
+ };
+ 61799342114B297000BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A23114ADD2600BA94A9 /* borderBottom.png */;
+ };
+ 61799343114B297000BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A21114ADD2600BA94A9 /* backgroundRight.png */;
+ };
+ 6179934E114BD5AB00BA94A9 /* menuCorner.png */ = {
+ uiCtxt = {
+ sepNavWindowFrame = "{{15, 381}, {1058, 792}}";
+ };
+ };
+ 6179937111501D7800BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A1E114ADD2600BA94A9 /* backgroundBottom.png */;
+ };
+ 6179937411501D7800BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A29114ADD2600BA94A9 /* settingsButton.png */;
+ };
+ 6179937511501D7800BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A2A114ADD2600BA94A9 /* storeButton.png */;
+ };
+ 6179938511501FFA00BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 6179934E114BD5AB00BA94A9 /* menuCorner.png */;
+ };
+ 6179943111502CEA00BA94A9 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 6179936711501D3D00BA94A9 /* arrowDown.png */;
+ };
+ 617B27B71171617A004A76A2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798864114AA4AA00BA94A9 /* SDL_uikitappdelegate.m */;
+ name = "SDL_uikitappdelegate.m: 153";
+ rLen = 0;
+ rLoc = 5144;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 617B27B81171617A004A76A2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179886F114AA4D000BA94A9 /* MainMenuViewController.m */;
+ name = "MainMenuViewController.m: 107";
+ rLen = 0;
+ rLoc = 3579;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 617B27B91171617A004A76A2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987E9114AA34C00BA94A9 /* hwLibrary.pas */;
+ name = "hwLibrary.pas: 11";
+ rLen = 7;
+ rLoc = 344;
+ rType = 0;
+ vrLen = 691;
+ vrLoc = 0;
+ };
+ 617B280E117164FC004A76A2 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AC81168DA9400359010 /* MasterViewController.m */;
+ name = "MasterViewController.m: 58";
+ rLen = 0;
+ rLoc = 2574;
+ rType = 0;
+ vrLen = 929;
+ vrLoc = 1909;
+ };
+ 617E1DB5116FEE5B002EF3D8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 611B0A9F116B626E00112153 /* GeneralSettingsViewController.h */;
+ name = "GeneralSettingsViewController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 144;
+ vrLoc = 0;
+ };
+ 6184DE201178F4BD00AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 614A818B1178C72A00552546 /* uMisc.s */;
+ name = "uMisc.s: 3086";
+ rLen = 0;
+ rLoc = 76263;
+ rType = 0;
+ vrLen = 336;
+ vrLoc = 125943;
+ };
+ 6184DEA111795DBD00AF6EFA /* UIImageExtra.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {943, 650}}";
+ sepNavSelRange = "{19, 0}";
+ sepNavVisRange = "{0, 406}";
+ };
+ };
+ 6184DEA211795DBD00AF6EFA /* UIImageExtra.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {474, 1245}}";
+ sepNavSelRange = "{145, 0}";
+ sepNavVisRange = "{0, 246}";
+ sepNavWindowFrame = "{{672, 213}, {1002, 778}}";
+ };
+ };
+ 6184DF001179666500AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798856114AA48A00BA94A9 /* CGPointUtils.c */;
+ name = "CGPointUtils.c: 19";
+ rLen = 0;
+ rLoc = 423;
+ rType = 0;
+ vrLen = 468;
+ vrLoc = 139;
+ };
+ 6184DF10117967DC00AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE60211751F4F00F22556 /* GravesViewController.m */;
+ name = "GravesViewController.m: 151";
+ rLen = 0;
+ rLoc = 4789;
+ rType = 0;
+ vrLen = 886;
+ vrLoc = 4427;
+ };
+ 6184DF4411796A9200AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AE01168DC6E00359010 /* SingleTeamViewController.m */;
+ name = "SingleTeamViewController.m: 40";
+ rLen = 48;
+ rLoc = 997;
+ rType = 0;
+ vrLen = 485;
+ vrLoc = 748;
+ };
+ 6184DF4511796A9200AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C5231116E4E810049FD84 /* FlagsViewController.m */;
+ name = "FlagsViewController.m: 70";
+ rLen = 0;
+ rLoc = 1822;
+ rType = 0;
+ vrLen = 306;
+ vrLoc = 1641;
+ };
+ 6184DF9A1179752300AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AE31168DC9400359010 /* HogHatViewController.m */;
+ name = "HogHatViewController.m: 102";
+ rLen = 0;
+ rLoc = 3376;
+ rType = 0;
+ vrLen = 499;
+ vrLoc = 3;
+ };
+ 6184DFE111797D2500AF6EFA /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C51BE116E40FC0049FD84 /* CommodityFunctions.m */;
+ name = "CommodityFunctions.m: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 671;
+ vrLoc = 150;
+ };
+ 6188FE60116F77AF004F3690 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11ACE1168DB1B00359010 /* TeamSettingsViewController.m */;
+ name = "TeamSettingsViewController.m: 42";
+ rLen = 0;
+ rLoc = 1568;
+ rType = 0;
+ vrLen = 253;
+ vrLoc = 1557;
+ };
+ 618AFC07115BE92A003D411B /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A20114ADD2600BA94A9 /* backgroundLeft.png */;
+ };
+ 618BE56511750F6B00F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C51BD116E40FC0049FD84 /* CommodityFunctions.h */;
+ name = "CommodityFunctions.h: 18";
+ rLen = 0;
+ rLoc = 566;
+ rType = 0;
+ vrLen = 1367;
+ vrLoc = 150;
+ };
+ 618BE5911175126900F22556 /* LevelViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {474, 390}}";
+ sepNavSelRange = "{26, 0}";
+ sepNavVisRange = "{0, 274}";
+ };
+ };
+ 618BE5921175126900F22556 /* LevelViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 2652}}";
+ sepNavSelRange = "{26, 0}";
+ sepNavVisRange = "{0, 1596}";
+ sepNavWindowFrame = "{{61, 334}, {1086, 797}}";
+ };
+ };
+ 618BE599117512E400F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11ACD1168DB1B00359010 /* TeamSettingsViewController.h */;
+ name = "TeamSettingsViewController.h: 17";
+ rLen = 0;
+ rLoc = 364;
+ rType = 0;
+ vrLen = 429;
+ vrLoc = 0;
+ };
+ 618BE59A117512E400F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AE21168DC9400359010 /* HogHatViewController.h */;
+ name = "HogHatViewController.h: 24";
+ rLen = 0;
+ rLoc = 547;
+ rType = 0;
+ vrLen = 598;
+ vrLoc = 53;
+ };
+ 618BE5FE11751F1C00F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C5230116E4E800049FD84 /* FlagsViewController.h */;
+ name = "FlagsViewController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 520;
+ vrLoc = 0;
+ };
+ 618BE60111751F4F00F22556 /* GravesViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 669}}";
+ sepNavSelRange = "{27, 0}";
+ sepNavVisRange = "{0, 601}";
+ };
+ };
+ 618BE60211751F4F00F22556 /* GravesViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 2496}}";
+ sepNavSelRange = "{27, 0}";
+ sepNavVisRange = "{0, 1611}";
+ sepNavWindowFrame = "{{38, 355}, {1086, 797}}";
+ };
+ };
+ 618BE6A1117527CD00F22556 /* VoicesViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {943, 627}}";
+ sepNavSelRange = "{177, 0}";
+ sepNavVisRange = "{0, 549}";
+ sepNavWindowFrame = "{{638, 196}, {1002, 778}}";
+ };
+ };
+ 618BE6A2117527CD00F22556 /* VoicesViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {943, 3225}}";
+ sepNavSelRange = "{52, 0}";
+ sepNavVisRange = "{3, 1067}";
+ sepNavWindowFrame = "{{493, 227}, {1002, 778}}";
+ };
+ };
+ 618BE6C2117528B200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE60111751F4F00F22556 /* GravesViewController.h */;
+ name = "GravesViewController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 595;
+ vrLoc = 0;
+ };
+ 618BE6C3117528B200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C533C116E70050049FD84 /* FortsViewController.h */;
+ name = "FortsViewController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 520;
+ vrLoc = 0;
+ };
+ 618BE6E81175298700F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE6A1117527CD00F22556 /* VoicesViewController.h */;
+ name = "VoicesViewController.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 399;
+ vrLoc = 0;
+ };
+ 618BE70111752C5200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE70211752C5200F22556 /* SDL_audiocvt.c */;
+ name = "SDL_audiocvt.c: 796";
+ rLen = 0;
+ rLoc = 25474;
+ rType = 0;
+ vrLen = 492;
+ vrLoc = 25149;
+ };
+ 618BE70211752C5200F22556 /* SDL_audiocvt.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = SDL_audiocvt.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL/src/audio/SDL_audiocvt.c";
+ sourceTree = "<absolute>";
+ };
+ 618BE70311752C5200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE70411752C5200F22556 /* music_ogg.c */;
+ name = "music_ogg.c: 171";
+ rLen = 0;
+ rLoc = 4193;
+ rType = 0;
+ vrLen = 545;
+ vrLoc = 4408;
+ };
+ 618BE70411752C5200F22556 /* music_ogg.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = music_ogg.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL_mixer/music_ogg.c";
+ sourceTree = "<absolute>";
+ };
+ 618BE70511752C5200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE70611752C5200F22556 /* music.c */;
+ name = "music.c: 285";
+ rLen = 0;
+ rLoc = 6392;
+ rType = 0;
+ vrLen = 428;
+ vrLoc = 6200;
+ };
+ 618BE70611752C5200F22556 /* music.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = music.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL_mixer/music.c";
+ sourceTree = "<absolute>";
+ };
+ 618BE70711752C5200F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE70811752C5200F22556 /* mixer.c */;
+ name = "mixer.c: 276";
+ rLen = 0;
+ rLoc = 6646;
+ rType = 0;
+ vrLen = 678;
+ vrLoc = 6380;
+ };
+ 618BE70811752C5200F22556 /* mixer.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = mixer.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL_mixer/mixer.c";
+ sourceTree = "<absolute>";
+ };
+ 618BE72C11752D7900F22556 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE6A2117527CD00F22556 /* VoicesViewController.m */;
+ name = "VoicesViewController.m: 47";
+ rLen = 0;
+ rLoc = 1147;
+ rType = 0;
+ vrLen = 512;
+ vrLoc = 943;
+ };
+ 6196317D116E89DF00C47CEE /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 32CA4F630368D1EE00C91783 /* HedgewarsMobile_Prefix.pch */;
+ name = "HedgewarsMobile_Prefix.pch: 7";
+ rLen = 0;
+ rLoc = 181;
+ rType = 0;
+ vrLen = 225;
+ vrLoc = 0;
+ };
+ 619C51BD116E40FC0049FD84 /* CommodityFunctions.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 641}}";
+ sepNavSelRange = "{1007, 0}";
+ sepNavVisRange = "{0, 1576}";
+ sepNavWindowFrame = "{{593, 138}, {1058, 792}}";
+ };
+ };
+ 619C51BE116E40FC0049FD84 /* CommodityFunctions.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {873, 676}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{150, 671}";
+ sepNavWindowFrame = "{{84, 204}, {1058, 792}}";
+ };
+ };
+ 619C51C6116E42850049FD84 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11A4D1168D13600359010 /* PopoverMenuViewController.m */;
+ name = "PopoverMenuViewController.m: 13";
+ rLen = 0;
+ rLoc = 330;
+ rType = 0;
+ vrLen = 7;
+ vrLoc = 0;
+ };
+ 619C51CB116E42850049FD84 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798857114AA48A00BA94A9 /* CGPointUtils.h */;
+ name = "CGPointUtils.h: 10";
+ rLen = 29;
+ rLoc = 152;
+ rType = 0;
+ vrLen = 38;
+ vrLoc = 144;
+ };
+ 619C51E0116E45820049FD84 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179885B114AA48A00BA94A9 /* SDL_image.h */;
+ name = "SDL_image.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 1;
+ vrLoc = 899;
+ };
+ 619C5230116E4E800049FD84 /* FlagsViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 582}";
+ sepNavWindowFrame = "{{86, 212}, {1058, 792}}";
+ };
+ };
+ 619C5231116E4E810049FD84 /* FlagsViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {754, 2548}}";
+ sepNavSelRange = "{1822, 0}";
+ sepNavVisRange = "{1641, 306}";
+ sepNavWindowFrame = "{{67, 264}, {1058, 792}}";
+ };
+ };
+ 619C523D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C523E116E56330049FD84 /* hh_small.png */;
+ };
+ 619C523E116E56330049FD84 /* hh_small.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = hh_small.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/hh_small.png;
+ sourceTree = "<absolute>";
+ };
+ 619C523F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5240116E56330049FD84 /* amWhip.png */;
+ };
+ 619C5240116E56330049FD84 /* amWhip.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amWhip.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amWhip.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5241116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5242116E56330049FD84 /* amVamp.png */;
+ };
+ 619C5242116E56330049FD84 /* amVamp.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amVamp.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amVamp.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5243116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5244116E56330049FD84 /* amSniperRifle.png */;
+ };
+ 619C5244116E56330049FD84 /* amSniperRifle.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amSniperRifle.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amSniperRifle.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5245116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5246116E56330049FD84 /* amSkip.png */;
+ };
+ 619C5246116E56330049FD84 /* amSkip.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amSkip.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amSkip.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5247116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5248116E56330049FD84 /* amShotgun_w.png */;
+ };
+ 619C5248116E56330049FD84 /* amShotgun_w.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amShotgun_w.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amShotgun_w.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5249116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C524A116E56330049FD84 /* amShotgun.png */;
+ };
+ 619C524A116E56330049FD84 /* amShotgun.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amShotgun.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amShotgun.png;
+ sourceTree = "<absolute>";
+ };
+ 619C524B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C524C116E56330049FD84 /* amSeduction.png */;
+ };
+ 619C524C116E56330049FD84 /* amSeduction.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amSeduction.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amSeduction.png;
+ sourceTree = "<absolute>";
+ };
+ 619C524D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C524E116E56330049FD84 /* amRope.png */;
+ };
+ 619C524E116E56330049FD84 /* amRope.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amRope.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amRope.png;
+ sourceTree = "<absolute>";
+ };
+ 619C524F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5250116E56330049FD84 /* amRCPlane.png */;
+ };
+ 619C5250116E56330049FD84 /* amRCPlane.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amRCPlane.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amRCPlane.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5251116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5252116E56330049FD84 /* amMortar.png */;
+ };
+ 619C5252116E56330049FD84 /* amMortar.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amMortar.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amMortar.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5253116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5254116E56330049FD84 /* amMolotov.png */;
+ };
+ 619C5254116E56330049FD84 /* amMolotov.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amMolotov.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amMolotov.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5255116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5256116E56330049FD84 /* amMine.png */;
+ };
+ 619C5256116E56330049FD84 /* amMine.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amMine.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amMine.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5257116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5258116E56330049FD84 /* amMelon.png */;
+ };
+ 619C5258116E56330049FD84 /* amMelon.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amMelon.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amMelon.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5259116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C525A116E56330049FD84 /* amKamikaze.png */;
+ };
+ 619C525A116E56330049FD84 /* amKamikaze.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amKamikaze.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amKamikaze.png;
+ sourceTree = "<absolute>";
+ };
+ 619C525B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C525C116E56330049FD84 /* amJetpack.png */;
+ };
+ 619C525C116E56330049FD84 /* amJetpack.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amJetpack.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amJetpack.png;
+ sourceTree = "<absolute>";
+ };
+ 619C525D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C525E116E56330049FD84 /* amHellish.png */;
+ };
+ 619C525E116E56330049FD84 /* amHellish.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amHellish.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amHellish.png;
+ sourceTree = "<absolute>";
+ };
+ 619C525F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5260116E56330049FD84 /* amGrenade.png */;
+ };
+ 619C5260116E56330049FD84 /* amGrenade.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amGrenade.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amGrenade.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5261116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5262116E56330049FD84 /* amGirder.png */;
+ };
+ 619C5262116E56330049FD84 /* amGirder.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amGirder.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amGirder.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5263116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5264116E56330049FD84 /* amDynamite.png */;
+ };
+ 619C5264116E56330049FD84 /* amDynamite.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amDynamite.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amDynamite.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5265116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5266116E56330049FD84 /* amDrill.png */;
+ };
+ 619C5266116E56330049FD84 /* amDrill.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amDrill.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amDrill.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5267116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5268116E56330049FD84 /* amDEagle_w.png */;
+ };
+ 619C5268116E56330049FD84 /* amDEagle_w.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amDEagle_w.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amDEagle_w.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5269116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C526A116E56330049FD84 /* amDEagle.png */;
+ };
+ 619C526A116E56330049FD84 /* amDEagle.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amDEagle.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amDEagle.png;
+ sourceTree = "<absolute>";
+ };
+ 619C526B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C526C116E56330049FD84 /* amConstruction.png */;
+ };
+ 619C526C116E56330049FD84 /* amConstruction.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amConstruction.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amConstruction.png;
+ sourceTree = "<absolute>";
+ };
+ 619C526D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C526E116E56330049FD84 /* amCluster.png */;
+ };
+ 619C526E116E56330049FD84 /* amCluster.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amCluster.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amCluster.png;
+ sourceTree = "<absolute>";
+ };
+ 619C526F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5270116E56330049FD84 /* amCake.png */;
+ };
+ 619C5270116E56330049FD84 /* amCake.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amCake.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amCake.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5271116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5272116E56330049FD84 /* amBee.png */;
+ };
+ 619C5272116E56330049FD84 /* amBee.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBee.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBee.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5273116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5274116E56330049FD84 /* amBazooka.png */;
+ };
+ 619C5274116E56330049FD84 /* amBazooka.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBazooka.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBazooka.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5275116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5276116E56330049FD84 /* amBaseball.png */;
+ };
+ 619C5276116E56330049FD84 /* amBaseball.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBaseball.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBaseball.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5277116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5278116E56330049FD84 /* amBallgun.png */;
+ };
+ 619C5278116E56330049FD84 /* amBallgun.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBallgun.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBallgun.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5279116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C527A116E56330049FD84 /* amBTorch_w.png */;
+ };
+ 619C527A116E56330049FD84 /* amBTorch_w.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBTorch_w.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBTorch_w.png;
+ sourceTree = "<absolute>";
+ };
+ 619C527B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C527C116E56330049FD84 /* amBTorch_i.png */;
+ };
+ 619C527C116E56330049FD84 /* amBTorch_i.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amBTorch_i.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amBTorch_i.png;
+ sourceTree = "<absolute>";
+ };
+ 619C527D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C527E116E56330049FD84 /* amAirAttack.png */;
+ };
+ 619C527E116E56330049FD84 /* amAirAttack.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = amAirAttack.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/amAirAttack.png;
+ sourceTree = "<absolute>";
+ };
+ 619C527F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5280116E56330049FD84 /* Wave.png */;
+ };
+ 619C5280116E56330049FD84 /* Wave.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Wave.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Wave.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5281116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5282116E56330049FD84 /* Vampiric.png */;
+ };
+ 619C5282116E56330049FD84 /* Vampiric.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Vampiric.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Vampiric.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5283116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5284116E56330049FD84 /* ThoughtTail.png */;
+ };
+ 619C5284116E56330049FD84 /* ThoughtTail.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ThoughtTail.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ThoughtTail.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5285116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5286116E56330049FD84 /* ThoughtEdge.png */;
+ };
+ 619C5286116E56330049FD84 /* ThoughtEdge.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ThoughtEdge.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ThoughtEdge.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5287116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5288116E56330049FD84 /* ThoughtCorner.png */;
+ };
+ 619C5288116E56330049FD84 /* ThoughtCorner.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ThoughtCorner.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ThoughtCorner.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5289116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C528A116E56330049FD84 /* SpeechTail.png */;
+ };
+ 619C528A116E56330049FD84 /* SpeechTail.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = SpeechTail.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/SpeechTail.png;
+ sourceTree = "<absolute>";
+ };
+ 619C528B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C528C116E56330049FD84 /* SpeechEdge.png */;
+ };
+ 619C528C116E56330049FD84 /* SpeechEdge.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = SpeechEdge.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/SpeechEdge.png;
+ sourceTree = "<absolute>";
+ };
+ 619C528D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C528E116E56330049FD84 /* SpeechCorner.png */;
+ };
+ 619C528E116E56330049FD84 /* SpeechCorner.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = SpeechCorner.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/SpeechCorner.png;
+ sourceTree = "<absolute>";
+ };
+ 619C528F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5290116E56330049FD84 /* Shrug.png */;
+ };
+ 619C5290116E56330049FD84 /* Shrug.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Shrug.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Shrug.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5291116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5292116E56330049FD84 /* ShoutTail.png */;
+ };
+ 619C5292116E56330049FD84 /* ShoutTail.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ShoutTail.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ShoutTail.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5293116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5294116E56330049FD84 /* ShoutEdge.png */;
+ };
+ 619C5294116E56330049FD84 /* ShoutEdge.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ShoutEdge.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ShoutEdge.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5295116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5296116E56330049FD84 /* ShoutCorner.png */;
+ };
+ 619C5296116E56330049FD84 /* ShoutCorner.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ShoutCorner.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ShoutCorner.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5297116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5298116E56330049FD84 /* Sad.png */;
+ };
+ 619C5298116E56330049FD84 /* Sad.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Sad.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Sad.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5299116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C529A116E56330049FD84 /* Kowtow.png */;
+ };
+ 619C529A116E56330049FD84 /* Kowtow.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Kowtow.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Kowtow.png;
+ sourceTree = "<absolute>";
+ };
+ 619C529B116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C529C116E56330049FD84 /* Juggle.png */;
+ };
+ 619C529C116E56330049FD84 /* Juggle.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Juggle.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Juggle.png;
+ sourceTree = "<absolute>";
+ };
+ 619C529D116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C529E116E56330049FD84 /* Invulnerable.png */;
+ };
+ 619C529E116E56330049FD84 /* Invulnerable.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Invulnerable.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Invulnerable.png;
+ sourceTree = "<absolute>";
+ };
+ 619C529F116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52A0116E56330049FD84 /* Idle.png */;
+ };
+ 619C52A0116E56330049FD84 /* Idle.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Idle.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Idle.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52A1116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52A2116E56330049FD84 /* ILoveLemonade.png */;
+ };
+ 619C52A2116E56330049FD84 /* ILoveLemonade.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ILoveLemonade.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/ILoveLemonade.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52A3116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52A4116E56330049FD84 /* Hurrah.png */;
+ };
+ 619C52A4116E56330049FD84 /* Hurrah.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Hurrah.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog/Hurrah.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52A5116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52A6116E56330049FD84 /* Health.png */;
+ };
+ 619C52A6116E56330049FD84 /* Health.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Health.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Health.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52A7116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52A8116E56330049FD84 /* Hammer.png */;
+ };
+ 619C52A8116E56330049FD84 /* Hammer.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Hammer.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hammer.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52A9116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52AA116E56330049FD84 /* HHDress.png */;
+ };
+ 619C52AA116E56330049FD84 /* HHDress.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = HHDress.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/HHDress.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52AB116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52AC116E56330049FD84 /* HHDeath.png */;
+ };
+ 619C52AC116E56330049FD84 /* HHDeath.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = HHDeath.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/HHDeath.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52AD116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52AE116E56330049FD84 /* Grenade.png */;
+ };
+ 619C52AE116E56330049FD84 /* Grenade.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Grenade.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Grenade.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52AF116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52B0116E56330049FD84 /* Hedgehog.png */;
+ };
+ 619C52B0116E56330049FD84 /* Hedgehog.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Hedgehog.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Hedgehog.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52B1116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52B2116E56330049FD84 /* HellishBomb.png */;
+ };
+ 619C52B2116E56330049FD84 /* HellishBomb.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = HellishBomb.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/HellishBomb.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52B4116E56330049FD84 /* Lag.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Lag.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Lag.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52B6116E56330049FD84 /* MineDead.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = MineDead.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/MineDead.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52B7116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52B8116E56330049FD84 /* MineOff.png */;
+ };
+ 619C52B8116E56330049FD84 /* MineOff.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = MineOff.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/MineOff.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52B9116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52BA116E56330049FD84 /* MineOn.png */;
+ };
+ 619C52BA116E56330049FD84 /* MineOn.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = MineOn.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/MineOn.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52BB116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52BC116E56330049FD84 /* Molotov.png */;
+ };
+ 619C52BC116E56330049FD84 /* Molotov.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Molotov.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Molotov.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52BD116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52BE116E56330049FD84 /* Parachute.png */;
+ };
+ 619C52BE116E56330049FD84 /* Parachute.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Parachute.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Parachute.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52BF116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52C0116E56330049FD84 /* PowerBar.png */;
+ };
+ 619C52C0116E56330049FD84 /* PowerBar.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = PowerBar.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/PowerBar.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52C1116E56330049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52C2116E56330049FD84 /* RCPlane.png */;
+ };
+ 619C52C2116E56330049FD84 /* RCPlane.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = RCPlane.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/RCPlane.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52C4116E56330049FD84 /* Feather.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Feather.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Feather.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52C6116E56330049FD84 /* Explosives.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Explosives.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Explosives.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52C8116E56330049FD84 /* ExplPart2.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ExplPart2.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/ExplPart2.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52CA116E56330049FD84 /* Expl50.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Expl50.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Expl50.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52CC116E56330049FD84 /* EvilTrace.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = EvilTrace.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/EvilTrace.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52CE116E56330049FD84 /* Droplet.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Droplet.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Droplet.png;
+ sourceTree = "<absolute>";
+ };
+ 619C52D1116E56330049FD84 /* Crosshair.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Crosshair.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Crosshair.png;
+ sourceTree = "<absolute>";
+ };
+ 619C533C116E70050049FD84 /* FortsViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{26, 0}";
+ sepNavVisRange = "{0, 582}";
+ sepNavWindowFrame = "{{628, 243}, {1058, 792}}";
+ };
+ };
+ 619C533D116E70050049FD84 /* FortsViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {845, 2818}}";
+ sepNavSelRange = "{650, 0}";
+ sepNavVisRange = "{507, 824}";
+ sepNavWindowFrame = "{{84, 361}, {1058, 792}}";
+ };
+ };
+ 619C5859116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C585A116E73B00049FD84 /* AirBomb.png */;
+ };
+ 619C585A116E73B00049FD84 /* AirBomb.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = AirBomb.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/AirBomb.png;
+ sourceTree = "<absolute>";
+ };
+ 619C585B116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C585C116E73B00049FD84 /* Airplane.png */;
+ };
+ 619C585C116E73B00049FD84 /* Airplane.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Airplane.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Airplane.png;
+ sourceTree = "<absolute>";
+ };
+ 619C585D116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C585E116E73B00049FD84 /* Arrow.png */;
+ };
+ 619C585E116E73B00049FD84 /* Arrow.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Arrow.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Arrow.png;
+ sourceTree = "<absolute>";
+ };
+ 619C585F116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5860116E73B00049FD84 /* Balls.png */;
+ };
+ 619C5860116E73B00049FD84 /* Balls.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Balls.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Balls.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5861116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5862116E73B00049FD84 /* Bee.png */;
+ };
+ 619C5862116E73B00049FD84 /* Bee.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Bee.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Bee.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5863116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5864116E73B00049FD84 /* BeeTrace.png */;
+ };
+ 619C5864116E73B00049FD84 /* BeeTrace.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = BeeTrace.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/BeeTrace.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5865116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5866116E73B00049FD84 /* BigDigits.png */;
+ };
+ 619C5866116E73B00049FD84 /* BigDigits.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = BigDigits.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/BigDigits.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5867116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5868116E73B00049FD84 /* BigExplosion.png */;
+ };
+ 619C5868116E73B00049FD84 /* BigExplosion.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = BigExplosion.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/BigExplosion.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5869116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C586A116E73B00049FD84 /* Birdy.png */;
+ };
+ 619C586A116E73B00049FD84 /* Birdy.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Birdy.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Birdy.png;
+ sourceTree = "<absolute>";
+ };
+ 619C586B116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C586C116E73B00049FD84 /* BlueWater.png */;
+ };
+ 619C586C116E73B00049FD84 /* BlueWater.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = BlueWater.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/BlueWater.png;
+ sourceTree = "<absolute>";
+ };
+ 619C586D116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C586E116E73B00049FD84 /* Bomb.png */;
+ };
+ 619C586E116E73B00049FD84 /* Bomb.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Bomb.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Bomb.png;
+ sourceTree = "<absolute>";
+ };
+ 619C586F116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5870116E73B00049FD84 /* Bubbles.png */;
+ };
+ 619C5870116E73B00049FD84 /* Bubbles.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Bubbles.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Bubbles.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5871116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5872116E73B00049FD84 /* Cake_down.png */;
+ };
+ 619C5872116E73B00049FD84 /* Cake_down.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Cake_down.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Cake_down.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5873116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5874116E73B00049FD84 /* Cake_walk.png */;
+ };
+ 619C5874116E73B00049FD84 /* Cake_walk.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Cake_walk.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Cake_walk.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5875116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5876116E73B00049FD84 /* Case.png */;
+ };
+ 619C5876116E73B00049FD84 /* Case.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Case.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Case.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5877116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5878116E73B00049FD84 /* Censored.png */;
+ };
+ 619C5878116E73B00049FD84 /* Censored.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Censored.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Censored.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5879116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C587A116E73B00049FD84 /* ClBomb.png */;
+ };
+ 619C587A116E73B00049FD84 /* ClBomb.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ClBomb.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/ClBomb.png;
+ sourceTree = "<absolute>";
+ };
+ 619C587B116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C587C116E73B00049FD84 /* ClParticle.png */;
+ };
+ 619C587C116E73B00049FD84 /* ClParticle.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ClParticle.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/ClParticle.png;
+ sourceTree = "<absolute>";
+ };
+ 619C587D116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C587E116E73B00049FD84 /* Clouds.png */;
+ };
+ 619C587E116E73B00049FD84 /* Clouds.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Clouds.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Clouds.png;
+ sourceTree = "<absolute>";
+ };
+ 619C587F116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52D1116E56330049FD84 /* Crosshair.png */;
+ };
+ 619C5880116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5881116E73B00049FD84 /* Drill.png */;
+ };
+ 619C5881116E73B00049FD84 /* Drill.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Drill.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Drill.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5882116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52CE116E56330049FD84 /* Droplet.png */;
+ };
+ 619C5883116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5884116E73B00049FD84 /* Dust.png */;
+ };
+ 619C5884116E73B00049FD84 /* Dust.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Dust.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Dust.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5885116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5886116E73B00049FD84 /* Egg.png */;
+ };
+ 619C5886116E73B00049FD84 /* Egg.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Egg.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Egg.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5887116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52CC116E56330049FD84 /* EvilTrace.png */;
+ };
+ 619C5888116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52CA116E56330049FD84 /* Expl50.png */;
+ };
+ 619C5889116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C588A116E73B00049FD84 /* ExplPart.png */;
+ };
+ 619C588A116E73B00049FD84 /* ExplPart.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ExplPart.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/ExplPart.png;
+ sourceTree = "<absolute>";
+ };
+ 619C588B116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52C8116E56330049FD84 /* ExplPart2.png */;
+ };
+ 619C588C116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52C6116E56330049FD84 /* Explosives.png */;
+ };
+ 619C588D116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C588E116E73B00049FD84 /* ExplosivesRoll.png */;
+ };
+ 619C588E116E73B00049FD84 /* ExplosivesRoll.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = ExplosivesRoll.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/ExplosivesRoll.png;
+ sourceTree = "<absolute>";
+ };
+ 619C588F116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52C4116E56330049FD84 /* Feather.png */;
+ };
+ 619C5890116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C5891116E73B00049FD84 /* Finger.png */;
+ };
+ 619C5891116E73B00049FD84 /* Finger.png */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = image.png;
+ name = Finger.png;
+ path = /Users/vittorio/hedgewars/trunk/project_files/HedgewarsMobile/Data/Graphics/Finger.png;
+ sourceTree = "<absolute>";
+ };
+ 619C5892116E73B00049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52B6116E56330049FD84 /* MineDead.png */;
+ };
+ 619C58B2116E76080049FD84 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 619C52B4116E56330049FD84 /* Lag.png */;
+ };
+ 61A11A4C1168D13600359010 /* PopoverMenuViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{221, 21}";
+ sepNavVisRange = "{0, 367}";
+ sepNavWindowFrame = "{{84, 318}, {1058, 792}}";
+ };
+ };
+ 61A11A4D1168D13600359010 /* PopoverMenuViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {670, 1807}}";
+ sepNavSelRange = "{288, 0}";
+ sepNavVisRange = "{0, 501}";
+ sepNavWindowFrame = "{{84, 318}, {1058, 792}}";
+ };
+ };
+ 61A11ABF1168D8B600359010 /* SplitViewRootController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{180, 0}";
+ sepNavVisRange = "{0, 396}";
+ };
+ };
+ 61A11AC01168D8B600359010 /* SplitViewRootController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 1235}}";
+ sepNavSelRange = "{550, 0}";
+ sepNavVisRange = "{0, 2100}";
+ sepNavWindowFrame = "{{725, 326}, {1058, 792}}";
+ };
+ };
+ 61A11AC71168DA9400359010 /* MasterViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 639}}";
+ sepNavSelRange = "{621, 13}";
+ sepNavVisRange = "{0, 673}";
+ };
+ };
+ 61A11AC81168DA9400359010 /* MasterViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1048, 1937}}";
+ sepNavSelRange = "{4792, 0}";
+ sepNavVisRange = "{4012, 1740}";
+ sepNavWindowFrame = "{{312, 236}, {1058, 792}}";
+ };
+ };
+ 61A11ACD1168DB1B00359010 /* TeamSettingsViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {472, 296}}";
+ sepNavSelRange = "{364, 0}";
+ sepNavVisRange = "{0, 429}";
+ sepNavWindowFrame = "{{730, 203}, {1058, 792}}";
+ };
+ };
+ 61A11ACE1168DB1B00359010 /* TeamSettingsViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1048, 2340}}";
+ sepNavSelRange = "{3228, 0}";
+ sepNavVisRange = "{5366, 1416}";
+ sepNavWindowFrame = "{{529, 227}, {1058, 792}}";
+ };
+ };
+ 61A11AD41168DB3700359010 /* DetailViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {999, 664}}";
+ sepNavSelRange = "{198, 0}";
+ sepNavVisRange = "{0, 611}";
+ sepNavWindowFrame = "{{690, 271}, {1058, 792}}";
+ };
+ };
+ 61A11AD51168DB3700359010 /* DetailViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1069, 1937}}";
+ sepNavSelRange = "{1555, 5}";
+ sepNavVisRange = "{0, 640}";
+ sepNavWindowFrame = "{{690, 271}, {1058, 792}}";
+ };
+ };
+ 61A11ADF1168DC6E00359010 /* SingleTeamViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1006, 668}}";
+ sepNavSelRange = "{755, 0}";
+ sepNavVisRange = "{0, 1248}";
+ sepNavWindowFrame = "{{38, 374}, {1002, 778}}";
+ };
+ };
+ 61A11AE01168DC6E00359010 /* SingleTeamViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 5343}}";
+ sepNavSelRange = "{14386, 0}";
+ sepNavVisRange = "{12295, 2832}";
+ sepNavWindowFrame = "{{715, 337}, {1086, 797}}";
+ };
+ };
+ 61A11AE21168DC9400359010 /* HogHatViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {472, 364}}";
+ sepNavSelRange = "{547, 0}";
+ sepNavVisRange = "{53, 598}";
+ sepNavWindowFrame = "{{49, 251}, {1058, 792}}";
+ };
+ };
+ 61A11AE31168DC9400359010 /* HogHatViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1048, 2691}}";
+ sepNavSelRange = "{3376, 0}";
+ sepNavVisRange = "{0, 1849}";
+ sepNavWindowFrame = "{{807, 320}, {1058, 792}}";
+ };
+ };
+ 61BD54C411789A020038D495 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61F6AB961177BE470013254C /* SDL_audiotypecvt.c */;
+ name = "SDL_audiotypecvt.c: 3861";
+ rLen = 0;
+ rLoc = 123570;
+ rType = 0;
+ vrLen = 779;
+ vrLoc = 123261;
+ };
+ 61C3251C1179A300001E70B1 /* openalbridge */ = {
+ activeExec = 0;
+ };
+ 61C325231179A314001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6184DEA211795DBD00AF6EFA /* UIImageExtra.m */;
+ name = "UIImageExtra.m: 9";
+ rLen = 0;
+ rLoc = 145;
+ rType = 0;
+ vrLen = 246;
+ vrLoc = 0;
+ };
+ 61C325391179A336001E70B1 /* errlib.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {579, 1425}}";
+ sepNavSelRange = "{871, 0}";
+ sepNavVisRange = "{509, 440}";
+ sepNavWindowFrame = "{{153, 250}, {1086, 797}}";
+ };
+ };
+ 61C3253A1179A336001E70B1 /* errlib.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 669}}";
+ sepNavSelRange = "{0, 839}";
+ sepNavVisRange = "{0, 839}";
+ sepNavWindowFrame = "{{130, 271}, {1086, 797}}";
+ };
+ };
+ 61C3253B1179A336001E70B1 /* globals.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {558, 2310}}";
+ sepNavSelRange = "{1163, 0}";
+ sepNavVisRange = "{977, 202}";
+ sepNavWindowFrame = "{{107, 292}, {1086, 797}}";
+ };
+ };
+ 61C3253C1179A336001E70B1 /* loaders.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {789, 3840}}";
+ sepNavSelRange = "{902, 0}";
+ sepNavVisRange = "{828, 595}";
+ };
+ };
+ 61C3253D1179A336001E70B1 /* loaders.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {803, 555}}";
+ sepNavSelRange = "{899, 0}";
+ sepNavVisRange = "{829, 414}";
+ };
+ };
+ 61C3253E1179A336001E70B1 /* openalbridge.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {768, 7860}}";
+ sepNavSelRange = "{4909, 0}";
+ sepNavVisRange = "{4612, 631}";
+ sepNavWindowFrame = "{{622, 369}, {1086, 797}}";
+ };
+ };
+ 61C325401179A336001E70B1 /* openalbridge.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 720}}";
+ sepNavSelRange = "{2053, 0}";
+ sepNavVisRange = "{3, 2114}";
+ sepNavWindowFrame = "{{622, 369}, {1086, 797}}";
+ };
+ };
+ 61C325411179A336001E70B1 /* wrappers.c */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {1027, 2175}}";
+ sepNavSelRange = "{0, 4432}";
+ sepNavVisRange = "{0, 1355}";
+ sepNavWindowFrame = "{{61, 334}, {1086, 797}}";
+ };
+ };
+ 61C325421179A336001E70B1 /* wrappers.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {558, 630}}";
+ sepNavSelRange = "{1077, 0}";
+ sepNavVisRange = "{901, 404}";
+ sepNavWindowFrame = "{{84, 313}, {1086, 797}}";
+ };
+ };
+ 61C325681179A3A0001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 618BE5911175126900F22556 /* LevelViewController.h */;
+ name = "LevelViewController.h: 2";
+ rLen = 0;
+ rLoc = 26;
+ rType = 0;
+ vrLen = 274;
+ vrLoc = 0;
+ };
+ 61C325691179A3A0001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61C325401179A336001E70B1 /* openalbridge.h */;
+ name = "openalbridge.h: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 684;
+ vrLoc = 0;
+ };
+ 61C325DD1179A993001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61C3253B1179A336001E70B1 /* globals.h */;
+ name = "globals.h: 39";
+ rLen = 0;
+ rLoc = 1163;
+ rType = 0;
+ vrLen = 202;
+ vrLoc = 977;
+ };
+ 61C326361179B0A5001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61C3253E1179A336001E70B1 /* openalbridge.c */;
+ name = "openalbridge.c: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 755;
+ vrLoc = 69;
+ };
+ 61C3263A1179B0A5001E70B1 /* oalTouchAppDelegate.m */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.objc;
+ name = oalTouchAppDelegate.m;
+ path = /Users/vittorio/Downloads/oalTouch/Classes/oalTouchAppDelegate.m;
+ sourceTree = "<absolute>";
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {621, 1635}}";
+ sepNavSelRange = "{0, 0}";
+ sepNavVisRange = "{0, 518}";
+ };
+ };
+ 61C3266D117A15C8001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61C3263A1179B0A5001E70B1 /* oalTouchAppDelegate.m */;
+ name = "oalTouchAppDelegate.m: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 518;
+ vrLoc = 0;
+ };
+ 61C3266E117A15C8001E70B1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987ED114AA34C00BA94A9 /* SDLh.pas */;
+ name = "SDLh.pas: 523";
+ rLen = 0;
+ rLoc = 13681;
+ rType = 0;
+ vrLen = 605;
+ vrLoc = 12570;
+ };
+ 61CCBE60116135FF00833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798800114AA34C00BA94A9 /* uLandGraphics.pas */;
+ name = "uLandGraphics.pas: 6";
+ rLen = 0;
+ rLoc = 204;
+ rType = 0;
+ vrLen = 130;
+ vrLoc = 186;
+ };
+ 61CCBF1E116162CA00833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F3114AA34C00BA94A9 /* uAIAmmoTests.pas */;
+ name = "uAIAmmoTests.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 125;
+ vrLoc = 3102;
+ };
+ 61CCBF451161637F00833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F0114AA34C00BA94A9 /* SinTable.inc */;
+ name = "SinTable.inc: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 49;
+ vrLoc = 0;
+ };
+ 61CCBF461161637F00833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F4114AA34C00BA94A9 /* uAIMisc.pas */;
+ name = "uAIMisc.pas: 205";
+ rLen = 0;
+ rLoc = 6716;
+ rType = 0;
+ vrLen = 49;
+ vrLoc = 2094;
+ };
+ 61CCBF471161637F00833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F5114AA34C00BA94A9 /* uAmmos.pas */;
+ name = "uAmmos.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 130;
+ vrLoc = 186;
+ };
+ 61CCBF7B1161657400833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FA114AA34C00BA94A9 /* uFloat.pas */;
+ name = "uFloat.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 49;
+ vrLoc = 0;
+ };
+ 61CCBF7C1161657400833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179880E114AA34C00BA94A9 /* uVisualGears.pas */;
+ name = "uVisualGears.pas: 23";
+ rLen = 0;
+ rLoc = 873;
+ rType = 0;
+ vrLen = 53;
+ vrLoc = 822;
+ };
+ 61CCBF7E1161657400833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798809114AA34C00BA94A9 /* uSound.pas */;
+ name = "uSound.pas: 42";
+ rLen = 0;
+ rLoc = 1282;
+ rType = 0;
+ vrLen = 128;
+ vrLoc = 1229;
+ };
+ 61CCBF7F1161657400833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798807114AA34C00BA94A9 /* uScript.pas */;
+ name = "uScript.pas: 32";
+ rLen = 0;
+ rLoc = 1143;
+ rType = 0;
+ vrLen = 219;
+ vrLoc = 1004;
+ };
+ 61CCBFD11161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FD114AA34C00BA94A9 /* uIO.pas */;
+ name = "uIO.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 3;
+ vrLoc = 0;
+ };
+ 61CCBFD21161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F7114AA34C00BA94A9 /* uCollisions.pas */;
+ name = "uCollisions.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 3;
+ vrLoc = 111;
+ };
+ 61CCBFD31161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F9114AA34C00BA94A9 /* uConsts.pas */;
+ name = "uConsts.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 72;
+ vrLoc = 114;
+ };
+ 61CCBFD41161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FB114AA34C00BA94A9 /* uGame.pas */;
+ name = "uGame.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 62;
+ vrLoc = 49;
+ };
+ 61CCBFD51161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FC114AA34C00BA94A9 /* uGears.pas */;
+ name = "uGears.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 58;
+ vrLoc = 258;
+ };
+ 61CCBFD71161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179880C114AA34C00BA94A9 /* uTeams.pas */;
+ name = "uTeams.pas: 23";
+ rLen = 0;
+ rLoc = 932;
+ rType = 0;
+ vrLen = 110;
+ vrLoc = 831;
+ };
+ 61CCBFD91161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798805114AA34C00BA94A9 /* uMisc.pas */;
+ name = "uMisc.pas: 24";
+ rLen = 0;
+ rLoc = 853;
+ rType = 0;
+ vrLen = 89;
+ vrLoc = 766;
+ };
+ 61CCBFDA1161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798802114AA34C00BA94A9 /* uLandTemplates.pas */;
+ name = "uLandTemplates.pas: 37";
+ rLen = 0;
+ rLoc = 1407;
+ rType = 0;
+ vrLen = 366;
+ vrLoc = 1225;
+ };
+ 61CCBFDB1161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987FF114AA34C00BA94A9 /* uLand.pas */;
+ name = "uLand.pas: 912";
+ rLen = 0;
+ rLoc = 25370;
+ rType = 0;
+ vrLen = 209;
+ vrLoc = 25434;
+ };
+ 61CCBFDC1161833800833FE8 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987E4114AA34C00BA94A9 /* GSHandlers.inc */;
+ name = "GSHandlers.inc: 716";
+ rLen = 0;
+ rLoc = 23048;
+ rType = 0;
+ vrLen = 148;
+ vrLoc = 22940;
+ };
+ 61CE23E7115E49560098C467 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179880F114AA34C00BA94A9 /* uWorld.pas */;
+ name = "uWorld.pas: 526";
+ rLen = 0;
+ rLoc = 16649;
+ rType = 0;
+ vrLen = 482;
+ vrLoc = 16577;
+ };
+ 61CE23FF115E4B290098C467 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 611FD9CB1155A28C00C2203D /* HedgewarsTitle.png */;
+ };
+ 61CE250B115E749A0098C467 /* OverlayViewController.h */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {879, 839}}";
+ sepNavSelRange = "{468, 0}";
+ sepNavVisRange = "{0, 1087}";
+ sepNavWindowFrame = "{{982, 125}, {938, 967}}";
+ };
+ };
+ 61CE250C115E749A0098C467 /* OverlayViewController.m */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {936, 4745}}";
+ sepNavSelRange = "{10697, 0}";
+ sepNavVisRange = "{7551, 1834}";
+ sepNavWindowFrame = "{{572, 185}, {938, 967}}";
+ };
+ };
+ 61CE251F115E75A70098C467 /* PBXBookmark */ = {
+ isa = PBXBookmark;
+ fRef = 61798A28114ADD2600BA94A9 /* playButton.png */;
+ };
+ 61CEDB60116ACBBB0067BAFC /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61798868114AA4AA00BA94A9 /* SDL_uikitwindow.m */;
+ name = "SDL_uikitwindow.m: 58";
+ rLen = 0;
+ rLoc = 1723;
+ rType = 0;
+ vrLen = 0;
+ vrLoc = 0;
+ };
+ 61D96559117180D9001EB3B4 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AD51168DB3700359010 /* DetailViewController.m */;
+ name = "DetailViewController.m: 42";
+ rLen = 5;
+ rLoc = 1555;
+ rType = 0;
+ vrLen = 640;
+ vrLoc = 0;
+ };
+ 61D96591117182B1001EB3B4 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61A11AC01168D8B600359010 /* SplitViewRootController.m */;
+ name = "SplitViewRootController.m: 33";
+ rLen = 0;
+ rLoc = 1211;
+ rType = 0;
+ vrLen = 1367;
+ vrLoc = 551;
+ };
+ 61E2F0811156B170002D33C1 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 617987F6114AA34C00BA94A9 /* uChat.pas */;
+ name = "uChat.pas: 1";
+ rLen = 0;
+ rLoc = 0;
+ rType = 0;
+ vrLen = 181;
+ vrLoc = 0;
+ };
+ 61F6AB931177BE470013254C /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 61CE250C115E749A0098C467 /* OverlayViewController.m */;
+ name = "OverlayViewController.m: 7";
+ rLen = 0;
+ rLoc = 152;
+ rType = 0;
+ vrLen = 547;
+ vrLoc = 51;
+ };
+ 61F6AB961177BE470013254C /* SDL_audiotypecvt.c */ = {
+ isa = PBXFileReference;
+ lastKnownFileType = sourcecode.c.c;
+ name = SDL_audiotypecvt.c;
+ path = "/Users/vittorio/hedgewars/Library/SDL-1.3/SDL/src/audio/SDL_audiotypecvt.c";
+ sourceTree = "<absolute>";
+ };
+ 61F8E0D6116E98A900108149 /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 619C533D116E70050049FD84 /* FortsViewController.m */;
+ name = "FortsViewController.m: 152";
+ rLen = 1;
+ rLoc = 4986;
+ rType = 0;
+ vrLen = 430;
+ vrLoc = 4835;
+ };
+ 61FE2AE4116D658700F76CDC /* PBXTextBookmark */ = {
+ isa = PBXTextBookmark;
+ fRef = 6179886E114AA4D000BA94A9 /* MainMenuViewController.h */;
+ name = "MainMenuViewController.h: 10";
+ rLen = 0;
+ rLoc = 172;
+ rType = 0;
+ vrLen = 80;
+ vrLoc = 148;
+ };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {
+ uiCtxt = {
+ sepNavWindowFrame = "{{777, 277}, {1058, 792}}";
+ };
+ };
+ 928301160F10CAFC00CC5A3C /* fpc */ = {
+ activeExec = 0;
+ };
+}
diff --git a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..57464fa
--- /dev/null
+++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj
@@ -0,0 +1,2396 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 6179928B114AE0C800BA94A9 /* UpdateDataFolder */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 61799290114AE0CD00BA94A9 /* Build configuration list for PBXAggregateTarget "UpdateDataFolder" */;
+ buildPhases = (
+ 61806B78170B83EA00C601BC /* config.inc */,
+ 6179928A114AE0C800BA94A9 /* data */,
+ );
+ dependencies = (
+ );
+ name = UpdateDataFolder;
+ productName = UpdateDataFolder;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD14FF0DC6FC520079059D /* OpenGLES.framework */; };
+ 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FD15070DC6FC5B0079059D /* QuartzCore.framework */; settings = {ATTRIBUTES = (Required, ); }; };
+ 61006F95128DE31F00EBA7F7 /* CreationChamber.m in Sources */ = {isa = PBXBuildFile; fileRef = 61006F94128DE31F00EBA7F7 /* CreationChamber.m */; };
+ 61077E87143FB09800645B29 /* MissionTrainingViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61077E86143FB09800645B29 /* MissionTrainingViewController-iPad.xib */; };
+ 6107802A143FCCC800645B29 /* startGameButton at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61078029143FCCC800645B29 /* startGameButton at 2x.png */; };
+ 610782961440EE5C00645B29 /* basicFlags.plist in Resources */ = {isa = PBXBuildFile; fileRef = 610782931440EE5C00645B29 /* basicFlags.plist */; };
+ 610782971440EE5C00645B29 /* credits.plist in Resources */ = {isa = PBXBuildFile; fileRef = 610782941440EE5C00645B29 /* credits.plist */; };
+ 610782981440EE5C00645B29 /* gameMods.plist in Resources */ = {isa = PBXBuildFile; fileRef = 610782951440EE5C00645B29 /* gameMods.plist */; };
+ 610C8E3714E018D200CF5C4C /* MNEValueTrackingSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 610C8E3614E018D200CF5C4C /* MNEValueTrackingSlider.m */; };
+ 610D5FB21270E2660033333A /* Icon-Small at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43411E290650040BA66 /* Icon-Small at 2x.png */; };
+ 610D5FB31270E26C0033333A /* Icon at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43611E290650040BA66 /* Icon at 2x.png */; };
+ 610FB7C81661390E002FB2A7 /* uPhysFSLayer.pas in Sources */ = {isa = PBXBuildFile; fileRef = 610FB7C71661390E002FB2A7 /* uPhysFSLayer.pas */; };
+ 61156521147F48B6006729A9 /* About.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156520147F48B6006729A9 /* About.strings */; };
+ 61156523147F48B7006729A9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156522147F48B7006729A9 /* Localizable.strings */; };
+ 61156525147F48B8006729A9 /* Scheme.strings in Resources */ = {isa = PBXBuildFile; fileRef = 61156524147F48B8006729A9 /* Scheme.strings */; };
+ 61177C02148B8BB100686905 /* uLandGenMaze.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61177C00148B8BB100686905 /* uLandGenMaze.pas */; };
+ 61177C03148B8BB100686905 /* uLandOutline.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61177C01148B8BB100686905 /* uLandOutline.pas */; };
+ 61188BF712A6FE5A0026C5DA /* backButton at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FED31298CE6600D73365 /* backButton at 2x.png */; };
+ 61188BF812A6FE5C0026C5DA /* background at 2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FED61298CF9800D73365 /* background at 2x~iphone.png */; };
+ 61188BF912A6FE5D0026C5DA /* checkbox at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 615FEAD912A2A4C10098EE92 /* checkbox at 2x.png */; };
+ 61188BFB12A6FE610026C5DA /* Default-ipad-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 6183D83C11E2BCE200A88903 /* Default-ipad-Landscape.png */; };
+ 61188BFC12A6FE630026C5DA /* Default at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEA21298C7F900D73365 /* Default at 2x.png */; };
+ 61188BFD12A6FE730026C5DA /* fb at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D383129B346A00911D8D /* fb at 2x.png */; };
+ 61188BFE12A6FE7C0026C5DA /* irc at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D384129B347700911D8D /* irc at 2x.png */; };
+ 61188C0212A6FE840026C5DA /* localplayButton at 2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 615FEADE12A2A6640098EE92 /* localplayButton at 2x~iphone.png */; };
+ 61188C0312A6FE860026C5DA /* netplayButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F9040D11DF59D10068B24D /* netplayButton.png */; };
+ 61188C0412A6FE880026C5DA /* savesButton at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEC81298CE4800D73365 /* savesButton at 2x.png */; };
+ 61188C0512A6FE8F0026C5DA /* Data in Resources */ = {isa = PBXBuildFile; fileRef = 61798A5E114AE08600BA94A9 /* Data */; };
+ 61188C0612A6FE950026C5DA /* smallerBackground at 2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEEC1298D25D00D73365 /* smallerBackground at 2x~iphone.png */; };
+ 61188C0712A6FE960026C5DA /* settingsButton at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FECA1298CE4E00D73365 /* settingsButton at 2x.png */; };
+ 61188C0812A6FE9A0026C5DA /* title at 2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 618899811299516000D55FD6 /* title at 2x~iphone.png */; };
+ 61188C0912A6FE9C0026C5DA /* tw at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6103D385129B348200911D8D /* tw at 2x.png */; };
+ 611D7A50142FDCD3006E0798 /* uTouch.pas in Sources */ = {isa = PBXBuildFile; fileRef = 611D7A4F142FDCD3006E0798 /* uTouch.pas */; };
+ 611D9BFB12497E9800008271 /* SavedGamesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 611D9BF912497E9800008271 /* SavedGamesViewController.m */; };
+ 611D9BFC12497E9800008271 /* SavedGamesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 611D9BFA12497E9800008271 /* SavedGamesViewController.xib */; };
+ 611E12FF117BBBDA0044B62F /* Entitlements-Development.plist in Resources */ = {isa = PBXBuildFile; fileRef = 611E12FE117BBBDA0044B62F /* Entitlements-Development.plist */; };
+ 611EE974122A9C4100DF6938 /* clickSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE973122A9C4100DF6938 /* clickSound.caf */; };
+ 611EE9DA122AA10A00DF6938 /* selSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D8122AA10A00DF6938 /* selSound.caf */; };
+ 611F4D4B11B27A9900F9759A /* uScript.pas in Sources */ = {isa = PBXBuildFile; fileRef = 611F4D4A11B27A9900F9759A /* uScript.pas */; };
+ 61272339117DF778005B90CF /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61272338117DF778005B90CF /* MobileCoreServices.framework */; };
+ 6129B9F711EFB04D0017E305 /* denied.png in Resources */ = {isa = PBXBuildFile; fileRef = 6129B9F611EFB04D0017E305 /* denied.png */; };
+ 612CABAB1391CE68005E9596 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 612CABAA1391CE68005E9596 /* AVFoundation.framework */; };
+ 61370653117B1D50004EE44A /* Entitlements-Distribution.plist in Resources */ = {isa = PBXBuildFile; fileRef = 61370652117B1D50004EE44A /* Entitlements-Distribution.plist */; };
+ 6147DAD31253DCDE0010357E /* savesButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 6147DAD21253DCDE0010357E /* savesButton.png */; };
+ 61536DF411CEAE7100D87A7E /* GameConfigViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924A11CA9CB400D6E256 /* GameConfigViewController-iPhone.xib */; };
+ 615AD96212073B4D00F2FF04 /* startGameButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 615AD96112073B4D00F2FF04 /* startGameButton.png */; };
+ 615AD9E9120764CA00F2FF04 /* backButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 615AD9E8120764CA00F2FF04 /* backButton.png */; };
+ 615AD9EB1207654E00F2FF04 /* helpButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 615AD9EA1207654E00F2FF04 /* helpButton.png */; };
+ 615BE3D4155C5DDF003CA34D /* uInputHandler.pas in Sources */ = {isa = PBXBuildFile; fileRef = 615BE3D3155C5DDF003CA34D /* uInputHandler.pas */; };
+ 615E755A14E41E8C00FBA131 /* MXAudioPlayerFadeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 615E755914E41E8C00FBA131 /* MXAudioPlayerFadeOperation.m */; };
+ 615E76BC14E4421200FBA131 /* MGSplitCornersView.m in Sources */ = {isa = PBXBuildFile; fileRef = 615E76B714E4421200FBA131 /* MGSplitCornersView.m */; };
+ 615E76BD14E4421200FBA131 /* MGSplitDividerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 615E76B914E4421200FBA131 /* MGSplitDividerView.m */; };
+ 615E76BE14E4421200FBA131 /* MGSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 615E76BB14E4421200FBA131 /* MGSplitViewController.m */; };
+ 615FEAE212A2A6640098EE92 /* localplayButton~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 615FEADF12A2A6640098EE92 /* localplayButton~ipad.png */; };
+ 615FEAE312A2A6640098EE92 /* localplayButton~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 615FEAE012A2A6640098EE92 /* localplayButton~iphone.png */; };
+ 616065A8159A71FD00CFAEF4 /* hwclassic.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 616065A7159A71FD00CFAEF4 /* hwclassic.mp3 */; };
+ 616245D114E6160200CC97FB /* libFreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6162456714E6159C00CC97FB /* libFreetype.a */; };
+ 6163EE7E11CC2600001C0453 /* SingleWeaponViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6163EE7D11CC2600001C0453 /* SingleWeaponViewController.m */; };
+ 6165920D11CA9BA200D6E256 /* FlagsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591E111CA9BA200D6E256 /* FlagsViewController.m */; };
+ 6165920E11CA9BA200D6E256 /* FortsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591E311CA9BA200D6E256 /* FortsViewController.m */; };
+ 6165920F11CA9BA200D6E256 /* GameConfigViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591E511CA9BA200D6E256 /* GameConfigViewController.m */; };
+ 6165921011CA9BA200D6E256 /* EngineProtocolNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591E711CA9BA200D6E256 /* EngineProtocolNetwork.m */; };
+ 6165921111CA9BA200D6E256 /* GeneralSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591E911CA9BA200D6E256 /* GeneralSettingsViewController.m */; };
+ 6165921211CA9BA200D6E256 /* GravesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591EB11CA9BA200D6E256 /* GravesViewController.m */; };
+ 6165921311CA9BA200D6E256 /* HogHatViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591ED11CA9BA200D6E256 /* HogHatViewController.m */; };
+ 6165921411CA9BA200D6E256 /* LevelViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591EF11CA9BA200D6E256 /* LevelViewController.m */; };
+ 6165921511CA9BA200D6E256 /* MainMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591F111CA9BA200D6E256 /* MainMenuViewController.m */; };
+ 6165921611CA9BA200D6E256 /* MapConfigViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591F311CA9BA200D6E256 /* MapConfigViewController.m */; };
+ 6165921711CA9BA200D6E256 /* SettingsBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591F511CA9BA200D6E256 /* SettingsBaseViewController.m */; };
+ 6165921A11CA9BA200D6E256 /* SchemeSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591FB11CA9BA200D6E256 /* SchemeSettingsViewController.m */; };
+ 6165921B11CA9BA200D6E256 /* SchemeWeaponConfigViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591FD11CA9BA200D6E256 /* SchemeWeaponConfigViewController.m */; };
+ 6165921C11CA9BA200D6E256 /* SingleSchemeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 616591FF11CA9BA200D6E256 /* SingleSchemeViewController.m */; };
+ 6165921D11CA9BA200D6E256 /* SingleTeamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920111CA9BA200D6E256 /* SingleTeamViewController.m */; };
+ 6165921E11CA9BA200D6E256 /* SettingsContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920311CA9BA200D6E256 /* SettingsContainerViewController.m */; };
+ 6165921F11CA9BA200D6E256 /* TeamConfigViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920511CA9BA200D6E256 /* TeamConfigViewController.m */; };
+ 6165922011CA9BA200D6E256 /* TeamSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920711CA9BA200D6E256 /* TeamSettingsViewController.m */; };
+ 6165922111CA9BA200D6E256 /* VoicesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920911CA9BA200D6E256 /* VoicesViewController.m */; };
+ 6165922211CA9BA200D6E256 /* WeaponSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165920B11CA9BA200D6E256 /* WeaponSettingsViewController.m */; };
+ 6165922E11CA9BD500D6E256 /* CGPointUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 6165922311CA9BD500D6E256 /* CGPointUtils.c */; };
+ 6165922F11CA9BD500D6E256 /* HWUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165922611CA9BD500D6E256 /* HWUtils.m */; };
+ 6165923111CA9BD500D6E256 /* SquareButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165922B11CA9BD500D6E256 /* SquareButtonView.m */; };
+ 6165923211CA9BD500D6E256 /* UIImageExtra.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165922D11CA9BD500D6E256 /* UIImageExtra.m */; };
+ 6165925311CA9CB400D6E256 /* MainMenuViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924B11CA9CB400D6E256 /* MainMenuViewController-iPad.xib */; };
+ 6165925511CA9CB400D6E256 /* MapConfigViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924D11CA9CB400D6E256 /* MapConfigViewController-iPad.xib */; };
+ 6165929E11CA9E2F00D6E256 /* HedgewarsAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6165929D11CA9E2F00D6E256 /* HedgewarsAppDelegate.m */; };
+ 6167A6761391514600AA6D07 /* RestoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6167A6741391514600AA6D07 /* RestoreViewController.m */; };
+ 6167A6771391514600AA6D07 /* RestoreViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6167A6751391514600AA6D07 /* RestoreViewController-iPhone.xib */; };
+ 6167A72D13919E6800AA6D07 /* RestoreViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6167A72C13919E6800AA6D07 /* RestoreViewController-iPad.xib */; };
+ 6167C87414294727003DD50F /* surprise at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C87314294727003DD50F /* surprise at 2x.png */; };
+ 6167C88C14294738003DD50F /* denied at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C88B14294738003DD50F /* denied at 2x.png */; };
+ 6167C8F51429502C003DD50F /* hedgehog.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8EF1429502C003DD50F /* hedgehog.png */; };
+ 6167C8F61429502C003DD50F /* hedgehog at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8F01429502C003DD50F /* hedgehog at 2x.png */; };
+ 6167C8F71429502C003DD50F /* robotBadge.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8F11429502C003DD50F /* robotBadge.png */; };
+ 6167C8F81429502C003DD50F /* robotBadge at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8F21429502C003DD50F /* robotBadge at 2x.png */; };
+ 6167C8F91429502C003DD50F /* star.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8F31429502C003DD50F /* star.png */; };
+ 6167C8FA1429502C003DD50F /* star at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167C8F41429502C003DD50F /* star at 2x.png */; };
+ 6167CA37142A6ED7003DD50F /* bot0.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA2B142A6ED7003DD50F /* bot0.png */; };
+ 6167CA38142A6ED7003DD50F /* bot0 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA2C142A6ED7003DD50F /* bot0 at 2x.png */; };
+ 6167CA39142A6ED7003DD50F /* bot1.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA2D142A6ED7003DD50F /* bot1.png */; };
+ 6167CA3A142A6ED7003DD50F /* bot1 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA2E142A6ED7003DD50F /* bot1 at 2x.png */; };
+ 6167CA3B142A6ED7003DD50F /* bot2.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA2F142A6ED7003DD50F /* bot2.png */; };
+ 6167CA3C142A6ED7003DD50F /* bot2 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA30142A6ED7003DD50F /* bot2 at 2x.png */; };
+ 6167CA3D142A6ED7003DD50F /* bot3.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA31142A6ED7003DD50F /* bot3.png */; };
+ 6167CA3E142A6ED7003DD50F /* bot3 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA32142A6ED7003DD50F /* bot3 at 2x.png */; };
+ 6167CA3F142A6ED7003DD50F /* bot4.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA33142A6ED7003DD50F /* bot4.png */; };
+ 6167CA40142A6ED7003DD50F /* bot4 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA34142A6ED7003DD50F /* bot4 at 2x.png */; };
+ 6167CA41142A6ED7003DD50F /* bot5.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA35142A6ED7003DD50F /* bot5.png */; };
+ 6167CA42142A6ED7003DD50F /* bot5 at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CA36142A6ED7003DD50F /* bot5 at 2x.png */; };
+ 6167CB48142A8769003DD50F /* basehat-hedgehog.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CB46142A8769003DD50F /* basehat-hedgehog.png */; };
+ 6167CB49142A8769003DD50F /* basehat-hedgehog at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6167CB47142A8769003DD50F /* basehat-hedgehog at 2x.png */; };
+ 6172FED91298CF9800D73365 /* background~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FED71298CF9800D73365 /* background~iphone.png */; };
+ 6172FEEF1298D25D00D73365 /* mediumBackground~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEEB1298D25D00D73365 /* mediumBackground~ipad.png */; };
+ 6172FEF11298D25D00D73365 /* smallerBackground~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEED1298D25D00D73365 /* smallerBackground~ipad.png */; };
+ 6172FEF21298D25D00D73365 /* smallerBackground~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 6172FEEE1298D25D00D73365 /* smallerBackground~iphone.png */; };
+ 6174F7C812CD62E300205D6F /* smallerTitle.png in Resources */ = {isa = PBXBuildFile; fileRef = 6174F7C612CD62E300205D6F /* smallerTitle.png */; };
+ 6174F7C912CD62E300205D6F /* smallerTitle at 2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6174F7C712CD62E300205D6F /* smallerTitle at 2x.png */; };
+ 61798816114AA34C00BA94A9 /* hwengine.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987E7114AA34C00BA94A9 /* hwengine.pas */; };
+ 61798818114AA34C00BA94A9 /* hwLibrary.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987E9114AA34C00BA94A9 /* hwLibrary.pas */; };
+ 6179881C114AA34C00BA94A9 /* SDLh.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987ED114AA34C00BA94A9 /* SDLh.pas */; };
+ 6179881F114AA34C00BA94A9 /* uAI.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F1114AA34C00BA94A9 /* uAI.pas */; };
+ 61798820114AA34C00BA94A9 /* uAIActions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F2114AA34C00BA94A9 /* uAIActions.pas */; };
+ 61798821114AA34C00BA94A9 /* uAIAmmoTests.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F3114AA34C00BA94A9 /* uAIAmmoTests.pas */; };
+ 61798822114AA34C00BA94A9 /* uAIMisc.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F4114AA34C00BA94A9 /* uAIMisc.pas */; };
+ 61798823114AA34C00BA94A9 /* uAmmos.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F5114AA34C00BA94A9 /* uAmmos.pas */; };
+ 61798824114AA34C00BA94A9 /* uChat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F6114AA34C00BA94A9 /* uChat.pas */; };
+ 61798825114AA34C00BA94A9 /* uCollisions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F7114AA34C00BA94A9 /* uCollisions.pas */; };
+ 61798826114AA34C00BA94A9 /* uConsole.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F8114AA34C00BA94A9 /* uConsole.pas */; };
+ 61798827114AA34C00BA94A9 /* uConsts.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987F9114AA34C00BA94A9 /* uConsts.pas */; };
+ 61798828114AA34C00BA94A9 /* uFloat.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FA114AA34C00BA94A9 /* uFloat.pas */; };
+ 61798829114AA34C00BA94A9 /* uGame.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FB114AA34C00BA94A9 /* uGame.pas */; };
+ 6179882A114AA34C00BA94A9 /* uGears.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FC114AA34C00BA94A9 /* uGears.pas */; };
+ 6179882B114AA34C00BA94A9 /* uIO.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FD114AA34C00BA94A9 /* uIO.pas */; };
+ 6179882D114AA34C00BA94A9 /* uLand.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FF114AA34C00BA94A9 /* uLand.pas */; };
+ 6179882E114AA34C00BA94A9 /* uLandGraphics.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798800114AA34C00BA94A9 /* uLandGraphics.pas */; };
+ 6179882F114AA34C00BA94A9 /* uLandObjects.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798801114AA34C00BA94A9 /* uLandObjects.pas */; };
+ 61798830114AA34C00BA94A9 /* uLandTemplates.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798802114AA34C00BA94A9 /* uLandTemplates.pas */; };
+ 61798831114AA34C00BA94A9 /* uLandTexture.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798803114AA34C00BA94A9 /* uLandTexture.pas */; };
+ 61798832114AA34C00BA94A9 /* uLocale.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798804114AA34C00BA94A9 /* uLocale.pas */; };
+ 61798833114AA34C00BA94A9 /* uMisc.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798805114AA34C00BA94A9 /* uMisc.pas */; };
+ 61798834114AA34C00BA94A9 /* uRandom.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798806114AA34C00BA94A9 /* uRandom.pas */; };
+ 61798837114AA34C00BA94A9 /* uSound.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61798809114AA34C00BA94A9 /* uSound.pas */; };
+ 61798838114AA34C00BA94A9 /* uStats.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880A114AA34C00BA94A9 /* uStats.pas */; };
+ 61798839114AA34C00BA94A9 /* uStore.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880B114AA34C00BA94A9 /* uStore.pas */; };
+ 6179883A114AA34C00BA94A9 /* uTeams.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880C114AA34C00BA94A9 /* uTeams.pas */; };
+ 6179883C114AA34C00BA94A9 /* uVisualGears.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880E114AA34C00BA94A9 /* uVisualGears.pas */; };
+ 6179883D114AA34C00BA94A9 /* uWorld.pas in Sources */ = {isa = PBXBuildFile; fileRef = 6179880F114AA34C00BA94A9 /* uWorld.pas */; };
+ 61798935114AB25F00BA94A9 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61798934114AB25F00BA94A9 /* AudioToolbox.framework */; };
+ 617D791E16D933060091D4D6 /* libPhysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 617D78E016D932310091D4D6 /* libPhysfs.a */; };
+ 617D795716D9345F0091D4D6 /* libPhyslayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 617D794816D933B00091D4D6 /* libPhyslayer.a */; };
+ 61808A5D128C930A005D0E2F /* backSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 611EE9D7122AA10A00DF6938 /* backSound.caf */; };
+ 61889985129995B500D55FD6 /* title~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 61889984129995B500D55FD6 /* title~ipad.png */; };
+ 61915D5B143A4E2C00299991 /* MissionTrainingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61915D59143A4E2C00299991 /* MissionTrainingViewController.m */; };
+ 61915D5C143A4E2C00299991 /* MissionTrainingViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61915D5A143A4E2C00299991 /* MissionTrainingViewController-iPhone.xib */; };
+ 619349C8160BAF3E00A08518 /* uAILandMarks.pas in Sources */ = {isa = PBXBuildFile; fileRef = 619349C5160BAF3E00A08518 /* uAILandMarks.pas */; };
+ 619349C9160BAF3E00A08518 /* uGearsHandlers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 619349C6160BAF3E00A08518 /* uGearsHandlers.pas */; };
+ 619349CA160BAF3E00A08518 /* uGearsHandlersRope.pas in Sources */ = {isa = PBXBuildFile; fileRef = 619349C7160BAF3E00A08518 /* uGearsHandlersRope.pas */; };
+ 6195981F1364BCEF00B429B6 /* libTremor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6195981D1364BCD200B429B6 /* libTremor.a */; };
+ 619599451364C83D00B429B6 /* libLua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 619599441364C82B00B429B6 /* libLua.a */; };
+ 6199E81612463EA800DADF8C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6199E81512463EA800DADF8C /* CFNetwork.framework */; };
+ 6199E81A12463EC400DADF8C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6199E81912463EC400DADF8C /* SystemConfiguration.framework */; };
+ 6199E839124647DE00DADF8C /* SupportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6199E837124647DE00DADF8C /* SupportViewController.m */; };
+ 6199E86D12464A8E00DADF8C /* surprise.png in Resources */ = {isa = PBXBuildFile; fileRef = 6199E86C12464A8E00DADF8C /* surprise.png */; };
+ 619C5AF4124F7E3100D041AE /* LuaPas.pas in Sources */ = {isa = PBXBuildFile; fileRef = 619C5AF3124F7E3100D041AE /* LuaPas.pas */; };
+ 619C5BA2124FA59000D041AE /* MapPreviewButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = 619C5BA1124FA59000D041AE /* MapPreviewButtonView.m */; };
+ 61A1188511683A8C00359010 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A117FE1168322700359010 /* CoreGraphics.framework */; settings = {ATTRIBUTES = (Required, ); }; };
+ 61A19AFC14D20170004B1E6D /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A19AEA14D2010A004B1E6D /* libSDL2.a */; };
+ 61A19B7714D20B7A004B1E6D /* libSDL2_image.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A19B6614D20B6C004B1E6D /* libSDL2_image.a */; };
+ 61A19BC714D20CE7004B1E6D /* libSDL2_ttf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A19BC614D20CDA004B1E6D /* libSDL2_ttf.a */; };
+ 61A19BFA14D20D95004B1E6D /* libSDL2_net.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A19BF914D20D83004B1E6D /* libSDL2_net.a */; };
+ 61A19C2414D20F5A004B1E6D /* libSDL2_mixer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61A19C2314D20F51004B1E6D /* libSDL2_mixer.a */; };
+ 61A4A39412A5CCC2004D81E6 /* uCommandHandlers.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38912A5CCC2004D81E6 /* uCommandHandlers.pas */; };
+ 61A4A39512A5CCC2004D81E6 /* uCommands.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38A12A5CCC2004D81E6 /* uCommands.pas */; };
+ 61A4A39612A5CCC2004D81E6 /* uDebug.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38B12A5CCC2004D81E6 /* uDebug.pas */; };
+ 61A4A39712A5CCC2004D81E6 /* uGearsRender.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38C12A5CCC2004D81E6 /* uGearsRender.pas */; };
+ 61A4A39812A5CCC2004D81E6 /* uRender.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38D12A5CCC2004D81E6 /* uRender.pas */; };
+ 61A4A39912A5CCC2004D81E6 /* uRenderUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38E12A5CCC2004D81E6 /* uRenderUtils.pas */; };
+ 61A4A39A12A5CCC2004D81E6 /* uSinTable.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A38F12A5CCC2004D81E6 /* uSinTable.pas */; };
+ 61A4A39B12A5CCC2004D81E6 /* uTextures.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A39012A5CCC2004D81E6 /* uTextures.pas */; };
+ 61A4A39C12A5CCC2004D81E6 /* uTypes.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A39112A5CCC2004D81E6 /* uTypes.pas */; };
+ 61A4A39D12A5CCC2004D81E6 /* uUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A39212A5CCC2004D81E6 /* uUtils.pas */; };
+ 61A4A39E12A5CCC2004D81E6 /* uVariables.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A39312A5CCC2004D81E6 /* uVariables.pas */; };
+ 61A4A3A212A5CD56004D81E6 /* uCaptions.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A4A3A112A5CD56004D81E6 /* uCaptions.pas */; };
+ 61A670C012747D9B00B06CE7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6183D83D11E2BCE200A88903 /* Default.png */; };
+ 61A670C112747DB900B06CE7 /* MainMenuViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924C11CA9CB400D6E256 /* MainMenuViewController-iPhone.xib */; };
+ 61A670C212747DBD00B06CE7 /* MapConfigViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924E11CA9CB400D6E256 /* MapConfigViewController-iPhone.xib */; };
+ 61A976B3136F668500DD9878 /* uCursor.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61A976B2136F668500DD9878 /* uCursor.pas */; };
+ 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AC067312B2E32D000B52A2 /* Appirater.m */; };
+ 61B7A33812CC21080086B604 /* StatsPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61B7A33712CC21080086B604 /* StatsPageViewController.m */; };
+ 61B9A86814423A9D001541C1 /* GameConfigViewController-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61B9A86714423A9D001541C1 /* GameConfigViewController-iPad.xib */; };
+ 61C079E411F35A300072BF46 /* EditableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C079E311F35A300072BF46 /* EditableCellView.m */; };
+ 61C28D3F142D380400DA16C2 /* AudioManagerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C28D3E142D380400DA16C2 /* AudioManagerController.m */; };
+ 61CADE331402EE290030C3EB /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61CADE321402EE290030C3EB /* ImageIO.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
+ 61D08D7414AEA7FE0007C078 /* uGearsHedgehog.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61D08D7114AEA7FE0007C078 /* uGearsHedgehog.pas */; };
+ 61D08D7514AEA7FE0007C078 /* uGearsList.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61D08D7214AEA7FE0007C078 /* uGearsList.pas */; };
+ 61D08D7614AEA7FE0007C078 /* uGearsUtils.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61D08D7314AEA7FE0007C078 /* uGearsUtils.pas */; };
+ 61D0BDF91457508C0011A899 /* ExtraCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 61D0BDF81457508C0011A899 /* ExtraCategories.m */; };
+ 61D205A1127CDD1100ABD83E /* ObjcExports.m in Sources */ = {isa = PBXBuildFile; fileRef = 61D205A0127CDD1100ABD83E /* ObjcExports.m */; };
+ 61D3D2A51290E03A003CE7C3 /* irc.png in Resources */ = {isa = PBXBuildFile; fileRef = 61D3D2A41290E03A003CE7C3 /* irc.png */; };
+ 61E1F4F811D004240016A5AA /* adler32.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61E1F4F711D004240016A5AA /* adler32.pas */; };
+ 61E2E12E12BAAEE30051B659 /* ServerProtocolNetwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 61E2E12D12BAAEE30051B659 /* ServerProtocolNetwork.m */; };
+ 61E2F7441283752C00E12521 /* fb.png in Resources */ = {isa = PBXBuildFile; fileRef = 61E2F7421283752C00E12521 /* fb.png */; };
+ 61E2F7451283752C00E12521 /* tw.png in Resources */ = {isa = PBXBuildFile; fileRef = 61E2F7431283752C00E12521 /* tw.png */; };
+ 61E5D68D12AB006F00566F29 /* uLandPainted.pas in Sources */ = {isa = PBXBuildFile; fileRef = 61E5D68C12AB006F00566F29 /* uLandPainted.pas */; };
+ 61EBA62A11DFF2BC0048B68A /* title~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 61EBA62811DFF2BC0048B68A /* title~iphone.png */; };
+ 61EDB5B0135B3F97009B29A6 /* GameInterfaceBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 61EDB5AF135B3F97009B29A6 /* GameInterfaceBridge.m */; };
+ 61F2E7CE1205EDE0005734F7 /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 61F2E7CC1205EDE0005734F7 /* AboutViewController.m */; };
+ 61F2E7CF1205EDE0005734F7 /* AboutViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 61F2E7CD1205EDE0005734F7 /* AboutViewController.xib */; };
+ 61F2E7EC12060E31005734F7 /* checkbox.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F2E7EB12060E31005734F7 /* checkbox.png */; };
+ 61F544C712AF1748007FD913 /* HoldTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 61F544C612AF1748007FD913 /* HoldTableViewCell.m */; };
+ 61F7A43811E290650040BA66 /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43111E290650040BA66 /* Icon-72.png */; };
+ 61F7A43911E290650040BA66 /* Icon-Small-50.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43211E290650040BA66 /* Icon-Small-50.png */; };
+ 61F7A43A11E290650040BA66 /* Icon-Small.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43311E290650040BA66 /* Icon-Small.png */; };
+ 61F7A43C11E290650040BA66 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43511E290650040BA66 /* Icon.png */; };
+ 61F7A43E11E290650040BA66 /* iTunesArtwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F7A43711E290650040BA66 /* iTunesArtwork.png */; };
+ 61F9040911DF58B00068B24D /* settingsButton.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F9040811DF58B00068B24D /* settingsButton.png */; };
+ 61F9040B11DF59370068B24D /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = 61F9040A11DF59370068B24D /* background.png */; };
+ 61F904D711DF7DA30068B24D /* WeaponCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61F904D611DF7DA30068B24D /* WeaponCellView.m */; };
+ 922F64900F10F53100DC6EC0 /* libfpc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 928301170F10CAFC00CC5A3C /* libfpc.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXBuildRule section */
+ 9283015B0F10E46D00CC5A3C /* PBXBuildRule */ = {
+ isa = PBXBuildRule;
+ compilerSpec = com.apple.compilers.proxy.script;
+ fileType = sourcecode.pascal;
+ isEditable = 1;
+ outputFiles = (
+ "$(DERIVED_SOURCES_DIR)-$(CURRENT_VARIANT)/$(CURRENT_ARCH)/$(INPUT_FILE_BASE).s",
+ );
+ script = "#!/bin/bash\n\n# Xcode's up-to-date checks are overzealous for us: a different SDK does not necessarily\n# mean we recompile all sources, because we do not have different units for different SDK\n# versions yet (and even if we did, not necessarily all files would be recompiled)...\n\ndestdir=\"${DERIVED_SOURCES_DIR}-${CURRENT_VARIANT}/${CURRENT_ARCH}\"\nif [ ! -f \"$destdir/compilefailed\" ]; then\n # check whether the assembler code is newer than the source code\n if [ \"$destdir/${INPUT_FILE_BASE}.s\" -nt \"$INPUT_FILE_PATH\" ]; then\n # in this case we're ok, just touch the assembler file to avoid us getting here again next time\n echo Updating assembler time stamp of \"$destdir/${INPUT_FILE_BASE}.s\"\n touch \"$destdir/${INPUT_FILE_BASE}.s\"\n exit 0\n fi\n\n echo File not found or not up-to-date: $destdir/${INPUT_FILE_BASE}.s\n echo \"$INPUT_FILE_PATH:1: error: 1: \\\"$INPUT_FILE_PATH\\\" was not (re)compiled. If it is no longer used, please remove it from the \\\"Compile Sources\\\" phase of the \\\"$TARGETNAME\\\" target.\"\n exit 1\nfi";
+ };
+/* End PBXBuildRule section */
+
+/* Begin PBXContainerItemProxy section */
+ 610FB7E116613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 619599BA1364E65900B429B6 /* Freetype.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = libFreetype;
+ };
+ 610FB7E316613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19BF414D20D83004B1E6D /* SDL_net.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = BE48FF6507AFA9A800BB41DA;
+ remoteInfo = "Static Library";
+ };
+ 610FB7E516613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6195993F1364C82B00B429B6 /* Lua.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = libLua;
+ };
+ 610FB7E716613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = FD6526620DE8FCCB002AD96B;
+ remoteInfo = libSDL;
+ };
+ 610FB7E916613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19C1E14D20F51004B1E6D /* SDL_mixer.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = BE1FA90707AF96B2004B6283;
+ remoteInfo = "Static Library";
+ };
+ 610FB7EB16613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19BC114D20CDA004B1E6D /* SDL_ttf.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = BE48FD6807AFA17000BB41DA;
+ remoteInfo = "Static Library";
+ };
+ 610FB7ED16613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 619598181364BCD200B429B6 /* Tremor.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = libTremor;
+ };
+ 610FB7EF16613980002FB2A7 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19B6114D20B6C004B1E6D /* SDL_image.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = BE1FA72F07AF4C45004B6283;
+ remoteInfo = libSDL_image;
+ };
+ 6162456614E6159C00CC97FB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 619599BA1364E65900B429B6 /* Freetype.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = libFreetype;
+ };
+ 617D78DF16D932310091D4D6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 617D78D816D932310091D4D6 /* Physfs.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = Physfs;
+ };
+ 617D791C16D932EC0091D4D6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 617D78D816D932310091D4D6 /* Physfs.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = Physfs;
+ };
+ 617D794716D933B00091D4D6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 617D794316D933B00091D4D6 /* Physlayer.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = Physlayer;
+ };
+ 617D794916D933BC0091D4D6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 617D794316D933B00091D4D6 /* Physlayer.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = D2AAC07D0554694100DB518D;
+ remoteInfo = Physlayer;
+ };
+ 6195981C1364BCD200B429B6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 619598181364BCD200B429B6 /* Tremor.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = libTremor;
+ };
+ 619599431364C82B00B429B6 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 6195993F1364C82B00B429B6 /* Lua.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = D2AAC07E0554694100DB518D;
+ remoteInfo = libLua;
+ };
+ 61A19AE914D2010A004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = FD6526630DE8FCCB002AD96B;
+ remoteInfo = libSDL;
+ };
+ 61A19AEB14D2010A004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 006E982211955059001DE610;
+ remoteInfo = testsdl;
+ };
+ 61A19B6514D20B6C004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19B6114D20B6C004B1E6D /* SDL_image.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = BE1FA74107AF4C45004B6283;
+ remoteInfo = libSDL_image;
+ };
+ 61A19BC514D20CDA004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19BC114D20CDA004B1E6D /* SDL_ttf.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = BE48FD6E07AFA17000BB41DA;
+ remoteInfo = "Static Library";
+ };
+ 61A19BF814D20D83004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19BF414D20D83004B1E6D /* SDL_net.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = BE48FF6F07AFA9A900BB41DA;
+ remoteInfo = "Static Library";
+ };
+ 61A19C2214D20F51004B1E6D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 61A19C1E14D20F51004B1E6D /* SDL_mixer.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = BE1FA95407AF96B2004B6283;
+ remoteInfo = "Static Library";
+ };
+ 928301590F10E41300CC5A3C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 928301160F10CAFC00CC5A3C;
+ remoteInfo = fpc;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 1D6058910D05DD3D006BFB54 /* Hedgewars.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Hedgewars.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
+ 28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ 32CA4F630368D1EE00C91783 /* Hedgewars_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hedgewars_Prefix.pch; sourceTree = "<group>"; };
+ 61006F93128DE31F00EBA7F7 /* CreationChamber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CreationChamber.h; path = Classes/CreationChamber.h; sourceTree = "<group>"; };
+ 61006F94128DE31F00EBA7F7 /* CreationChamber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CreationChamber.m; path = Classes/CreationChamber.m; sourceTree = "<group>"; };
+ 6103D383129B346A00911D8D /* fb at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "fb at 2x.png"; path = "Resources/Icons/fb at 2x.png"; sourceTree = "<group>"; };
+ 6103D384129B347700911D8D /* irc at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "irc at 2x.png"; path = "Resources/Icons/irc at 2x.png"; sourceTree = "<group>"; };
+ 6103D385129B348200911D8D /* tw at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tw at 2x.png"; path = "Resources/Icons/tw at 2x.png"; sourceTree = "<group>"; };
+ 61077E86143FB09800645B29 /* MissionTrainingViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MissionTrainingViewController-iPad.xib"; sourceTree = "<group>"; };
+ 61078029143FCCC800645B29 /* startGameButton at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "startGameButton at 2x.png"; path = "Resources/Frontend/startGameButton at 2x.png"; sourceTree = "<group>"; };
+ 610782931440EE5C00645B29 /* basicFlags.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = basicFlags.plist; path = Resources/basicFlags.plist; sourceTree = "<group>"; };
+ 610782941440EE5C00645B29 /* credits.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = credits.plist; path = Resources/credits.plist; sourceTree = "<group>"; };
+ 610782951440EE5C00645B29 /* gameMods.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = gameMods.plist; path = Resources/gameMods.plist; sourceTree = "<group>"; };
+ 610C8E3514E018D200CF5C4C /* MNEValueTrackingSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MNEValueTrackingSlider.h; path = Classes/MNEValueTrackingSlider.h; sourceTree = "<group>"; };
+ 610C8E3614E018D200CF5C4C /* MNEValueTrackingSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MNEValueTrackingSlider.m; path = Classes/MNEValueTrackingSlider.m; sourceTree = "<group>"; };
+ 610FB7C71661390E002FB2A7 /* uPhysFSLayer.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uPhysFSLayer.pas; path = ../../hedgewars/uPhysFSLayer.pas; sourceTree = SOURCE_ROOT; };
+ 6115651A147F48AE006729A9 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Locale/English.lproj/About.strings; sourceTree = "<group>"; };
+ 6115651B147F48AE006729A9 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Locale/English.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 6115651C147F48AE006729A9 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = Locale/English.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61156526147F49E1006729A9 /* Spanish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Spanish; path = Locale/Spanish.lproj/About.strings; sourceTree = "<group>"; };
+ 61156527147F4A2E006729A9 /* Spanish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Spanish; path = Locale/Spanish.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61156528147F4A3C006729A9 /* Spanish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Spanish; path = Locale/Spanish.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 6115652B147F4C45006729A9 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = Locale/French.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 6115652C147F4C4C006729A9 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = Locale/French.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 6115652D147F4C52006729A9 /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = Locale/French.lproj/About.strings; sourceTree = "<group>"; };
+ 61156530147F4D10006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/About.strings; sourceTree = "<group>"; };
+ 61156531147F4D17006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61156532147F4D1E006729A9 /* Polish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Polish; path = Locale/Polish.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61177BA7148A658900686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61177BA9148A660C00686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61177BAA148A661600686905 /* German */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = German; path = Locale/German.lproj/About.strings; sourceTree = "<group>"; };
+ 61177BAC148A671600686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/About.strings; sourceTree = "<group>"; };
+ 61177BAD148A672000686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61177BAE148A672C00686905 /* Turkish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Turkish; path = Locale/Turkish.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61177BE4148B881C00686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/About.strings; sourceTree = "<group>"; };
+ 61177BF0148B882500686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61177BF1148B882F00686905 /* Danish */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Danish; path = Locale/Danish.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61177C00148B8BB100686905 /* uLandGenMaze.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandGenMaze.pas; path = ../../hedgewars/uLandGenMaze.pas; sourceTree = SOURCE_ROOT; };
+ 61177C01148B8BB100686905 /* uLandOutline.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandOutline.pas; path = ../../hedgewars/uLandOutline.pas; sourceTree = SOURCE_ROOT; };
+ 611D7A4F142FDCD3006E0798 /* uTouch.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uTouch.pas; path = ../../hedgewars/uTouch.pas; sourceTree = SOURCE_ROOT; };
+ 611D9BF812497E9800008271 /* SavedGamesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SavedGamesViewController.h; sourceTree = "<group>"; };
+ 611D9BF912497E9800008271 /* SavedGamesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SavedGamesViewController.m; sourceTree = "<group>"; };
+ 611D9BFA12497E9800008271 /* SavedGamesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SavedGamesViewController.xib; sourceTree = "<group>"; };
+ 611E12FE117BBBDA0044B62F /* Entitlements-Development.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Entitlements-Development.plist"; sourceTree = "<group>"; };
+ 611EE973122A9C4100DF6938 /* clickSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = clickSound.caf; path = Resources/clickSound.caf; sourceTree = "<group>"; };
+ 611EE9D7122AA10A00DF6938 /* backSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = backSound.caf; path = Resources/backSound.caf; sourceTree = "<group>"; };
+ 611EE9D8122AA10A00DF6938 /* selSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; name = selSound.caf; path = Resources/selSound.caf; sourceTree = "<group>"; };
+ 611F4D4A11B27A9900F9759A /* uScript.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uScript.pas; path = ../../hedgewars/uScript.pas; sourceTree = SOURCE_ROOT; };
+ 61272338117DF778005B90CF /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
+ 6129B9F611EFB04D0017E305 /* denied.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = denied.png; path = Resources/denied.png; sourceTree = "<group>"; };
+ 612CABAA1391CE68005E9596 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
+ 61370652117B1D50004EE44A /* Entitlements-Distribution.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Entitlements-Distribution.plist"; sourceTree = "<group>"; };
+ 6147DAD21253DCDE0010357E /* savesButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = savesButton.png; path = Resources/Frontend/savesButton.png; sourceTree = "<group>"; };
+ 614E333D11DE9A93009DBA4E /* VGSHandlers.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = VGSHandlers.inc; path = ../../hedgewars/VGSHandlers.inc; sourceTree = SOURCE_ROOT; };
+ 6154A53114C37E4A00F6EEF6 /* Romanian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Romanian; path = Locale/Romanian.lproj/About.strings; sourceTree = "<group>"; };
+ 6154A53E14C37E5400F6EEF6 /* Romanian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Romanian; path = Locale/Romanian.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 6154A54014C37EB100F6EEF6 /* Romanian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Romanian; path = Locale/Romanian.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61589C5A144B4322007BFAA4 /* config.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = config.inc; sourceTree = "<group>"; };
+ 615AD96112073B4D00F2FF04 /* startGameButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = startGameButton.png; path = Resources/Frontend/startGameButton.png; sourceTree = "<group>"; };
+ 615AD9E8120764CA00F2FF04 /* backButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = backButton.png; path = Resources/Frontend/backButton.png; sourceTree = "<group>"; };
+ 615AD9EA1207654E00F2FF04 /* helpButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = helpButton.png; path = Resources/Frontend/helpButton.png; sourceTree = "<group>"; };
+ 615BE3D3155C5DDF003CA34D /* uInputHandler.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uInputHandler.pas; path = ../../hedgewars/uInputHandler.pas; sourceTree = SOURCE_ROOT; };
+ 615E755814E41E8C00FBA131 /* MXAudioPlayerFadeOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MXAudioPlayerFadeOperation.h; path = Classes/MXAudioPlayerFadeOperation.h; sourceTree = "<group>"; };
+ 615E755914E41E8C00FBA131 /* MXAudioPlayerFadeOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MXAudioPlayerFadeOperation.m; path = Classes/MXAudioPlayerFadeOperation.m; sourceTree = "<group>"; };
+ 615E76B514E4406400FBA131 /* LICENCE.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = LICENCE.rtf; path = Classes/MGSplitViewController/LICENCE.rtf; sourceTree = "<group>"; };
+ 615E76B614E4421200FBA131 /* MGSplitCornersView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGSplitCornersView.h; path = Classes/MGSplitViewController/MGSplitCornersView.h; sourceTree = "<group>"; };
+ 615E76B714E4421200FBA131 /* MGSplitCornersView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGSplitCornersView.m; path = Classes/MGSplitViewController/MGSplitCornersView.m; sourceTree = "<group>"; };
+ 615E76B814E4421200FBA131 /* MGSplitDividerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGSplitDividerView.h; path = Classes/MGSplitViewController/MGSplitDividerView.h; sourceTree = "<group>"; };
+ 615E76B914E4421200FBA131 /* MGSplitDividerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGSplitDividerView.m; path = Classes/MGSplitViewController/MGSplitDividerView.m; sourceTree = "<group>"; };
+ 615E76BA14E4421200FBA131 /* MGSplitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGSplitViewController.h; path = Classes/MGSplitViewController/MGSplitViewController.h; sourceTree = "<group>"; };
+ 615E76BB14E4421200FBA131 /* MGSplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGSplitViewController.m; path = Classes/MGSplitViewController/MGSplitViewController.m; sourceTree = "<group>"; };
+ 615FEAD912A2A4C10098EE92 /* checkbox at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "checkbox at 2x.png"; path = "Resources/Icons/checkbox at 2x.png"; sourceTree = "<group>"; };
+ 615FEADE12A2A6640098EE92 /* localplayButton at 2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "localplayButton at 2x~iphone.png"; path = "Resources/Frontend/localplayButton at 2x~iphone.png"; sourceTree = "<group>"; };
+ 615FEADF12A2A6640098EE92 /* localplayButton~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "localplayButton~ipad.png"; path = "Resources/Frontend/localplayButton~ipad.png"; sourceTree = "<group>"; };
+ 615FEAE012A2A6640098EE92 /* localplayButton~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "localplayButton~iphone.png"; path = "Resources/Frontend/localplayButton~iphone.png"; sourceTree = "<group>"; };
+ 616065A7159A71FD00CFAEF4 /* hwclassic.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = hwclassic.mp3; path = Resources/hwclassic.mp3; sourceTree = "<group>"; };
+ 6163EE7C11CC2600001C0453 /* SingleWeaponViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleWeaponViewController.h; sourceTree = "<group>"; };
+ 6163EE7D11CC2600001C0453 /* SingleWeaponViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleWeaponViewController.m; sourceTree = "<group>"; };
+ 61641FE31437CDAA006E049C /* DefinesAndMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DefinesAndMacros.h; path = Classes/DefinesAndMacros.h; sourceTree = "<group>"; };
+ 616591E011CA9BA200D6E256 /* FlagsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlagsViewController.h; sourceTree = "<group>"; };
+ 616591E111CA9BA200D6E256 /* FlagsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FlagsViewController.m; sourceTree = "<group>"; };
+ 616591E211CA9BA200D6E256 /* FortsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FortsViewController.h; sourceTree = "<group>"; };
+ 616591E311CA9BA200D6E256 /* FortsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FortsViewController.m; sourceTree = "<group>"; };
+ 616591E411CA9BA200D6E256 /* GameConfigViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameConfigViewController.h; sourceTree = "<group>"; };
+ 616591E511CA9BA200D6E256 /* GameConfigViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameConfigViewController.m; sourceTree = "<group>"; };
+ 616591E611CA9BA200D6E256 /* EngineProtocolNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EngineProtocolNetwork.h; sourceTree = "<group>"; };
+ 616591E711CA9BA200D6E256 /* EngineProtocolNetwork.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EngineProtocolNetwork.m; sourceTree = "<group>"; };
+ 616591E811CA9BA200D6E256 /* GeneralSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneralSettingsViewController.h; sourceTree = "<group>"; };
+ 616591E911CA9BA200D6E256 /* GeneralSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneralSettingsViewController.m; sourceTree = "<group>"; };
+ 616591EA11CA9BA200D6E256 /* GravesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GravesViewController.h; sourceTree = "<group>"; };
+ 616591EB11CA9BA200D6E256 /* GravesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GravesViewController.m; sourceTree = "<group>"; };
+ 616591EC11CA9BA200D6E256 /* HogHatViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HogHatViewController.h; sourceTree = "<group>"; };
+ 616591ED11CA9BA200D6E256 /* HogHatViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HogHatViewController.m; sourceTree = "<group>"; };
+ 616591EE11CA9BA200D6E256 /* LevelViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LevelViewController.h; sourceTree = "<group>"; };
+ 616591EF11CA9BA200D6E256 /* LevelViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LevelViewController.m; sourceTree = "<group>"; };
+ 616591F011CA9BA200D6E256 /* MainMenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainMenuViewController.h; sourceTree = "<group>"; };
+ 616591F111CA9BA200D6E256 /* MainMenuViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainMenuViewController.m; sourceTree = "<group>"; };
+ 616591F211CA9BA200D6E256 /* MapConfigViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapConfigViewController.h; sourceTree = "<group>"; };
+ 616591F311CA9BA200D6E256 /* MapConfigViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapConfigViewController.m; sourceTree = "<group>"; };
+ 616591F411CA9BA200D6E256 /* SettingsBaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsBaseViewController.h; sourceTree = "<group>"; };
+ 616591F511CA9BA200D6E256 /* SettingsBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsBaseViewController.m; sourceTree = "<group>"; };
+ 616591FA11CA9BA200D6E256 /* SchemeSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchemeSettingsViewController.h; sourceTree = "<group>"; };
+ 616591FB11CA9BA200D6E256 /* SchemeSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SchemeSettingsViewController.m; sourceTree = "<group>"; };
+ 616591FC11CA9BA200D6E256 /* SchemeWeaponConfigViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchemeWeaponConfigViewController.h; sourceTree = "<group>"; };
+ 616591FD11CA9BA200D6E256 /* SchemeWeaponConfigViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SchemeWeaponConfigViewController.m; sourceTree = "<group>"; };
+ 616591FE11CA9BA200D6E256 /* SingleSchemeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleSchemeViewController.h; sourceTree = "<group>"; };
+ 616591FF11CA9BA200D6E256 /* SingleSchemeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleSchemeViewController.m; sourceTree = "<group>"; };
+ 6165920011CA9BA200D6E256 /* SingleTeamViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SingleTeamViewController.h; sourceTree = "<group>"; };
+ 6165920111CA9BA200D6E256 /* SingleTeamViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SingleTeamViewController.m; sourceTree = "<group>"; };
+ 6165920211CA9BA200D6E256 /* SettingsContainerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsContainerViewController.h; sourceTree = "<group>"; };
+ 6165920311CA9BA200D6E256 /* SettingsContainerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsContainerViewController.m; sourceTree = "<group>"; };
+ 6165920411CA9BA200D6E256 /* TeamConfigViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamConfigViewController.h; sourceTree = "<group>"; };
+ 6165920511CA9BA200D6E256 /* TeamConfigViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamConfigViewController.m; sourceTree = "<group>"; };
+ 6165920611CA9BA200D6E256 /* TeamSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeamSettingsViewController.h; sourceTree = "<group>"; };
+ 6165920711CA9BA200D6E256 /* TeamSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeamSettingsViewController.m; sourceTree = "<group>"; };
+ 6165920811CA9BA200D6E256 /* VoicesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VoicesViewController.h; sourceTree = "<group>"; };
+ 6165920911CA9BA200D6E256 /* VoicesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VoicesViewController.m; sourceTree = "<group>"; };
+ 6165920A11CA9BA200D6E256 /* WeaponSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeaponSettingsViewController.h; sourceTree = "<group>"; };
+ 6165920B11CA9BA200D6E256 /* WeaponSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WeaponSettingsViewController.m; sourceTree = "<group>"; };
+ 6165922311CA9BD500D6E256 /* CGPointUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CGPointUtils.c; path = Classes/CGPointUtils.c; sourceTree = "<group>"; };
+ 6165922411CA9BD500D6E256 /* CGPointUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CGPointUtils.h; path = Classes/CGPointUtils.h; sourceTree = "<group>"; };
+ 6165922511CA9BD500D6E256 /* HWUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HWUtils.h; path = Classes/HWUtils.h; sourceTree = "<group>"; };
+ 6165922611CA9BD500D6E256 /* HWUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HWUtils.m; path = Classes/HWUtils.m; sourceTree = "<group>"; };
+ 6165922911CA9BD500D6E256 /* PascalImports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PascalImports.h; path = Classes/PascalImports.h; sourceTree = "<group>"; };
+ 6165922A11CA9BD500D6E256 /* SquareButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SquareButtonView.h; path = Classes/SquareButtonView.h; sourceTree = "<group>"; };
+ 6165922B11CA9BD500D6E256 /* SquareButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SquareButtonView.m; path = Classes/SquareButtonView.m; sourceTree = "<group>"; };
+ 6165922C11CA9BD500D6E256 /* UIImageExtra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UIImageExtra.h; path = Classes/UIImageExtra.h; sourceTree = "<group>"; };
+ 6165922D11CA9BD500D6E256 /* UIImageExtra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UIImageExtra.m; path = Classes/UIImageExtra.m; sourceTree = "<group>"; };
+ 6165924A11CA9CB400D6E256 /* GameConfigViewController-iPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "GameConfigViewController-iPhone.xib"; sourceTree = "<group>"; };
+ 6165924B11CA9CB400D6E256 /* MainMenuViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MainMenuViewController-iPad.xib"; sourceTree = "<group>"; };
+ 6165924C11CA9CB400D6E256 /* MainMenuViewController-iPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MainMenuViewController-iPhone.xib"; sourceTree = "<group>"; };
+ 6165924D11CA9CB400D6E256 /* MapConfigViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MapConfigViewController-iPad.xib"; sourceTree = "<group>"; };
+ 6165924E11CA9CB400D6E256 /* MapConfigViewController-iPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MapConfigViewController-iPhone.xib"; sourceTree = "<group>"; };
+ 6165929C11CA9E2F00D6E256 /* HedgewarsAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HedgewarsAppDelegate.h; path = Classes/HedgewarsAppDelegate.h; sourceTree = "<group>"; };
+ 6165929D11CA9E2F00D6E256 /* HedgewarsAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HedgewarsAppDelegate.m; path = Classes/HedgewarsAppDelegate.m; sourceTree = "<group>"; };
+ 6167A6731391514600AA6D07 /* RestoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoreViewController.h; sourceTree = "<group>"; };
+ 6167A6741391514600AA6D07 /* RestoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoreViewController.m; sourceTree = "<group>"; };
+ 6167A6751391514600AA6D07 /* RestoreViewController-iPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "RestoreViewController-iPhone.xib"; sourceTree = "<group>"; };
+ 6167A72C13919E6800AA6D07 /* RestoreViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "RestoreViewController-iPad.xib"; sourceTree = "<group>"; };
+ 6167C87314294727003DD50F /* surprise at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "surprise at 2x.png"; path = "Resources/surprise at 2x.png"; sourceTree = "<group>"; };
+ 6167C88B14294738003DD50F /* denied at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "denied at 2x.png"; path = "Resources/denied at 2x.png"; sourceTree = "<group>"; };
+ 6167C8EF1429502C003DD50F /* hedgehog.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hedgehog.png; path = Resources/Icons/hedgehog.png; sourceTree = "<group>"; };
+ 6167C8F01429502C003DD50F /* hedgehog at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "hedgehog at 2x.png"; path = "Resources/Icons/hedgehog at 2x.png"; sourceTree = "<group>"; };
+ 6167C8F11429502C003DD50F /* robotBadge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = robotBadge.png; path = Resources/Icons/robotBadge.png; sourceTree = "<group>"; };
+ 6167C8F21429502C003DD50F /* robotBadge at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "robotBadge at 2x.png"; path = "Resources/Icons/robotBadge at 2x.png"; sourceTree = "<group>"; };
+ 6167C8F31429502C003DD50F /* star.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = star.png; path = Resources/Icons/star.png; sourceTree = "<group>"; };
+ 6167C8F41429502C003DD50F /* star at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "star at 2x.png"; path = "Resources/Icons/star at 2x.png"; sourceTree = "<group>"; };
+ 6167CA2B142A6ED7003DD50F /* bot0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot0.png; path = Resources/Icons/bot0.png; sourceTree = "<group>"; };
+ 6167CA2C142A6ED7003DD50F /* bot0 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot0 at 2x.png"; path = "Resources/Icons/bot0 at 2x.png"; sourceTree = "<group>"; };
+ 6167CA2D142A6ED7003DD50F /* bot1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot1.png; path = Resources/Icons/bot1.png; sourceTree = "<group>"; };
+ 6167CA2E142A6ED7003DD50F /* bot1 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot1 at 2x.png"; path = "Resources/Icons/bot1 at 2x.png"; sourceTree = "<group>"; };
+ 6167CA2F142A6ED7003DD50F /* bot2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot2.png; path = Resources/Icons/bot2.png; sourceTree = "<group>"; };
+ 6167CA30142A6ED7003DD50F /* bot2 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot2 at 2x.png"; path = "Resources/Icons/bot2 at 2x.png"; sourceTree = "<group>"; };
+ 6167CA31142A6ED7003DD50F /* bot3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot3.png; path = Resources/Icons/bot3.png; sourceTree = "<group>"; };
+ 6167CA32142A6ED7003DD50F /* bot3 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot3 at 2x.png"; path = "Resources/Icons/bot3 at 2x.png"; sourceTree = "<group>"; };
+ 6167CA33142A6ED7003DD50F /* bot4.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot4.png; path = Resources/Icons/bot4.png; sourceTree = "<group>"; };
+ 6167CA34142A6ED7003DD50F /* bot4 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot4 at 2x.png"; path = "Resources/Icons/bot4 at 2x.png"; sourceTree = "<group>"; };
+ 6167CA35142A6ED7003DD50F /* bot5.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bot5.png; path = Resources/Icons/bot5.png; sourceTree = "<group>"; };
+ 6167CA36142A6ED7003DD50F /* bot5 at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "bot5 at 2x.png"; path = "Resources/Icons/bot5 at 2x.png"; sourceTree = "<group>"; };
+ 6167CB46142A8769003DD50F /* basehat-hedgehog.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "basehat-hedgehog.png"; path = "Resources/Icons/basehat-hedgehog.png"; sourceTree = "<group>"; };
+ 6167CB47142A8769003DD50F /* basehat-hedgehog at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "basehat-hedgehog at 2x.png"; path = "Resources/Icons/basehat-hedgehog at 2x.png"; sourceTree = "<group>"; };
+ 6172FEA21298C7F900D73365 /* Default at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default at 2x.png"; path = "Resources/Icons/Default at 2x.png"; sourceTree = "<group>"; };
+ 6172FEC81298CE4800D73365 /* savesButton at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "savesButton at 2x.png"; path = "Resources/Frontend/savesButton at 2x.png"; sourceTree = "<group>"; };
+ 6172FECA1298CE4E00D73365 /* settingsButton at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "settingsButton at 2x.png"; path = "Resources/Frontend/settingsButton at 2x.png"; sourceTree = "<group>"; };
+ 6172FED31298CE6600D73365 /* backButton at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "backButton at 2x.png"; path = "Resources/Frontend/backButton at 2x.png"; sourceTree = "<group>"; };
+ 6172FED61298CF9800D73365 /* background at 2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background at 2x~iphone.png"; path = "Resources/Frontend/background at 2x~iphone.png"; sourceTree = "<group>"; };
+ 6172FED71298CF9800D73365 /* background~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "background~iphone.png"; path = "Resources/Frontend/background~iphone.png"; sourceTree = "<group>"; };
+ 6172FEEB1298D25D00D73365 /* mediumBackground~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "mediumBackground~ipad.png"; path = "Resources/Frontend/mediumBackground~ipad.png"; sourceTree = "<group>"; };
+ 6172FEEC1298D25D00D73365 /* smallerBackground at 2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "smallerBackground at 2x~iphone.png"; path = "Resources/Frontend/smallerBackground at 2x~iphone.png"; sourceTree = "<group>"; };
+ 6172FEED1298D25D00D73365 /* smallerBackground~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "smallerBackground~ipad.png"; path = "Resources/Frontend/smallerBackground~ipad.png"; sourceTree = "<group>"; };
+ 6172FEEE1298D25D00D73365 /* smallerBackground~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "smallerBackground~iphone.png"; path = "Resources/Frontend/smallerBackground~iphone.png"; sourceTree = "<group>"; };
+ 6174F7C612CD62E300205D6F /* smallerTitle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = smallerTitle.png; path = Resources/Frontend/smallerTitle.png; sourceTree = "<group>"; };
+ 6174F7C712CD62E300205D6F /* smallerTitle at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "smallerTitle at 2x.png"; path = "Resources/Frontend/smallerTitle at 2x.png"; sourceTree = "<group>"; };
+ 617987E4114AA34C00BA94A9 /* GSHandlers.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = GSHandlers.inc; path = ../../hedgewars/GSHandlers.inc; sourceTree = SOURCE_ROOT; };
+ 617987E7114AA34C00BA94A9 /* hwengine.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = hwengine.pas; path = ../../hedgewars/hwengine.pas; sourceTree = SOURCE_ROOT; };
+ 617987E9114AA34C00BA94A9 /* hwLibrary.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = hwLibrary.pas; path = ../../hedgewars/hwLibrary.pas; sourceTree = SOURCE_ROOT; };
+ 617987EB114AA34C00BA94A9 /* options.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = options.inc; path = ../../hedgewars/options.inc; sourceTree = SOURCE_ROOT; };
+ 617987ED114AA34C00BA94A9 /* SDLh.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SDLh.pas; path = ../../hedgewars/SDLh.pas; sourceTree = SOURCE_ROOT; };
+ 617987F1114AA34C00BA94A9 /* uAI.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAI.pas; path = ../../hedgewars/uAI.pas; sourceTree = SOURCE_ROOT; };
+ 617987F2114AA34C00BA94A9 /* uAIActions.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAIActions.pas; path = ../../hedgewars/uAIActions.pas; sourceTree = SOURCE_ROOT; };
+ 617987F3114AA34C00BA94A9 /* uAIAmmoTests.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAIAmmoTests.pas; path = ../../hedgewars/uAIAmmoTests.pas; sourceTree = SOURCE_ROOT; };
+ 617987F4114AA34C00BA94A9 /* uAIMisc.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAIMisc.pas; path = ../../hedgewars/uAIMisc.pas; sourceTree = SOURCE_ROOT; };
+ 617987F5114AA34C00BA94A9 /* uAmmos.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAmmos.pas; path = ../../hedgewars/uAmmos.pas; sourceTree = SOURCE_ROOT; };
+ 617987F6114AA34C00BA94A9 /* uChat.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uChat.pas; path = ../../hedgewars/uChat.pas; sourceTree = SOURCE_ROOT; };
+ 617987F7114AA34C00BA94A9 /* uCollisions.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCollisions.pas; path = ../../hedgewars/uCollisions.pas; sourceTree = SOURCE_ROOT; };
+ 617987F8114AA34C00BA94A9 /* uConsole.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uConsole.pas; path = ../../hedgewars/uConsole.pas; sourceTree = SOURCE_ROOT; };
+ 617987F9114AA34C00BA94A9 /* uConsts.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uConsts.pas; path = ../../hedgewars/uConsts.pas; sourceTree = SOURCE_ROOT; };
+ 617987FA114AA34C00BA94A9 /* uFloat.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uFloat.pas; path = ../../hedgewars/uFloat.pas; sourceTree = SOURCE_ROOT; };
+ 617987FB114AA34C00BA94A9 /* uGame.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGame.pas; path = ../../hedgewars/uGame.pas; sourceTree = SOURCE_ROOT; };
+ 617987FC114AA34C00BA94A9 /* uGears.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGears.pas; path = ../../hedgewars/uGears.pas; sourceTree = SOURCE_ROOT; };
+ 617987FD114AA34C00BA94A9 /* uIO.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uIO.pas; path = ../../hedgewars/uIO.pas; sourceTree = SOURCE_ROOT; };
+ 617987FF114AA34C00BA94A9 /* uLand.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLand.pas; path = ../../hedgewars/uLand.pas; sourceTree = SOURCE_ROOT; };
+ 61798800114AA34C00BA94A9 /* uLandGraphics.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandGraphics.pas; path = ../../hedgewars/uLandGraphics.pas; sourceTree = SOURCE_ROOT; };
+ 61798801114AA34C00BA94A9 /* uLandObjects.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandObjects.pas; path = ../../hedgewars/uLandObjects.pas; sourceTree = SOURCE_ROOT; };
+ 61798802114AA34C00BA94A9 /* uLandTemplates.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandTemplates.pas; path = ../../hedgewars/uLandTemplates.pas; sourceTree = SOURCE_ROOT; };
+ 61798803114AA34C00BA94A9 /* uLandTexture.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandTexture.pas; path = ../../hedgewars/uLandTexture.pas; sourceTree = SOURCE_ROOT; };
+ 61798804114AA34C00BA94A9 /* uLocale.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLocale.pas; path = ../../hedgewars/uLocale.pas; sourceTree = SOURCE_ROOT; };
+ 61798805114AA34C00BA94A9 /* uMisc.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uMisc.pas; path = ../../hedgewars/uMisc.pas; sourceTree = SOURCE_ROOT; };
+ 61798806114AA34C00BA94A9 /* uRandom.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uRandom.pas; path = ../../hedgewars/uRandom.pas; sourceTree = SOURCE_ROOT; };
+ 61798809114AA34C00BA94A9 /* uSound.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uSound.pas; path = ../../hedgewars/uSound.pas; sourceTree = SOURCE_ROOT; };
+ 6179880A114AA34C00BA94A9 /* uStats.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uStats.pas; path = ../../hedgewars/uStats.pas; sourceTree = SOURCE_ROOT; };
+ 6179880B114AA34C00BA94A9 /* uStore.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uStore.pas; path = ../../hedgewars/uStore.pas; sourceTree = SOURCE_ROOT; };
+ 6179880C114AA34C00BA94A9 /* uTeams.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uTeams.pas; path = ../../hedgewars/uTeams.pas; sourceTree = SOURCE_ROOT; };
+ 6179880E114AA34C00BA94A9 /* uVisualGears.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uVisualGears.pas; path = ../../hedgewars/uVisualGears.pas; sourceTree = SOURCE_ROOT; };
+ 6179880F114AA34C00BA94A9 /* uWorld.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uWorld.pas; path = ../../hedgewars/uWorld.pas; sourceTree = SOURCE_ROOT; };
+ 61798934114AB25F00BA94A9 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+ 61798A5E114AE08600BA94A9 /* Data */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Data; sourceTree = SOURCE_ROOT; };
+ 617BC22D1490210E00E1C294 /* Italian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Italian; path = Locale/Italian.lproj/About.strings; sourceTree = "<group>"; };
+ 617BC2391490211500E1C294 /* Italian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Italian; path = Locale/Italian.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 617BC23A1490211F00E1C294 /* Italian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Italian; path = Locale/Italian.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 617D78D816D932310091D4D6 /* Physfs.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Physfs.xcodeproj; path = ../../misc/libphysfs/Xcode/Physfs.xcodeproj; sourceTree = SOURCE_ROOT; };
+ 617D794316D933B00091D4D6 /* Physlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Physlayer.xcodeproj; path = ../../misc/libphyslayer/Xcode/Physlayer.xcodeproj; sourceTree = SOURCE_ROOT; };
+ 61806BDA170B963800C601BC /* weapons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = weapons.h; path = ../../QTfrontend/weapons.h; sourceTree = SOURCE_ROOT; };
+ 61806BE0170B969D00C601BC /* hwconsts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hwconsts.h; path = ../../QTfrontend/hwconsts.h; sourceTree = SOURCE_ROOT; };
+ 6183D83C11E2BCE200A88903 /* Default-ipad-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-ipad-Landscape.png"; path = "Resources/Icons/Default-ipad-Landscape.png"; sourceTree = "<group>"; };
+ 6183D83D11E2BCE200A88903 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Icons/Default.png; sourceTree = "<group>"; };
+ 618899811299516000D55FD6 /* title at 2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "title at 2x~iphone.png"; path = "Resources/Frontend/title at 2x~iphone.png"; sourceTree = "<group>"; };
+ 61889984129995B500D55FD6 /* title~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "title~ipad.png"; path = "Resources/Frontend/title~ipad.png"; sourceTree = "<group>"; };
+ 61915D58143A4E2C00299991 /* MissionTrainingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MissionTrainingViewController.h; sourceTree = "<group>"; };
+ 61915D59143A4E2C00299991 /* MissionTrainingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MissionTrainingViewController.m; sourceTree = "<group>"; };
+ 61915D5A143A4E2C00299991 /* MissionTrainingViewController-iPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "MissionTrainingViewController-iPhone.xib"; sourceTree = "<group>"; };
+ 619349C5160BAF3E00A08518 /* uAILandMarks.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uAILandMarks.pas; path = ../../hedgewars/uAILandMarks.pas; sourceTree = SOURCE_ROOT; };
+ 619349C6160BAF3E00A08518 /* uGearsHandlers.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsHandlers.pas; path = ../../hedgewars/uGearsHandlers.pas; sourceTree = SOURCE_ROOT; };
+ 619349C7160BAF3E00A08518 /* uGearsHandlersRope.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsHandlersRope.pas; path = ../../hedgewars/uGearsHandlersRope.pas; sourceTree = SOURCE_ROOT; };
+ 619598181364BCD200B429B6 /* Tremor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Tremor.xcodeproj; path = ../../misc/libtremor/Xcode/Tremor.xcodeproj; sourceTree = SOURCE_ROOT; };
+ 6195993F1364C82B00B429B6 /* Lua.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Lua.xcodeproj; path = ../../misc/liblua/Xcode/Lua.xcodeproj; sourceTree = SOURCE_ROOT; };
+ 619599BA1364E65900B429B6 /* Freetype.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Freetype.xcodeproj; path = "../../misc/libfreetype/Xcode-iOS/Freetype.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 6199E81512463EA800DADF8C /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; };
+ 6199E81912463EC400DADF8C /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
+ 6199E836124647DE00DADF8C /* SupportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SupportViewController.h; sourceTree = "<group>"; };
+ 6199E837124647DE00DADF8C /* SupportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SupportViewController.m; sourceTree = "<group>"; };
+ 6199E86C12464A8E00DADF8C /* surprise.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = surprise.png; path = Resources/surprise.png; sourceTree = "<group>"; };
+ 619BCEC41495615700C1C409 /* Bulgarian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Bulgarian; path = Locale/Bulgarian.lproj/About.strings; sourceTree = "<group>"; };
+ 619BCED01495615F00C1C409 /* Bulgarian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Bulgarian; path = Locale/Bulgarian.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 619BCED11495616700C1C409 /* Bulgarian */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Bulgarian; path = Locale/Bulgarian.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 619C5AF3124F7E3100D041AE /* LuaPas.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = LuaPas.pas; path = ../../hedgewars/LuaPas.pas; sourceTree = SOURCE_ROOT; };
+ 619C5BA0124FA59000D041AE /* MapPreviewButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapPreviewButtonView.h; path = Classes/MapPreviewButtonView.h; sourceTree = "<group>"; };
+ 619C5BA1124FA59000D041AE /* MapPreviewButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MapPreviewButtonView.m; path = Classes/MapPreviewButtonView.m; sourceTree = "<group>"; };
+ 61A117FE1168322700359010 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = "../../../Library/SDL/Xcode-iOS/SDL/SDL.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 61A19B6114D20B6C004B1E6D /* SDL_image.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL_image.xcodeproj; path = "../../../Library/SDL_image/Xcode-iOS/SDL_image.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 61A19BC114D20CDA004B1E6D /* SDL_ttf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL_ttf.xcodeproj; path = "../../../Library/SDL_ttf/Xcode-iOS/SDL_ttf.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 61A19BF414D20D83004B1E6D /* SDL_net.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL_net.xcodeproj; path = "../../../Library/SDL_net/Xcode-iOS/SDL_net.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 61A19C1E14D20F51004B1E6D /* SDL_mixer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL_mixer.xcodeproj; path = "../../../Library/SDL_mixer/Xcode-iOS/SDL_mixer.xcodeproj"; sourceTree = SOURCE_ROOT; };
+ 61A4A38912A5CCC2004D81E6 /* uCommandHandlers.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCommandHandlers.pas; path = ../../hedgewars/uCommandHandlers.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38A12A5CCC2004D81E6 /* uCommands.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCommands.pas; path = ../../hedgewars/uCommands.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38B12A5CCC2004D81E6 /* uDebug.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uDebug.pas; path = ../../hedgewars/uDebug.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38C12A5CCC2004D81E6 /* uGearsRender.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsRender.pas; path = ../../hedgewars/uGearsRender.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38D12A5CCC2004D81E6 /* uRender.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uRender.pas; path = ../../hedgewars/uRender.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38E12A5CCC2004D81E6 /* uRenderUtils.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uRenderUtils.pas; path = ../../hedgewars/uRenderUtils.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A38F12A5CCC2004D81E6 /* uSinTable.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uSinTable.pas; path = ../../hedgewars/uSinTable.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A39012A5CCC2004D81E6 /* uTextures.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uTextures.pas; path = ../../hedgewars/uTextures.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A39112A5CCC2004D81E6 /* uTypes.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uTypes.pas; path = ../../hedgewars/uTypes.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A39212A5CCC2004D81E6 /* uUtils.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uUtils.pas; path = ../../hedgewars/uUtils.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A39312A5CCC2004D81E6 /* uVariables.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uVariables.pas; path = ../../hedgewars/uVariables.pas; sourceTree = SOURCE_ROOT; };
+ 61A4A3A112A5CD56004D81E6 /* uCaptions.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCaptions.pas; path = ../../hedgewars/uCaptions.pas; sourceTree = SOURCE_ROOT; };
+ 61A976B2136F668500DD9878 /* uCursor.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCursor.pas; path = ../../hedgewars/uCursor.pas; sourceTree = SOURCE_ROOT; };
+ 61AC067212B2E32D000B52A2 /* Appirater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Appirater.h; path = Classes/Appirater.h; sourceTree = "<group>"; };
+ 61AC067312B2E32D000B52A2 /* Appirater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Appirater.m; path = Classes/Appirater.m; sourceTree = "<group>"; };
+ 61B7A33612CC21080086B604 /* StatsPageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatsPageViewController.h; sourceTree = "<group>"; };
+ 61B7A33712CC21080086B604 /* StatsPageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatsPageViewController.m; sourceTree = "<group>"; };
+ 61B9A86714423A9D001541C1 /* GameConfigViewController-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = "GameConfigViewController-iPad.xib"; sourceTree = "<group>"; };
+ 61C079E211F35A300072BF46 /* EditableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditableCellView.h; path = Classes/EditableCellView.h; sourceTree = "<group>"; };
+ 61C079E311F35A300072BF46 /* EditableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditableCellView.m; path = Classes/EditableCellView.m; sourceTree = "<group>"; };
+ 61C28D3D142D380400DA16C2 /* AudioManagerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioManagerController.h; path = Classes/AudioManagerController.h; sourceTree = "<group>"; };
+ 61C28D3E142D380400DA16C2 /* AudioManagerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AudioManagerController.m; path = Classes/AudioManagerController.m; sourceTree = "<group>"; };
+ 61C6783F14B3DD020087425A /* Portuguese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Portuguese; path = Locale/Portuguese.lproj/About.strings; sourceTree = "<group>"; };
+ 61C6784B14B3DD0B0087425A /* Portuguese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Portuguese; path = Locale/Portuguese.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61C6784C14B3DD140087425A /* Portuguese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Portuguese; path = Locale/Portuguese.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61CADE321402EE290030C3EB /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
+ 61D08D7114AEA7FE0007C078 /* uGearsHedgehog.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsHedgehog.pas; path = ../../hedgewars/uGearsHedgehog.pas; sourceTree = SOURCE_ROOT; };
+ 61D08D7214AEA7FE0007C078 /* uGearsList.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsList.pas; path = ../../hedgewars/uGearsList.pas; sourceTree = SOURCE_ROOT; };
+ 61D08D7314AEA7FE0007C078 /* uGearsUtils.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uGearsUtils.pas; path = ../../hedgewars/uGearsUtils.pas; sourceTree = SOURCE_ROOT; };
+ 61D08D8714AEA9670007C078 /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Japanese; path = Locale/Japanese.lproj/About.strings; sourceTree = "<group>"; };
+ 61D08D8814AEA9700007C078 /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Japanese; path = Locale/Japanese.lproj/Localizable.strings; sourceTree = "<group>"; };
+ 61D08D8914AEA9780007C078 /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Japanese; path = Locale/Japanese.lproj/Scheme.strings; sourceTree = "<group>"; };
+ 61D0BDF71457508C0011A899 /* ExtraCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExtraCategories.h; path = Classes/ExtraCategories.h; sourceTree = "<group>"; };
+ 61D0BDF81457508C0011A899 /* ExtraCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ExtraCategories.m; path = Classes/ExtraCategories.m; sourceTree = "<group>"; };
+ 61D2059F127CDD1100ABD83E /* ObjcExports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjcExports.h; path = Classes/ObjcExports.h; sourceTree = "<group>"; };
+ 61D205A0127CDD1100ABD83E /* ObjcExports.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ObjcExports.m; path = Classes/ObjcExports.m; sourceTree = "<group>"; };
+ 61D3D2A41290E03A003CE7C3 /* irc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = irc.png; path = Resources/Icons/irc.png; sourceTree = "<group>"; };
+ 61E1F4F711D004240016A5AA /* adler32.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = adler32.pas; path = ../../hedgewars/adler32.pas; sourceTree = SOURCE_ROOT; };
+ 61E2E12C12BAAEE30051B659 /* ServerProtocolNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ServerProtocolNetwork.h; sourceTree = "<group>"; };
+ 61E2E12D12BAAEE30051B659 /* ServerProtocolNetwork.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ServerProtocolNetwork.m; sourceTree = "<group>"; };
+ 61E2F7421283752C00E12521 /* fb.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fb.png; path = Resources/Icons/fb.png; sourceTree = "<group>"; };
+ 61E2F7431283752C00E12521 /* tw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tw.png; path = Resources/Icons/tw.png; sourceTree = "<group>"; };
+ 61E5D68C12AB006F00566F29 /* uLandPainted.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uLandPainted.pas; path = ../../hedgewars/uLandPainted.pas; sourceTree = SOURCE_ROOT; };
+ 61EBA62811DFF2BC0048B68A /* title~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "title~iphone.png"; path = "Resources/Frontend/title~iphone.png"; sourceTree = "<group>"; };
+ 61EDB5AE135B3F97009B29A6 /* GameInterfaceBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameInterfaceBridge.h; sourceTree = "<group>"; };
+ 61EDB5AF135B3F97009B29A6 /* GameInterfaceBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GameInterfaceBridge.m; sourceTree = "<group>"; };
+ 61F2E7CB1205EDE0005734F7 /* AboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutViewController.h; sourceTree = "<group>"; };
+ 61F2E7CC1205EDE0005734F7 /* AboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutViewController.m; sourceTree = "<group>"; };
+ 61F2E7CD1205EDE0005734F7 /* AboutViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutViewController.xib; sourceTree = "<group>"; };
+ 61F2E7EB12060E31005734F7 /* checkbox.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = checkbox.png; path = Resources/Icons/checkbox.png; sourceTree = "<group>"; };
+ 61F544C512AF1748007FD913 /* HoldTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HoldTableViewCell.h; path = Classes/HoldTableViewCell.h; sourceTree = "<group>"; };
+ 61F544C612AF1748007FD913 /* HoldTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HoldTableViewCell.m; path = Classes/HoldTableViewCell.m; sourceTree = "<group>"; };
+ 61F7A43111E290650040BA66 /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "Resources/Icons/Icon-72.png"; sourceTree = "<group>"; };
+ 61F7A43211E290650040BA66 /* Icon-Small-50.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50.png"; path = "Resources/Icons/Icon-Small-50.png"; sourceTree = "<group>"; };
+ 61F7A43311E290650040BA66 /* Icon-Small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small.png"; path = "Resources/Icons/Icon-Small.png"; sourceTree = "<group>"; };
+ 61F7A43411E290650040BA66 /* Icon-Small at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small at 2x.png"; path = "Resources/Icons/Icon-Small at 2x.png"; sourceTree = "<group>"; };
+ 61F7A43511E290650040BA66 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = Resources/Icons/Icon.png; sourceTree = "<group>"; };
+ 61F7A43611E290650040BA66 /* Icon at 2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon at 2x.png"; path = "Resources/Icons/Icon at 2x.png"; sourceTree = "<group>"; };
+ 61F7A43711E290650040BA66 /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = iTunesArtwork.png; path = Resources/Icons/iTunesArtwork.png; sourceTree = "<group>"; };
+ 61F9040811DF58B00068B24D /* settingsButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settingsButton.png; path = Resources/Frontend/settingsButton.png; sourceTree = "<group>"; };
+ 61F9040A11DF59370068B24D /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = background.png; path = Resources/Frontend/background.png; sourceTree = "<group>"; };
+ 61F9040D11DF59D10068B24D /* netplayButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = netplayButton.png; path = Resources/Frontend/netplayButton.png; sourceTree = "<group>"; };
+ 61F904D511DF7DA30068B24D /* WeaponCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WeaponCellView.h; path = Classes/WeaponCellView.h; sourceTree = "<group>"; };
+ 61F904D611DF7DA30068B24D /* WeaponCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WeaponCellView.m; path = Classes/WeaponCellView.m; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 928301170F10CAFC00CC5A3C /* libfpc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libfpc.a; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 617D791E16D933060091D4D6 /* libPhysfs.a in Frameworks */,
+ 617D795716D9345F0091D4D6 /* libPhyslayer.a in Frameworks */,
+ 922F64900F10F53100DC6EC0 /* libfpc.a in Frameworks */,
+ 616245D114E6160200CC97FB /* libFreetype.a in Frameworks */,
+ 619599451364C83D00B429B6 /* libLua.a in Frameworks */,
+ 6195981F1364BCEF00B429B6 /* libTremor.a in Frameworks */,
+ 61A19AFC14D20170004B1E6D /* libSDL2.a in Frameworks */,
+ 61A19B7714D20B7A004B1E6D /* libSDL2_image.a in Frameworks */,
+ 61A19C2414D20F5A004B1E6D /* libSDL2_mixer.a in Frameworks */,
+ 61A19BFA14D20D95004B1E6D /* libSDL2_net.a in Frameworks */,
+ 61A19BC714D20CE7004B1E6D /* libSDL2_ttf.a in Frameworks */,
+ 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
+ 61A1188511683A8C00359010 /* CoreGraphics.framework in Frameworks */,
+ 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
+ 28FD15000DC6FC520079059D /* OpenGLES.framework in Frameworks */,
+ 28FD15080DC6FC5B0079059D /* QuartzCore.framework in Frameworks */,
+ 61798935114AB25F00BA94A9 /* AudioToolbox.framework in Frameworks */,
+ 61272339117DF778005B90CF /* MobileCoreServices.framework in Frameworks */,
+ 6199E81612463EA800DADF8C /* CFNetwork.framework in Frameworks */,
+ 6199E81A12463EC400DADF8C /* SystemConfiguration.framework in Frameworks */,
+ 612CABAB1391CE68005E9596 /* AVFoundation.framework in Frameworks */,
+ 61CADE331402EE290030C3EB /* ImageIO.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 6163EE4D11CC247D001C0453 /* Game Configuration */,
+ 6163EE4C11CC2478001C0453 /* Settings Page */,
+ 611D9BF312497B7700008271 /* Satellite Controllers */,
+ 616591F011CA9BA200D6E256 /* MainMenuViewController.h */,
+ 616591F111CA9BA200D6E256 /* MainMenuViewController.m */,
+ 6165924B11CA9CB400D6E256 /* MainMenuViewController-iPad.xib */,
+ 6165924C11CA9CB400D6E256 /* MainMenuViewController-iPhone.xib */,
+ 61EDB5AE135B3F97009B29A6 /* GameInterfaceBridge.h */,
+ 61EDB5AF135B3F97009B29A6 /* GameInterfaceBridge.m */,
+ 616591E611CA9BA200D6E256 /* EngineProtocolNetwork.h */,
+ 616591E711CA9BA200D6E256 /* EngineProtocolNetwork.m */,
+ 61E2E12C12BAAEE30051B659 /* ServerProtocolNetwork.h */,
+ 61E2E12D12BAAEE30051B659 /* ServerProtocolNetwork.m */,
+ );
+ path = Classes;
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 1D6058910D05DD3D006BFB54 /* Hedgewars.app */,
+ 928301170F10CAFC00CC5A3C /* libfpc.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
+ isa = PBXGroup;
+ children = (
+ 9283015C0F10E48900CC5A3C /* Pascal Sources */,
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 61156510147F481B006729A9 /* Locale */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ 61370652117B1D50004EE44A /* Entitlements-Distribution.plist */,
+ 611E12FE117BBBDA0044B62F /* Entitlements-Development.plist */,
+ );
+ name = CustomTemplate;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 61F8535314578999002CA294 /* Helpers */,
+ 61641FE21437CD8F006E049C /* Headers */,
+ 61DE91561258B76800B80214 /* Custom UIs */,
+ 61AC067212B2E32D000B52A2 /* Appirater.h */,
+ 61AC067312B2E32D000B52A2 /* Appirater.m */,
+ 61006F93128DE31F00EBA7F7 /* CreationChamber.h */,
+ 61006F94128DE31F00EBA7F7 /* CreationChamber.m */,
+ 6165929C11CA9E2F00D6E256 /* HedgewarsAppDelegate.h */,
+ 6165929D11CA9E2F00D6E256 /* HedgewarsAppDelegate.m */,
+ 61D2059F127CDD1100ABD83E /* ObjcExports.h */,
+ 61D205A0127CDD1100ABD83E /* ObjcExports.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 6129B9F611EFB04D0017E305 /* denied.png */,
+ 6167C88B14294738003DD50F /* denied at 2x.png */,
+ 6199E86C12464A8E00DADF8C /* surprise.png */,
+ 6167C87314294727003DD50F /* surprise at 2x.png */,
+ 612CABCA1391D3D1005E9596 /* Sounds */,
+ 61F7A42811E2905C0040BA66 /* Icons */,
+ 61F903FA11DF58680068B24D /* Frontend */,
+ 6179936611501D1E00BA94A9 /* Overlay */,
+ 61798A5E114AE08600BA94A9 /* Data */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 610782931440EE5C00645B29 /* basicFlags.plist */,
+ 610782941440EE5C00645B29 /* credits.plist */,
+ 610782951440EE5C00645B29 /* gameMods.plist */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 617D78D816D932310091D4D6 /* Physfs.xcodeproj */,
+ 617D794316D933B00091D4D6 /* Physlayer.xcodeproj */,
+ 619599BA1364E65900B429B6 /* Freetype.xcodeproj */,
+ 6195993F1364C82B00B429B6 /* Lua.xcodeproj */,
+ 619598181364BCD200B429B6 /* Tremor.xcodeproj */,
+ 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */,
+ 61A19B6114D20B6C004B1E6D /* SDL_image.xcodeproj */,
+ 61A19C1E14D20F51004B1E6D /* SDL_mixer.xcodeproj */,
+ 61A19BF414D20D83004B1E6D /* SDL_net.xcodeproj */,
+ 61A19BC114D20CDA004B1E6D /* SDL_ttf.xcodeproj */,
+ 61798934114AB25F00BA94A9 /* AudioToolbox.framework */,
+ 612CABAA1391CE68005E9596 /* AVFoundation.framework */,
+ 61A117FE1168322700359010 /* CoreGraphics.framework */,
+ 1D30AB110D05D00D00671497 /* Foundation.framework */,
+ 28FD14FF0DC6FC520079059D /* OpenGLES.framework */,
+ 28FD15070DC6FC5B0079059D /* QuartzCore.framework */,
+ 61CADE321402EE290030C3EB /* ImageIO.framework */,
+ 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
+ 61272338117DF778005B90CF /* MobileCoreServices.framework */,
+ 6199E81512463EA800DADF8C /* CFNetwork.framework */,
+ 6199E81912463EC400DADF8C /* SystemConfiguration.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 61156510147F481B006729A9 /* Locale */ = {
+ isa = PBXGroup;
+ children = (
+ 61156520147F48B6006729A9 /* About.strings */,
+ 61156522147F48B7006729A9 /* Localizable.strings */,
+ 61156524147F48B8006729A9 /* Scheme.strings */,
+ );
+ name = Locale;
+ sourceTree = "<group>";
+ };
+ 611D9BF312497B7700008271 /* Satellite Controllers */ = {
+ isa = PBXGroup;
+ children = (
+ 61F2E7CB1205EDE0005734F7 /* AboutViewController.h */,
+ 61F2E7CC1205EDE0005734F7 /* AboutViewController.m */,
+ 61F2E7CD1205EDE0005734F7 /* AboutViewController.xib */,
+ 6167A6731391514600AA6D07 /* RestoreViewController.h */,
+ 6167A6741391514600AA6D07 /* RestoreViewController.m */,
+ 6167A6751391514600AA6D07 /* RestoreViewController-iPhone.xib */,
+ 6167A72C13919E6800AA6D07 /* RestoreViewController-iPad.xib */,
+ 611D9BF812497E9800008271 /* SavedGamesViewController.h */,
+ 611D9BF912497E9800008271 /* SavedGamesViewController.m */,
+ 611D9BFA12497E9800008271 /* SavedGamesViewController.xib */,
+ 61B7A33612CC21080086B604 /* StatsPageViewController.h */,
+ 61B7A33712CC21080086B604 /* StatsPageViewController.m */,
+ 61915D58143A4E2C00299991 /* MissionTrainingViewController.h */,
+ 61915D59143A4E2C00299991 /* MissionTrainingViewController.m */,
+ 61915D5A143A4E2C00299991 /* MissionTrainingViewController-iPhone.xib */,
+ 61077E86143FB09800645B29 /* MissionTrainingViewController-iPad.xib */,
+ );
+ name = "Satellite Controllers";
+ sourceTree = "<group>";
+ };
+ 612CABCA1391D3D1005E9596 /* Sounds */ = {
+ isa = PBXGroup;
+ children = (
+ 616065A7159A71FD00CFAEF4 /* hwclassic.mp3 */,
+ 611EE973122A9C4100DF6938 /* clickSound.caf */,
+ 611EE9D7122AA10A00DF6938 /* backSound.caf */,
+ 611EE9D8122AA10A00DF6938 /* selSound.caf */,
+ );
+ name = Sounds;
+ sourceTree = "<group>";
+ };
+ 615E75C014E42C9000FBA131 /* MGSplitViewController */ = {
+ isa = PBXGroup;
+ children = (
+ 615E76B514E4406400FBA131 /* LICENCE.rtf */,
+ 615E76B614E4421200FBA131 /* MGSplitCornersView.h */,
+ 615E76B714E4421200FBA131 /* MGSplitCornersView.m */,
+ 615E76B814E4421200FBA131 /* MGSplitDividerView.h */,
+ 615E76B914E4421200FBA131 /* MGSplitDividerView.m */,
+ 615E76BA14E4421200FBA131 /* MGSplitViewController.h */,
+ 615E76BB14E4421200FBA131 /* MGSplitViewController.m */,
+ );
+ name = MGSplitViewController;
+ sourceTree = "<group>";
+ };
+ 6162456314E6159C00CC97FB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 6162456714E6159C00CC97FB /* libFreetype.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 6163EE4C11CC2478001C0453 /* Settings Page */ = {
+ isa = PBXGroup;
+ children = (
+ 6165920211CA9BA200D6E256 /* SettingsContainerViewController.h */,
+ 6165920311CA9BA200D6E256 /* SettingsContainerViewController.m */,
+ 616591F411CA9BA200D6E256 /* SettingsBaseViewController.h */,
+ 616591F511CA9BA200D6E256 /* SettingsBaseViewController.m */,
+ 6163EE4E11CC248D001C0453 /* First Level */,
+ 6163EE4F11CC2497001C0453 /* Second Level */,
+ 6163EE5011CC24A1001C0453 /* Third Level */,
+ );
+ name = "Settings Page";
+ sourceTree = "<group>";
+ };
+ 6163EE4D11CC247D001C0453 /* Game Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ 616591E411CA9BA200D6E256 /* GameConfigViewController.h */,
+ 616591E511CA9BA200D6E256 /* GameConfigViewController.m */,
+ 61B9A86714423A9D001541C1 /* GameConfigViewController-iPad.xib */,
+ 6165924A11CA9CB400D6E256 /* GameConfigViewController-iPhone.xib */,
+ 6165920411CA9BA200D6E256 /* TeamConfigViewController.h */,
+ 6165920511CA9BA200D6E256 /* TeamConfigViewController.m */,
+ 616591FC11CA9BA200D6E256 /* SchemeWeaponConfigViewController.h */,
+ 616591FD11CA9BA200D6E256 /* SchemeWeaponConfigViewController.m */,
+ 616591F211CA9BA200D6E256 /* MapConfigViewController.h */,
+ 616591F311CA9BA200D6E256 /* MapConfigViewController.m */,
+ 6165924D11CA9CB400D6E256 /* MapConfigViewController-iPad.xib */,
+ 6165924E11CA9CB400D6E256 /* MapConfigViewController-iPhone.xib */,
+ );
+ name = "Game Configuration";
+ sourceTree = "<group>";
+ };
+ 6163EE4E11CC248D001C0453 /* First Level */ = {
+ isa = PBXGroup;
+ children = (
+ 616591E811CA9BA200D6E256 /* GeneralSettingsViewController.h */,
+ 616591E911CA9BA200D6E256 /* GeneralSettingsViewController.m */,
+ 6165920611CA9BA200D6E256 /* TeamSettingsViewController.h */,
+ 6165920711CA9BA200D6E256 /* TeamSettingsViewController.m */,
+ 6165920A11CA9BA200D6E256 /* WeaponSettingsViewController.h */,
+ 6165920B11CA9BA200D6E256 /* WeaponSettingsViewController.m */,
+ 616591FA11CA9BA200D6E256 /* SchemeSettingsViewController.h */,
+ 616591FB11CA9BA200D6E256 /* SchemeSettingsViewController.m */,
+ 6199E836124647DE00DADF8C /* SupportViewController.h */,
+ 6199E837124647DE00DADF8C /* SupportViewController.m */,
+ );
+ name = "First Level";
+ sourceTree = "<group>";
+ };
+ 6163EE4F11CC2497001C0453 /* Second Level */ = {
+ isa = PBXGroup;
+ children = (
+ 6165920011CA9BA200D6E256 /* SingleTeamViewController.h */,
+ 6165920111CA9BA200D6E256 /* SingleTeamViewController.m */,
+ 6163EE7C11CC2600001C0453 /* SingleWeaponViewController.h */,
+ 6163EE7D11CC2600001C0453 /* SingleWeaponViewController.m */,
+ 616591FE11CA9BA200D6E256 /* SingleSchemeViewController.h */,
+ 616591FF11CA9BA200D6E256 /* SingleSchemeViewController.m */,
+ );
+ name = "Second Level";
+ sourceTree = "<group>";
+ };
+ 6163EE5011CC24A1001C0453 /* Third Level */ = {
+ isa = PBXGroup;
+ children = (
+ 616591EC11CA9BA200D6E256 /* HogHatViewController.h */,
+ 616591ED11CA9BA200D6E256 /* HogHatViewController.m */,
+ 616591EE11CA9BA200D6E256 /* LevelViewController.h */,
+ 616591EF11CA9BA200D6E256 /* LevelViewController.m */,
+ 616591E011CA9BA200D6E256 /* FlagsViewController.h */,
+ 616591E111CA9BA200D6E256 /* FlagsViewController.m */,
+ 616591E211CA9BA200D6E256 /* FortsViewController.h */,
+ 616591E311CA9BA200D6E256 /* FortsViewController.m */,
+ 616591EA11CA9BA200D6E256 /* GravesViewController.h */,
+ 616591EB11CA9BA200D6E256 /* GravesViewController.m */,
+ 6165920811CA9BA200D6E256 /* VoicesViewController.h */,
+ 6165920911CA9BA200D6E256 /* VoicesViewController.m */,
+ );
+ name = "Third Level";
+ sourceTree = "<group>";
+ };
+ 61641FE21437CD8F006E049C /* Headers */ = {
+ isa = PBXGroup;
+ children = (
+ 61806BE0170B969D00C601BC /* hwconsts.h */,
+ 61806BDA170B963800C601BC /* weapons.h */,
+ 61641FE31437CDAA006E049C /* DefinesAndMacros.h */,
+ 32CA4F630368D1EE00C91783 /* Hedgewars_Prefix.pch */,
+ 6165922911CA9BD500D6E256 /* PascalImports.h */,
+ );
+ name = Headers;
+ sourceTree = "<group>";
+ };
+ 61798892114AA56300BA94A9 /* inc */ = {
+ isa = PBXGroup;
+ children = (
+ 61589C5A144B4322007BFAA4 /* config.inc */,
+ 617987EB114AA34C00BA94A9 /* options.inc */,
+ 617987E4114AA34C00BA94A9 /* GSHandlers.inc */,
+ 614E333D11DE9A93009DBA4E /* VGSHandlers.inc */,
+ );
+ name = inc;
+ sourceTree = "<group>";
+ };
+ 6179936611501D1E00BA94A9 /* Overlay */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Overlay;
+ sourceTree = "<group>";
+ };
+ 617D78D916D932310091D4D6 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 617D78E016D932310091D4D6 /* libPhysfs.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 617D794416D933B00091D4D6 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 617D794816D933B00091D4D6 /* libPhyslayer.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 619598191364BCD200B429B6 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 6195981D1364BCD200B429B6 /* libTremor.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 619599401364C82B00B429B6 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 619599441364C82B00B429B6 /* libLua.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61A19AE414D2010A004B1E6D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61A19AEA14D2010A004B1E6D /* libSDL2.a */,
+ 61A19AEC14D2010A004B1E6D /* testsdl.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61A19B6214D20B6C004B1E6D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61A19B6614D20B6C004B1E6D /* libSDL2_image.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61A19BC214D20CDA004B1E6D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61A19BC614D20CDA004B1E6D /* libSDL2_ttf.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61A19BF514D20D83004B1E6D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61A19BF914D20D83004B1E6D /* libSDL2_net.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61A19C1F14D20F51004B1E6D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 61A19C2314D20F51004B1E6D /* libSDL2_mixer.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 61DE91561258B76800B80214 /* Custom UIs */ = {
+ isa = PBXGroup;
+ children = (
+ 615E75C014E42C9000FBA131 /* MGSplitViewController */,
+ 610C8E3514E018D200CF5C4C /* MNEValueTrackingSlider.h */,
+ 610C8E3614E018D200CF5C4C /* MNEValueTrackingSlider.m */,
+ 619C5BA0124FA59000D041AE /* MapPreviewButtonView.h */,
+ 619C5BA1124FA59000D041AE /* MapPreviewButtonView.m */,
+ 61F544C512AF1748007FD913 /* HoldTableViewCell.h */,
+ 61F544C612AF1748007FD913 /* HoldTableViewCell.m */,
+ 6165922A11CA9BD500D6E256 /* SquareButtonView.h */,
+ 6165922B11CA9BD500D6E256 /* SquareButtonView.m */,
+ 61C079E211F35A300072BF46 /* EditableCellView.h */,
+ 61C079E311F35A300072BF46 /* EditableCellView.m */,
+ 61F904D511DF7DA30068B24D /* WeaponCellView.h */,
+ 61F904D611DF7DA30068B24D /* WeaponCellView.m */,
+ );
+ name = "Custom UIs";
+ sourceTree = "<group>";
+ };
+ 61F7A42811E2905C0040BA66 /* Icons */ = {
+ isa = PBXGroup;
+ children = (
+ 61F2E7EB12060E31005734F7 /* checkbox.png */,
+ 615FEAD912A2A4C10098EE92 /* checkbox at 2x.png */,
+ 61D3D2A41290E03A003CE7C3 /* irc.png */,
+ 6103D384129B347700911D8D /* irc at 2x.png */,
+ 61E2F7421283752C00E12521 /* fb.png */,
+ 6103D383129B346A00911D8D /* fb at 2x.png */,
+ 61E2F7431283752C00E12521 /* tw.png */,
+ 6103D385129B348200911D8D /* tw at 2x.png */,
+ 6167C8EF1429502C003DD50F /* hedgehog.png */,
+ 6167C8F01429502C003DD50F /* hedgehog at 2x.png */,
+ 6167C8F11429502C003DD50F /* robotBadge.png */,
+ 6167C8F21429502C003DD50F /* robotBadge at 2x.png */,
+ 6167C8F31429502C003DD50F /* star.png */,
+ 6167C8F41429502C003DD50F /* star at 2x.png */,
+ 6167CB46142A8769003DD50F /* basehat-hedgehog.png */,
+ 6167CB47142A8769003DD50F /* basehat-hedgehog at 2x.png */,
+ 6167CA2B142A6ED7003DD50F /* bot0.png */,
+ 6167CA2C142A6ED7003DD50F /* bot0 at 2x.png */,
+ 6167CA2D142A6ED7003DD50F /* bot1.png */,
+ 6167CA2E142A6ED7003DD50F /* bot1 at 2x.png */,
+ 6167CA2F142A6ED7003DD50F /* bot2.png */,
+ 6167CA30142A6ED7003DD50F /* bot2 at 2x.png */,
+ 6167CA31142A6ED7003DD50F /* bot3.png */,
+ 6167CA32142A6ED7003DD50F /* bot3 at 2x.png */,
+ 6167CA33142A6ED7003DD50F /* bot4.png */,
+ 6167CA34142A6ED7003DD50F /* bot4 at 2x.png */,
+ 6167CA35142A6ED7003DD50F /* bot5.png */,
+ 6167CA36142A6ED7003DD50F /* bot5 at 2x.png */,
+ 6183D83C11E2BCE200A88903 /* Default-ipad-Landscape.png */,
+ 6183D83D11E2BCE200A88903 /* Default.png */,
+ 6172FEA21298C7F900D73365 /* Default at 2x.png */,
+ 61F7A43111E290650040BA66 /* Icon-72.png */,
+ 61F7A43211E290650040BA66 /* Icon-Small-50.png */,
+ 61F7A43311E290650040BA66 /* Icon-Small.png */,
+ 61F7A43411E290650040BA66 /* Icon-Small at 2x.png */,
+ 61F7A43511E290650040BA66 /* Icon.png */,
+ 61F7A43611E290650040BA66 /* Icon at 2x.png */,
+ 61F7A43711E290650040BA66 /* iTunesArtwork.png */,
+ );
+ name = Icons;
+ sourceTree = "<group>";
+ };
+ 61F8535314578999002CA294 /* Helpers */ = {
+ isa = PBXGroup;
+ children = (
+ 615E755814E41E8C00FBA131 /* MXAudioPlayerFadeOperation.h */,
+ 615E755914E41E8C00FBA131 /* MXAudioPlayerFadeOperation.m */,
+ 61C28D3D142D380400DA16C2 /* AudioManagerController.h */,
+ 61C28D3E142D380400DA16C2 /* AudioManagerController.m */,
+ 6165922411CA9BD500D6E256 /* CGPointUtils.h */,
+ 6165922311CA9BD500D6E256 /* CGPointUtils.c */,
+ 61D0BDF71457508C0011A899 /* ExtraCategories.h */,
+ 61D0BDF81457508C0011A899 /* ExtraCategories.m */,
+ 6165922511CA9BD500D6E256 /* HWUtils.h */,
+ 6165922611CA9BD500D6E256 /* HWUtils.m */,
+ 6165922C11CA9BD500D6E256 /* UIImageExtra.h */,
+ 6165922D11CA9BD500D6E256 /* UIImageExtra.m */,
+ );
+ name = Helpers;
+ sourceTree = "<group>";
+ };
+ 61F903FA11DF58680068B24D /* Frontend */ = {
+ isa = PBXGroup;
+ children = (
+ 6147DAD21253DCDE0010357E /* savesButton.png */,
+ 6172FEC81298CE4800D73365 /* savesButton at 2x.png */,
+ 61F9040811DF58B00068B24D /* settingsButton.png */,
+ 6172FECA1298CE4E00D73365 /* settingsButton at 2x.png */,
+ 615AD9EA1207654E00F2FF04 /* helpButton.png */,
+ 615AD9E8120764CA00F2FF04 /* backButton.png */,
+ 6172FED31298CE6600D73365 /* backButton at 2x.png */,
+ 615AD96112073B4D00F2FF04 /* startGameButton.png */,
+ 61078029143FCCC800645B29 /* startGameButton at 2x.png */,
+ 615FEADE12A2A6640098EE92 /* localplayButton at 2x~iphone.png */,
+ 615FEAE012A2A6640098EE92 /* localplayButton~iphone.png */,
+ 615FEADF12A2A6640098EE92 /* localplayButton~ipad.png */,
+ 61F9040D11DF59D10068B24D /* netplayButton.png */,
+ 61EBA62811DFF2BC0048B68A /* title~iphone.png */,
+ 618899811299516000D55FD6 /* title at 2x~iphone.png */,
+ 61889984129995B500D55FD6 /* title~ipad.png */,
+ 6174F7C612CD62E300205D6F /* smallerTitle.png */,
+ 6174F7C712CD62E300205D6F /* smallerTitle at 2x.png */,
+ 61F9040A11DF59370068B24D /* background.png */,
+ 6172FED61298CF9800D73365 /* background at 2x~iphone.png */,
+ 6172FED71298CF9800D73365 /* background~iphone.png */,
+ 6172FEEB1298D25D00D73365 /* mediumBackground~ipad.png */,
+ 6172FEEC1298D25D00D73365 /* smallerBackground at 2x~iphone.png */,
+ 6172FEEE1298D25D00D73365 /* smallerBackground~iphone.png */,
+ 6172FEED1298D25D00D73365 /* smallerBackground~ipad.png */,
+ );
+ name = Frontend;
+ sourceTree = "<group>";
+ };
+ 9283015C0F10E48900CC5A3C /* Pascal Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 610FB7C71661390E002FB2A7 /* uPhysFSLayer.pas */,
+ 619349C5160BAF3E00A08518 /* uAILandMarks.pas */,
+ 619349C6160BAF3E00A08518 /* uGearsHandlers.pas */,
+ 619349C7160BAF3E00A08518 /* uGearsHandlersRope.pas */,
+ 615BE3D3155C5DDF003CA34D /* uInputHandler.pas */,
+ 61798892114AA56300BA94A9 /* inc */,
+ 61D08D7114AEA7FE0007C078 /* uGearsHedgehog.pas */,
+ 61D08D7214AEA7FE0007C078 /* uGearsList.pas */,
+ 61D08D7314AEA7FE0007C078 /* uGearsUtils.pas */,
+ 61177C00148B8BB100686905 /* uLandGenMaze.pas */,
+ 61177C01148B8BB100686905 /* uLandOutline.pas */,
+ 611D7A4F142FDCD3006E0798 /* uTouch.pas */,
+ 61A976B2136F668500DD9878 /* uCursor.pas */,
+ 61E5D68C12AB006F00566F29 /* uLandPainted.pas */,
+ 61A4A3A112A5CD56004D81E6 /* uCaptions.pas */,
+ 61A4A38912A5CCC2004D81E6 /* uCommandHandlers.pas */,
+ 61A4A38A12A5CCC2004D81E6 /* uCommands.pas */,
+ 61A4A38B12A5CCC2004D81E6 /* uDebug.pas */,
+ 61A4A38C12A5CCC2004D81E6 /* uGearsRender.pas */,
+ 61A4A38D12A5CCC2004D81E6 /* uRender.pas */,
+ 61A4A38E12A5CCC2004D81E6 /* uRenderUtils.pas */,
+ 61A4A38F12A5CCC2004D81E6 /* uSinTable.pas */,
+ 61A4A39012A5CCC2004D81E6 /* uTextures.pas */,
+ 61A4A39112A5CCC2004D81E6 /* uTypes.pas */,
+ 61A4A39212A5CCC2004D81E6 /* uUtils.pas */,
+ 61A4A39312A5CCC2004D81E6 /* uVariables.pas */,
+ 619C5AF3124F7E3100D041AE /* LuaPas.pas */,
+ 61E1F4F711D004240016A5AA /* adler32.pas */,
+ 617987E7114AA34C00BA94A9 /* hwengine.pas */,
+ 617987E9114AA34C00BA94A9 /* hwLibrary.pas */,
+ 617987ED114AA34C00BA94A9 /* SDLh.pas */,
+ 617987F1114AA34C00BA94A9 /* uAI.pas */,
+ 617987F2114AA34C00BA94A9 /* uAIActions.pas */,
+ 617987F3114AA34C00BA94A9 /* uAIAmmoTests.pas */,
+ 617987F4114AA34C00BA94A9 /* uAIMisc.pas */,
+ 617987F5114AA34C00BA94A9 /* uAmmos.pas */,
+ 617987F6114AA34C00BA94A9 /* uChat.pas */,
+ 617987F7114AA34C00BA94A9 /* uCollisions.pas */,
+ 617987F8114AA34C00BA94A9 /* uConsole.pas */,
+ 617987F9114AA34C00BA94A9 /* uConsts.pas */,
+ 617987FA114AA34C00BA94A9 /* uFloat.pas */,
+ 617987FB114AA34C00BA94A9 /* uGame.pas */,
+ 617987FC114AA34C00BA94A9 /* uGears.pas */,
+ 617987FD114AA34C00BA94A9 /* uIO.pas */,
+ 617987FF114AA34C00BA94A9 /* uLand.pas */,
+ 61798800114AA34C00BA94A9 /* uLandGraphics.pas */,
+ 61798801114AA34C00BA94A9 /* uLandObjects.pas */,
+ 61798802114AA34C00BA94A9 /* uLandTemplates.pas */,
+ 61798803114AA34C00BA94A9 /* uLandTexture.pas */,
+ 61798804114AA34C00BA94A9 /* uLocale.pas */,
+ 61798805114AA34C00BA94A9 /* uMisc.pas */,
+ 61798806114AA34C00BA94A9 /* uRandom.pas */,
+ 611F4D4A11B27A9900F9759A /* uScript.pas */,
+ 61798809114AA34C00BA94A9 /* uSound.pas */,
+ 6179880A114AA34C00BA94A9 /* uStats.pas */,
+ 6179880B114AA34C00BA94A9 /* uStore.pas */,
+ 6179880C114AA34C00BA94A9 /* uTeams.pas */,
+ 6179880E114AA34C00BA94A9 /* uVisualGears.pas */,
+ 6179880F114AA34C00BA94A9 /* uWorld.pas */,
+ );
+ name = "Pascal Sources";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 1D6058900D05DD3D006BFB54 /* Hedgewars */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Hedgewars" */;
+ buildPhases = (
+ 1D60588D0D05DD3D006BFB54 /* Resources */,
+ 1D60588E0D05DD3D006BFB54 /* Sources */,
+ 1D60588F0D05DD3D006BFB54 /* Frameworks */,
+ 6137A859164732120043D108 /* Update Revision Information */,
+ );
+ buildRules = (
+ 9283015B0F10E46D00CC5A3C /* PBXBuildRule */,
+ );
+ dependencies = (
+ 9283015A0F10E41300CC5A3C /* PBXTargetDependency */,
+ 610FB7E216613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7E416613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7E616613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7E816613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7EA16613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7EC16613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7EE16613980002FB2A7 /* PBXTargetDependency */,
+ 610FB7F016613980002FB2A7 /* PBXTargetDependency */,
+ 617D791D16D932EC0091D4D6 /* PBXTargetDependency */,
+ 617D794A16D933BC0091D4D6 /* PBXTargetDependency */,
+ );
+ name = Hedgewars;
+ productName = HedgewarsMobile;
+ productReference = 1D6058910D05DD3D006BFB54 /* Hedgewars.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 928301160F10CAFC00CC5A3C /* fpc */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 9283011C0F10CB4B00CC5A3C /* Build configuration list for PBXNativeTarget "fpc" */;
+ buildPhases = (
+ 9283011B0F10CB2D00CC5A3C /* Build libfpc.a */,
+ 928301560F10E04C00CC5A3C /* Compile Pascal Sources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = fpc;
+ productName = fpc;
+ productReference = 928301170F10CAFC00CC5A3C /* libfpc.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ };
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Hedgewars" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ Spanish,
+ Polish,
+ Turkish,
+ Danish,
+ Italian,
+ Bulgarian,
+ Portuguese,
+ Romanian,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 6162456314E6159C00CC97FB /* Products */;
+ ProjectRef = 619599BA1364E65900B429B6 /* Freetype.xcodeproj */;
+ },
+ {
+ ProductGroup = 619599401364C82B00B429B6 /* Products */;
+ ProjectRef = 6195993F1364C82B00B429B6 /* Lua.xcodeproj */;
+ },
+ {
+ ProductGroup = 617D78D916D932310091D4D6 /* Products */;
+ ProjectRef = 617D78D816D932310091D4D6 /* Physfs.xcodeproj */;
+ },
+ {
+ ProductGroup = 617D794416D933B00091D4D6 /* Products */;
+ ProjectRef = 617D794316D933B00091D4D6 /* Physlayer.xcodeproj */;
+ },
+ {
+ ProductGroup = 61A19AE414D2010A004B1E6D /* Products */;
+ ProjectRef = 61A19AE314D2010A004B1E6D /* SDL.xcodeproj */;
+ },
+ {
+ ProductGroup = 61A19B6214D20B6C004B1E6D /* Products */;
+ ProjectRef = 61A19B6114D20B6C004B1E6D /* SDL_image.xcodeproj */;
+ },
+ {
+ ProductGroup = 61A19C1F14D20F51004B1E6D /* Products */;
+ ProjectRef = 61A19C1E14D20F51004B1E6D /* SDL_mixer.xcodeproj */;
+ },
+ {
+ ProductGroup = 61A19BF514D20D83004B1E6D /* Products */;
+ ProjectRef = 61A19BF414D20D83004B1E6D /* SDL_net.xcodeproj */;
+ },
+ {
+ ProductGroup = 61A19BC214D20CDA004B1E6D /* Products */;
+ ProjectRef = 61A19BC114D20CDA004B1E6D /* SDL_ttf.xcodeproj */;
+ },
+ {
+ ProductGroup = 619598191364BCD200B429B6 /* Products */;
+ ProjectRef = 619598181364BCD200B429B6 /* Tremor.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ 1D6058900D05DD3D006BFB54 /* Hedgewars */,
+ 928301160F10CAFC00CC5A3C /* fpc */,
+ 6179928B114AE0C800BA94A9 /* UpdateDataFolder */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ 6162456714E6159C00CC97FB /* libFreetype.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libFreetype.a;
+ remoteRef = 6162456614E6159C00CC97FB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 617D78E016D932310091D4D6 /* libPhysfs.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libPhysfs.a;
+ remoteRef = 617D78DF16D932310091D4D6 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 617D794816D933B00091D4D6 /* libPhyslayer.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libPhyslayer.a;
+ remoteRef = 617D794716D933B00091D4D6 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 6195981D1364BCD200B429B6 /* libTremor.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libTremor.a;
+ remoteRef = 6195981C1364BCD200B429B6 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 619599441364C82B00B429B6 /* libLua.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libLua.a;
+ remoteRef = 619599431364C82B00B429B6 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19AEA14D2010A004B1E6D /* libSDL2.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libSDL2.a;
+ remoteRef = 61A19AE914D2010A004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19AEC14D2010A004B1E6D /* testsdl.app */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.application;
+ path = testsdl.app;
+ remoteRef = 61A19AEB14D2010A004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19B6614D20B6C004B1E6D /* libSDL2_image.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libSDL2_image.a;
+ remoteRef = 61A19B6514D20B6C004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19BC614D20CDA004B1E6D /* libSDL2_ttf.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libSDL2_ttf.a;
+ remoteRef = 61A19BC514D20CDA004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19BF914D20D83004B1E6D /* libSDL2_net.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libSDL2_net.a;
+ remoteRef = 61A19BF814D20D83004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 61A19C2314D20F51004B1E6D /* libSDL2_mixer.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libSDL2_mixer.a;
+ remoteRef = 61A19C2214D20F51004B1E6D /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 1D60588D0D05DD3D006BFB54 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 61536DF411CEAE7100D87A7E /* GameConfigViewController-iPhone.xib in Resources */,
+ 61370653117B1D50004EE44A /* Entitlements-Distribution.plist in Resources */,
+ 611E12FF117BBBDA0044B62F /* Entitlements-Development.plist in Resources */,
+ 6165925311CA9CB400D6E256 /* MainMenuViewController-iPad.xib in Resources */,
+ 6165925511CA9CB400D6E256 /* MapConfigViewController-iPad.xib in Resources */,
+ 61F9040911DF58B00068B24D /* settingsButton.png in Resources */,
+ 61F9040B11DF59370068B24D /* background.png in Resources */,
+ 61EBA62A11DFF2BC0048B68A /* title~iphone.png in Resources */,
+ 61F7A43811E290650040BA66 /* Icon-72.png in Resources */,
+ 61F7A43911E290650040BA66 /* Icon-Small-50.png in Resources */,
+ 61F7A43A11E290650040BA66 /* Icon-Small.png in Resources */,
+ 61F7A43C11E290650040BA66 /* Icon.png in Resources */,
+ 61F7A43E11E290650040BA66 /* iTunesArtwork.png in Resources */,
+ 6129B9F711EFB04D0017E305 /* denied.png in Resources */,
+ 61F2E7CF1205EDE0005734F7 /* AboutViewController.xib in Resources */,
+ 61F2E7EC12060E31005734F7 /* checkbox.png in Resources */,
+ 615AD96212073B4D00F2FF04 /* startGameButton.png in Resources */,
+ 615AD9E9120764CA00F2FF04 /* backButton.png in Resources */,
+ 615AD9EB1207654E00F2FF04 /* helpButton.png in Resources */,
+ 611EE974122A9C4100DF6938 /* clickSound.caf in Resources */,
+ 611EE9DA122AA10A00DF6938 /* selSound.caf in Resources */,
+ 6199E86D12464A8E00DADF8C /* surprise.png in Resources */,
+ 611D9BFC12497E9800008271 /* SavedGamesViewController.xib in Resources */,
+ 6147DAD31253DCDE0010357E /* savesButton.png in Resources */,
+ 610D5FB21270E2660033333A /* Icon-Small at 2x.png in Resources */,
+ 610D5FB31270E26C0033333A /* Icon at 2x.png in Resources */,
+ 61A670C012747D9B00B06CE7 /* Default.png in Resources */,
+ 61A670C112747DB900B06CE7 /* MainMenuViewController-iPhone.xib in Resources */,
+ 61A670C212747DBD00B06CE7 /* MapConfigViewController-iPhone.xib in Resources */,
+ 61E2F7441283752C00E12521 /* fb.png in Resources */,
+ 61E2F7451283752C00E12521 /* tw.png in Resources */,
+ 61808A5D128C930A005D0E2F /* backSound.caf in Resources */,
+ 61D3D2A51290E03A003CE7C3 /* irc.png in Resources */,
+ 6172FED91298CF9800D73365 /* background~iphone.png in Resources */,
+ 6172FEEF1298D25D00D73365 /* mediumBackground~ipad.png in Resources */,
+ 6172FEF11298D25D00D73365 /* smallerBackground~ipad.png in Resources */,
+ 6172FEF21298D25D00D73365 /* smallerBackground~iphone.png in Resources */,
+ 61889985129995B500D55FD6 /* title~ipad.png in Resources */,
+ 615FEAE212A2A6640098EE92 /* localplayButton~ipad.png in Resources */,
+ 615FEAE312A2A6640098EE92 /* localplayButton~iphone.png in Resources */,
+ 61188BF712A6FE5A0026C5DA /* backButton at 2x.png in Resources */,
+ 61188BF812A6FE5C0026C5DA /* background at 2x~iphone.png in Resources */,
+ 61188BF912A6FE5D0026C5DA /* checkbox at 2x.png in Resources */,
+ 61188BFB12A6FE610026C5DA /* Default-ipad-Landscape.png in Resources */,
+ 61188BFC12A6FE630026C5DA /* Default at 2x.png in Resources */,
+ 61188BFD12A6FE730026C5DA /* fb at 2x.png in Resources */,
+ 61188BFE12A6FE7C0026C5DA /* irc at 2x.png in Resources */,
+ 61188C0212A6FE840026C5DA /* localplayButton at 2x~iphone.png in Resources */,
+ 61188C0312A6FE860026C5DA /* netplayButton.png in Resources */,
+ 61188C0412A6FE880026C5DA /* savesButton at 2x.png in Resources */,
+ 61188C0512A6FE8F0026C5DA /* Data in Resources */,
+ 61188C0612A6FE950026C5DA /* smallerBackground at 2x~iphone.png in Resources */,
+ 61188C0712A6FE960026C5DA /* settingsButton at 2x.png in Resources */,
+ 61188C0812A6FE9A0026C5DA /* title at 2x~iphone.png in Resources */,
+ 61188C0912A6FE9C0026C5DA /* tw at 2x.png in Resources */,
+ 6174F7C812CD62E300205D6F /* smallerTitle.png in Resources */,
+ 6174F7C912CD62E300205D6F /* smallerTitle at 2x.png in Resources */,
+ 6167A6771391514600AA6D07 /* RestoreViewController-iPhone.xib in Resources */,
+ 6167A72D13919E6800AA6D07 /* RestoreViewController-iPad.xib in Resources */,
+ 6167C87414294727003DD50F /* surprise at 2x.png in Resources */,
+ 6167C88C14294738003DD50F /* denied at 2x.png in Resources */,
+ 6167C8F51429502C003DD50F /* hedgehog.png in Resources */,
+ 6167C8F61429502C003DD50F /* hedgehog at 2x.png in Resources */,
+ 6167C8F71429502C003DD50F /* robotBadge.png in Resources */,
+ 6167C8F81429502C003DD50F /* robotBadge at 2x.png in Resources */,
+ 6167C8F91429502C003DD50F /* star.png in Resources */,
+ 6167C8FA1429502C003DD50F /* star at 2x.png in Resources */,
+ 6167CA37142A6ED7003DD50F /* bot0.png in Resources */,
+ 6167CA38142A6ED7003DD50F /* bot0 at 2x.png in Resources */,
+ 6167CA39142A6ED7003DD50F /* bot1.png in Resources */,
+ 6167CA3A142A6ED7003DD50F /* bot1 at 2x.png in Resources */,
+ 6167CA3B142A6ED7003DD50F /* bot2.png in Resources */,
+ 6167CA3C142A6ED7003DD50F /* bot2 at 2x.png in Resources */,
+ 6167CA3D142A6ED7003DD50F /* bot3.png in Resources */,
+ 6167CA3E142A6ED7003DD50F /* bot3 at 2x.png in Resources */,
+ 6167CA3F142A6ED7003DD50F /* bot4.png in Resources */,
+ 6167CA40142A6ED7003DD50F /* bot4 at 2x.png in Resources */,
+ 6167CA41142A6ED7003DD50F /* bot5.png in Resources */,
+ 6167CA42142A6ED7003DD50F /* bot5 at 2x.png in Resources */,
+ 6167CB48142A8769003DD50F /* basehat-hedgehog.png in Resources */,
+ 6167CB49142A8769003DD50F /* basehat-hedgehog at 2x.png in Resources */,
+ 61915D5C143A4E2C00299991 /* MissionTrainingViewController-iPhone.xib in Resources */,
+ 61077E87143FB09800645B29 /* MissionTrainingViewController-iPad.xib in Resources */,
+ 6107802A143FCCC800645B29 /* startGameButton at 2x.png in Resources */,
+ 610782961440EE5C00645B29 /* basicFlags.plist in Resources */,
+ 610782971440EE5C00645B29 /* credits.plist in Resources */,
+ 610782981440EE5C00645B29 /* gameMods.plist in Resources */,
+ 61B9A86814423A9D001541C1 /* GameConfigViewController-iPad.xib in Resources */,
+ 61156521147F48B6006729A9 /* About.strings in Resources */,
+ 61156523147F48B7006729A9 /* Localizable.strings in Resources */,
+ 61156525147F48B8006729A9 /* Scheme.strings in Resources */,
+ 616065A8159A71FD00CFAEF4 /* hwclassic.mp3 in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 6137A859164732120043D108 /* Update Revision Information */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Update Revision Information";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "HEDGEWARS_REVISION=`/usr/local/bin/hg identify -n ${SOURCE_DIR}|sed -e 's/\\+//'`\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $HEDGEWARS_REVISION\" \"${TARGET_BUILD_DIR}\"/\"${INFOPLIST_PATH}\"";
+ };
+ 6179928A114AE0C800BA94A9 /* data */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = data;
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "SOURCE_DIR=${PROJECT_DIR}/../../\n\n#copy new stuff over old stuff\nrm -rf ${PROJECT_DIR}/Data\n\necho \"Copying Data...\"\ncp -R ${SOURCE_DIR}/share/hedgewars/Data ${PROJECT_DIR}/Data\n\n#copy some other files\necho \"Fetching additional graphics...\"\nmkdir -p ${PROJECT_DIR}/Data/Graphics/Icons\ncp ${SOURCE_DIR}/QTfrontend/res/{btn*,icon*,StatsMedal*,ammopic*}.png ${PROJECT_DIR}/Data/Graphics/Icons/\ncp -R ${SOURCE_DIR}/project_files/Android-build/SDL-android-project/assets/Data/Graphics/Buttons ${PROJECT_DIR}/Data/Graphics/\n\necho \"Removing text and dummy files...\"\n#delete all CMakeLists.txt and image source files\nfind ${PROJECT_DIR}/Data -name CMakeLists.txt -delete\nfind ${PROJECT_DIR}/Data -name *.svg* -delete\nfind ${PROJECT_DIR}/Data -name *.psd -delete\nfind ${PROJECT_DIR}/Data -name *.sifz -delete\nfind ${PROJECT_DIR}/Data -name *.xcf -delete\nfind ${PROJECT_DIR}/Data -name *.orig -delete\nfind ${PROJECT_DIR}/Data -name *.ts -delete\n\n#delete dummy maps and hats, misc stuff\nrm -rf ${PROJECT_DIR}/Data/Maps/test*\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/{TeamCap,TeamHeadband,TeamHair}\nrm -rf ${PROJECT_DIR}/Data/misc/\n\n#delete forbidden maps and WIP themes (remember to check that no Map uses them)\nrm -rf ${PROJECT_DIR}/Data/Maps/{Cheese,FlightJoust}\nrm -rf ${PROJECT_DIR}/Data/Themes/{Beach,Digital}\n\n#delete all names, reserved hats and unused fonts\nrm -rf ${PROJECT_DIR}/Data/Names/\nrm -rf ${PROJECT_DIR}/Data/Graphics/Hats/Reserved/\nrm -rf ${PROJECT_DIR}/Data/Fonts/{wqy-zenhei.ttc,DroidSansFallback.ttf}\n\necho \"Handling audio files...\"\n#copy mono audio\ncp -R ${SOURCE_DIR}/project_files/AudioMono/* ${PROJECT_DIR}/Data/\n#delete the Classic voice\nrm -rf ${PROJECT_DIR}/Data/Sounds/voices/Classic\n#delete the main theme file\nrm -rf ${PROJECT_DIR}/Data/Music/main_theme.ogg\n\n#remove unused voices\nfor i in {Amazing,Brilliant,Bugger,Bungee,Cutitout,Drat,Excellent,Fire,FlawlessPossibility,Gonnagetyou,Grenade,Hmm,Justyouwait,Leavemealone,Ohdear,Ouch,Perfect,Revenge,Runaway,Solong,Thisoneismine,VictoryPossibility,Watchthis,Whatthe,Whoopsee}; do find Data/Sounds/voices/ -name $i.ogg -delete; done\n\necho \"Tweaking Data contents...\"\n#move Lua maps in Missions\nmkdir ${PROJECT_DIR}/Data/Missions/Maps/\nfor i in `ls ${PROJECT_DIR}/Data/Maps/`;\ndo \n if [[ `ls -f ${PROJECT_DIR}/Data/Maps/$i/map.lua 2> /dev/null` != '' ]];\n then\n mv ${PROJECT_DIR}/Data/Maps/$i ${PROJECT_DIR}/Data/Missions/Maps/;\n fi;\ndone;\n\n#workaround for missing map in CTF_Blizzard\nln -s ../../../Maps/Blizzard/map.png ${PROJECT_DIR}/Data/Missions/Maps/CTF_Blizzard/map.png\n\n#reduce the number of flakes for City\nsed -i -e 's/1500/50/' ${PROJECT_DIR}/Data/Themes/City/theme.cfg\n\necho \"Done\"";
+ };
+ 61806B78170B83EA00C601BC /* config.inc */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = config.inc;
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/myfile",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "HG=/usr/local/bin/hg\nSOURCE_DIR=${PROJECT_DIR}/../../\n\n#create config.inc\necho \"Updating config file...\"\nPRON=`grep HEDGEWARS_PROTO_VER ${SOURCE_DIR}/CMakeLists.txt | grep -o -E [0-9]+`\nMAJN=`grep CPACK_PACKAGE_VERSION_MAJOR ${SOURCE_DIR}/CMakeLists.txt | grep -o -E \"[0-9]+\"`\nMINN=`grep CPACK_PACKAGE_VERSION_MINOR ${SOURCE_DIR}/CMakeLists.txt | grep -o -E \"[0-9]+\"`\nPATN=`grep CPACK_PACKAGE_VERSION_PATCH ${SOURCE_DIR}/CMakeLists.txt | grep -o -E \"[0-9]+\"`\nREVN=`$HG id -n ${SOURCE_DIR}`\nHASH=`$HG id -i ${SOURCE_DIR}`\n\necho \"{Do not change this file, use the project target to regenerate}\" > ${PROJECT_DIR}/config.inc\necho \"const cNetProtoVersion = $PRON;\" >> ${PROJECT_DIR}/config.inc\necho \"const cVersionString = '$MAJN.$MINN.$PATN';\" >> ${PROJECT_DIR}/config.inc\necho \"const cRevisionString = '$REVN';\" >> ${PROJECT_DIR}/config.inc\necho \"const cHashString = '$HASH';\" >> ${PROJECT_DIR}/config.inc\necho \"const cLuaLibrary = '';\" >> ${PROJECT_DIR}/config.inc";
+ };
+ 9283011B0F10CB2D00CC5A3C /* Build libfpc.a */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ comments = "The current FPC runtime is distributed as (a massive) collection of .o files. This run script combines the .o files into an archive, making linking (a lot) easier since we don't have to think about what to link with (i.e the linker will extract what's needed from the archive).";
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Build libfpc.a";
+ outputPaths = (
+ "$(TARGET_BUILD_DIR)/libfpc.a",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Build libfpc.a\n# 9 July 2006 (Jonas Maebe)\n# * original version\n# 15 September 2006 (Erling Johansen)\n# * simplified\n# 26 April 2007 (Jonas Maebe)\n# * added support for ppc64/x86_64 (future proofing)\n# 4 August 2007 (Jonas Maebe)\n# * call ranlib after ar so the toc of the library is up-to-date\n# 3 January 2009 (Jonas Maebe)\n# * support for ARM\n# 24 October 2009 (Jonas Maebe)\n# * don't hardcode version 2.3.1 anymore under certain circumstances\n# * use the FPC_RTL_UNITS_BASE setting\n# 13 December 2009 (Jonas Maebe)\n# * use new FPC_COMPILER_BINARY_DIR setting to make it easier to change the used FPC version\n\nrm -f \"$TARGET_TEMP_DIR\"/*.a\nnarch=\n\ntemparchs=`echo $ARCHS|sed -e 's/arm[^\\w]*/arm\\\n/'|sort -u`\nfor arch in $temparchs\ndo\n\ttargetos=darwin;\n\tcase $arch in\n\t\tppc) fpc_arch=ppc; fpc_rtl=powerpc ;;\n\t\ti386) fpc_arch=386; fpc_rtl=i386; targetos=iphonesim ;;\n\t\tppc64) fpc_arch=ppc64; fpc_rtl=powerpc64 ;;\n\t\tx86_64) fpc_arch=x64; fpc_rtl=x86_64 ;;\n\t\tarm*) fpc_arch=arm; fpc_rtl=arm ;;\n\t\t*) continue\n\tesac\n\tif test -e \"${FPC_COMPILER_BINARY_DIR}\"/ppc${fpc_arch}\n\tthen\n\t\tupath=\"$FPC_RTL_UNITS_BASE\"/`\"${FPC_COMPILER_BINARY_DIR}\"/ppc${fpc_arch} -iV`/units/${fpc_rtl}-${targetos}\n\t\tar -q \"$TARGET_TEMP_DIR\"/libfpc${narch}.a `ls \"$upath\"/*/*.o | grep -v 'darwin/fv/'`\n\t\tranlib \"$TARGET_TEMP_DIR\"/libfpc${narch}.a\n\t\tnarch=${narch}x\n\telse\n\t\techo error: can\\'t build libfpc.a for $arch \\(${FPC_COMPILER_BINARY_DIR}/ppc${fpc_arch} not found, derived from FPC_COMPILER_BINARY_DIR project setting\\)\n\tfi\ndone\n\nif test ${#narch} -gt 1\nthen\n\tlipo -create \"$TARGET_TEMP_DIR\"/libfpc*.a -output \"$TARGET_BUILD_DIR\"/libfpc.a\n\trm -f \"$TARGET_TEMP_DIR\"/*.a\nelse\n\tmv \"$TARGET_TEMP_DIR\"/libfpc.a \"$TARGET_BUILD_DIR\"\nfi\n";
+ };
+ 928301560F10E04C00CC5A3C /* Compile Pascal Sources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ comments = "This run script compiles (all) pascal sources into assembler by calling FPC with the main program (only) as argument. FPC will in turn compile dependent units as necessary. The Compile Sources build phase will detect the outdated .o files and assemble the modified sources (because the Pascal source files rule states that output from pascal compilation is assembler files in derived source folders). ";
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Compile Pascal Sources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Compile Pascal Sources\n# 15sep06,ejo written.\n# 26 April 2007 - Jonas Maebe\n# * support for ppc64 and x86_64\n# * don't run when cleaning (in case running scripts when cleaning is ever fixed by Apple)\n# * split the options in FPC_COMMON_FLAGS (common to all configurations) and FPC_CFG_SPECIFIC_FLAGS (per configuration)\n# 4 January 2009 - Jonas Maebe\n# * support for ARM\n# 24 October 2009 - Jonas Maebe\n# * don't hardcode 2.3.1 in some cases anymore\n# 13 December 2009 (Jonas Maebe)\n# * use new FPC_COMPILER_BINARY_DIR setting to make it easier to change the used FPC version\n\nif [ x\"$ACTION\" != \"xbuild\" ]; then\n # in case running scripts during cleaning gets fixed\n exit 0\nfi\n\nif test ! -e \"$FPC_MAIN_FILE\"\nthen\n\techo error: FPC_MAIN_FILE not found \\($FPC_MAIN_FILE\\)\n\texit 2\nfi\n\nfor variant in $BUILD_VARIANTS\ndo\n\tfor arch in $ARCHS\n\tdo\n\t\ttargetos=darwin;\n\t\tcase $arch in\n\t\t\tppc) fpc_arch=ppc; fpc_rtl=powerpc ;;\n\t\t\ti386) fpc_arch=386; fpc_rtl=i386; targetos=iphonesim ;;\n\t\t\tppc64) fpc_arch=ppc64; fpc_rtl=powerpc64 ;;\n\t\t\tx86_64) fpc_arch=x64; fpc_rtl=x86_64 ;;\n\t\t\tarm*) fpc_arch=arm; fpc_rtl=arm ;;\n\t\t\t*) continue\n\t\tesac\n\n\t\tapp_target_temp_dir=$CONFIGURATION_TEMP_DIR/`basename \"$PROJECT_TEMP_DIR\"`\n\t\tout_dir=$app_target_temp_dir/`basename \"$DERIVED_SOURCES_DIR\"`-$variant/$arch\n\t\tfpccompiler=\"${FPC_COMPILER_BINARY_DIR}/ppc${fpc_arch}\"\n\t\tif test -e \"$fpccompiler\"\n\t\tthen\n\t\t\tfpcversion=`\"$fpccompiler\" -iV`\n\t\t\tmainunitdir=\"$FPC_RTL_UNITS_BASE/$fpcversion/units/${fpc_rtl}-${targetos}/\"\n\t\t\tmkdir -p \"$out_dir\"\n\t\t\tcd \"$out_dir\"\n\t\t\techo \"Compiling to $out_dir\"\n\t\t\trm -f compilefailed\n\t\n\t\t\t# delete any ppu files for which the \".s\" file was somehow deleted (Xcode does that sometimes in case of errors),\n\t\t\t# so that FPC will recompile the unit\n\t\t\tfor file in *.ppu\n\t\t\tdo\n\t\t\t\tasmname=`basename \"$file\" ppu`s\n\t\t\t\tif [ ! -f \"$asmname\" ]; then\n\t\t\t\t\t# can fail in case there are no .ppu files, since then it will try to erase the file with name '*.ppu'\n\t\t\t\t\t# -> use -f so it won't give an error message\n\t\t\t\t\trm -f \"$file\"\n\t\t\t\tfi\n\t\t\tdone\n\n\t\t\techo $fpccompiler -n -l -viwn -a -s -vbr -FE. $FPC_COMMON_OPTIONS $FPC_SPECIFIC_OPTIONS '\\' >ppccmd.sh\n\t\t\techo -Fi\\\"`dirname \"$FPC_MAIN_FILE\"`\\\" '\\' >>ppccmd.sh\n\t\t\techo -Fu\"$mainunitdir/*\" -Fu\"$mainunitdir/rtl\" '\\' >>ppccmd.sh\n\t\t\t# allow FPC_UNIT_PATHS to override default search directory\n\t\t\techo $FPC_UNIT_PATHS '\\' >>ppccmd.sh\n\t\t\techo \\\"$FPC_MAIN_FILE\\\" >>ppccmd.sh\n\t\t\t# cat ppccmd.sh\n\n\t\t\t/bin/sh ppccmd.sh\n\t\t\tif [ $? != 0 ]; then\n\t\t\t\ttouch \"$out_dir\"/compilefailed\n\t\t\t\texit 1\n\t\t\tfi\n\t\telse\n\t\t\ttouch \"$out_dir\"/compilefailed\n\t\t\techo $FPC_MAIN_FILE:1: error: 1: can\\'t compile for $arch \\(ppc${fpc_arch} not found\\)\n\t\t\texit 2\n\t\tfi\n\tdone\ndone\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 1D60588E0D05DD3D006BFB54 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 61798816114AA34C00BA94A9 /* hwengine.pas in Sources */,
+ 61798818114AA34C00BA94A9 /* hwLibrary.pas in Sources */,
+ 6179881C114AA34C00BA94A9 /* SDLh.pas in Sources */,
+ 6179881F114AA34C00BA94A9 /* uAI.pas in Sources */,
+ 61798820114AA34C00BA94A9 /* uAIActions.pas in Sources */,
+ 61798821114AA34C00BA94A9 /* uAIAmmoTests.pas in Sources */,
+ 61798822114AA34C00BA94A9 /* uAIMisc.pas in Sources */,
+ 61798823114AA34C00BA94A9 /* uAmmos.pas in Sources */,
+ 61798824114AA34C00BA94A9 /* uChat.pas in Sources */,
+ 61798825114AA34C00BA94A9 /* uCollisions.pas in Sources */,
+ 61798826114AA34C00BA94A9 /* uConsole.pas in Sources */,
+ 61798827114AA34C00BA94A9 /* uConsts.pas in Sources */,
+ 61798828114AA34C00BA94A9 /* uFloat.pas in Sources */,
+ 61798829114AA34C00BA94A9 /* uGame.pas in Sources */,
+ 6179882A114AA34C00BA94A9 /* uGears.pas in Sources */,
+ 6179882B114AA34C00BA94A9 /* uIO.pas in Sources */,
+ 6179882D114AA34C00BA94A9 /* uLand.pas in Sources */,
+ 6179882E114AA34C00BA94A9 /* uLandGraphics.pas in Sources */,
+ 6179882F114AA34C00BA94A9 /* uLandObjects.pas in Sources */,
+ 61798830114AA34C00BA94A9 /* uLandTemplates.pas in Sources */,
+ 61798831114AA34C00BA94A9 /* uLandTexture.pas in Sources */,
+ 61798832114AA34C00BA94A9 /* uLocale.pas in Sources */,
+ 61798833114AA34C00BA94A9 /* uMisc.pas in Sources */,
+ 61798834114AA34C00BA94A9 /* uRandom.pas in Sources */,
+ 61798837114AA34C00BA94A9 /* uSound.pas in Sources */,
+ 61798838114AA34C00BA94A9 /* uStats.pas in Sources */,
+ 61798839114AA34C00BA94A9 /* uStore.pas in Sources */,
+ 6179883A114AA34C00BA94A9 /* uTeams.pas in Sources */,
+ 6179883C114AA34C00BA94A9 /* uVisualGears.pas in Sources */,
+ 6179883D114AA34C00BA94A9 /* uWorld.pas in Sources */,
+ 611F4D4B11B27A9900F9759A /* uScript.pas in Sources */,
+ 6165920D11CA9BA200D6E256 /* FlagsViewController.m in Sources */,
+ 6165920E11CA9BA200D6E256 /* FortsViewController.m in Sources */,
+ 6165920F11CA9BA200D6E256 /* GameConfigViewController.m in Sources */,
+ 6165921011CA9BA200D6E256 /* EngineProtocolNetwork.m in Sources */,
+ 6165921111CA9BA200D6E256 /* GeneralSettingsViewController.m in Sources */,
+ 6165921211CA9BA200D6E256 /* GravesViewController.m in Sources */,
+ 6165921311CA9BA200D6E256 /* HogHatViewController.m in Sources */,
+ 6165921411CA9BA200D6E256 /* LevelViewController.m in Sources */,
+ 6165921511CA9BA200D6E256 /* MainMenuViewController.m in Sources */,
+ 6165921611CA9BA200D6E256 /* MapConfigViewController.m in Sources */,
+ 6165921711CA9BA200D6E256 /* SettingsBaseViewController.m in Sources */,
+ 6165921A11CA9BA200D6E256 /* SchemeSettingsViewController.m in Sources */,
+ 6165921B11CA9BA200D6E256 /* SchemeWeaponConfigViewController.m in Sources */,
+ 6165921C11CA9BA200D6E256 /* SingleSchemeViewController.m in Sources */,
+ 6165921D11CA9BA200D6E256 /* SingleTeamViewController.m in Sources */,
+ 6165921E11CA9BA200D6E256 /* SettingsContainerViewController.m in Sources */,
+ 6165921F11CA9BA200D6E256 /* TeamConfigViewController.m in Sources */,
+ 6165922011CA9BA200D6E256 /* TeamSettingsViewController.m in Sources */,
+ 6165922111CA9BA200D6E256 /* VoicesViewController.m in Sources */,
+ 6165922211CA9BA200D6E256 /* WeaponSettingsViewController.m in Sources */,
+ 6165922E11CA9BD500D6E256 /* CGPointUtils.c in Sources */,
+ 6165922F11CA9BD500D6E256 /* HWUtils.m in Sources */,
+ 6165923111CA9BD500D6E256 /* SquareButtonView.m in Sources */,
+ 6165923211CA9BD500D6E256 /* UIImageExtra.m in Sources */,
+ 6165929E11CA9E2F00D6E256 /* HedgewarsAppDelegate.m in Sources */,
+ 6163EE7E11CC2600001C0453 /* SingleWeaponViewController.m in Sources */,
+ 61E1F4F811D004240016A5AA /* adler32.pas in Sources */,
+ 61F904D711DF7DA30068B24D /* WeaponCellView.m in Sources */,
+ 61C079E411F35A300072BF46 /* EditableCellView.m in Sources */,
+ 61F2E7CE1205EDE0005734F7 /* AboutViewController.m in Sources */,
+ 6199E839124647DE00DADF8C /* SupportViewController.m in Sources */,
+ 611D9BFB12497E9800008271 /* SavedGamesViewController.m in Sources */,
+ 619C5AF4124F7E3100D041AE /* LuaPas.pas in Sources */,
+ 619C5BA2124FA59000D041AE /* MapPreviewButtonView.m in Sources */,
+ 61D205A1127CDD1100ABD83E /* ObjcExports.m in Sources */,
+ 61006F95128DE31F00EBA7F7 /* CreationChamber.m in Sources */,
+ 61A4A39412A5CCC2004D81E6 /* uCommandHandlers.pas in Sources */,
+ 61A4A39512A5CCC2004D81E6 /* uCommands.pas in Sources */,
+ 61A4A39612A5CCC2004D81E6 /* uDebug.pas in Sources */,
+ 61A4A39712A5CCC2004D81E6 /* uGearsRender.pas in Sources */,
+ 61A4A39812A5CCC2004D81E6 /* uRender.pas in Sources */,
+ 61A4A39912A5CCC2004D81E6 /* uRenderUtils.pas in Sources */,
+ 61A4A39A12A5CCC2004D81E6 /* uSinTable.pas in Sources */,
+ 61A4A39B12A5CCC2004D81E6 /* uTextures.pas in Sources */,
+ 61A4A39C12A5CCC2004D81E6 /* uTypes.pas in Sources */,
+ 61A4A39D12A5CCC2004D81E6 /* uUtils.pas in Sources */,
+ 61A4A39E12A5CCC2004D81E6 /* uVariables.pas in Sources */,
+ 61A4A3A212A5CD56004D81E6 /* uCaptions.pas in Sources */,
+ 61E5D68D12AB006F00566F29 /* uLandPainted.pas in Sources */,
+ 61F544C712AF1748007FD913 /* HoldTableViewCell.m in Sources */,
+ 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */,
+ 61E2E12E12BAAEE30051B659 /* ServerProtocolNetwork.m in Sources */,
+ 61B7A33812CC21080086B604 /* StatsPageViewController.m in Sources */,
+ 61EDB5B0135B3F97009B29A6 /* GameInterfaceBridge.m in Sources */,
+ 61A976B3136F668500DD9878 /* uCursor.pas in Sources */,
+ 6167A6761391514600AA6D07 /* RestoreViewController.m in Sources */,
+ 61C28D3F142D380400DA16C2 /* AudioManagerController.m in Sources */,
+ 611D7A50142FDCD3006E0798 /* uTouch.pas in Sources */,
+ 61915D5B143A4E2C00299991 /* MissionTrainingViewController.m in Sources */,
+ 61D0BDF91457508C0011A899 /* ExtraCategories.m in Sources */,
+ 61177C02148B8BB100686905 /* uLandGenMaze.pas in Sources */,
+ 61177C03148B8BB100686905 /* uLandOutline.pas in Sources */,
+ 61D08D7414AEA7FE0007C078 /* uGearsHedgehog.pas in Sources */,
+ 61D08D7514AEA7FE0007C078 /* uGearsList.pas in Sources */,
+ 61D08D7614AEA7FE0007C078 /* uGearsUtils.pas in Sources */,
+ 610C8E3714E018D200CF5C4C /* MNEValueTrackingSlider.m in Sources */,
+ 615E755A14E41E8C00FBA131 /* MXAudioPlayerFadeOperation.m in Sources */,
+ 615E76BC14E4421200FBA131 /* MGSplitCornersView.m in Sources */,
+ 615E76BD14E4421200FBA131 /* MGSplitDividerView.m in Sources */,
+ 615E76BE14E4421200FBA131 /* MGSplitViewController.m in Sources */,
+ 615BE3D4155C5DDF003CA34D /* uInputHandler.pas in Sources */,
+ 619349C8160BAF3E00A08518 /* uAILandMarks.pas in Sources */,
+ 619349C9160BAF3E00A08518 /* uGearsHandlers.pas in Sources */,
+ 619349CA160BAF3E00A08518 /* uGearsHandlersRope.pas in Sources */,
+ 610FB7C81661390E002FB2A7 /* uPhysFSLayer.pas in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 610FB7E216613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libFreetype;
+ targetProxy = 610FB7E116613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7E416613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "Static Library";
+ targetProxy = 610FB7E316613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7E616613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libLua;
+ targetProxy = 610FB7E516613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7E816613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libSDL;
+ targetProxy = 610FB7E716613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7EA16613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "Static Library";
+ targetProxy = 610FB7E916613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7EC16613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "Static Library";
+ targetProxy = 610FB7EB16613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7EE16613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libTremor;
+ targetProxy = 610FB7ED16613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 610FB7F016613980002FB2A7 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = libSDL_image;
+ targetProxy = 610FB7EF16613980002FB2A7 /* PBXContainerItemProxy */;
+ };
+ 617D791D16D932EC0091D4D6 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = Physfs;
+ targetProxy = 617D791C16D932EC0091D4D6 /* PBXContainerItemProxy */;
+ };
+ 617D794A16D933BC0091D4D6 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = Physlayer;
+ targetProxy = 617D794916D933BC0091D4D6 /* PBXContainerItemProxy */;
+ };
+ 9283015A0F10E41300CC5A3C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 928301160F10CAFC00CC5A3C /* fpc */;
+ targetProxy = 928301590F10E41300CC5A3C /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 61156520147F48B6006729A9 /* About.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6115651A147F48AE006729A9 /* English */,
+ 61156526147F49E1006729A9 /* Spanish */,
+ 6115652D147F4C52006729A9 /* French */,
+ 61156530147F4D10006729A9 /* Polish */,
+ 61177BAA148A661600686905 /* German */,
+ 61177BAC148A671600686905 /* Turkish */,
+ 61177BE4148B881C00686905 /* Danish */,
+ 617BC22D1490210E00E1C294 /* Italian */,
+ 619BCEC41495615700C1C409 /* Bulgarian */,
+ 61D08D8714AEA9670007C078 /* Japanese */,
+ 61C6783F14B3DD020087425A /* Portuguese */,
+ 6154A53114C37E4A00F6EEF6 /* Romanian */,
+ );
+ name = About.strings;
+ sourceTree = "<group>";
+ };
+ 61156522147F48B7006729A9 /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6115651B147F48AE006729A9 /* English */,
+ 61156527147F4A2E006729A9 /* Spanish */,
+ 6115652C147F4C4C006729A9 /* French */,
+ 61156531147F4D17006729A9 /* Polish */,
+ 61177BA7148A658900686905 /* German */,
+ 61177BAD148A672000686905 /* Turkish */,
+ 61177BF0148B882500686905 /* Danish */,
+ 617BC2391490211500E1C294 /* Italian */,
+ 619BCED01495615F00C1C409 /* Bulgarian */,
+ 61D08D8814AEA9700007C078 /* Japanese */,
+ 61C6784B14B3DD0B0087425A /* Portuguese */,
+ 6154A53E14C37E5400F6EEF6 /* Romanian */,
+ );
+ name = Localizable.strings;
+ sourceTree = "<group>";
+ };
+ 61156524147F48B8006729A9 /* Scheme.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 6115651C147F48AE006729A9 /* English */,
+ 61156528147F4A3C006729A9 /* Spanish */,
+ 6115652B147F4C45006729A9 /* French */,
+ 61156532147F4D1E006729A9 /* Polish */,
+ 61177BA9148A660C00686905 /* German */,
+ 61177BAE148A672C00686905 /* Turkish */,
+ 61177BF1148B882F00686905 /* Danish */,
+ 617BC23A1490211F00E1C294 /* Italian */,
+ 619BCED11495616700C1C409 /* Bulgarian */,
+ 61D08D8914AEA9780007C078 /* Japanese */,
+ 61C6784C14B3DD140087425A /* Portuguese */,
+ 6154A54014C37EB100F6EEF6 /* Romanian */,
+ );
+ name = Scheme.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1D6058940D05DD3E006BFB54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_GENERATE_TEST_COVERAGE_FILES = YES;
+ GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Hedgewars_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Hedgewars;
+ };
+ name = Debug;
+ };
+ 1D6058950D05DD3E006BFB54 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Hedgewars_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Hedgewars;
+ };
+ name = Release;
+ };
+ 61022D7C12305A2800B08935 /* Distro AppStore */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ APPLY_RULES_IN_COPY_FILES = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Distribution";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -Fi${PROJECT_DIR}";
+ FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.7.1;
+ FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc;
+ FPC_SPECIFIC_OPTIONS = "-Ci- -Cr- -Co- -Os -Xs -Cfvfpv3 -dNOCONSOLE";
+ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\"";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DEBUGGING_SYMBOLS = default;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_FAST_MATH = YES;
+ GCC_OPTIMIZATION_LEVEL = s;
+ GCC_PREPROCESSOR_DEFINITIONS = "";
+ GCC_STRICT_ALIASING = YES;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_VALUE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../../Library/SDL/include/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_net/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_mixer/\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ LLVM_LTO = NO;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_CODE_SIGN_FLAGS = "";
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-Wl,-no_order_inits",
+ );
+ PREBINDING = NO;
+ PROVISIONING_PROFILE = "";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VALID_ARCHS = "armv7 armv6";
+ WARNING_CFLAGS = (
+ "-Wall",
+ "-Wbad-function-cast",
+ "-Wmissing-declarations",
+ "-Wnested-externs",
+ );
+ };
+ name = "Distro AppStore";
+ };
+ 61022D7D12305A2800B08935 /* Distro AppStore */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Hedgewars_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Hedgewars;
+ };
+ name = "Distro AppStore";
+ };
+ 61022D7E12305A2800B08935 /* Distro AppStore */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpc;
+ ZERO_LINK = NO;
+ };
+ name = "Distro AppStore";
+ };
+ 61022D7F12305A2800B08935 /* Distro AppStore */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = UpdateDataFolder;
+ ZERO_LINK = NO;
+ };
+ name = "Distro AppStore";
+ };
+ 6137064B117B1CB3004EE44A /* Distro Adhoc */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ APPLY_RULES_IN_COPY_FILES = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_ENTITLEMENTS = "Entitlements-Distribution.plist";
+ CODE_SIGN_IDENTITY = "iPhone Distribution";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -Fi${PROJECT_DIR}";
+ FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.7.1;
+ FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc;
+ FPC_SPECIFIC_OPTIONS = "-dDEBUGFILE -O- -g -gl -gw2 -gt -ghttt -Xs- -Cfvfpv3";
+ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\"";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_DYNAMIC_NO_PIC = YES;
+ GCC_FAST_MATH = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
+ GCC_STRICT_ALIASING = YES;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_VALUE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../../Library/SDL/include/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_net/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_mixer/\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-Wl,-no_order_inits",
+ );
+ PREBINDING = NO;
+ PROVISIONING_PROFILE = "";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ VALID_ARCHS = "armv7 armv6";
+ WARNING_CFLAGS = (
+ "-Wall",
+ "-Wbad-function-cast",
+ "-Wmissing-declarations",
+ "-Wnested-externs",
+ );
+ };
+ name = "Distro Adhoc";
+ };
+ 6137064C117B1CB3004EE44A /* Distro Adhoc */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = Hedgewars_Prefix.pch;
+ INFOPLIST_FILE = Info.plist;
+ PRODUCT_NAME = Hedgewars;
+ };
+ name = "Distro Adhoc";
+ };
+ 6137064D117B1CB3004EE44A /* Distro Adhoc */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpc;
+ ZERO_LINK = NO;
+ };
+ name = "Distro Adhoc";
+ };
+ 6137064F117B1CB3004EE44A /* Distro Adhoc */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = UpdateDataFolder;
+ ZERO_LINK = NO;
+ };
+ name = "Distro Adhoc";
+ };
+ 6179928C114AE0C800BA94A9 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = UpdateDataFolder;
+ };
+ name = Debug;
+ };
+ 6179928D114AE0C800BA94A9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = UpdateDataFolder;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 928301180F10CAFD00CC5A3C /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpc;
+ };
+ name = Debug;
+ };
+ 928301190F10CAFD00CC5A3C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PREBINDING = NO;
+ PRODUCT_NAME = fpc;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ APPLY_RULES_IN_COPY_FILES = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -Fi${PROJECT_DIR}";
+ FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.6.0;
+ FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc;
+ FPC_SPECIFIC_OPTIONS = "-Tiphonesim -dDEBUGFILE -O- -g -gl -gw2 -gt -ghttt -Xs-";
+ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\"";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DEBUGGING_SYMBOLS = full;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_FAST_MATH = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
+ GCC_STRICT_ALIASING = YES;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_VALUE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../../Library/SDL/include/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_net/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_mixer/\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-Wl,-no_order_inits",
+ );
+ PREBINDING = NO;
+ PROVISIONING_PROFILE = "";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = NO;
+ VALID_ARCHS = "armv7 armv6";
+ WARNING_CFLAGS = (
+ "-Wall",
+ "-Wbad-function-cast",
+ "-Wmissing-declarations",
+ "-Wnested-externs",
+ );
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ APPLY_RULES_IN_COPY_FILES = YES;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CODE_SIGN_ENTITLEMENTS = "Entitlements-Development.plist";
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -Fi${PROJECT_DIR}";
+ FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.6.0;
+ FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas";
+ FPC_RTL_UNITS_BASE = /usr/local/lib/fpc;
+ FPC_SPECIFIC_OPTIONS = "-Ci- -Cr- -Co- -Os -Xs -Cfvfpv3 -dDEBUGFILE";
+ FPC_UNITS_PATH = "-Fu\"$(PROJECT_DIR)\"";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DEBUGGING_SYMBOLS = default;
+ GCC_DYNAMIC_NO_PIC = YES;
+ GCC_FAST_MATH = YES;
+ GCC_OPTIMIZATION_LEVEL = s;
+ GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
+ GCC_STRICT_ALIASING = YES;
+ GCC_THUMB_SUPPORT = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_MISSING_PARENTHESES = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_VALUE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/../../../Library/SDL/include/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_net/\"",
+ "\"$(SRCROOT)/../../../Library/SDL_mixer/\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
+ LLVM_LTO = NO;
+ ONLY_ACTIVE_ARCH = NO;
+ OTHER_LDFLAGS = (
+ "-lz",
+ "-Wl,-no_order_inits",
+ );
+ PREBINDING = NO;
+ PROVISIONING_PROFILE = "";
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = NO;
+ VALID_ARCHS = "armv7 armv6";
+ WARNING_CFLAGS = (
+ "-Wall",
+ "-Wbad-function-cast",
+ "-Wmissing-declarations",
+ "-Wnested-externs",
+ );
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Hedgewars" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D6058940D05DD3E006BFB54 /* Debug */,
+ 1D6058950D05DD3E006BFB54 /* Release */,
+ 6137064C117B1CB3004EE44A /* Distro Adhoc */,
+ 61022D7D12305A2800B08935 /* Distro AppStore */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 61799290114AE0CD00BA94A9 /* Build configuration list for PBXAggregateTarget "UpdateDataFolder" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 6179928C114AE0C800BA94A9 /* Debug */,
+ 6179928D114AE0C800BA94A9 /* Release */,
+ 6137064F117B1CB3004EE44A /* Distro Adhoc */,
+ 61022D7F12305A2800B08935 /* Distro AppStore */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 9283011C0F10CB4B00CC5A3C /* Build configuration list for PBXNativeTarget "fpc" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 928301180F10CAFD00CC5A3C /* Debug */,
+ 928301190F10CAFD00CC5A3C /* Release */,
+ 6137064D117B1CB3004EE44A /* Distro Adhoc */,
+ 61022D7E12305A2800B08935 /* Distro AppStore */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Hedgewars" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ 6137064B117B1CB3004EE44A /* Distro Adhoc */,
+ 61022D7C12305A2800B08935 /* Distro AppStore */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/project_files/HedgewarsMobile/Hedgewars_Prefix.pch b/project_files/HedgewarsMobile/Hedgewars_Prefix.pch
new file mode 100644
index 0000000..0ba9e21
--- /dev/null
+++ b/project_files/HedgewarsMobile/Hedgewars_Prefix.pch
@@ -0,0 +1,34 @@
+/*
+ * Hedgewars-iOS, a Hedgewars port for iOS devices
+ * Copyright (c) 2009-2010 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#import <CoreGraphics/CoreGraphics.h>
+#import <UIKit/UIKit.h>
+#import "HedgewarsAppDelegate.h"
+#import "AudioManagerController.h"
+#import "ExtraCategories.h"
+#import "UIImageExtra.h"
+#import "PascalImports.h"
+#import "DefinesAndMacros.h"
+#import "EditableCellView.h"
+#import "CreationChamber.h"
+#import "HWUtils.h"
+#endif
+
diff --git a/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/About.strings
new file mode 100644
index 0000000..a68b709
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Localizable.strings
new file mode 100644
index 0000000..786fb52
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Scheme.strings
new file mode 100644
index 0000000..3884656
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Bulgarian.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Danish.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Danish.lproj/About.strings
new file mode 100644
index 0000000..5857d8e
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Danish.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Danish.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Danish.lproj/Localizable.strings
new file mode 100644
index 0000000..2c930ac
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Danish.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Danish.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Danish.lproj/Scheme.strings
new file mode 100644
index 0000000..9116025
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Danish.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/English.lproj/About.strings b/project_files/HedgewarsMobile/Locale/English.lproj/About.strings
new file mode 100644
index 0000000..a412566
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/English.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/English.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/English.lproj/Localizable.strings
new file mode 100644
index 0000000..0ced5d2
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/English.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/English.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/English.lproj/Scheme.strings
new file mode 100644
index 0000000..97e14cf
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/English.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/French.lproj/About.strings b/project_files/HedgewarsMobile/Locale/French.lproj/About.strings
new file mode 100644
index 0000000..ef56b5f
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/French.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/French.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/French.lproj/Localizable.strings
new file mode 100644
index 0000000..68ec691
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/French.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/French.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/French.lproj/Scheme.strings
new file mode 100644
index 0000000..6476087
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/French.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/German.lproj/About.strings b/project_files/HedgewarsMobile/Locale/German.lproj/About.strings
new file mode 100644
index 0000000..ad7427e
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/German.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/German.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/German.lproj/Localizable.strings
new file mode 100644
index 0000000..cba76a9
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/German.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/German.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/German.lproj/Scheme.strings
new file mode 100644
index 0000000..0146203
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/German.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Italian.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Italian.lproj/About.strings
new file mode 100644
index 0000000..d93d929
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Italian.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Italian.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Italian.lproj/Localizable.strings
new file mode 100644
index 0000000..3823984
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Italian.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Italian.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Italian.lproj/Scheme.strings
new file mode 100644
index 0000000..b43a7b0
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Italian.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings
new file mode 100644
index 0000000..41a3341
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/About.strings
@@ -0,0 +1,44 @@
+/* code credit */
+"Engine, frontend, net server" = "ã¨ã³ã¸ã³ãããã³ãã¨ã³ããããããµã¼ãã¼";
+"Many desktop frontend improvements" = "å¤ãã®ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Many engine and desktop frontend improvements" = "å¤ãã®ã¨ã³ã¸ã³ã¨ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Drillrocket, Ballgun, RC Plane weapons" = "ããªã«ãã±ããããã¼ã«ã¬ã³ãã©ã¸ã³ã³æ¦å¨";
+"Mine number and time game settings" = "å°é·çªå·ã¨ã¿ã¤ã ã²ã¼ã è¨å®";
+"Desktop frontend improvements" = "ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Desktop frontend improvements" = "ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Mac OS X and iPhone version" = "Mac OS X 㨠iPhone ãã¼ã¸ã§ã³";
+"Many engine and desktop frontend improvements" = "å¤ãã®ã¨ã³ã¸ã³ã¨ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Gamepad and Lua integration" = "ã²ã¼ã ãããã¨Luaã®çµ±åå";
+"Many engine improvements and graphics" = "å¤ãã®ã¨ã³ã¸ã³æ¹åã¨ã°ã©ãã£ãã¯";
+"Maze maps" = "è¿·è·¯å°å³";
+"Engine and desktop frontend improvements" = "ã¨ã³ã¸ã³ã¨ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Lua game modes and missions" = "Lua ã²ã¼ã ã¢ã¼ãã¨ããã·ã§ã³";
+"Desktop frontend improvements" = "ãã¹ã¯ãããããã³ãã¨ã³ãã®æ¹å";
+"Android port" = "ã¢ã³ããã¤ããã¼ã";
+
+/* art credit */
+"Main graphics" = "ã¡ã¤ã³ã°ã©ãã£ãã¯";
+"Some hats" = "帽å";
+"Hedgehogs voice" = "ããªããºãã®å£°";
+
+/* translation credit */
+"Brazilian Portuguese" = "ãã«ãã¬ã«èªï¼ãã©ã¸ã«ï¼";
+"Bulgarian" = "ãã«ã¬ãªã¢èª";
+"Czech" = "ãã§ã³èª";
+"Chinese" = "ä¸å½èª";
+"English" = "è±èª";
+"Finnish" = "ãã£ã³ã©ã³ãèª";
+"French" = "ãã©ã³ã¹èª";
+"German" = "ãã¤ãèª";
+"Greek" = "ã®ãªã·ã£èª";
+"Italian" = "ã¤ã¿ãªã¢èª";
+"Japanese" = "æ¥æ¬èª";
+"Korean" = "éå½èª";
+"Lithuanian" = "ãªãã¢ãã¢èª";
+"Polish" = "ãã¼ã©ã³ãèª";
+"Portuguese" = "ãã«ãã¬ã«èª";
+"Russian" = "ãã·ã¢èª";
+"Slovak" = "ã¹ãããã¢èª";
+"Spanish" = "ã¹ãã¤ã³èª";
+"Swedish" = "ã¹ã¦ã§ã¼ãã³èª";
+"Ukrainian" = "ã¦ã¯ã©ã¤ãèª";
diff --git a/project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings
new file mode 100644
index 0000000..275c039
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Localizable.strings
@@ -0,0 +1,380 @@
+/* No comment provided by engineer. */
+"A monitor has been disconnected while playing and this has ended the match! You need to restart the game if you wish to use the second display again." = "ã¢ãã¿ã¼ã®æ¥ç¶ãåæãããããããçµäºãã¦ãã¾ãã¾ããï¼äºçªç®ã®ãã£ã¹ãã¬ã¼ãã¾ã使ç¨ãããå ´åã¯ã²ã¼ã ããªã¹ã¿ã¼ãããªããã°ããã¾ããã";
+
+/* from the scheme panel
+ from the team panel */
+"Add" = "追å ";
+
+/* No comment provided by engineer. */
+"Aggressive" = "ç©æ¥µç";
+
+/* No comment provided by engineer. */
+"All" = "å
¨ã¦";
+
+/* from the settings table */
+"Alternate Damage" = "代ããã®ãã¡ã¼ã¸";
+
+/* No comment provided by engineer. */
+"Are you reeeeeally sure?" = "æ¬å½ã«ããã§ãã?";
+
+/* from the settings table */
+"Audio Preferences" = "ãªã¼ãã£ãªè¨å®";
+
+/* No comment provided by engineer. */
+"Available Teams" = "å©ç¨å¯è½ãªãã¼ã ";
+
+/* No comment provided by engineer. */
+"Average" = "å¹³å";
+
+/* No comment provided by engineer. */
+"Backup" = "ããã¯ã¢ãã";
+
+/* No comment provided by engineer. */
+"Before playing the preview needs to be generated" = "ãã¬ã¼ããåã«ãã¬ãã¥ã¼ãçæããå¿
è¦ãããã¾ã";
+
+/* No comment provided by engineer. */
+"Before returning the preview needs to be generated" = "æ»ãåã«ãã¬ãã¥ã¼ãçæããå¿
è¦ãããã¾ã";
+
+/* No comment provided by engineer. */
+"Brutal" = "æ®å¿";
+
+/* No comment provided by engineer. */
+"Bully" = "ãããã£å";
+
+/* No comment provided by engineer. */
+"Cancel" = "ãã£ã³ã»ã«";
+
+/* No comment provided by engineer. */
+"Cavern" = "æ´çª";
+
+/* No comment provided by engineer. */
+"Change hedgehogs' hat" = "ããªããºãã®å¸½åãå¤ãã";
+
+/* No comment provided by engineer. */
+"Chat with the devs in IRC" = "IRC ã§ãããããéã¨ãã£ãããã";
+
+/* No comment provided by engineer. */
+"Choose a charismatic symbol for your team" = "ãã¼ã ã®ããã®ã«ãªã¹ãçãªã·ã³ãã«ãé¸æãã";
+
+/* No comment provided by engineer. */
+"Choose hedgehog graves" = "ããªããºãã®å¢ãé¸æãã";
+
+/* No comment provided by engineer. */
+"Choose team fort" = "ãã¼ã ã®ç ¦ãé¸æãã";
+
+/* from the settings table */
+"Choosing a Scheme will select its associated Weapon" = "ã¹ãã¼ã ãé¸æããã¨é¢é£ããæ¦å¨ãé¸æãã¾ãã";
+
+/* No comment provided by engineer. */
+"Classic Ammo Menu" = "ã¯ã©ã·ãã¯ãªå¼¾è¬ã¡ãã¥ã¼";
+
+/* No comment provided by engineer. */
+"Community" = "ã³ãã¥ããã£ã¼";
+
+/* from the settings table */
+"Damage popups will notify you on every single hit" = "ãã¡ã¼ã¸ãããã¢ããã¯ãã¹ã¦ã®ããããéç¥ãã¦ããã¾ãã";
+
+/* from the scheme panel
+ from the team panel */
+"Done" = "çµäº";
+
+/* from the scheme panel
+ from the team panel */
+"Edit" = "ç·¨é";
+
+/* No comment provided by engineer. */
+"Edit scheme preferences" = "ã¹ãã¼ã è¨å®ãç·¨é";
+
+/* No comment provided by engineer. */
+"Edit team settings" = "ãã¼ã è¨å®ãç·¨é";
+
+/* No comment provided by engineer. */
+"Edit weapons preferences" = "æ¦å¨è¨å®ãç·¨é";
+
+/* No comment provided by engineer. */
+"End Game" = "ã²ã¼ã ãçµäºãã";
+
+/* No comment provided by engineer. */
+"Flag" = "ãã©ã°";
+
+/* No comment provided by engineer. */
+"Follow us on Twitter" = "ãã¤ãã¿ã¼ã§ãã©ãã¼ãã";
+
+/* No comment provided by engineer. */
+"Fort" = "ç ¦";
+
+/* No comment provided by engineer. */
+"Game Modifiers" = "ã²ã¼ã ã®å¤æ´";
+
+/* No comment provided by engineer. */
+"Game Settings" = "ã²ã¼ã ã®è¨å®";
+
+/* No comment provided by engineer. */
+"General" = "ä¸è¬";
+
+/* No comment provided by engineer. */
+"Grave" = "å¢";
+
+/* No comment provided by engineer. */
+"Hedgewars supports multi-monitor configurations, but the screen has to be connected before launching the game." = "Hedgewarsã¯ãã«ãã¢ãã¿ã¼è¨å®ããµãã¼ããã¦ãã¾ãããã¹ã¯ãªã¼ã³ã¯ã²ã¼ã ãã¹ã¿ã¼ãããåã«æ¥ç¶ããã¦ããªããã°ããã¾ããã";
+
+/* No comment provided by engineer. */
+"Hogs controlled by AI" = "AIã«ã³ã³ããã¼ã«ãããããªããºã";
+
+/* No comment provided by engineer. */
+"Hold your finger on a weapon to see what it does.\nTap anywhere to dismiss." = "æ¦å¨ã®ä¸ã§ãã¼ã«ããã¦ä½ããããè¦ãã\nã»ãã®é¨åãã¿ãããã¦éããã";
+
+/* No comment provided by engineer. */
+"Hold your finger on a weapon to see what it does.\nYou can move this window anywhere on the screen." = "æ¦å¨ã®ä¸ã§ãã¼ã«ããã¦ä½ããããè¦ãã\nãã®ã¦ã£ã³ãã¦ã¯ã¹ã¯ãªã¼ã³ã®ã©ãã«ã§ãåãããã¨ãã§ãã¾ãã";
+
+/* ammo selection */
+"Initial quantity " = "åæé";
+
+/* from the settings table */
+"Insert your password" = "ãã¹ã¯ã¼ããå
¥å";
+
+/* from the settings table */
+"Insert your username (if you have one)" = "ã¦ã¼ã¶ã¼ãã¼ã ãå
¥å (æã£ã¦ããå ´å)";
+
+/* No comment provided by engineer. */
+"Join us on Facebook" = "Facebookã§åå ãã";
+
+/* No comment provided by engineer. */
+"Large" = "大ããª";
+
+/* No comment provided by engineer. */
+"Large Floating Islands" = "大ããªæµ®ã島";
+
+/* No comment provided by engineer. */
+"Large Tunnels" = "大ããªãã³ãã«";
+
+/* No comment provided by engineer. */
+"Leave a positive review on iTunes!" = "iTunesã§ãã¸ãã£ããªã¬ãã¥ã¼ãæ®ã!";
+
+/* No comment provided by engineer. */
+"Level" = "ã¬ãã«";
+
+/* No comment provided by engineer. */
+"Loading..." = "ãã¼ãä¸...";
+
+/* from the settings table */
+"Main Configuration" = "ã¡ã¤ã³è¨å®";
+
+/* No comment provided by engineer. */
+"Mark the death of your fallen warriors" = "ããªãã®åããæ¦å£«ã®æ»ããã¼ã¯";
+
+/* No comment provided by engineer. */
+"Max Hogs:" = "ããªããºãã®æ大æ°:";
+
+/* No comment provided by engineer. */
+"Medium" = "ä¸ããã";
+
+/* No comment provided by engineer. */
+"Medium Floating Islands" = "ä¸ãããã®æµ®ã島";
+
+/* No comment provided by engineer. */
+"Medium Tunnels" = "ä¸ãããã®ãã³ãã«";
+
+/* No comment provided by engineer. */
+"Missing detail" = "詳細ãæãã¦ãã¾ã";
+
+/* No comment provided by engineer. */
+"Missions don't need further configuration" = "ããã·ã§ã³ã¯ãã以ä¸ã®è¨å®ãå¿
è¦ã¨ãã¾ãã";
+
+/* from the settings table */
+"Music" = "é³æ¥½";
+
+/* No comment provided by engineer. */
+"Names and Hats" = "ãã¼ã ã¨å¸½å";
+
+/* from the settings table */
+"Nickname" = "ããã¯ãã¼ã ";
+
+/* No comment provided by engineer. */
+"No filter" = "ãã£ã«ã¿ã¼ãªã";
+
+/* No comment provided by engineer. */
+"No thanks" = "é æ
®ãã¾ã";
+
+/* ammo selection */
+"Number of turns before you can use this weapon " = "ãã®æ¦å¨ã使ããããã«ãªãã¾ã§ã®ã¿ã¼ã³æ°";
+
+/* Short for 'Never' */
+"Nvr" = "絶対ã«ãªã";
+
+/* No comment provided by engineer. */
+"Of course!" = "ãã¡ãã!";
+
+/* No comment provided by engineer. */
+"Ok, got it" = "Ok, ããã£ã";
+
+/* No comment provided by engineer. */
+"Opt for controlling the team or let the AI lead" = "ãã¼ã ãã³ã³ããã¼ã«ãããAIããªã¼ãããã";
+
+/* from the settings table */
+"Other Settings" = "ã»ãã®è¨å®";
+
+/* from the settings table */
+"Password" = "ãã¹ã¯ã¼ã";
+
+/* No comment provided by engineer. */
+"Pick a slang your hogs will speak" = "ããªãã®ããªããºãã話ãã¹ã©ã³ã°ãé¸æ";
+
+/* No comment provided by engineer. */
+"Playing Teams" = "ãã¬ã¼ä¸ã®ãã¼ã ";
+
+/* ammo selection */
+"Presence probability in crates " = "ã¯ã¬ã¼ãã®ä¸ã®åå¨ç¢ºç";
+
+/* No comment provided by engineer. */
+"Press to resume playing or swipe to delete the save file." = "æ¼ãã¦ãã¬ã¼ãåéããããã¹ã¯ã¤ããã¦ã»ã¼ããã¡ã¤ã«ãåé¤ã";
+
+/* No comment provided by engineer. */
+"Preview not available" = "ãã¬ãã¥ã¼ãå©ç¨ã§ãã¾ãã";
+
+/* ammo selection */
+"Quantity that you will find in a crate " = "ã¯ã¬ã¼ã¨ã®ä¸ã§è¦ã¤ããé";
+
+/* No comment provided by engineer. */
+"Remind me later" = "å¾ã§é£çµ¡";
+
+/* Short for 'Random' */
+"Rnd" = "ã©ã³ãã ";
+
+/* No comment provided by engineer. */
+"Save" = "ä¿å";
+
+/* No comment provided by engineer. */
+"Scheme" = "ã¹ãã¼ã ";
+
+/* No comment provided by engineer. */
+"Scheme mismatch" = "ã¹ãã¼ã ãã¹ããã";
+
+/* No comment provided by engineer. */
+"Scheme Name" = "ã¹ãã¼ã å";
+
+/* No comment provided by engineer. */
+"Schemes" = "ã¹ãã¼ã ";
+
+/* No comment provided by engineer. */
+"Select at least two teams to play a game" = "ã²ã¼ã ããã¬ã¼ããã«ã¯æä½äºãã¼ã é¸æãã¦ãã ããã";
+
+/* No comment provided by engineer. */
+"Select one Scheme and one Weapon for this game" = "ãã®ã²ã¼ã ã®ããã«ã¹ãã¼ã ã¨æ¦å¨ãä¸ã¤ãã¤é¸æãã¦ãã ããã";
+
+/* No comment provided by engineer. */
+"Select the team invincible fortress (only valid for fort games)" = "ç¡æµç ¦ã®ãã¼ã ãé¸æãã (ç ¦ã²ã¼ã ã®ã¿æå¹)";
+
+/* from the settings table */
+"Select which style of ammo menu you prefer" = "å¼¾è¬ã¡ãã¥ã¼ã®ã¹ã¿ã¤ã«ãé¸æãã¦ãã ãã";
+
+/* No comment provided by engineer. */
+"Set difficulty level" = "é£æ度ã¬ãã«ãã»ãããã";
+
+/* No comment provided by engineer. */
+"Set hedgehog voices" = "ããªããºãã®å£°ãã»ãããã";
+
+/* No comment provided by engineer. */
+"Set team flag" = "ãã¼ã ãã©ã°ãã»ãããã";
+
+/* on the overlay */
+"Set!" = "ã»ãã!";
+
+/* No comment provided by engineer. */
+"Show Help" = "ãã«ãã表示ãã";
+
+/* No comment provided by engineer. */
+"Small" = "å°ãã";
+
+/* No comment provided by engineer. */
+"Small Floating Islands" = "å°ããªæµ®ã島";
+
+/* No comment provided by engineer. */
+"Small Tunnels" = "å°ããªãã³ãã«";
+
+/* from the settings table */
+"Sound" = "ãµã¦ã³ã";
+
+/* No comment provided by engineer. */
+"Style" = "ã¹ã¿ã¤ã«";
+
+/* No comment provided by engineer. */
+"Support" = "ãµãã¼ã";
+
+/* No comment provided by engineer. */
+"Sync Schemes and Weapons" = "ã¹ãã¼ã ã¨æ¦å¨ãåæãã";
+
+/* No comment provided by engineer. */
+"Tag" = "ã¿ã°";
+
+/* No comment provided by engineer. */
+"Tap to add hogs or change color, touch and hold to remove a team." = "ããªããºãã追å ãããè²ãå¤æ´ããã«ã¯ã¿ããããã¼ã ãåãé¤ãã«ã¯ã¿ãããã¦ãã¼ã«ããã¦ãã ããã";
+
+/* No comment provided by engineer. */
+"Team Name" = "ãã¼ã å";
+
+/* No comment provided by engineer. */
+"Team Preferences" = "ãã¼ã è¨å®";
+
+/* No comment provided by engineer. */
+"Teams" = "ãã¼ã ";
+
+/* No comment provided by engineer. */
+"The map is too small for that many hogs" = "ãã®ãããã¯ããã ãã®ããªããºãã«ã¯å°ãããã¾ãã";
+
+/* No comment provided by engineer. */
+"The robot badge indicates an AI-controlled team." = "ããããããã¸ã¯AIãã³ã³ããã¼ã«ãããã¼ã ãæãã¾ãã";
+
+/* No comment provided by engineer. */
+"The scheme you selected allows only for two teams" = "é¸æããã¹ãã¼ã ã¯äºãã¼ã ç¨ã§ãã";
+
+/* No comment provided by engineer. */
+"This weapon is locked" = "ãã®æ¦å¨ã¯ããã¯ããã¦ãã¾ã";
+
+/* No comment provided by engineer. */
+"Too few teams playing" = "ãã¬ã¼ãã¦ãããã¼ã ãå°ãªããã¾ã";
+
+/* No comment provided by engineer. */
+"Too many hogs" = "ããªããºããå¤ããã¾ã";
+
+/* No comment provided by engineer. */
+"Too many teams" = "ãã¼ã ãå¤ããã¾ã";
+
+/* No comment provided by engineer. */
+"Visit our website" = "ã¦ã§ããµã¤ããè¦ã";
+
+/* No comment provided by engineer. */
+"Voice" = "é³é";
+
+/* No comment provided by engineer. */
+"Wacky" = "å¥æ";
+
+/* No comment provided by engineer. */
+"Wait for the Preview" = "ãã¬ãã¥ã¼ãå¾
ã¤";
+
+/* No comment provided by engineer. */
+"Weaky" = "å¼±ãè
";
+
+/* No comment provided by engineer. */
+"Weapon" = "æ¦å¨";
+
+/* No comment provided by engineer. */
+"Weapon Ammuntions" = "æ¦å¨å¼¾è¬";
+
+/* No comment provided by engineer. */
+"Weapons" = "æ¦å¨";
+
+/* No comment provided by engineer. */
+"Weaponset Name" = "æ¦å¨ã»ããå";
+
+/* No comment provided by engineer. */
+"Well, maybe not..." = "ã¾ããããã§ãªãããããã¾ãã...";
+
+/* No comment provided by engineer. */
+"Worldwide" = "ã¯ã¼ã«ãã¯ã¤ã";
+
+/* No comment provided by engineer. */
+"You can add a description if you wish" = "ãæã¿ãªã説æã追å ãããã¨ãã§ãã¾ãã";
+
+/* No comment provided by engineer. */
+"You exceeded the maximum number of tems allowed in a game" = "ã²ã¼ã ã§è¨±å¯ããã¦ãããã¼ã ã®æ大æ°ãè¶
ãã¾ããã";
\ No newline at end of file
diff --git a/project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings
new file mode 100644
index 0000000..4e4aa56
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/Japanese.lproj/Scheme.strings
@@ -0,0 +1,194 @@
+/* game mod description */
+"Land can not be destroyed" = "åå°ã¯ç ´å£ãããã¨ãã§ãã¾ãã";
+
+/* game mod title */
+"Solid Land" = "åºå½¢ã®åå°";
+
+/* game mod description */
+"Add an indestructable border around the terrain" = "å°å½¢ã®å¨ãã«ç ´å£ã§ããªããã¼ãã¼ã追å ãã";
+
+/* game mod title */
+"Add Border" = "ãã¼ãã¼ã追å ãã";
+
+/* game mod description */
+"Teams will start on opposite sides of the terrain" = "ãã¼ã ã¯å°å½¢ã®å対å´ããã¹ã¿ã¼ãææ¡ã";
+
+/* game mod title */
+"Divide Team (max 2 teams)" = "ãã¼ã ãåãã (æ大äºãã¼ã )";
+
+/* game mod description */
+"Lower gravity" = "ä½ãéå";
+
+/* game mod title */
+"Low Gravity" = "ä½éå";
+
+/* game mod description */
+"Assisted aiming with laser sight" = "ã¬ã¼ã¶ã¼ãµã¤ãã§çãã®è£å©";
+
+/* game mod title */
+"Laser Sight" = "ã¬ã¼ã¶ã¼ãµã¤ã";
+
+/* game mod description */
+"All hogs have a personal forcefield" = "å
¨ã¦ã®ããªããºãã¯èªåã®åå ´ãæã£ã¦ãã¾ã";
+
+/* game mod title */
+"Invulnerable" = "ç¡æµ";
+
+/* game mod description */
+"All (living) hedgehogs are fully restored at the end of turn" = "å
¨ã¦ã® (çãã¦ãã) ããªããºãã®ä½åã¯ã¿ã¼ã³çµäºæã«å®å
¨ã«å¾©å
ããã¾ã";
+
+/* game mod title */
+"Reset Health" = "ä½åããªã»ãã";
+
+/* game mod description */
+"Gain 80% of the damage you do back in health" = "ãã¡ã¼ã¸ã®80% ãä½åã¨ãã¦ããã";
+
+/* game mod title */
+"Vampirism Mode" = "å¸è¡ã¢ã¼ã";
+
+/* game mod description */
+"Share your opponents pain, share their damage" = "ç¸æã®çã¿ãå
±æãã ãã¡ã¼ã¸ãå
±æãã";
+
+/* game mod title */
+"Karma Mode" = "ã«ã«ãã¢ã¼ã";
+
+/* game mod description */
+"Your hogs are unable to move, test your aim" = "ããªãã®ããªããºãã¯åããªã, çãã試ã";
+
+/* game mod title */
+"Artillery Mode" = "ç ²å
µã¢ã¼ã";
+
+/* game mod description */
+"Defend your fort and destroy the opponents" = "ç ¦ãå®ã£ã¦ç¸æãæ½°ã";
+
+/* game mod title */
+"Fort Mode" = "ç ¦ã¢ã¼ã";
+
+/* game mod description */
+"Order of play is random instead of in room order" = "ãã¬ã¼é ã¯ã«ã¼ã é ã§ã¯ãªãã©ã³ãã ã§ã";
+
+/* game mod title */
+"Random Order" = "ã©ã³ãã ãªã¼ãã¼";
+
+/* game mod description */
+"Play with a King; when he dies, your side loses" = "ãã³ã°ã¨ãã¬ã¼ãã; ãã³ã°ãæ»ã¬ã¨ãããªãã®è² ãã§ã";
+
+/* game mod title */
+"King Mode" = "ãã³ã°ã¢ã¼ã";
+
+/* game mod description */
+"Take turns placing your hedgehogs pre-game" = "ã²ã¼ã ã®åã«ã¿ã¼ã³ãåã£ã¦ããªããºããç½®ã";
+
+/* game mod title */
+"Place Hedgehogs" = "ããªããºããç½®ã";
+
+/* game mod description */
+"Ammo is shared between all clan teams" = "å¼¾è¬ã¯å
¨ã¦ã®ä¸æãã¼ã ã®éã§å
±æããã¾ã";
+
+/* game mod title */
+"Clan Shares Ammo" = "ä¸æã¯å¼¾è¬ãå
±æãã¾ã";
+
+/* game mod description */
+"Disable girders when generating random maps" = "ã©ã³ãã ããããä½æããã¨ãã¯ã¬ã¼ããç¡å¹ã«ãã";
+
+/* game mod title */
+"Disable Girders" = "ã¬ã¼ããç¡å¹ã«ãã";
+
+/* game mod description */
+"Disable land objects when generating maps" = "ãããä½æä¸ã¯åå°ã®ãªãã¸ã§ã¯ããç¡å¹ã«ãã";
+
+/* game mod title */
+"Disable Land Objects" = "åå°ã®ãªãã¸ã§ã¯ããç¡å¹ã«ãã";
+
+/* game mod description */
+"AI-controlled hogs respawn on death" = "AIãã³ã³ããã¼ã«ããããªããºãã¯æ»ã¬ã¨ååºç¾ãã¾ã";
+
+/* game mod title */
+"AI Survival Mode" = "AI ãµãã¤ãã«ã¢ã¼ã";
+
+/* game mod description */
+"Attacking does not end your turn" = "æ»æãã¦ãã¿ã¼ã³ã¯çµäºãã¾ãã";
+
+/* game mod title */
+"Unlimited Attacks" = "ç¡éæ»æ";
+
+/* game mod description */
+"Weapons are reset to starting values each turn" = "æ¦å¨ã¯æ¯ã¿ã¼ã³åæå¤ã«ãªã»ããããã¾ã";
+
+/* game mod title */
+"Reset Weapons" = "æ¦å¨ããªã»ãã";
+
+/* game mod description */
+"Each hedgehog has its own ammo" = "åããªããºããèªåã®å¼¾è¬ãæã£ã¦ãã¾ã";
+
+/* game mod title */
+"Per Hedgehog Ammo" = "ããªããºããããã®å¼¾è¬";
+
+/* game mod description */
+"You will not have to worry about wind any more" = "風ã®ãã¨ã¯æ°ã«ããã«è¯ããªãã¾ã";
+
+/* game mod title */
+"Disable Wind" = "風ãç¡å¹ã«ãã";
+
+/* game mod description */
+"Wind will affect almost everything" = "風ã¯ã»ã¨ãã©ã®ãã®ã«å½±é¿ãã¾ã";
+
+/* game mod title */
+"More Wind" = "ããå¼·ã風";
+
+/* game mod description */
+"Clan teams take turns sharing their time" = "ä¸æã®ãã¼ã ã¯ã¿ã¤ã ãå
±æãã¦ã¿ã¼ã³ãåãã¾ã";
+
+/* game mod title */
+"Tag Team" = "ã¿ãã°ãã¼ã ";
+
+/* game mod description */
+"Add an indestructible border along the bottom" = "ç ´å£ã§ããªããã¼ãã¼ãä¸ã«è¿½å ãã";
+
+/* game mod title */
+"Bottom Border" = "ããã ãã¼ãã¼";
+
+
+/* flag description */
+"Initial Health" = "åæä½å";
+
+/* flag description */
+"Damage Modifier" = "ãã¡ã¼ã¸å¤æ´";
+
+/* flag description */
+"Turn Time" = "ã¿ã¼ã³ã¿ã¤ã ";
+/* flag description */
+"Sudden Death Timeout" = "ãµãã³ã»ãã¹ ã¿ã¤ã ã¢ã¦ã";
+
+/* flag description */
+"Water Rise Amount" = "æ°´ä½ä¸æé";
+
+/* flag description */
+"Health Decrease" = "ä½åã®æ¸å°";
+
+/* flag description */
+"Rope Length (%)" = "ãã¼ãã®é·ã (%)";
+
+/* flag description */
+"Crate Drop Turns" = "ã¯ã¬ã¼ãããããã¿ã¼ã³";
+
+/* flag description */
+"Health Kit Probability (%)" = "ä½åãããã®ç¢ºç (%)";
+
+/* flag description */
+"Health Amount in Kit" = "ãããã®ä½åé";
+
+/* flag description */
+"Mines Time" = "å°é·ã¿ã¤ã ";
+
+/* flag description */
+"Mines Number" = "å°é·ãã³ãã¼";
+
+/* flag description */
+"Dud Mines Probability (%)" = "ä¸çºå°é·ã®ç¢ºç(%)";
+
+/* flag description */
+"Explosives" = "ççºç©";
+
+/* flag description */
+"Get Away Time (%)" = "è±åºã¿ã¤ã (%)";
\ No newline at end of file
diff --git a/project_files/HedgewarsMobile/Locale/Polish.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Polish.lproj/About.strings
new file mode 100644
index 0000000..974b1a0
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Polish.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Polish.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Polish.lproj/Localizable.strings
new file mode 100644
index 0000000..40d1560
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Polish.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Polish.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Polish.lproj/Scheme.strings
new file mode 100644
index 0000000..8d79e57
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Polish.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Portuguese.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/About.strings
new file mode 100644
index 0000000..998a83d
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Localizable.strings
new file mode 100644
index 0000000..acaa585
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Scheme.strings
new file mode 100644
index 0000000..94abfe9
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Portuguese.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Romanian.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Romanian.lproj/About.strings
new file mode 100644
index 0000000..c38a8b8
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Romanian.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Romanian.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Romanian.lproj/Localizable.strings
new file mode 100644
index 0000000..7fe46bd
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Romanian.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Romanian.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Romanian.lproj/Scheme.strings
new file mode 100644
index 0000000..a0dc187
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Romanian.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Spanish.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Spanish.lproj/About.strings
new file mode 100644
index 0000000..ece85a2
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Spanish.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Spanish.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Spanish.lproj/Localizable.strings
new file mode 100644
index 0000000..a5fc140
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Spanish.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Spanish.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Spanish.lproj/Scheme.strings
new file mode 100644
index 0000000..2ecdccf
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Spanish.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Turkish.lproj/About.strings b/project_files/HedgewarsMobile/Locale/Turkish.lproj/About.strings
new file mode 100644
index 0000000..c4b6143
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Turkish.lproj/About.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings b/project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings
new file mode 100644
index 0000000..90bd7cf
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Turkish.lproj/Localizable.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings b/project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings
new file mode 100644
index 0000000..d73b7e4
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/Turkish.lproj/Scheme.strings differ
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_bg.txt b/project_files/HedgewarsMobile/Locale/hw-desc_bg.txt
new file mode 100644
index 0000000..bf05843
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_bg.txt
@@ -0,0 +1,31 @@
+Hedgewars, много Ñко!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars е доÑÑÑпна в Mac Appstore ! ÐоÑÑÑÑеÑе hedgewars на ваÑÐ¸Ñ Ð¼Ð°Ðº и вземеÑе ваÑеÑо ÐÐÐÐÐÐТÐРкопие днеÑ!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+iOS поÑÑа има нÑÐºÐ¾Ð¸Ì ÐµÐºÑклÑзивни екÑÑÑи каÑо
+* iPad VGA Out: ÐакаÑеÑе вÑнÑен диÑÐ¿Ð»ÐµÐ¸Ì Ð¸ игÑаиÌÑе на пÑлна ÑезолÑÑиÑ;
+* ÐоддÑÑжка на ÑеÑина диÑплеиÌ: игÑаиÌÑе на по-виÑока ÑезолÑÑÐ¸Ñ Ð¿Ñез ÑÑлаÑа игÑа;
+* ÐногозадаÑноÑÑ: пÑекÑÑнеÑе игÑаÑа по вÑÑко вÑеме;
+* ÐÑзÑÑановÑване на игÑа: Ðинаги Ñе можеÑе да завÑÑÑиÑе ваÑаÑа игÑа, незавиÑимо какво.
+
+ÐпиÑание:
+Това е наиÌ-забавнаÑа и пÑиÑÑÑаÑÑÑваÑа игÑа, коÑÑо нÑкога Ñе игÑаеÑе - забава, на коÑÑо можеÑе да Ñе наÑлаждаваÑе навÑÑкÑде, по вÑÑко вÑеме. Hedgewars е ÑÑÑаÑÐµÐ³Ð¸Ñ Ð½Ð¾ иÑÑинÑкаÑа забава е Ð¾Ñ ÑазÑÑÑениÑÑа пÑиÑинени Ð¾Ñ Ñези доÑадни ÑаÑалежи Ñ Ñези ÑанÑаÑÑиÑни оÑÑÐ¶Ð¸Ñ - подли малки гадини Ñ Ð»Ð¾Ñ Ñ
аÑакÑеÑ!
+
+С дÑÑги дÑми Hedgewars е ÑÑÑаÑегиÑ, аÑÑилеÑииÌна, екÑÑн и комедииÌна игÑа, коÑÑо вклÑÑва лÑдоÑииÑе на Ñозови ÑаÑалежи Ñ Ñ
аÑакÑÐµÑ Ð´Ð¾ÐºÐ°Ñо Ñе Ñе биÑÑ Ð¾Ñ Ð´ÑлбиниÑе на ада до дÑлбиниÑе на коÑмоÑа.
+
+ÐаÑо командиÑ, ваÑаÑа ÑабоÑа е да подбеÑеÑе ваÑÐ¸Ñ Ð¾ÑÐ±Ð¾Ñ Ð¾Ñ ÑаÑалежи и да занеÑеÑе воиÌнаÑа на вÑага Ñи.
+
+ÐÑеки игÑÐ°Ñ ÐºÐ¾Ð½ÑÑолиÑа оÑÐ±Ð¾Ñ Ð¾Ñ Ð½Ñколко ÑаÑалежа. ÐгÑаÑиÑе Ñе ÑедÑÐ²Ð°Ñ Ñ Ð¿Ð¾ един ÑаÑалеж на Ñед. Те Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ Ð²ÑÑкакви оÑÑÐ¶Ð¸Ñ Ð¸ инÑÑÑÑменÑи за да ÑбиÑÑ Ð¿ÑоÑивниковиÑе ÑаÑалежи и ÑÑоÑвеÑно да ÑпеÑелÑÑ Ð¸Ð³ÑаÑа. ТаÑалежиÑе Ð¼Ð¾Ð³Ð°Ñ Ð´Ð° Ñе Ð´Ð²Ð¸Ð¶Ð°Ñ Ð¿Ð¾ ÑазлиÑни наÑини, обикновено каÑо Ñ
одÑÑ Ð¸ ÑкаÑÐ°Ñ Ð½Ð¾ и каÑо Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ Ð¾Ð¿Ñеделени инÑÑÑÑменÑи каÑо "ÐÑжеÑо" или "ÐаÑаÑÑÑа" за да доÑÑÐ¸Ð´Ð½Ð°Ñ Ð¸Ð½Ð°Ñе недоÑÑÑпни меÑÑа. ÐÑеки Ñед е огÑаниÑен по вÑеме, за да не Ñе задÑÑжа игÑаÑа Ñ Ð¿Ñекалено много миÑлене или движение. ÐолÑм Ð½Ð°Ð±Ð¾Ñ Ð¾Ñ Ð¸Ð½ÑÑÑÑменÑи и оÑÑÐ¶Ð¸Ñ Ñа на Ñазположение на игÑаÑиÑе : ÐÑанаÑа, ÐлÑÑÑеÑна бомба, ÐазÑка, ÐÐÐ, ÐÑÑка, РеволвеÑ, Ðгнен пÑнÑ, ÐÑÑ
алка, ÐинамиÑ, Ðина, ÐÑже, ÐневмаÑиÑна моÑика, ÐаÑаÑÑÑ. ÐÑи използванеÑо Ñи, повеÑеÑо оÑÑÐ¶Ð¸Ñ Ð¿ÑÐµÐ´Ð¸Ð·Ð²Ð¸ÐºÐ²Ð°Ñ ÐµÐºÑплозии, коиÑо деÑоÑмиÑÐ°Ñ ÑеÑена, пÑемаÑ
ваиÌки кÑÑгли паÑÑеÑа. ÐеиÌзажÑÑ Ðµ Ð¿Ð»Ð°Ð²Ð°Ñ Ð¾ÑÑÑов или пеÑеÑа Ñ Ð²Ð¾Ð´Ð° в дÑноÑо Ñи.ТаÑалежиÑе ÑмиÑÐ°Ñ ÐºÐ¾Ð³Ð°Ñо Ð¿Ð°Ð´Ð½Ð°Ñ Ð²Ñв вода(или каÑо Ð¿Ð°Ð´Ð½Ð°Ñ Ð¾Ñ Ð¾ÑÑÑова, или пÑез дÑпка в него), Ñа изÑ
вÑÑлени Ð¾Ñ Ð°ÑенаÑа или когаÑо здÑавеÑо им доÑÑигне 0, обикновно Ð¾Ñ ÐºÐ¾Ð½ÑÐ°ÐºÑ Ñ ÐµÐºÑплозии (ÑеÑиÑе вÑÑÑ
Ñ Ð´Ð°Ð´ÐµÐ½ ÑаÑалеж Ñе Ð¿Ð¾ÐºÐ°Ð·Ð²Ð°Ñ Ñамо Ñлед кÑÐ°Ñ Ð½Ð° Ñеда).
+
+* Ðживена и опÑÑÑоÑиÑелна Ñедово базиÑана биÑка за до 6 игÑаÑа
+* Ðокален и мÑежови мÑлÑиплеиÌÑÑ Ñ Ð²ÑзможноÑÑ Ð·Ð° пÑоÑивниÑи конÑÑолиÑани Ð¾Ñ ÐÐ
+* ÐииÌÑе Ñе на безкÑаиÌни пÑоизволно генеÑиÑани каÑÑи Ñ Ð½Ð°Ð´ 20 ÑазлиÑни ÑÑеди
+* ÐзползваиÌÑе над 48 ÑдивлиÑелни оÑÑжиÑ! ÐклÑÑиÑелно падаÑоÑо пиано и екÑплодиÑаÑаÑа ÑобоÑизиÑана ÑоÑÑа
+* ÐгÑаиÌÑе игÑаÑа по ваÑиÑÑ Ð½Ð°Ñин, Ñ Ð½Ð°Ð´ 20 игÑови Ñежима, можеÑе да пÑомениÑе поÑÑи вÑеки аÑÐ¿ÐµÐºÑ Ð½Ð° игÑаÑа
+* ÐеÑÑонализиÑаиÌÑе ваÑиÑÑ Ð¾ÑбоÑ, Ñ Ð½Ð°Ð´ 120 коÑÑÑма, 30 гÑоба, 12 кÑепоÑÑи, ÑÑоÑиÑи Ñлагове и Ñникални глаÑови пакеÑи
+* ÐгÑомни биÑки Ñ Ð´Ð¾ 64 ÑаÑалежа
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_da.txt b/project_files/HedgewarsMobile/Locale/hw-desc_da.txt
new file mode 100644
index 0000000..7c72825
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_da.txt
@@ -0,0 +1,31 @@
+Hedgewars, det' Vildt!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars er tilgængeligt i Mac App Store! Søg efter Hedgewars på din Mac og få din GRATIS kopi i dag!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+iOS versionen har flere eksklusive funktioner, så som
+* iPad VGA-udgangssignal: tilslut en ekstern skærm og spil i fuld oplysning;
+* Understøttelse af Retina-skærmen: spil hele spillet i en højere opløsning;
+* Multitasking: sæt spillet på pause når som helst;
+* Genoptagelse af Spil: du kan altid færdiggøre din kamp, lige meget hvad.
+
+Beskrivelse:
+Det her er det sjoveste og mest afhængighedsskabende spil du nogensinde kommer til at prøve - hylende morsomt og lige til at tage op af lommen hvor som helst, når som helst. Hedgewars er et turbaseret strategispil, men det fedeste er at se de utrolige ødelæggelser de forbistrede pindsvin laver med deres fantasifulde våben - luskede små fyre med en uforskammet holdning.
+
+Med andre ord er Hedgewars et turbaseret strategi-, artilleri-, action- og komediespil som byder på an narrestreger fra små lyserøde pindsvin med attitude og som viser hvordan de slås overalt, fra det dybeste helvede til den yderste afkroge af rummet.
+
+Som hærfører er det dit arbejde at sammensætte et førsteklasses hold af pindsvinesoldater og føre krig mod fjenderne helt fremme ved frontlinjen.
+
+Hver spiller styrer et hold bestående af adskillige pindsvin. I løbet af spillet tager spillerne ture med et af deres pindsvin. De bruger her et hvilket som helst tilgængeligt værktøj eller våben til at angribe og dræbe deres modstanderes pindsvin, og vinder derved spillet. Pindsvinene kan bevæge sig rundt i terrænet på mange forskellige måder, normalt ved at gå og hoppe, men også ved at bruge forskellige værktøjer som f.eks. et reb, en teleporter eller en faldskærm for at nå ellers utilgængelige steder. Hver tur er tidsbegrænset for at sikre at spillere ikke forsinker spillet med for mange tanker eller bevægelser. Et stort assortiment af våben er tilgængeligt i løbet af spillet: Granater, klyngebomber, bazookaer, UFO'er, haglgeværer, pistoler, slag med brændende næver, baseballbatter, dynamit, miner, reb, trykluftsbor, faldskærme, osv. De fleste våben laver eksplosioner som deformerer terrænet ved at fjerne cirkulære stykker. Landskabet består af en flydende ø i en vandmasse, eller en begrænset grotte med vand i bunden. Pindsvin dør hvis de falder i vandet (enten ved at falde ud over kanten af øen, eller gennem et hul i bunden), falder ud over kanten af banen eller hvis deres liv bliver reduceret (typisk ved nærkontakt med for mange eksplosioner) til nul.
+
+* Vandvittig morsom og ødelæggende turbaseret krigsførsel for op til 6 spillere
+* Multiplayer, både lokalt og over et netværk, men valgfri computerstyrede modstandere
+* Kæmp på et uendeligt antal tilfældigt genererede baner med over 20 forskellige typer omgivelser
+* Brug 48 (forøges løbende) overvældende våben! Inklusiv klaveranslaget og den eksplosive robotkage
+* Spil lige som du har lyst til! Med mere end 20 forskellige måder at justere spillet på, kan du selv bestemme over næsten alle aspekter af kampen
+* Skræddersy dit hold med over 120 kostumer, 30 gravsten, 12 forter, hundredvis af flag og mange unikke sæt stemmer
+* Enorme slag med op til 64 pindsvin
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_de.txt b/project_files/HedgewarsMobile/Locale/hw-desc_de.txt
new file mode 100644
index 0000000..7318e9e
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_de.txt
@@ -0,0 +1,31 @@
+Hedgewars, einfach Bombastisch!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars ist jetzt auch im Mac Appstore verfügbar! Suche Hedgewars von deinem Mac und bekomme deine GRATIS Kopie!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+Der iOS-Port hat einige exklusiven Features, wie z.B.:
+* iPad VGA-Ausgabe: SchlieÃe einen externen Bildschirm an und spiele mit voller Auflösung;
+* Retina Display-Unterstützung: Spiele das gesamte Spiel mit noch höherer Auflösung;
+* Multitasking: Pausiere das Spiel wann immer du willst;
+* Spielstandwiederherstellung: Egal was passiert, du wirst immer in der Lage sein die Partie zu Ende zu spielen.
+
+Beschreibung:
+Es ist das lustigste und süchtig-machendste Spiel auf der Welt - wahnsinniger SpielspaÃ, wo und wann du willst. Hedgewars ist ein rundenbasiertes Strategiespiel. Aber die richtige Begeisterung verursacht erst, diesen nervigen kleinen Igeln zu zuschauen, wie sie mit ihren fantastischen Waffen alles zerstören - hinterhältige kleine Mistkerle mit bösen Absichten!
+
+Anders gesagt, Hedgewars ist ein rundenbasiertes Strategie-, Artillerie-, Action- und Comedy-Spiel. In den Hauptrollen die Grimassen der pinken Igel, mit dem Anschein als wollten sie sich aus den Tiefen der Hölle in die Tiefen des Universums vorkämpfen.
+
+Als Kommandant ist es deine Aufgabe ein Sondereinsatzkommando aus Igelsoldaten zusammenzustellen und deine Feinde mit Krieg zu überziehen.
+
+Jeder Spieler befehligt ein aus mehreren Igeln bestehendes Team. Im Spielverlauf ziehen die Spieler mit einem ihrer Igel. Sie benutzen dann alle zur Verfügung stehende Hilfsmittel und Waffen um die gegnerischen Igel zu töten. Dadurch gewinnen sie das Spiel. Igel können sich auf verschiedene Arten und Weisen auf dem Gelände bewegen, normalerweise durch laufen und springen, sie können aber auch spezielle Hilfsmittel wie zum Beispiel ein Seil oder einen Fallschirm benutzen, um zu ansonsten unerreichbaren Regionen vorzudringen. Um zu verhindern, dass Teilnehmer nicht das Spiel durch übermäÃiges Nachdenken oder Bewegen aufhalten, ist jeder Zug zeitlich begrenzt. Während dem Spiel gibt es eine Vielzahl von Waffen und Hilfsmitteln: Granaten, Streubomben, Panzerfäuste, UFOs, Schrotflinten, Desert Eagles, Feuerschläge, Baseballschläger, Dynamit, Minen, Seile, Presslufthammer und Fallschirme. Die meisten Waffen verursachen Explosionen, die auch kreisförmige Stücke des Geländes heraus sprengen. Die verfügbaren Umgebungen sind eine auf einem Gewässer schwimmende Insel oder eine beschränkt zugängliche Höhle mit Wasser auf dem Boden. Ein Igel stirbt wenn er ins Wasser fällt (z.B. weil er von der Insel oder durch ein Loch in deren Boden fällt), er auf irgendeiner Seite aus dem Spielfeld fliegt oder wenn seine Gesundheit unter Null fällt, typischerweise aber durch Explosionen. (Der einem oder mehreren Igeln durch einen Spieler- oder KI-Zug zugefügte Schaden wird erst angerechnet, nachdem alle Bewegungen auf dem Schlachtfeld abgeschlossen ist).
+
+* Sensationeller, zerstörerischer, rundenbasierter Krieg für bis zu 6 Spieler
+* Lokale- und Online-Multiplayerspiele, mit zusätzlichen KI-Gegnern
+* Kämpfe auf unendlichen vielen, zufällig generierten Karten mit über 20 Umgebungen
+* Benutze 48 (und es werden laufend mehr) überwältigende Waffen! Inklusive dem Piano-Schlag und dem explosiven Roboterkuchen
+* Spiel das Spiel auf deine Weise, mit mehr als 20 verschiedenen Modifikatoren kannst du so gut wie jedes Detail anpassen
+* Passe dein Team an, mit über 120 Kostümen, 30 Gräbern, 12 Festungen, 100ten von Flaggen und einzigartigen Stimmen
+* Riesige Schlachten mit bis zu 64 Igeln
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_en.txt b/project_files/HedgewarsMobile/Locale/hw-desc_en.txt
new file mode 100644
index 0000000..8427016
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_en.txt
@@ -0,0 +1,31 @@
+Hedgewars, it's a Blast!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars is available for the Mac Appstore! Search Hedgewars on your Mac and get your FREE copy today!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+The iOS port has some exclusive features, such as
+* iPad VGA Out: hook an external display and play at full resolution;
+* Retina Display Support: play at a higher resolution the whole game;
+* Multitasking: pause the game at any time;
+* Game Restore: you will be always able to complete your match, no matter what.
+
+Description:
+This is the funniest and most addictive game you'll ever play - hilarious fun that you can enjoy anywhere, anytime. Hedgewars is a turn based strategy game but the real buzz is from watching the devastation caused by those pesky hedgehogs with those fantastic weapons - sneaky little blighters with a bad attitude!
+
+In other words Hedgewars is a turn based strategy, artillery, action and comedy game, featuring the antics of pink hedgehogs with attitude as they battle from the depths of hell to the depths of space.
+
+As commander, it's your job to assemble your crack team of hedgehog soldiers and bring the war to your enemy.
+
+Each player controls a team of several hedgehogs. During the course of the game, players take turns with one of their hedgehogs. They then use whatever tools and weapons are available to attack and kill the opponents' hedgehogs, thereby winning the game. Hedgehogs may move around the terrain in a variety of ways, normally by walking and jumping but also by using particular tools such as the "Rope" or "Parachute", to move to otherwise inaccessible areas. Each turn is time-limited to ensure that players do not hold up the game with excessive thinking or moving. A large variety of tools and weapons are available for players during the game: Grenade, Cluster Bomb, Bazooka, UFO, Shotgun, Desert Eagle, Fire Punch, Baseball Bat, Dynamite, Mine, Rope, Pneumatic pick, Parachute. Most weapons, when used, cause explosions that deform the terrain, removing circular chunks. The landscape is an island floating on a body of water, or a restricted cave with water at the bottom. A hedgehog dies when it enters the water (either by falling off the island, or through a hole in the bottom of it), it is thrown off either side of the arena or when its health is reduced, typically from contact with explosions, to zero (the damage dealt to the attacked hedgehog or hedgehogs after a player's or CPU turn is shown only when all movement on the battlefield has ceased).
+
+* Hilarious and devastating turn based combat for up to 6 players
+* Both local and network multiplayer, with optional AI opponents
+* Battle on an infinite number of randomly generated maps, with over 20 environments
+* Use 48 (and counting) overwhelming weapons! Including the piano strike and explosive robotic cake
+* Play the game your way, with more than 20 different game modifiers, tweak almost every aspect of the match
+* Customize your team, with over 120 costumes, 30 graves, 12 forts, 100s of flags and unique voice packs
+* Huge battles with up to 64 hogs
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_es.txt b/project_files/HedgewarsMobile/Locale/hw-desc_es.txt
new file mode 100644
index 0000000..d9c9051
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_es.txt
@@ -0,0 +1,31 @@
+Hedgewars, ¡es la leche!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+¡Hedgewars esta disponible en la Mac Appstore! ¡Busca Hedgewars en tu Mac y consigue tu copia gratuita hoy!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+La versión para iOS contiene algunas caracterÃsticas exclusivas, como:
+* Salida VGA para iPad: conecta un monitor externo y juega a resolución completa;
+* Soporte para pantalla Retina: juega el juego entero a una resolución mayor;
+* Multitarea: pausa el juego en cualquier momento;
+* Restauración de partidas: siempre podrás completar tu partida, pase lo que pase.
+
+Descripción:
+Este es el juego más adictivo que jugarás - diviértete en cualquier sitio, en cualquier momento. Hedgewars es un juego de estrategia por turnos pero la verdadera diversión esta en ver como estos molestos erizos con sus fantásticas armas destrozan el entorno - unos pequeños pero gamberros tÃos con ganas de liarla parda!
+
+En otras palabra, Hedgewars es un juego de estrategia por turnos, con toques de artillerÃa, acción y comedia, protagonizado por las travesuras de erizos rosas con mal carácter que luchan desde el fondo del infierno hasta el espacio exterior.
+
+Eres el comandante, tu tarea es crear un potente equipo de erizos soldado y llevar la guerra a las puertas de tus enemigos.
+
+Cada jugador controla un equipo de varios erizos. Durante el transcurso de la partida, los jugador usan un turno con cada uno de sus erizos. Entonces pueden usar cualquier herramienta o arma disponible para atacar y matar a los erizos de los oponentes, ganando asà la partida. Los erizos se pueden mover por el campo de juego de muchas maneras, normalmente andando o saltando pero también usando herramientas especiales como la "Cuerda" o el "ParacaÃdas", para moverse a lugares de otra forma incaccesibles. Cada turno tiene un lÃmite de tiempo para asegurar que los jugadores no se pasan demasiado tiempo pensando o moviendo. Una gran variedad de armas y herramientas están disponibles durante la partida: Granada, Bomba de Racimo, Bazoka, UFO, Escopeta, Desert Eagle, Puñetazo de fuego, Bate de Beisbol, Dinamita, Minas, Cuerda, Taladro Neumático, Paracaidas. Casi todas las armas, cuando son usadas, causan explosiones que deforman el terreno, destruyendo sectores circulares. El paisaje es una isla que flota en el agua, o una restringida cueva con agua en el fondo. Un erizo muere cuando entra en el agua (ya sea callendose por un borde o un agujero), es lanzado fuera del campo de juego o cuando se queda sin vida, normalmente por las explosiones (el daño hecho a un erizo o unos erizos es mostrado después del turno del jugador o de la CPU cuando todo el movimiento en el campo de batalla ha terminado).
+
+* Divertido y devastador combate basado en turnos para un máximo de 6 jugadores.
+* Juego multijugador tanto local como en red, con oponentes virtuales opcionales
+* Lucha en infinitos mapas generados aleatoriamente, con más de 20 entornos.
+* Usa 48 (y la cuenta sigue) poderosas armas! Incluido el golpe de piano o la explosiva tarta robot
+* Juega a tu manera, con más de 20 modificadores de juego puedes configurar todo los aspectos de la partida
+* Personaliza to equipo, con más de 120 trajes, 30 tumbas, 12 fuertes, y cientos de banderas y voces únicas
+* Grandes batallas con hasta 64 puercos
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_fr.txt b/project_files/HedgewarsMobile/Locale/hw-desc_fr.txt
new file mode 100644
index 0000000..08c3f91
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_fr.txt
@@ -0,0 +1,31 @@
+Hedgewars, c'est génial!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars est disponible sur le Mac Appstore ! Cherchez Hedgewars sur votre Mac et obtenez une copie gratuite aujourd'hui !
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+Le portage vers iOS a quelques fonctionnalités exclusives, comme :
+* Sortie VGA de l'iPad: connectez un affichage externe et jouez à la résolution maximale;
+* Support de l'Affichage Rétinien: jouez le jeu entier à une résolution supérieure;
+* Multitâche: mettez le jeu en pause à n'importe-quel moment;
+* Restoration de Jeu: vous aurez toujours la possibilité de finir votre match, quoiqu'il arrive.
+
+Description :
+C'est le jeu le plus amusant et le plus addictif auquel vous ne jouerez jamais - de l'amusement que vous pouvez apprécier partout, tout le temps. Hedgewars est un jeu de stratégie au tour par tout mais le vrai intérêt est de regarder la dévastation causée par ces satanés hérissons avec ces armes fantastiques - sournois petits gars au mauvais comportement!
+
+En d'autres mots Hedgewars est un jeu au tour par tour basé sur la stratégie, l'artillerie, l'action et la comédie, présentant les pitreries des hérissons roses pendant qu'ils combattent des profondeurs de l'enfer aux profondeurs de l'espace.
+
+En tant que commandant, c'est votre devoir de rassembler votre folle équipe de soldats hérissons et de partir en guerre contre l'ennemi.
+
+Chaque joueur contrôle une équipe de plusieurs hérissons. Pendant le déroulement du jeu, les joueurs prennent leur tour avec un de leurs hérissons. Ils peuvent utiliser n'importe-quels outils ou armes disponibles pour attaquer et tuer les hérissons des opposants, et ainsi gagner la partie. Les hérissons peuvent bouger autour du terrain de diverses façons, généralement en marchant et sautant mais aussi en utilisant des outils particuliers comme la "Corbe" ou le "Parachute", pour atteindre des zones inaccessibles en d'autres circonstances. Chaque tour est limité en temps afin d'être sûr que les joueurs ne mettent pas le jeu en suspens en pensant ou bougeant à excès. Une grande diversité d'outils et d'armes sont disponibles pour les joueurs pendant le jeu : la Grenade, la Grenade à Fragmentation, le Bazooka, l'OVNI, le fusil à pompes, le Desert Eagle, le Poing de Feu, la Batte de Baseball, la Dynamite, la Mine, la Corbe, le Ramassage Pneumatique, le Parachute. La plupart des armes, lorsqu'elles sont utilisées, causent des explosions qui déforment le terrain, en enlevant des morceaux circulaires. Le paysage est une île flottant sur un plan d'eau. Un hérisson meure quand il entre dans de l'eau (soit en tombant en dehors de l'île, soit à travers un trou situé au fond de celle-ci), quand il est éjecté de n'importe-quel côté de l'arène ou quand sa santé est réduite, généralement au contact des explosions, à zéro (les dégâts infligés à l'hérisson ou aux hérissons attaqués après le tour d'un joueur ou d'un ordinateur est seulement montré quand tous les mouvements sur le champ de bataille ont cessé).
+
+* des combats tordants et dévastateurs basés sur le tour par tour jusqu'à 6 joueurs
+* multijoueur à la fois local et en réseau, avec d'optionnels opposants IA
+* Combattez sur un nombre infini de cartes générées aléatoirement, avec plus de 20 environnements
+* Utilisez 48 (et plus) d'armes écrasantes! Y compris la frappe de piano et le gateau explostif robotique
+* Jouez au jeu à votre façon, avec plus de 20 modificateurs de jeux différents, déformez presque chaque aspect du match
+* Personnalisez votre équipe, avec plus de 120 costumes, 30 tombes, 12 forts, 100s de drapeaux et d'uniques packs de voix
+* D'énormes batailles avec jusqu'à 64 hérissons
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_it.txt b/project_files/HedgewarsMobile/Locale/hw-desc_it.txt
new file mode 100644
index 0000000..48c4f38
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_it.txt
@@ -0,0 +1,31 @@
+Hedgewars, è Esplosivo!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars è disponiile sul Mac Appstore! Cerca Hedgewars sul tuo Mac e scarica la tua copia gratuitamente!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+La verisone per iOS offre alcune fantastiche esclusive, come
+* iPad VGA Out: attacca un dispaly esterno e gioca a piena risoluzione;
+* Retina Display Support: gioca ad una risoluzione pià alta per tutta la durata della partita;
+* Multitasking: metti in pausa il gioco in qualunque istante;
+* Game Restore: potrai ripristinare la partita in qualunque momento.
+
+Descrizione:
+Questio è videogioco più divertente che potrai provare - esilaranti momenti di divertimento che potrai sperimentare in qualsiasi momento e luogo. Hedgewars è un gioco di strategia a turni ma con una marcia in più: vedrai che devastazione sono in grado di causare questi riccetti rosa - creature scaltre con un pessimo carattere!
+
+In altre parole, Hedgewars è un gioco di strategia a turni, con elementi di artiglieria e azione, e con protagonisti ricci rosa che combattano dall profondità dell'inferno all'infinità dello spazio.
+
+Come comandante, dovrai radunare la tua squadra di ricci soldato e dichiarare guerra al tuo nemico.
+
+Ogni giocatore controlla una squadra di parecchi ricci; durante lo svologimento della partita, i giocatori controllano a turno uno dei loro ricci. Dopodiché usano una qualunque arma e strumento a disposizione per attare e uccidere i ricci nemici, vicendo così la parita. I ricci si posso muovere sul terreno di gioco in parecchi modi, normalmente camminando e saltando qua e là , ma anche usando strumenti particolari, come la "Corda", il "Paracadute" e il "Teletrasporto", per raggiungere posizioni impossibili. Ogni turno è dura una certa quantità di tempo per permettere ai giocatori una partita fluida senza stalli per preparare una strategia. Una grande varietà di strumenti sono disponibili per i giocatori: Granata, Bomba a Frammentazione, Bazooka, UFO, Fucile a Pompa, Aquila del Deserto, Pugno di Fuoco, Mazza da Baseball, Dinamite, Mina, Corda, Martello Pneumatico, Paracadute. La maggior parte delle armi quando utilizzate causano esplosioni che modificano il terreno, eliminando elementi circolari. Il terreno di gioco è un'isola circondata dal mare o una caverna sperduta con acqua a portata di mano. I ricci non sanno nuotare per cui affogheranno se vi cadranno (o se veranno lanciati); l'effetto sarà identico se i punti salute dei ricci raggiungeranno lo zero (i danni inflitti al riccio sono mostrati solo alla fine del turno quando tutti i ricci saranno fermi).
+
+* Esilaranti turni di devastazione fino a 8 giocatori
+* Partite in locale e in multiplayer su rete, con squadre controllate dall'intelligenza artificiale (opzionale)
+* Combatti su un numero infinito di mappe casuali, con oltre 20 temi disponibili
+* Usa 48 (e oltre) armi devastanti! Incluso il Paino e la Torta esplosiva
+* Gioca come ti pare, con oltre 20 tipi di modificatori di gioco, puoi cambiare qualsiasi aspetto della partita
+* Personalizza la tua squadra, con oltre 120 cappelli, 30 tombe, 12 fortini, centinaia di bandiere e voci uniche
+* Gigantesche battaglie con oltre 64 ricci
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_ja.txt b/project_files/HedgewarsMobile/Locale/hw-desc_ja.txt
new file mode 100644
index 0000000..e43216b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_ja.txt
@@ -0,0 +1,28 @@
+
+Hedgewars, ãã©ã¹ãã ï¼
+
+Hedgewars ã Mac ã¢ããã¹ãã¢ã«ç»å ´! Mac 㧠Hedgewars ãæ¤ç´¢ãã¦ç¡æã³ãã¼ãä»ãããã¦ã³ãã¼ãããã!
+
+iOS ãã¼ãã¯ããã¤ãã®éå®ãã£ã¼ãã£ã¼ãããã¾ããä¾ãã°ï¼
+* iPad VGA ã¢ã¦ã: å¤é¨ãã£ã¹ãã¬ã¤ãæ¥ç¶ãã¦ãã«è§£å度ã§ãã¬ã¼
+* Retina ãã£ã¹rãã¬ã¤ãµãã¼ã: ã²ã¼ã ã®å
¨ã¦ãé«ã解å度ã§ãã¬ã¼;
+* ãã«ãã¿ã¹ãã³ã°: ãã¤ã§ãã²ã¼ã ããã¼ãº;
+* ã²ã¼ã ãªã¹ãã¢: ããªãã¯ä½ãä½ã§ãããããå®æããããã¨ãã§ãã¾ãã
+
+説æ:
+ããã¯ããªããéã¶ä¸çªé¢ç½ãã¦ä¾åçã®ããã²ã¼ã ã§ã - ãã¤ã§ããã©ãã§ã楽ãããé½æ°ãªæ¥½ãã¿ã Hedgewars ã¯ã¿ã¼ã³å¶ã¹ãã©ãã¸ã¼ã²ã¼ã ã§ãããæ¬å½ã®æ¥½ãã¿ã¯ãã®åä»ãªããªããºãããã°ãããæ¦å¨ã使ã£ã¦èµ·ããç ´å£ãè¦ããã¨ã§ã - æªãæ
度ã®å°ããªåä»è
!
+
+è¨ãæããã°ã Hedgewars ã¯ã¿ã¼ã³è£½ã¹ãã©ãã¸ã¼ãç ²å
µãã¢ã¯ã·ã§ã³ã¨ã³ã¡ãã£ã²ã¼ã ã§ãå°çããå®å®ã¾ã§ãæªãµããããããã³ã¯ã®ããªããºããç¹è²ã§ãã
+
+å¸ä»¤å®ã¨ãã¦ã®ããªãã®å½¹ç®ã¯ããªããºãå
µã®ãã¼ã ãç·¨æããæµã«æ¦äºãæã£ã¦ãããã¨ã§ãã
+
+ãã¬ã¤ã¤ã¼ã¯ããããè¤æ°ã®ããªããºããã³ã³ããã¼ã«ãã¾ããã²ã¼ã ä¸ã¯ãããªããºãã®ä¸ã¤ã使ã£ã¦äº¤ä»£ãã¾ããå©ç¨å¯è½ãªæ¦å¨ãéå
·ã使ã£ã¦æµã®ããªããºããæ»æãã¦æ®ºããåå©ãåãã¾ãã
+Hedgehogs ã¯å°å½¢ããã¾ãã¾ãªæ¹æ³ã§åãåãã¾ããæ®æ®µã¯æ©ãããã¸ã£ã³ãããããã¾ããã"ãã¼ã"ã"ãã©ã·ã¥ã¼ã"ãªã©ã®ç¹å®ã®éå
·ã使ã£ã¦æ¬æ¥ãªãå±ããªãã¨ãªã¢ã«ç§»åãããã¨ãã§ãã¾ããã¿ã¼ã³ã¯ãã¬ã¤ã¤ã¼ãåããããèãããããæéãã¨ãéããªãããã«ã¿ã¤ã ãªããããããã£ã¦ãã¾ããã²ã¼ã ä¸ã¯ãã¾ãã¾ãªéå
·ãæ¦å¨ã使ãã¾ãï¼æ榴弾ãã¯ã©ã¹ã¿ã¼çå¼¾ãUFOãã·ã§ããã¬ã³ããã¶ã¼ãã¤ã¼ã°ã«ããã¡ã¤ã¢ã¼ãã³ããéçãããããã¤ããã¤ããå°é·ããã¼ãããã¥ã¼ãããã¯ããã¯ããã©ã·ã¥ã¼ãã§ããã»ã¨ãã©ã®æ¦å¨ã¯ã使ç¨æã«ãå°å½¢ãå¤ããççºãèµ·ããã¾ããå°å½¢ã¯æ°´ã®ä¸ã«æµ®ããã§ãã島ããä¸ã«æ°´ãããæ´çªã§ããããªããºãã¯æ°´ã®ä¸ã«å
¥ããï¼å³¶ããè½ã¡ãããç©´ãéã£ã¦ï¼ãã¢ãªã¼ãã®æ¨ªããè½ã¨ãããããççºãªã©ã§ä½åãã¼ãã«æ¸ãã¨ï¼ãã¬ã¼ã¤ã¼ãCPUã®ã¿ã¼ã³ã®ãã¡ã¼ã¸ã¯å
¨ã¦ã®åããæ¢ã¾ã£ãå¾è¡¨ç¤ºããã¾ãï¼æ»ãã§ãã¾ãã¾ãã
+
+* å
人ã¾ã§ã®é½æ°ã¨å£æ»
çãªã¿ã¼ã³å¶ã³ã³ããã
+* AIã追å å¯è½ãªãã¼ã«ã«ã¨ãããã¯ã¼ã¯ä¸ã®ãã«ããã¬ã¼ã¤ã¼
+* ã©ã³ãã ã§ä½æãããç¡éã®ãããã¨äºå以ä¸ã®ç°å¢ã®ä¸ã§æ¦ãã
+* 48ï¼ä¸æä¸ï¼ã®å§åçãªæ¦å¨ã使ããï¼ãã¢ãã¹ãã©ã¤ã¯ã¨ççºçãªããããã±ã¼ããå«ã¿ã¾ãã
+* äºå種é¡ä»¥ä¸ã®ã²ã¼ã 修飾æ³ã§æ¦ãã®ã»ã¨ãã©ã®é¨åã微調æ´ãã¦èªåã®ããæ¹ã§ãã¬ã¼ããã
+* 120以ä¸ã®ã³ã¹ãã¥ã¼ã ã30以ä¸ã®å¢ã12以ä¸ã®ç ¦ã100以ä¸ã®ãã©ã°ãã¦ãã¼ã¯ãªãã¤ã¹ããã¯ã§ãã¼ã ãã«ã¹ã¿ãã¤ãº
+* 64ä½ã¾ã§ã®åºå¤§ãªæ¦ã
\ No newline at end of file
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_pl.txt b/project_files/HedgewarsMobile/Locale/hw-desc_pl.txt
new file mode 100644
index 0000000..a88b9fc
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_pl.txt
@@ -0,0 +1,31 @@
+Hedgewars jest super!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+Hedgewars jest dostÄpny na Mac Appstore! Poszukaj Hedgewars na swoim Mac'u i otrzymaj kopiÄ za darmo!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+Port na iOS posiada kilka unikalnych funkcji, takich jak:
+* Wtyczka iPad VGA : podÅÄ
cz zewnÄtrzny ekran i graj w peÅnej rozdzielczoÅci;
+* Wsparcie dla Retina Display: graj caÅÄ
grÄ w wyższej rozdzielczoÅci;
+* WielozadaniowoÅÄ: pauzuj grÄ kiedy chcesz;
+* Wznawianie gry: zawsze możesz dokoÅczyÄ swój mecz;.
+
+Opis:
+To najzabawniejsza i najbardziej uzależniajÄ
ca gra w jakÄ
kiedykolwiek graÅeÅ - niezwykÅa zabawa, w którÄ
możesz wciÄ
gnÄ
Ä siÄ zawsze i wszÄdzie. Hedgewars to turowa gra strategiczna, jednak najlepsze jest patrzenie, jak te maÅe jeże niszczÄ
otoczenie swoim niecodziennym orÄżem. Nie daj siÄ zmyliÄ pozorom - to podstÄpne maÅe gagatki z nie do koÅca dobrÄ
postawÄ
.
+
+Inaczej mówiÄ
c Hedgewars jest komediowÄ
grÄ
strategicznÄ
, artylerii i akcji, w której do Åez rozbawiÄ
ciÄ wybryki jeżów z charakterkiem, które walczÄ
ze sobÄ
przy każdej okazji.
+
+W roli dowódcy, TwojÄ
robotÄ
bÄdzie zorganizowanie ekipy jeży i sprawienie piekÅa przeciwnikowi.
+
+Każdy gracz kontroluje drużynÄ zÅożonÄ
z kilku jeży. Podczas gry, uczestnicy kierujÄ
jednym jeżem na turÄ. MogÄ
wtedy używaÄ przeróżnych narzÄdzi i broni, którymi rozniesie w pyÅ jeże wroga, w ten sposób zwyciÄżajÄ
c. Jeże przemieszczaÄ siÄ mogÄ
na różnorakie sposoby, m.in. chodzÄ
c lub skaczÄ
c, ale również używajÄ
c narzÄdzi takich jak lina, czy spadochron, aby dostaÄ siÄ do trudno dostÄpnych obszarów. Każda tura jest ograniczona czasowo, aby zapewniÄ brak sytuacji, w których gracz zbyt dÅugo "zastanawia siÄ nad ruchem". Gracze do dyspozycji majÄ
dużÄ
pulÄ broni i narzÄdzi: granaty, bomby kasetowe, bazooki, UFO, strzelby, pistolety Desert Eagle, kije baseballowe, dynamity, miny, mÅoty pneumatyczne. WiÄkszoÅÄ typów orÄża powoduje eksplozje, które deformujÄ
teren zostawiajÄ
c okrÄ
gÅe wyrwy. Mapa jest unoszÄ
cÄ
siÄ na wodzie wyspÄ
, lub ograniczonÄ
jaskiniÄ
, z wodÄ
na dnie. Jeż umiera, gdy znajdzie siÄ w wodzie (na przykÅad przez wyrzucenie poza wyspÄ lub wpadniÄcie do dziury), wypadnie poza mapÄ, lub jeÅli jego poziom zdrowia wyniesie 0 (obrażenia zadane jeżom przez gracza lub CPU ukazujÄ
siÄ gdy wszystkie ruchy sÄ
zatrzymane).
+
+* Komiczne i niszczycielskie boje podzielone na tury dla maksymalnie 6 graczy
+* Możliwa jest gra zarówno lokalna jak i sieciowa z opcjonalnymi przeciwnikami AI
+* Bitwy na nieskoÅczonej iloÅci, losowo generowanych map z ponad 20 różnymi Årodowiskami
+* Aż 48 rodzajów (liczba ciÄ
gle roÅnie) druzgocÄ
cych broni! MiÄdzy innymi zrzut pianina, czy eksplodujÄ
ce ciasto urodzinowe
+* Graj jak tylko chcesz. Masz do dyspozycji ponad 20 modyfikacji, możesz zasmakowaÄ każdego aspektu rozgrywki.
+* Dostosuj swojÄ
drużynÄ do wÅasnych zachcianek. Możesz wybraÄ 120 przebraÅ, 30 grobów, 12 fortów, setki flag oraz unikalne zestawy gÅosów
+* Ogromne bitwy, w których mogÄ
uczestniczyÄ aż 64 jeże.
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_pt.txt b/project_files/HedgewarsMobile/Locale/hw-desc_pt.txt
new file mode 100644
index 0000000..71a2918
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_pt.txt
@@ -0,0 +1,31 @@
+Hedgewars, é um Estrondo!
+
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+O Hedgewars está disponÃvel na Mac App Store! Pesquisa Hedgewars no teu MacBook e obtém a tua cópia GRATUITA hoje!
+âââââââââââââââââââââââââââ
+âââââââââââââââââââââââââââ
+
+A versão para iOS tem algumas funcionalidades exclusivas, como
+* SaÃda VGA no iPad: liga-o a um ecrã externo e joga em resolução completa;
+* Suporte para Retina Display: joga numa resolução mais alta durante todo o jogo;
+* Multitarefa: pausa o jogo a qualquer altura;
+* Restaurar o jogo: vais ser sempre capaz de completar o teu jogo.
+
+Descrição:
+Este é o mais divertido e viciante jogo que alguma vez vais jogar - diversão hilariante a qual podes aproveitar onde estives, quando quiseres. Hedgewars é um jogo de estratégia por turnos, mas o que é ainda mais espetacular, é ver a destruição causada pelos pequenos ouriços e o seu fantásticas arsenal!
+
+Por outras palavras, Hedgewars é um jogo de estratégia por turnos, artilharia, ação e comédia, patrocinado pelas palhaçadas dos pequenos ouriços cor-de-rosa cheios de atitude, enquanto lutam das profundezas do inferno ás do espaço.
+
+Como comandante, é o teu trabalho reunir uma equipa de ouriços especialistas e levar a guerra ao teu inimigo.
+
+Cada jogador controla uma equipa de vários ouriços. Durante o decorrer do jogo, os jogadores controlam alternadamente um dos seus ouriços. Depois utilizam qualquer ferramenta ou arma disponÃvel para atacar e destruir os ouriços oponentes, ganhando assim o jogo. Os ouriços podem deslocar-se pelo terreno de variadÃssimas maneiras, normalmente a andar e a saltar, mas também utilizando ferramentas como a "Corda" ou o "Paraquedas", para chegarem a áreas de outro modo inacessÃveis. Cada turno tem tempo limitado para garantir que os jogadores não passam demasiado tempo a pensar ou a movimentar-se. Uma grande variedade de ferramentas e armas estão disponÃveis durante o jogo: Granada, Bomba de Fragmentos, Bazuca, Disco Voador, Caçadeira, Desert Eagle, Shoryuken, Taco de Basebol, Dinamite, Mina, Corda, Martelo Pneumático, Paraquedas. A maioria das armas, quando utilizadas, causam explosões que deformam o terreno, removendo pedaços circulares. A paisagem é simplesmente uma ilha a flutuar numa massa de água, ou uma caverna com água no fundo. Um ouriço morre quando entra na água (caindo da ilha, ou através de um buraco), é atirado para fora da arena ou quando a sua vida é reduzida, tipicamente quando entra em contacto com explosões, a zero (o dano causado ao ouriço ou ouriços atacados, após o turno de um jogador ou CPU, é apenas mostrado quando todo o movimento no campo de batalha tiver acabado).
+
+* Hilariante e devastador jogo de combate por turnos para até 6 jogadores
+* Modo local e multijogador por rede, com oponentes IA opcionais
+* Batalha num número ilimitado de mapas gerados aleatoriamente, e em mais de 20 ambientes diferentes
+* Utiliza 48 (e a aumentar) impressionantes armas! Incluindo o ataque piano e o bolo robótico explosivo
+* Joga o jogo à tua maneira, com mais de 20 modificadores de jogo diferentes, muda quase todos os aspectos do jogo
+* Personaliza a tua equipa, com mais de 120 chapéus, 30 sepulturas, 12 fortes, 100s de bandeiras e packs de voz únicos
+* Enormes batalhas com até 64 ouriços
+
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_ro.txt b/project_files/HedgewarsMobile/Locale/hw-desc_ro.txt
new file mode 100644
index 0000000..a0d3ff6
--- /dev/null
+++ b/project_files/HedgewarsMobile/Locale/hw-desc_ro.txt
@@ -0,0 +1,25 @@
+RÄzboiul aricilor! E beton!
+RÄzboiul aricilor este disponibil pentru Mac Appstore! CautÄ RÄzboiul aricilor pe Mac-ul tÄu Èi downloadeazÄ o copie GRATUITÄ acum!
+
+Portarea iOS are câteva caracteristici exclusive, cum ar fi:
+* IeÈire VGA pe iPad: ataÈezÄ un dispozitiv extern Èi joacÄ la rezoluÈie maximÄ;
+* Suport pentru ecran Retina: joacÄ la o rezoluÈie mai mare tot jocul;
+* Multitasking : întrerupe jocul oricând;
+* Restaurarea joc: vei putea sÄ termini meciul oricând, indiferent de situaÈie;
+
+Descriere:
+Acesta este cel mai distractiv Èi cel mai captivant joc pe care îl vei juca - distracÈie hilarÄ, putând sÄ te distrezi oriunde, oricând. RÄzboiul aricilor este un joc de strategie bazat pe runde dar adevÄratul zumzet e sÄ vezi devastarea fÄcutÄ de acei arici plictisitori cu armele lor fantastice - mici distrugÄtori laÈi cu o atitudine rea.
+
+Cu alte cuvinte, RÄzboiul aricilor este un joc de strategie, artilerie, de acÈiune Èi comedie, bazat pe runde, oferind aricii rozi Èi antici cu atitudine, în timp ce se bat din adâncurile iadului pânÄ la suprafaÈa cosmosului.
+
+Ca Èi comandant, este responsabilitatea ta sa asamblezi o echipÄ tare de arici soldaÈi Èi sÄ declari rÄzboi inamicului.
+
+Fiecare jucÄtor controleazÄ o echipÄ de mai mulÈi arici. Ãn timpul jocului, jucÄtorii joacÄ pe rând în fiecare rând cu aricii lor. Pot folosi orice unelte sau arme au la dispoziÈie, pentru a ataca aricii inamicului, câÈtigând jocul. Aricii se pot muta pe teren în o mulÈime de metode, în mod normal mergând Èi sÄrind, dar Èi folosind unelte particulare ca Èi âFunieâ sau âParaÈutÄâ, pentru a ajunge în zone de altfel inaccesibile. Fiecare rundÄ e limitatÄ la timp pentru a se asigura cÄ jucÄtorii nu Èin jocul prin gândire sau mutare excesivÄ. O mare varietate de unelte Èi arme sunt valabile pentru jucÄtori în timpul jocului: Grenade, BombÄ Ã®ndesatÄ, Bazuca, OZN, Shotgun, Desert Eagle, Pumn de foc, Minge de baseball, DinamitÄ, MinÄ, Funie, Ciocan pneumatic, ParaÈutÄ. Majoritatea armelor, când sunt utilizate cauzeazÄ explozii care deformeazÄ terenul, eliminând pÄrÈile circulare. Peisajul este o insulÄ plutitoare, sau o peÈterÄ restrictivÄ cu apÄ pe jos. Un arici moare când ajunge în apÄ (fie cÄzând de pe insulÄ sau printr-o cauzÄ Ã®n fundul ei), este aruncat într-o parte a arenei sau când viaÈa îi este redusÄ, în mod normal din cauza unei explozii, la 0 (dauna datÄ la ariciul sau aricii atacaÈi, dupÄ ce runda jucÄtorului sau UCP-ului este arÄtatÄ, doar când toatÄ miÈcarea de pe câmpul de luptÄ se terminÄ)
+
+* BÄtaie hilarÄ Èi devastatoare pe runde, pentru pânÄ la 6 jucÄtori
+* Multiplayer local sau în reÈea, cu inamici IA opÈionali
+* Bate-te pe o infinitate de hÄrÈi generate aleator, în peste 20 de medii
+* FoloseÈte 48 (Èi încÄ se mai numÄrÄ) de arme copleÈitoare! Incluzând lovitura de pian Èi tortul robotic exploziv
+* JoacÄ-te în felul tÄu, cu mai mult de 20 de modificatori ai jocului, optimizând fiecare aspect al meciului
+* PersonalizeazÄ-Èi echipa, cu peste 120 de costume, 30 de morminte, 12 fortÄreÈe, 100 de steaguri Èi pachete de voce unice.
+* BÄtÄli imense cu pânÄ la 64 de arici.
\ No newline at end of file
diff --git a/project_files/HedgewarsMobile/Locale/hw-desc_tr.txt b/project_files/HedgewarsMobile/Locale/hw-desc_tr.txt
new file mode 100644
index 0000000..8f5600f
Binary files /dev/null and b/project_files/HedgewarsMobile/Locale/hw-desc_tr.txt differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/backButton.png b/project_files/HedgewarsMobile/Resources/Frontend/backButton.png
new file mode 100644
index 0000000..f4fc794
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/backButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/backButton at 2x.png b/project_files/HedgewarsMobile/Resources/Frontend/backButton at 2x.png
new file mode 100644
index 0000000..b02726d
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/backButton at 2x.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-xlarge-mdpi/background.png b/project_files/HedgewarsMobile/Resources/Frontend/background.png
similarity index 100%
copy from project_files/Android-build/SDL-android-project/res/drawable-xlarge-mdpi/background.png
copy to project_files/HedgewarsMobile/Resources/Frontend/background.png
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/helpButton.png b/project_files/HedgewarsMobile/Resources/Frontend/helpButton.png
new file mode 100644
index 0000000..329d666
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/helpButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/netplayButton.png b/project_files/HedgewarsMobile/Resources/Frontend/netplayButton.png
new file mode 100644
index 0000000..c0b4701
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/netplayButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/savesButton.png b/project_files/HedgewarsMobile/Resources/Frontend/savesButton.png
new file mode 100644
index 0000000..6b1c64c
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/savesButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/savesButton at 2x.png b/project_files/HedgewarsMobile/Resources/Frontend/savesButton at 2x.png
new file mode 100644
index 0000000..ef4f108
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/savesButton at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/settingsButton.png b/project_files/HedgewarsMobile/Resources/Frontend/settingsButton.png
new file mode 100644
index 0000000..bca73ef
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/settingsButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/settingsButton at 2x.png b/project_files/HedgewarsMobile/Resources/Frontend/settingsButton at 2x.png
new file mode 100644
index 0000000..26de34d
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/settingsButton at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle.png b/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle.png
new file mode 100644
index 0000000..5f00cd8
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle at 2x.png b/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle at 2x.png
new file mode 100644
index 0000000..93992b0
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/smallerTitle at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/startGameButton.png b/project_files/HedgewarsMobile/Resources/Frontend/startGameButton.png
new file mode 100644
index 0000000..ecbf586
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/startGameButton.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Frontend/startGameButton at 2x.png b/project_files/HedgewarsMobile/Resources/Frontend/startGameButton at 2x.png
new file mode 100644
index 0000000..d16a364
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Frontend/startGameButton at 2x.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-xlarge-mdpi/background.png b/project_files/HedgewarsMobile/Resources/Icons/Default-ipad-Landscape.png
similarity index 100%
copy from project_files/Android-build/SDL-android-project/res/drawable-xlarge-mdpi/background.png
copy to project_files/HedgewarsMobile/Resources/Icons/Default-ipad-Landscape.png
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Default.png b/project_files/HedgewarsMobile/Resources/Icons/Default.png
new file mode 100644
index 0000000..15fd42d
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Default.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Default at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/Default at 2x.png
new file mode 100644
index 0000000..6770298
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Default at 2x.png differ
diff --git a/project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/icon.png b/project_files/HedgewarsMobile/Resources/Icons/Icon-72.png
similarity index 100%
copy from project_files/Android-build/SDL-android-project/res/drawable-large-mdpi/icon.png
copy to project_files/HedgewarsMobile/Resources/Icons/Icon-72.png
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Icon-Small-50.png b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small-50.png
new file mode 100644
index 0000000..feb3883
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small-50.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Icon-Small.png b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small.png
new file mode 100644
index 0000000..100bc6c
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Icon-Small at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small at 2x.png
new file mode 100644
index 0000000..1f387ff
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Icon-Small at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Icon.png b/project_files/HedgewarsMobile/Resources/Icons/Icon.png
new file mode 100644
index 0000000..35aeb51
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Icon.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/Icon at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/Icon at 2x.png
new file mode 100644
index 0000000..9ea773f
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/Icon at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog.png b/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog.png
new file mode 100644
index 0000000..6ff742e
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog at 2x.png
new file mode 100644
index 0000000..2c8218f
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/basehat-hedgehog at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot0.png b/project_files/HedgewarsMobile/Resources/Icons/bot0.png
new file mode 100644
index 0000000..8558c86
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot0.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot0 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot0 at 2x.png
new file mode 100644
index 0000000..5fbcf33
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot0 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot1.png b/project_files/HedgewarsMobile/Resources/Icons/bot1.png
new file mode 100644
index 0000000..02a07f6
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot1.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot1 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot1 at 2x.png
new file mode 100644
index 0000000..c206a31
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot1 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot2.png b/project_files/HedgewarsMobile/Resources/Icons/bot2.png
new file mode 100644
index 0000000..586ccc6
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot2.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot2 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot2 at 2x.png
new file mode 100644
index 0000000..fab1be0
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot2 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot3.png b/project_files/HedgewarsMobile/Resources/Icons/bot3.png
new file mode 100644
index 0000000..a3d57f5
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot3.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot3 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot3 at 2x.png
new file mode 100644
index 0000000..4bfc8eb
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot3 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot4.png b/project_files/HedgewarsMobile/Resources/Icons/bot4.png
new file mode 100644
index 0000000..15f3457
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot4.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot4 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot4 at 2x.png
new file mode 100644
index 0000000..095cc91
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot4 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot5.png b/project_files/HedgewarsMobile/Resources/Icons/bot5.png
new file mode 100644
index 0000000..6117a8c
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot5.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/bot5 at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/bot5 at 2x.png
new file mode 100644
index 0000000..8d998e8
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/bot5 at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/checkbox.png b/project_files/HedgewarsMobile/Resources/Icons/checkbox.png
new file mode 100644
index 0000000..1a5774e
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/checkbox.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/checkbox at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/checkbox at 2x.png
new file mode 100644
index 0000000..3cb6d18
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/checkbox at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/fb.png b/project_files/HedgewarsMobile/Resources/Icons/fb.png
new file mode 100644
index 0000000..3a36a46
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/fb.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/fb at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/fb at 2x.png
new file mode 100644
index 0000000..6060ef4
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/fb at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/hedgehog.png b/project_files/HedgewarsMobile/Resources/Icons/hedgehog.png
new file mode 100644
index 0000000..40dfa75
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/hedgehog.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/hedgehog at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/hedgehog at 2x.png
new file mode 100644
index 0000000..bdcc4dc
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/hedgehog at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/iTunesArtwork.png b/project_files/HedgewarsMobile/Resources/Icons/iTunesArtwork.png
new file mode 100644
index 0000000..76ecb4d
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/iTunesArtwork.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/irc.png b/project_files/HedgewarsMobile/Resources/Icons/irc.png
new file mode 100644
index 0000000..9047b6a
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/irc.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/irc at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/irc at 2x.png
new file mode 100644
index 0000000..4f8fd96
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/irc at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/robotBadge.png b/project_files/HedgewarsMobile/Resources/Icons/robotBadge.png
new file mode 100644
index 0000000..9a6d285
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/robotBadge.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/robotBadge at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/robotBadge at 2x.png
new file mode 100644
index 0000000..f33b2c0
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/robotBadge at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/star.png b/project_files/HedgewarsMobile/Resources/Icons/star.png
new file mode 100644
index 0000000..2a5ec59
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/star.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/star at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/star at 2x.png
new file mode 100644
index 0000000..b1cdd3d
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/star at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/tw.png b/project_files/HedgewarsMobile/Resources/Icons/tw.png
new file mode 100644
index 0000000..3d94874
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/tw.png differ
diff --git a/project_files/HedgewarsMobile/Resources/Icons/tw at 2x.png b/project_files/HedgewarsMobile/Resources/Icons/tw at 2x.png
new file mode 100644
index 0000000..8c8f9af
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/Icons/tw at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/backSound.caf b/project_files/HedgewarsMobile/Resources/backSound.caf
new file mode 100644
index 0000000..74c1360
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/backSound.caf differ
diff --git a/project_files/HedgewarsMobile/Resources/basicFlags.plist b/project_files/HedgewarsMobile/Resources/basicFlags.plist
new file mode 100644
index 0000000..6decf0b
--- /dev/null
+++ b/project_files/HedgewarsMobile/Resources/basicFlags.plist
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <dict>
+ <key>default</key>
+ <integer>100</integer>
+ <key>image</key>
+ <string>Health</string>
+ <key>max</key>
+ <integer>200</integer>
+ <key>min</key>
+ <integer>50</integer>
+ <key>title</key>
+ <string>Initial Health</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$damagepct</string>
+ <key>default</key>
+ <integer>100</integer>
+ <key>image</key>
+ <string>Damage</string>
+ <key>max</key>
+ <integer>300</integer>
+ <key>min</key>
+ <integer>10</integer>
+ <key>title</key>
+ <string>Damage Modifier</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <true/>
+ <key>times1000</key>
+ <true/>
+ <key>command</key>
+ <string>e$turntime</string>
+ <key>default</key>
+ <integer>45</integer>
+ <key>image</key>
+ <string>Time</string>
+ <key>max</key>
+ <integer>100</integer>
+ <key>min</key>
+ <integer>1</integer>
+ <key>title</key>
+ <string>Turn Time</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <true/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$sd_turns</string>
+ <key>default</key>
+ <integer>15</integer>
+ <key>image</key>
+ <string>SuddenDeath</string>
+ <key>max</key>
+ <integer>50</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Sudden Death Timeout</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$waterrise</string>
+ <key>default</key>
+ <integer>47</integer>
+ <key>image</key>
+ <string>SuddenDeath</string>
+ <key>max</key>
+ <integer>100</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Water Rise Amount</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$healthdec</string>
+ <key>default</key>
+ <integer>5</integer>
+ <key>image</key>
+ <string>SuddenDeath</string>
+ <key>max</key>
+ <integer>100</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Health Decrease</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$ropepct</string>
+ <key>default</key>
+ <integer>100</integer>
+ <key>image</key>
+ <string>Rope</string>
+ <key>max</key>
+ <integer>999</integer>
+ <key>min</key>
+ <integer>25</integer>
+ <key>title</key>
+ <string>Rope Length (%)</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$casefreq</string>
+ <key>default</key>
+ <integer>5</integer>
+ <key>image</key>
+ <string>Box</string>
+ <key>max</key>
+ <integer>9</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Crate Drop Turns</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$healthprob</string>
+ <key>default</key>
+ <integer>35</integer>
+ <key>image</key>
+ <string>Health</string>
+ <key>max</key>
+ <integer>100</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Health Kit Probability (%)</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$hcaseamount</string>
+ <key>default</key>
+ <integer>25</integer>
+ <key>image</key>
+ <string>Health</string>
+ <key>max</key>
+ <integer>200</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Health Amount in Kit</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <true/>
+ <key>command</key>
+ <string>e$minestime</string>
+ <key>default</key>
+ <integer>3</integer>
+ <key>image</key>
+ <string>Time</string>
+ <key>max</key>
+ <integer>5</integer>
+ <key>min</key>
+ <integer>-1</integer>
+ <key>title</key>
+ <string>Mines Time</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$minesnum</string>
+ <key>default</key>
+ <integer>4</integer>
+ <key>image</key>
+ <string>Mine</string>
+ <key>max</key>
+ <integer>80</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Mines Number</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$minedudpct</string>
+ <key>default</key>
+ <integer>0</integer>
+ <key>image</key>
+ <string>Dud</string>
+ <key>max</key>
+ <integer>100</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Dud Mines Probability (%)</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$explosives</string>
+ <key>default</key>
+ <integer>2</integer>
+ <key>image</key>
+ <string>Damage</string>
+ <key>max</key>
+ <integer>40</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Explosives</string>
+ </dict>
+ <dict>
+ <key>checkOverMax</key>
+ <false/>
+ <key>times1000</key>
+ <false/>
+ <key>command</key>
+ <string>e$getawaytime</string>
+ <key>default</key>
+ <integer>100</integer>
+ <key>image</key>
+ <string>Time</string>
+ <key>max</key>
+ <integer>999</integer>
+ <key>min</key>
+ <integer>0</integer>
+ <key>title</key>
+ <string>Get Away Time (%)</string>
+ </dict>
+</array>
+</plist>
diff --git a/project_files/HedgewarsMobile/Resources/clickSound.caf b/project_files/HedgewarsMobile/Resources/clickSound.caf
new file mode 100644
index 0000000..7a43514
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/clickSound.caf differ
diff --git a/project_files/HedgewarsMobile/Resources/credits.plist b/project_files/HedgewarsMobile/Resources/credits.plist
new file mode 100644
index 0000000..d3584ab
--- /dev/null
+++ b/project_files/HedgewarsMobile/Resources/credits.plist
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <array>
+ <string>Andrey "UnC0Rr" Korotaev</string>
+ <string>Igor "Displacer" Ulyanov</string>
+ <string>Derek "Nemo" Pomery</string>
+ <string>Martin "Affect" Boze</string>
+ <string>David "Krawek" Cuadrado</string>
+ <string>Martin "Ttsmj" Minarik</string>
+ <string>Kristian "TheXception" Lehmann</string>
+ <string>Vittorio "Koda" Giovara</string>
+ <string>Mario "Smaxx" Liebisch</string>
+ <string>Carlos "Palewolf" Vives</string>
+ <string>Richard "Sheepluva" Korlyi</string>
+ <string>Henning "Prg" Kühn</string>
+ <string>Henrik "Henek" Rostedt</string>
+ <string>John "Mikade" Lambert</string>
+ <string>Mayur "Zorg" Pawashe</string>
+ <string>Richard "Xeli" Deurwaarder</string>
+ </array>
+ <array>
+ <string>John "Fizzy" Dum</string>
+ <string>Joshua Frese</string>
+ <string>Stanko TadiÄ</string>
+ <string>Julien Koesten</string>
+ <string>Joshua O'Sullivan</string>
+ <string>Nils Luck</string>
+ <string>Trey Perry</string>
+ </array>
+ <array>
+ <string>Stephen "Armagon" Alexander</string>
+ <string>John "Fizzy" Dum</string>
+ <string>Jonatan Nilsson</string>
+ <string>Daniel Martin</string>
+ </array>
+ <array>
+ <string>Romulo Fernandes Machado</string>
+ <string>Svetoslav Stefanov</string>
+ <string>Petr ÅezáÄek</string>
+ <string>Jie Luo</string>
+ <string>Andrey Korotaev</string>
+ <string>Nina Kuisma</string>
+ <string>Antoine Turmel</string>
+ <string>Peter Hüwe, Mario Liebisch, Richard Karolyi</string>
+ <string>Talos Kriti</string>
+ <string>Luca Bonora, Marco Bresciani</string>
+ <string>Adam Etienne</string>
+ <string>Anthony Bellew</string>
+ <string>Lukas Urbonas</string>
+ <string>Maciej MroziÅski, Wojciech Latkowski, Piotr Mitana, Maciej Górny</string>
+ <string>Fábio Canário</string>
+ <string>Andrey Korotaev</string>
+ <string>Jose Riha</string>
+ <string>Carlos Vives</string>
+ <string>Niklas Grahn, Henrik Rostedt</string>
+ <string>Eugene V. Lyubimkin, Igor Paliychuk, Eugene Sakara</string>
+ </array>
+ <array>
+ <string>Aleksey Andreev</string>
+ <string>Aleksander Rudalev</string>
+ <string>Natasha Korotaeva</string>
+ <string>Adam Higerd</string>
+ </array>
+ <array>
+ <string>Engine, frontend, net server</string>
+ <string>Many desktop frontend improvements</string>
+ <string>Many engine and desktop frontend improvements</string>
+ <string>Drillrocket, Ballgun, RC Plane weapons</string>
+ <string>Mine number and time game settings</string>
+ <string>Desktop frontend improvements</string>
+ <string>Desktop frontend improvements</string>
+ <string>Mac OS X and iPhone version</string>
+ <string>Many engine and desktop frontend improvements</string>
+ <string>Gamepad and Lua integration</string>
+ <string>Many engine improvements and graphics</string>
+ <string>Maze maps</string>
+ <string>Engine and desktop frontend improvements</string>
+ <string>Lua game modes and missions</string>
+ <string>Desktop frontend improvements</string>
+ <string>Android port</string>
+ </array>
+ <array>
+ <string>Main graphics</string>
+ <string></string>
+ <string></string>
+ <string></string>
+ <string></string>
+ <string></string>
+ <string>Some hats</string>
+ </array>
+ <array>
+ <string>Hedgehogs voice</string>
+ <string></string>
+ <string></string>
+ <string></string>
+ </array>
+ <array>
+ <string>Brazilian Portuguese</string>
+ <string>Bulgarian</string>
+ <string>Czech</string>
+ <string>Chinese</string>
+ <string>English</string>
+ <string>Finnish</string>
+ <string>French</string>
+ <string>German</string>
+ <string>Greek</string>
+ <string>Italian</string>
+ <string>Japanese</string>
+ <string>Korean</string>
+ <string>Lithuanian</string>
+ <string>Polish</string>
+ <string>Portuguese</string>
+ <string>Russian</string>
+ <string>Slovak</string>
+ <string>Spanish</string>
+ <string>Swedish</string>
+ <string>Ukrainian</string>
+ </array>
+ <array>
+ <string></string>
+ <string></string>
+ <string></string>
+ <string></string>
+ </array>
+</array>
+</plist>
diff --git a/project_files/HedgewarsMobile/Resources/denied.png b/project_files/HedgewarsMobile/Resources/denied.png
new file mode 100644
index 0000000..d33d89c
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/denied.png differ
diff --git a/project_files/HedgewarsMobile/Resources/denied at 2x.png b/project_files/HedgewarsMobile/Resources/denied at 2x.png
new file mode 100644
index 0000000..56734d3
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/denied at 2x.png differ
diff --git a/project_files/HedgewarsMobile/Resources/gameMods.plist b/project_files/HedgewarsMobile/Resources/gameMods.plist
new file mode 100644
index 0000000..2a00a75
--- /dev/null
+++ b/project_files/HedgewarsMobile/Resources/gameMods.plist
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <dict>
+ <key>description</key>
+ <string>Land can not be destroyed</string>
+ <key>image</key>
+ <string>Solid</string>
+ <key>title</key>
+ <string>Solid Land</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Add an indestructable border around the terrain</string>
+ <key>image</key>
+ <string>Border</string>
+ <key>title</key>
+ <string>Add Border</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Teams will start on opposite sides of the terrain</string>
+ <key>image</key>
+ <string>TeamsDivide</string>
+ <key>title</key>
+ <string>Divide Team (max 2 teams)</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Lower gravity</string>
+ <key>image</key>
+ <string>LowGravity</string>
+ <key>title</key>
+ <string>Low Gravity</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Assisted aiming with laser sight</string>
+ <key>image</key>
+ <string>LaserSight</string>
+ <key>title</key>
+ <string>Laser Sight</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>All hogs have a personal forcefield</string>
+ <key>image</key>
+ <string>Invulnerable</string>
+ <key>title</key>
+ <string>Invulnerable</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>All (living) hedgehogs are fully restored at the end of turn</string>
+ <key>image</key>
+ <string>ResetHealth</string>
+ <key>title</key>
+ <string>Reset Health</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Gain 80% of the damage you do back in health</string>
+ <key>image</key>
+ <string>Vampiric</string>
+ <key>title</key>
+ <string>Vampirism Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Share your opponents pain, share their damage</string>
+ <key>image</key>
+ <string>Karma</string>
+ <key>title</key>
+ <string>Karma Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Your hogs are unable to move, test your aim</string>
+ <key>image</key>
+ <string>Artillery</string>
+ <key>title</key>
+ <string>Artillery Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Defend your fort and destroy the opponents</string>
+ <key>image</key>
+ <string>Forts</string>
+ <key>title</key>
+ <string>Fort Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Order of play is random instead of in room order</string>
+ <key>image</key>
+ <string>RandomOrder</string>
+ <key>title</key>
+ <string>Random Order</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Play with a King; when he dies, your side loses</string>
+ <key>image</key>
+ <string>King</string>
+ <key>title</key>
+ <string>King Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Take turns placing your hedgehogs pre-game</string>
+ <key>image</key>
+ <string>PlaceHog</string>
+ <key>title</key>
+ <string>Place Hedgehogs</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Ammo is shared between all clan teams</string>
+ <key>image</key>
+ <string>SharedAmmo</string>
+ <key>title</key>
+ <string>Clan Shares Ammo</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Disable girders when generating random maps</string>
+ <key>image</key>
+ <string>DisableGirders</string>
+ <key>title</key>
+ <string>Disable Girders</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Disable land objects when generating maps</string>
+ <key>image</key>
+ <string>DisableLandObjects</string>
+ <key>title</key>
+ <string>Disable Land Objects</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>AI-controlled hogs respawn on death</string>
+ <key>image</key>
+ <string>AISurvival</string>
+ <key>title</key>
+ <string>AI Survival Mode</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Attacking does not end your turn</string>
+ <key>image</key>
+ <string>InfAttack</string>
+ <key>title</key>
+ <string>Unlimited Attacks</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Weapons are reset to starting values each turn</string>
+ <key>image</key>
+ <string>ResetWeps</string>
+ <key>title</key>
+ <string>Reset Weapons</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Each hedgehog has its own ammo</string>
+ <key>image</key>
+ <string>PerHogAmmo</string>
+ <key>title</key>
+ <string>Per Hedgehog Ammo</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>You will not have to worry about wind any more</string>
+ <key>image</key>
+ <string>NoWind</string>
+ <key>title</key>
+ <string>Disable Wind</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Wind will affect almost everything</string>
+ <key>image</key>
+ <string>MoreWind</string>
+ <key>title</key>
+ <string>More Wind</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Clan teams take turns sharing their time</string>
+ <key>image</key>
+ <string>TagTeam</string>
+ <key>title</key>
+ <string>Tag Team</string>
+ </dict>
+ <dict>
+ <key>description</key>
+ <string>Add an indestructible border along the bottom</string>
+ <key>image</key>
+ <string>BottomBorder</string>
+ <key>title</key>
+ <string>Bottom Border</string>
+ </dict>
+</array>
+</plist>
diff --git a/project_files/HedgewarsMobile/Resources/hwclassic.mp3 b/project_files/HedgewarsMobile/Resources/hwclassic.mp3
new file mode 100644
index 0000000..f97eac9
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/hwclassic.mp3 differ
diff --git a/project_files/HedgewarsMobile/Resources/selSound.caf b/project_files/HedgewarsMobile/Resources/selSound.caf
new file mode 100644
index 0000000..691dabf
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/selSound.caf differ
diff --git a/project_files/HedgewarsMobile/Resources/surprise.png b/project_files/HedgewarsMobile/Resources/surprise.png
new file mode 100644
index 0000000..b04833f
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/surprise.png differ
diff --git a/project_files/HedgewarsMobile/Resources/surprise at 2x.png b/project_files/HedgewarsMobile/Resources/surprise at 2x.png
new file mode 100644
index 0000000..7d57254
Binary files /dev/null and b/project_files/HedgewarsMobile/Resources/surprise at 2x.png differ
diff --git a/project_files/hedgewars.pro b/project_files/hedgewars.pro
index 4753772..9985c16 100644
--- a/project_files/hedgewars.pro
+++ b/project_files/hedgewars.pro
@@ -1,261 +1,283 @@
-TEMPLATE = app
-TARGET = hedgewars
-DEPENDPATH += ../QTfrontend/
-INCLUDEPATH += ../QTfrontend/
-INCLUDEPATH += ../QTfrontend/model
-INCLUDEPATH += ../QTfrontend/ui
-INCLUDEPATH += ../QTfrontend/ui/widget
-INCLUDEPATH += ../QTfrontend/ui/page
-INCLUDEPATH += ../QTfrontend/ui/dialog
-INCLUDEPATH += ../QTfrontend/net
-INCLUDEPATH += ../QTfrontend/util
-INCLUDEPATH += ../misc/quazip/
-
-DESTDIR = ../bin
-
-QT += network
-QT += webkit
-
-HEADERS += ../QTfrontend/model/ThemeModel.h \
- ../QTfrontend/model/MapModel.h \
- ../QTfrontend/model/ammoSchemeModel.h \
- ../QTfrontend/model/netserverslist.h \
- ../QTfrontend/ui/page/pagedrawmap.h \
- ../QTfrontend/ui/page/pagedata.h \
- ../QTfrontend/ui/page/pagetraining.h \
- ../QTfrontend/ui/page/pageselectweapon.h \
- ../QTfrontend/ui/page/pagesingleplayer.h \
- ../QTfrontend/ui/page/pagenettype.h \
- ../QTfrontend/ui/page/pageingame.h \
- ../QTfrontend/ui/page/pageadmin.h \
- ../QTfrontend/ui/page/pagescheme.h \
- ../QTfrontend/ui/page/pagemultiplayer.h \
- ../QTfrontend/ui/page/pageplayrecord.h \
- ../QTfrontend/ui/page/pagemain.h \
- ../QTfrontend/ui/page/pageoptions.h \
- ../QTfrontend/ui/page/pagenetgame.h \
- ../QTfrontend/ui/page/pageeditteam.h \
- ../QTfrontend/ui/page/pageconnecting.h \
- ../QTfrontend/ui/page/pageroomslist.h \
- ../QTfrontend/ui/page/pagenet.h \
- ../QTfrontend/ui/page/pagecampaign.h \
- ../QTfrontend/ui/page/pageinfo.h \
- ../QTfrontend/ui/page/pagenetserver.h \
- ../QTfrontend/ui/page/pagegamestats.h \
- ../QTfrontend/ui/dialog/input_ip.h \
- ../QTfrontend/ui/qaspectratiolayout.h \
- ../QTfrontend/ui/widget/bgwidget.h \
- ../QTfrontend/ui/widget/fpsedit.h \
- ../QTfrontend/ui/widget/FreqSpinBox.h \
- ../QTfrontend/ui/widget/igbox.h \
- ../QTfrontend/ui/widget/chatwidget.h \
- ../QTfrontend/ui/widget/togglebutton.h \
- ../QTfrontend/ui/widget/SquareLabel.h \
- ../QTfrontend/ui/widget/itemNum.h \
- ../QTfrontend/ui/widget/frameTeam.h \
- ../QTfrontend/ui/widget/teamselect.h \
- ../QTfrontend/ui/widget/vertScrollArea.h \
- ../QTfrontend/ui/widget/about.h \
- ../QTfrontend/ui/widget/teamselhelper.h \
- ../QTfrontend/ui/widget/drawmapwidget.h \
- ../QTfrontend/ui/widget/databrowser.h \
- ../QTfrontend/ui/widget/hedgehogerWidget.h \
- ../QTfrontend/ui/widget/selectWeapon.h \
- ../QTfrontend/ui/widget/weaponItem.h \
- ../QTfrontend/ui/widget/gamecfgwidget.h \
- ../QTfrontend/ui/widget/mapContainer.h \
- ../QTfrontend/ui/widget/HistoryLineEdit.h \
- ../QTfrontend/ui/widget/SmartLineEdit.h \
- ../QTfrontend/util/DataManager.h \
- ../QTfrontend/net/netregister.h \
- ../QTfrontend/net/netserver.h \
- ../QTfrontend/net/netudpwidget.h \
- ../QTfrontend/net/tcpBase.h \
- ../QTfrontend/net/proto.h \
- ../QTfrontend/net/newnetclient.h \
- ../QTfrontend/net/netudpserver.h \
- ../QTfrontend/net/hwmap.h \
- ../QTfrontend/util/namegen.h \
- ../QTfrontend/ui/page/AbstractPage.h \
- ../QTfrontend/drawmapscene.h \
- ../QTfrontend/game.h \
- ../QTfrontend/gameuiconfig.h \
- ../QTfrontend/HWApplication.h \
- ../QTfrontend/hwform.h \
- ../QTfrontend/util/SDLInteraction.h \
- ../QTfrontend/team.h \
- ../QTfrontend/achievements.h \
- ../QTfrontend/binds.h \
- ../QTfrontend/ui_hwform.h \
- ../QTfrontend/KB.h \
- ../QTfrontend/hwconsts.h \
- ../QTfrontend/sdlkeys.h \
- ../QTfrontend/ui/mouseoverfilter.h \
- ../QTfrontend/ui/qpushbuttonwithsound.h \
- ../QTfrontend/ui/widget/qpushbuttonwithsound.h \
- ../QTfrontend/ui/page/pagefeedback.h \
- ../QTfrontend/model/roomslistmodel.h \
- ../QTfrontend/ui/dialog/input_password.h \
- ../QTfrontend/ui/widget/colorwidget.h \
- ../QTfrontend/model/HatModel.h \
- ../QTfrontend/model/GameStyleModel.h \
- ../QTfrontend/ui/page/pagevideos.h \
- ../QTfrontend/net/recorder.h \
- ../QTfrontend/ui/dialog/ask_quit.h \
- ../QTfrontend/ui/dialog/upload_video.h \
- ../QTfrontend/campaign.h \
- ../QTfrontend/model/playerslistmodel.h \
- ../QTfrontend/util/LibavInteraction.h
-
-SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \
- ../QTfrontend/model/MapModel.cpp \
- ../QTfrontend/model/ThemeModel.cpp \
- ../QTfrontend/model/netserverslist.cpp \
- ../QTfrontend/ui/qaspectratiolayout.cpp \
- ../QTfrontend/ui/page/pagemain.cpp \
- ../QTfrontend/ui/page/pagetraining.cpp \
- ../QTfrontend/ui/page/pageroomslist.cpp \
- ../QTfrontend/ui/page/pagemultiplayer.cpp \
- ../QTfrontend/ui/page/pagegamestats.cpp \
- ../QTfrontend/ui/page/pagenettype.cpp \
- ../QTfrontend/ui/page/pageeditteam.cpp \
- ../QTfrontend/ui/page/pagenetgame.cpp \
- ../QTfrontend/ui/page/pagedata.cpp \
- ../QTfrontend/ui/page/pagedrawmap.cpp \
- ../QTfrontend/ui/page/pageplayrecord.cpp \
- ../QTfrontend/ui/page/pageselectweapon.cpp \
- ../QTfrontend/ui/page/pageingame.cpp \
- ../QTfrontend/ui/page/pagenetserver.cpp \
- ../QTfrontend/ui/page/pagecampaign.cpp \
- ../QTfrontend/ui/page/pageadmin.cpp \
- ../QTfrontend/ui/page/pageinfo.cpp \
- ../QTfrontend/ui/page/pageconnecting.cpp \
- ../QTfrontend/ui/page/pagesingleplayer.cpp \
- ../QTfrontend/ui/page/pagenet.cpp \
- ../QTfrontend/ui/page/pagescheme.cpp \
- ../QTfrontend/ui/page/pageoptions.cpp \
- ../QTfrontend/ui/dialog/input_ip.cpp \
- ../QTfrontend/ui/widget/igbox.cpp \
- ../QTfrontend/ui/widget/selectWeapon.cpp \
- ../QTfrontend/ui/widget/FreqSpinBox.cpp \
- ../QTfrontend/ui/widget/SquareLabel.cpp \
- ../QTfrontend/ui/widget/frameTeam.cpp \
- ../QTfrontend/ui/widget/fpsedit.cpp \
- ../QTfrontend/ui/widget/databrowser.cpp \
- ../QTfrontend/ui/widget/teamselect.cpp \
- ../QTfrontend/ui/widget/gamecfgwidget.cpp \
- ../QTfrontend/ui/widget/chatwidget.cpp \
- ../QTfrontend/ui/widget/itemNum.cpp \
- ../QTfrontend/ui/widget/bgwidget.cpp \
- ../QTfrontend/ui/widget/about.cpp \
- ../QTfrontend/ui/widget/togglebutton.cpp \
- ../QTfrontend/ui/widget/vertScrollArea.cpp \
- ../QTfrontend/ui/widget/hedgehogerWidget.cpp \
- ../QTfrontend/ui/widget/teamselhelper.cpp \
- ../QTfrontend/ui/widget/drawmapwidget.cpp \
- ../QTfrontend/ui/widget/weaponItem.cpp \
- ../QTfrontend/ui/widget/mapContainer.cpp \
- ../QTfrontend/ui/widget/HistoryLineEdit.cpp \
- ../QTfrontend/ui/widget/SmartLineEdit.cpp \
- ../QTfrontend/util/DataManager.cpp \
- ../QTfrontend/net/tcpBase.cpp \
- ../QTfrontend/net/netregister.cpp \
- ../QTfrontend/net/proto.cpp \
- ../QTfrontend/net/hwmap.cpp \
- ../QTfrontend/net/netudpserver.cpp \
- ../QTfrontend/net/newnetclient.cpp \
- ../QTfrontend/net/netudpwidget.cpp \
- ../QTfrontend/net/netserver.cpp \
- ../QTfrontend/util/namegen.cpp \
- ../QTfrontend/ui/page/AbstractPage.cpp \
- ../QTfrontend/achievements.cpp \
- ../QTfrontend/binds.cpp \
- ../QTfrontend/drawmapscene.cpp \
- ../QTfrontend/game.cpp \
- ../QTfrontend/gameuiconfig.cpp \
- ../QTfrontend/HWApplication.cpp \
- ../QTfrontend/hwform.cpp \
- ../QTfrontend/main.cpp \
- ../QTfrontend/util/SDLInteraction.cpp \
- ../QTfrontend/team.cpp \
- ../QTfrontend/ui_hwform.cpp \
- ../QTfrontend/hwconsts.cpp \
- ../QTfrontend/ui/mouseoverfilter.cpp \
- ../QTfrontend/ui/widget/qpushbuttonwithsound.cpp \
- ../QTfrontend/ui/page/pagefeedback.cpp \
- ../QTfrontend/model/roomslistmodel.cpp \
- ../QTfrontend/ui/dialog/input_password.cpp \
- ../QTfrontend/ui/widget/colorwidget.cpp \
- ../QTfrontend/model/HatModel.cpp \
- ../QTfrontend/model/GameStyleModel.cpp \
- ../QTfrontend/ui/page/pagevideos.cpp \
- ../QTfrontend/net/recorder.cpp \
- ../QTfrontend/ui/dialog/ask_quit.cpp \
- ../QTfrontend/ui/dialog/upload_video.cpp \
- ../QTfrontend/campaign.cpp \
- ../QTfrontend/model/playerslistmodel.cpp \
- ../QTfrontend/util/LibavInteraction.cpp
-
-
-TRANSLATIONS += ../share/hedgewars/Data/Locale/hedgewars_ar.ts \
- ../share/hedgewars/Data/Locale/hedgewars_bg.ts \
- ../share/hedgewars/Data/Locale/hedgewars_cs.ts \
- ../share/hedgewars/Data/Locale/hedgewars_de.ts \
- ../share/hedgewars/Data/Locale/hedgewars_en.ts \
- ../share/hedgewars/Data/Locale/hedgewars_es.ts \
- ../share/hedgewars/Data/Locale/hedgewars_fi.ts \
- ../share/hedgewars/Data/Locale/hedgewars_fr.ts \
- ../share/hedgewars/Data/Locale/hedgewars_hu.ts \
- ../share/hedgewars/Data/Locale/hedgewars_it.ts \
- ../share/hedgewars/Data/Locale/hedgewars_ja.ts \
- ../share/hedgewars/Data/Locale/hedgewars_ko.ts \
- ../share/hedgewars/Data/Locale/hedgewars_lt.ts \
- ../share/hedgewars/Data/Locale/hedgewars_nl.ts \
- ../share/hedgewars/Data/Locale/hedgewars_pl.ts \
- ../share/hedgewars/Data/Locale/hedgewars_pt_BR.ts \
- ../share/hedgewars/Data/Locale/hedgewars_pt_PT.ts \
- ../share/hedgewars/Data/Locale/hedgewars_ru.ts \
- ../share/hedgewars/Data/Locale/hedgewars_sk.ts \
- ../share/hedgewars/Data/Locale/hedgewars_sv.ts \
- ../share/hedgewars/Data/Locale/hedgewars_tr_TR.ts \
- ../share/hedgewars/Data/Locale/hedgewars_uk.ts \
- ../share/hedgewars/Data/Locale/hedgewars_zh_CN.ts \
- ../share/hedgewars/Data/Locale/hedgewars_zh_TW.ts
-
-RESOURCES += ../QTfrontend/hedgewars.qrc
-
-LIBS += -L../bin -lquazip
-
-macx {
- QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
- QMAKE_MAC_SDK=/Developer/SDKs/MacOSX10.6.sdk
-
- OBJECTIVE_SOURCES += ../QTfrontend/*.m ../QTfrontend/*.mm
- SOURCES += ../QTfrontend/AutoUpdater.cpp ../QTfrontend/InstallController.cpp \
- ../../build/QTfrontend/hwconsts.cpp
- HEADERS += ../QTfrontend/M3InstallController.h ../QTfrontend/M3Panel.h \
- ../QTfrontend/NSWorkspace_RBAdditions.h ../QTfrontend/AutoUpdater.h \
- ../QTfrontend/CocoaInitializer.h ../QTfrontend/InstallController.h \
- ../QTfrontend/SparkleAutoUpdater.h
-
- LIBS += -lobjc -framework AppKit -framework IOKit -framework Foundation -framework SDL -framework SDL_Mixer -framework Sparkle -DSPARKLE_ENABLED
- INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers /Library/Frameworks/SDL_Mixer.framework/Headers
- CONFIG += warn_on x86
- #CONFIG += x86 ppc x86_64 ppc64
-}
-
-win32 {
- RC_FILE = ../QTfrontend/hedgewars.rc
- SOURCES += ../QTfrontend/xfire.cpp
- INCLUDEPATH += ../misc/winutils/include
- LIBS += -L../misc/winutils/lib
-}
-
-!macx {
- LIBS += -lSDL -lSDL_mixer
- !win32 {
- INCLUDEPATH += /usr/local/include/SDL /usr/include/SDL
- }
-}
-
-FORMS +=
+TEMPLATE = app
+TARGET = hedgewars
+DEPENDPATH += ../QTfrontend/
+INCLUDEPATH += ../QTfrontend
+INCLUDEPATH += ../QTfrontend/model
+INCLUDEPATH += ../QTfrontend/ui
+INCLUDEPATH += ../QTfrontend/ui/widget
+INCLUDEPATH += ../QTfrontend/ui/page
+INCLUDEPATH += ../QTfrontend/ui/dialog
+INCLUDEPATH += ../QTfrontend/net
+INCLUDEPATH += ../QTfrontend/util
+INCLUDEPATH += ../QTfrontend/util/platform
+INCLUDEPATH += ../misc/libphysfs
+INCLUDEPATH += ../misc/libphyslayer
+
+DESTDIR = ../bin
+
+QT += network
+QT += webkit
+
+HEADERS += ../QTfrontend/model/ThemeModel.h \
+ ../QTfrontend/model/MapModel.h \
+ ../QTfrontend/model/ammoSchemeModel.h \
+ ../QTfrontend/model/netserverslist.h \
+ ../QTfrontend/ui/page/pagedrawmap.h \
+ ../QTfrontend/ui/page/pagedata.h \
+ ../QTfrontend/ui/page/pagetraining.h \
+ ../QTfrontend/ui/page/pageselectweapon.h \
+ ../QTfrontend/ui/page/pagesingleplayer.h \
+ ../QTfrontend/ui/page/pageingame.h \
+ ../QTfrontend/ui/page/pageadmin.h \
+ ../QTfrontend/ui/page/pagescheme.h \
+ ../QTfrontend/ui/page/pagemultiplayer.h \
+ ../QTfrontend/ui/page/pageplayrecord.h \
+ ../QTfrontend/ui/page/pagemain.h \
+ ../QTfrontend/ui/page/pageoptions.h \
+ ../QTfrontend/ui/page/pagenetgame.h \
+ ../QTfrontend/ui/page/pageeditteam.h \
+ ../QTfrontend/ui/page/pageconnecting.h \
+ ../QTfrontend/ui/page/pageroomslist.h \
+ ../QTfrontend/ui/page/pagenet.h \
+ ../QTfrontend/ui/page/pagecampaign.h \
+ ../QTfrontend/ui/page/pageinfo.h \
+ ../QTfrontend/ui/page/pagenetserver.h \
+ ../QTfrontend/ui/page/pagegamestats.h \
+ ../QTfrontend/ui/dialog/input_ip.h \
+ ../QTfrontend/ui/qaspectratiolayout.h \
+ ../QTfrontend/ui/widget/bgwidget.h \
+ ../QTfrontend/ui/widget/fpsedit.h \
+ ../QTfrontend/ui/widget/FreqSpinBox.h \
+ ../QTfrontend/ui/widget/igbox.h \
+ ../QTfrontend/ui/widget/chatwidget.h \
+ ../QTfrontend/ui/widget/togglebutton.h \
+ ../QTfrontend/ui/widget/SquareLabel.h \
+ ../QTfrontend/ui/widget/itemNum.h \
+ ../QTfrontend/ui/widget/frameTeam.h \
+ ../QTfrontend/ui/widget/teamselect.h \
+ ../QTfrontend/ui/widget/vertScrollArea.h \
+ ../QTfrontend/ui/widget/about.h \
+ ../QTfrontend/ui/widget/teamselhelper.h \
+ ../QTfrontend/ui/widget/drawmapwidget.h \
+ ../QTfrontend/ui/widget/databrowser.h \
+ ../QTfrontend/ui/widget/hedgehogerWidget.h \
+ ../QTfrontend/ui/widget/selectWeapon.h \
+ ../QTfrontend/ui/widget/weaponItem.h \
+ ../QTfrontend/ui/widget/gamecfgwidget.h \
+ ../QTfrontend/ui/widget/mapContainer.h \
+ ../QTfrontend/ui/widget/HistoryLineEdit.h \
+ ../QTfrontend/ui/widget/SmartLineEdit.h \
+ ../QTfrontend/util/DataManager.h \
+ ../QTfrontend/net/netregister.h \
+ ../QTfrontend/net/netserver.h \
+ ../QTfrontend/net/netudpwidget.h \
+ ../QTfrontend/net/tcpBase.h \
+ ../QTfrontend/net/proto.h \
+ ../QTfrontend/net/newnetclient.h \
+ ../QTfrontend/net/netudpserver.h \
+ ../QTfrontend/net/hwmap.h \
+ ../QTfrontend/util/namegen.h \
+ ../QTfrontend/ui/page/AbstractPage.h \
+ ../QTfrontend/drawmapscene.h \
+ ../QTfrontend/game.h \
+ ../QTfrontend/gameuiconfig.h \
+ ../QTfrontend/HWApplication.h \
+ ../QTfrontend/hwform.h \
+ ../QTfrontend/util/SDLInteraction.h \
+ ../QTfrontend/team.h \
+ ../QTfrontend/achievements.h \
+ ../QTfrontend/binds.h \
+ ../QTfrontend/ui_hwform.h \
+ ../QTfrontend/KB.h \
+ ../QTfrontend/hwconsts.h \
+ ../QTfrontend/sdlkeys.h \
+ ../QTfrontend/ui/mouseoverfilter.h \
+ ../QTfrontend/ui/widget/qpushbuttonwithsound.h \
+ ../QTfrontend/model/roomslistmodel.h \
+ ../QTfrontend/ui/dialog/input_password.h \
+ ../QTfrontend/ui/widget/colorwidget.h \
+ ../QTfrontend/model/HatModel.h \
+ ../QTfrontend/model/GameStyleModel.h \
+ ../QTfrontend/ui/page/pagevideos.h \
+ ../QTfrontend/net/recorder.h \
+ ../QTfrontend/ui/dialog/ask_quit.h \
+ ../QTfrontend/ui/dialog/upload_video.h \
+ ../QTfrontend/campaign.h \
+ ../QTfrontend/model/playerslistmodel.h \
+ ../QTfrontend/util/LibavInteraction.h \
+ ../QTfrontend/util/FileEngine.h \
+ ../QTfrontend/ui/dialog/bandialog.h \
+ ../QTfrontend/ui/widget/keybinder.h \
+ ../QTfrontend/ui/widget/seedprompt.h \
+ ../QTfrontend/ui/widget/themeprompt.h \
+ ../QTfrontend/ui/widget/hatbutton.h \
+ ../QTfrontend/util/MessageDialog.h \
+ ../QTfrontend/ui/widget/hatprompt.h \
+ ../QTfrontend/ui/widget/feedbackdialog.h \
+ ../QTfrontend/ui/widget/lineeditcursor.h \
+ ../QTfrontend/servermessages.h \
+ ../QTfrontend/ui/widget/roomnameprompt.h
+
+
+SOURCES += ../QTfrontend/model/ammoSchemeModel.cpp \
+ ../QTfrontend/model/MapModel.cpp \
+ ../QTfrontend/model/ThemeModel.cpp \
+ ../QTfrontend/model/netserverslist.cpp \
+ ../QTfrontend/ui/qaspectratiolayout.cpp \
+ ../QTfrontend/ui/page/pagemain.cpp \
+ ../QTfrontend/ui/page/pagetraining.cpp \
+ ../QTfrontend/ui/page/pageroomslist.cpp \
+ ../QTfrontend/ui/page/pagemultiplayer.cpp \
+ ../QTfrontend/ui/page/pagegamestats.cpp \
+ ../QTfrontend/ui/page/pageeditteam.cpp \
+ ../QTfrontend/ui/page/pagenetgame.cpp \
+ ../QTfrontend/ui/page/pagedata.cpp \
+ ../QTfrontend/ui/page/pagedrawmap.cpp \
+ ../QTfrontend/ui/page/pageplayrecord.cpp \
+ ../QTfrontend/ui/page/pageselectweapon.cpp \
+ ../QTfrontend/ui/page/pageingame.cpp \
+ ../QTfrontend/ui/page/pagenetserver.cpp \
+ ../QTfrontend/ui/page/pagecampaign.cpp \
+ ../QTfrontend/ui/page/pageadmin.cpp \
+ ../QTfrontend/ui/page/pageinfo.cpp \
+ ../QTfrontend/ui/page/pageconnecting.cpp \
+ ../QTfrontend/ui/page/pagesingleplayer.cpp \
+ ../QTfrontend/ui/page/pagenet.cpp \
+ ../QTfrontend/ui/page/pagescheme.cpp \
+ ../QTfrontend/ui/page/pageoptions.cpp \
+ ../QTfrontend/ui/dialog/input_ip.cpp \
+ ../QTfrontend/ui/widget/igbox.cpp \
+ ../QTfrontend/ui/widget/selectWeapon.cpp \
+ ../QTfrontend/ui/widget/FreqSpinBox.cpp \
+ ../QTfrontend/ui/widget/SquareLabel.cpp \
+ ../QTfrontend/ui/widget/frameTeam.cpp \
+ ../QTfrontend/ui/widget/fpsedit.cpp \
+ ../QTfrontend/ui/widget/databrowser.cpp \
+ ../QTfrontend/ui/widget/teamselect.cpp \
+ ../QTfrontend/ui/widget/gamecfgwidget.cpp \
+ ../QTfrontend/ui/widget/chatwidget.cpp \
+ ../QTfrontend/ui/widget/itemNum.cpp \
+ ../QTfrontend/ui/widget/bgwidget.cpp \
+ ../QTfrontend/ui/widget/about.cpp \
+ ../QTfrontend/ui/widget/togglebutton.cpp \
+ ../QTfrontend/ui/widget/vertScrollArea.cpp \
+ ../QTfrontend/ui/widget/hedgehogerWidget.cpp \
+ ../QTfrontend/ui/widget/teamselhelper.cpp \
+ ../QTfrontend/ui/widget/drawmapwidget.cpp \
+ ../QTfrontend/ui/widget/weaponItem.cpp \
+ ../QTfrontend/ui/widget/mapContainer.cpp \
+ ../QTfrontend/ui/widget/HistoryLineEdit.cpp \
+ ../QTfrontend/ui/widget/SmartLineEdit.cpp \
+ ../QTfrontend/util/DataManager.cpp \
+ ../QTfrontend/net/tcpBase.cpp \
+ ../QTfrontend/net/netregister.cpp \
+ ../QTfrontend/net/proto.cpp \
+ ../QTfrontend/net/hwmap.cpp \
+ ../QTfrontend/net/netudpserver.cpp \
+ ../QTfrontend/net/newnetclient.cpp \
+ ../QTfrontend/net/netudpwidget.cpp \
+ ../QTfrontend/net/netserver.cpp \
+ ../QTfrontend/util/namegen.cpp \
+ ../QTfrontend/ui/page/AbstractPage.cpp \
+ ../QTfrontend/achievements.cpp \
+ ../QTfrontend/binds.cpp \
+ ../QTfrontend/drawmapscene.cpp \
+ ../QTfrontend/game.cpp \
+ ../QTfrontend/gameuiconfig.cpp \
+ ../QTfrontend/HWApplication.cpp \
+ ../QTfrontend/hwform.cpp \
+ ../QTfrontend/main.cpp \
+ ../QTfrontend/util/SDLInteraction.cpp \
+ ../QTfrontend/team.cpp \
+ ../QTfrontend/ui_hwform.cpp \
+ ../QTfrontend/hwconsts.cpp \
+ ../QTfrontend/ui/mouseoverfilter.cpp \
+ ../QTfrontend/ui/widget/qpushbuttonwithsound.cpp \
+ ../QTfrontend/model/roomslistmodel.cpp \
+ ../QTfrontend/ui/dialog/input_password.cpp \
+ ../QTfrontend/ui/widget/colorwidget.cpp \
+ ../QTfrontend/ui/widget/hatbutton.cpp \
+ ../QTfrontend/ui/widget/hatprompt.cpp \
+ ../QTfrontend/model/HatModel.cpp \
+ ../QTfrontend/model/GameStyleModel.cpp \
+ ../QTfrontend/ui/page/pagevideos.cpp \
+ ../QTfrontend/net/recorder.cpp \
+ ../QTfrontend/ui/dialog/ask_quit.cpp \
+ ../QTfrontend/ui/dialog/upload_video.cpp \
+ ../QTfrontend/campaign.cpp \
+ ../QTfrontend/model/playerslistmodel.cpp \
+ ../QTfrontend/util/LibavInteraction.cpp \
+ ../QTfrontend/util/FileEngine.cpp \
+ ../QTfrontend/ui/dialog/bandialog.cpp \
+ ../QTfrontend/ui/widget/keybinder.cpp \
+ ../QTfrontend/ui/widget/seedprompt.cpp \
+ ../QTfrontend/ui/widget/themeprompt.cpp \
+ ../QTfrontend/util/MessageDialog.cpp \
+ ../QTfrontend/ui/widget/feedbackdialog.cpp \
+ ../QTfrontend/ui/widget/lineeditcursor.cpp \
+ ../QTfrontend/ui/widget/roomnameprompt.cpp
+
+
+TRANSLATIONS += ../share/hedgewars/Data/Locale/hedgewars_ar.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_bg.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_cs.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_da.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_de.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_el.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_en.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_es.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_fi.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_fr.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_gl.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_hu.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_it.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_ja.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_ko.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_lt.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_ms.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_nl.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_pl.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_pt_BR.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_pt_PT.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_ro.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_ru.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_sk.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_sv.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_tr_TR.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_uk.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_zh_CN.ts \
+ ../share/hedgewars/Data/Locale/hedgewars_zh_TW.ts
+
+RESOURCES += ../QTfrontend/hedgewars.qrc
+
+LIBS += -L../bin -lhw_physfs -lphyslayer
+
+macx {
+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
+ QMAKE_MAC_SDK = /Developer/SDKs/MacOSX10.6.sdk
+
+ OBJECTIVE_SOURCES += ../QTfrontend/util/platform/*.m ../QTfrontend/util/platform/*.mm
+ SOURCES += ../QTfrontend/util/platform/AutoUpdater.cpp \
+ ../QTfrontend/util/platform/InstallController.cpp \
+ ../../build/QTfrontend/hwconsts.cpp
+ HEADERS += ../QTfrontend/util/platform/*.h
+
+ LIBS += -lobjc -framework AppKit -framework IOKit -framework Foundation -framework SDL -framework SDL_Mixer -framework Sparkle -DSPARKLE_ENABLED
+ INCLUDEPATH += /Library/Frameworks/SDL.framework/Headers /Library/Frameworks/SDL_Mixer.framework/Headers
+ CONFIG += warn_on x86
+ #CONFIG += x86 ppc x86_64 ppc64
+}
+
+win32 {
+ RC_FILE = ../QTfrontend/hedgewars.rc
+ SOURCES += ../QTfrontend/util/platform/xfire.cpp ../QTfrontend/util/platform/xfiregameclient.cpp
+ LIBS += -L../misc/winutils/lib
+ INCLUDEPATH += ../misc/winutils/include
+}
+
+!macx {
+ LIBS += -lSDL -lSDL_mixer -lSDL_net
+ !win32 {
+ INCLUDEPATH += /usr/local/include/SDL /usr/include/SDL
+ }
+}
diff --git a/project_files/promotional_art/Icon.png b/project_files/promotional_art/Icon.png
deleted file mode 100644
index bf8814a..0000000
Binary files a/project_files/promotional_art/Icon.png and /dev/null differ
diff --git a/project_files/promotional_art/Marketplace-header.png b/project_files/promotional_art/Marketplace-header.png
deleted file mode 100644
index 477bb10..0000000
Binary files a/project_files/promotional_art/Marketplace-header.png and /dev/null differ
diff --git a/project_files/promotional_art/Promo-graphic.png b/project_files/promotional_art/Promo-graphic.png
deleted file mode 100644
index 118ae3a..0000000
Binary files a/project_files/promotional_art/Promo-graphic.png and /dev/null differ
diff --git a/share/CMakeLists.txt b/share/CMakeLists.txt
index ce4e9f8..2d4ad11 100644
--- a/share/CMakeLists.txt
+++ b/share/CMakeLists.txt
@@ -1,27 +1,26 @@
-add_subdirectory(hedgewars)
-IF(APPLE OR CROSSAPPLE)
- #needed for CFBundleVersion and CFBundleShortVersionString
- FIND_PROGRAM(HGCOMMAND hg)
- IF (HGCOMMAND AND (EXISTS ${hedgewars_SOURCE_DIR}/.hg))
- exec_program(${HGCOMMAND}
- ARGS identify -n ${hedgewars_SOURCE_DIR}
- OUTPUT_VARIABLE version_suffix
- )
- STRING(REGEX REPLACE "([0-9]+)(.*)" "\\1" version_suffix ${version_suffix})
- set (HEDGEWARS_REVISION ${version_suffix})
- ELSE ()
- set (HEDGEWARS_REVISION ${HEDGEWARS_VERSION})
- ENDIF ()
+set(SHAREPATH ${HEDGEWARS_DATADIR})
- configure_file(${hedgewars_SOURCE_DIR}/share/Info.plist.in
- ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
- install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/Info.plist"
- DESTINATION ../)
- install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/Icon.icns"
- DESTINATION ../Resources/)
- install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/hwico.icns"
- DESTINATION ../Resources/)
- install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/dsa_pub.pem"
- DESTINATION ../Resources/)
-ENDIF(APPLE OR CROSSAPPLE)
+add_subdirectory(hedgewars/Data)
+
+if(APPLE)
+ #CFBundleVersion is HEDGEWARS_REVISION
+ #CFBundleShortVersionString is HEDGEWARS_VERSION
+
+ #libav/ffmpeg always brings in VideoDecoderAcceleration, avaible only from 10.6.3
+ if(${FFMPEG_FOUND} AND ${minimum_macosx_version} VERSION_EQUAL "10.6")
+ set(minimum_macosx_version "10.6.3")
+ endif()
+
+ configure_file(${hedgewars_SOURCE_DIR}/share/Info.plist.in
+ ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
+ #path here should be Hedgewars.app/Contents/MacOS
+ install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/Info.plist"
+ DESTINATION ../)
+ install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/Icon.icns"
+ DESTINATION ../Resources/)
+ install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/hwico.icns"
+ DESTINATION ../Resources/)
+ install(PROGRAMS "${hedgewars_SOURCE_DIR}/share/dsa_pub.pem"
+ DESTINATION ../Resources/)
+endif(APPLE)
diff --git a/share/Info.plist.in b/share/Info.plist.in
index 5c16bf2..8f923d0 100644
--- a/share/Info.plist.in
+++ b/share/Info.plist.in
@@ -2,159 +2,175 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>LSApplicationCategoryType</key>
- <string>public.app-category.strategy-games</string>
- <key>CFBundleName</key>
- <string>Hedgewars</string>
- <key>CFBundleExecutable</key>
- <string>hedgewars</string>
- <key>CFBundleGetInfoString</key>
- <string>http://www.hedgewars.org</string>
- <key>CFBundleIconFile</key>
- <string>Icon.icns</string>
- <key>CFBundleIdentifier</key>
- <string>org.hedgewars.desktop</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleSignature</key>
- <string>Hedge</string>
- <key>CFBundleVersion</key>
- <string>${HEDGEWARS_REVISION}</string>
- <key>CFBundleShortVersionString</key>
- <string>${HEDGEWARS_VERSION}</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2004-2012, Hedgewars Project</string>
- <key>NSAppleScriptEnabled</key>
- <false/>
- <key>LSRequiresNativeExecution</key>
- <true/>
- <key>LSMinimumSystemVersionByArchitecture</key>
- <dict>
- <key>x86_64</key>
- <string>10.6.0</string>
- <key>i386</key>
- <string>10.4.0</string>
- <key>ppc</key>
- <string>10.4.0</string>
- </dict>
- <key>LSArchitecturePriority</key>
- <array>
- <string>x86_64</string>
- <string>i386</string>
- <string>ppc</string>
- </array>
- <key>LSMinimumSystemVersion</key>
- <string>${minimum_macosx_version}</string>
- <key>SUPublicDSAKeyFile</key>
- <string>dsa_pub.pem</string>
- <key>SUFeedURL</key>
- <string>http://www.hedgewars.org/download/appcast.xml</string>
- <key>CFBundleLocalizations</key>
- <array>
- <string>ar</string>
- <string>bg</string>
- <string>cs</string>
- <string>da</string>
- <string>de</string>
- <string>el</string>
- <string>en</string>
- <string>es</string>
- <string>fi</string>
- <string>fr</string>
- <string>gl</string>
- <string>hu</string>
- <string>it</string>
- <string>ja</string>
- <string>ko</string>
- <string>lt</string>
- <string>nl</string>
- <string>pl</string>
- <string>pt_BR</string>
- <string>pt_PT</string>
- <string>ro</string>
- <string>ru</string>
- <string>sk</string>
- <string>sv</string>
- <string>tr_TR</string>
- <string>uk</string>
- <string>zh_CN</string>
- <string>zh_TW</string>
- </array>
- <key>UTExportedTypeDeclarations</key>
- <array>
- <dict>
- <key>UTTypeIdentifier</key>
- <string>org.hedgewars.desktop.hws</string>
- <key>UTTypeReferenceURL</key>
- <string>http://www.hedgewars.org/demos/</string>
- <key>UTTypeDescription</key>
- <string>Hedgewars Save Game</string>
- <key>UTTypeIconFile</key>
- <string>public.text.icns</string>
- <key>UTTypeConformsTo</key>
- <array>
- <string>public.data</string>
- </array>
- <key>UTTypeTagSpecification</key>
- <dict>
- <key>public.filename-extension</key>
- <array>
- <string>hws</string>
- </array>
- <key>public.mime-type</key>
- <string>application/x-hedgewars-save</string>
- </dict>
- </dict>
- <dict>
- <key>UTTypeIdentifier</key>
- <string>org.hedgewars.desktop.hwd</string>
- <key>UTTypeReferenceURL</key>
- <string>http://www.hedgewars.org/demos/</string>
- <key>UTTypeIconFile</key>
- <string>public.text.icns</string>
- <key>UTTypeDescription</key>
- <string>Hedgewars Demo Game</string>
- <key>UTTypeConformsTo</key>
- <array>
- <string>public.data</string>
- </array>
- <key>UTTypeTagSpecification</key>
- <dict>
- <key>public.filename-extension</key>
- <array>
- <string>hwd</string>
- </array>
- <key>public.mime-type</key>
- <string>application/x-hedgewars-demo</string>
- </dict>
- </dict>
- </array>
- <key>CFBundleDocumentTypes</key>
- <array>
- <dict>
- <key>CFBundleTypeIconFile</key>
- <string>hwico.icns</string>
- <key>CFBundleTypeName</key>
- <string>Hedgewars Savefile</string>
- <key>LSItemContentTypes</key>
- <array>
- <string>org.hedgewars.desktop.hws</string>
- </array>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- </dict>
- <dict>
- <key>CFBundleTypeIconFile</key>
- <string>hwico.icns</string>
- <key>CFBundleTypeName</key>
- <string>Hedgewars Demofile</string>
- <key>LSItemContentTypes</key>
- <array>
- <string>org.hedgewars.desktop.hwd</string>
- </array>
- <key>CFBundleTypeRole</key>
- <string>Viewer</string>
- </dict>
- </array>
+ <key>LSApplicationCategoryType</key>
+ <string>public.app-category.strategy-games</string>
+ <key>CFBundleName</key>
+ <string>Hedgewars</string>
+ <key>CFBundleExecutable</key>
+ <string>hedgewars</string>
+ <key>CFBundleGetInfoString</key>
+ <string>http://www.hedgewars.org</string>
+ <key>CFBundleIconFile</key>
+ <string>Icon.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.hedgewars.desktop</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>Hedge</string>
+ <key>CFBundleVersion</key>
+ <string>${HEDGEWARS_REVISION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${HEDGEWARS_VERSION}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2004-2012, Hedgewars Project</string>
+ <key>NSAppleScriptEnabled</key>
+ <true/>
+ <key>LSRequiresNativeExecution</key>
+ <true/>
+ <key>LSMinimumSystemVersionByArchitecture</key>
+ <dict>
+ <key>x86_64</key>
+ <string>10.6.0</string>
+ <key>i386</key>
+ <string>10.4.0</string>
+ <key>ppc</key>
+ <string>10.4.0</string>
+ </dict>
+ <key>LSArchitecturePriority</key>
+ <array>
+ <string>x86_64</string>
+ <string>i386</string>
+ <string>ppc</string>
+ </array>
+ <key>LSMinimumSystemVersion</key>
+ <string>${minimum_macosx_version}</string>
+ <key>SUPublicDSAKeyFile</key>
+ <string>dsa_pub.pem</string>
+ <key>SUFeedURL</key>
+ <string>http://www.hedgewars.org/download/appcast.xml</string>
+ <key>CFBundleLocalizations</key>
+ <array>
+ <string>ar</string>
+ <string>bg</string>
+ <string>cs</string>
+ <string>da</string>
+ <string>de</string>
+ <string>el</string>
+ <string>en</string>
+ <string>es</string>
+ <string>fi</string>
+ <string>fr</string>
+ <string>gl</string>
+ <string>hu</string>
+ <string>it</string>
+ <string>ja</string>
+ <string>ko</string>
+ <string>lt</string>
+ <string>nl</string>
+ <string>pl</string>
+ <string>pt_BR</string>
+ <string>pt_PT</string>
+ <string>ro</string>
+ <string>ru</string>
+ <string>sk</string>
+ <string>sv</string>
+ <string>tr_TR</string>
+ <string>uk</string>
+ <string>zh_CN</string>
+ <string>zh_TW</string>
+ </array>
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeIdentifier</key>
+ <string>org.hedgewars.desktop.hws</string>
+ <key>UTTypeReferenceURL</key>
+ <string>http://www.hedgewars.org/demos/</string>
+ <key>UTTypeDescription</key>
+ <string>Hedgewars Save Game</string>
+ <key>UTTypeIconFile</key>
+ <string>public.text.icns</string>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>hws</string>
+ </array>
+ <key>public.mime-type</key>
+ <string>application/x-hedgewars-save</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>UTTypeIdentifier</key>
+ <string>org.hedgewars.desktop.hwd</string>
+ <key>UTTypeReferenceURL</key>
+ <string>http://www.hedgewars.org/demos/</string>
+ <key>UTTypeIconFile</key>
+ <string>public.text.icns</string>
+ <key>UTTypeDescription</key>
+ <string>Hedgewars Demo Game</string>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.data</string>
+ </array>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>hwd</string>
+ </array>
+ <key>public.mime-type</key>
+ <string>application/x-hedgewars-demo</string>
+ </dict>
+ </dict>
+ </array>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeIconFile</key>
+ <string>hwico.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Hedgewars Savefile</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.hedgewars.desktop.hws</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ </dict>
+ <dict>
+ <key>CFBundleTypeIconFile</key>
+ <string>hwico.icns</string>
+ <key>CFBundleTypeName</key>
+ <string>Hedgewars Demofile</string>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>org.hedgewars.desktop.hwd</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
+ <key>CFBundleURLTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleURLName</key>
+ <string>Hedgewars URIs</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <!--
+ <string>hwd</string>
+ <string>hws</string>
+ <string>hwdlc</string>
+ -->
+ <string>hwplay</string>
+ </array>
+ </dict>
+ </array>
</dict>
</plist>
diff --git a/share/hedgewars/CMakeLists.txt b/share/hedgewars/CMakeLists.txt
deleted file mode 100644
index 0c4e44f..0000000
--- a/share/hedgewars/CMakeLists.txt
+++ /dev/null
@@ -1 +0,0 @@
-add_subdirectory(Data)
diff --git a/share/hedgewars/Data/Fonts/CMakeLists.txt b/share/hedgewars/Data/Fonts/CMakeLists.txt
index 4f9e168..5dd7e94 100644
--- a/share/hedgewars/Data/Fonts/CMakeLists.txt
+++ b/share/hedgewars/Data/Fonts/CMakeLists.txt
@@ -1,4 +1,4 @@
install(FILES
- DejaVuSans-Bold.ttf
+ DejaVuSans-Bold.ttf
wqy-zenhei.ttc
- DESTINATION ${SHAREPATH}Data/Fonts)
+ DESTINATION ${SHAREPATH}Data/Fonts)
diff --git a/share/hedgewars/Data/Forts/CMakeLists.txt b/share/hedgewars/Data/Forts/CMakeLists.txt
index 955bdba..6ca8d7d 100644
--- a/share/hedgewars/Data/Forts/CMakeLists.txt
+++ b/share/hedgewars/Data/Forts/CMakeLists.txt
@@ -1,7 +1,7 @@
-file(GLOB FortSprites *L.png *R.png)
+file(GLOB FortSprites *L.png *R.png)
list(REMOVE_ITEM FortSprites *@2x.png)
list(REMOVE_ITEM FortSprites *-icon.png)
install(FILES
- ${FortSprites}
- DESTINATION ${SHAREPATH}Data/Forts)
+ ${FortSprites}
+ DESTINATION ${SHAREPATH}Data/Forts)
diff --git a/share/hedgewars/Data/Forts/SteelTower-icon.png b/share/hedgewars/Data/Forts/SteelTower-icon.png
new file mode 100644
index 0000000..122f668
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTower-icon.png differ
diff --git a/share/hedgewars/Data/Forts/SteelTower-icon at 2x.png b/share/hedgewars/Data/Forts/SteelTower-icon at 2x.png
new file mode 100644
index 0000000..9bd5e9d
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTower-icon at 2x.png differ
diff --git a/share/hedgewars/Data/Forts/SteelTower-preview.png b/share/hedgewars/Data/Forts/SteelTower-preview.png
new file mode 100644
index 0000000..43695d1
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTower-preview.png differ
diff --git a/share/hedgewars/Data/Forts/SteelTower-preview at 2x.png b/share/hedgewars/Data/Forts/SteelTower-preview at 2x.png
new file mode 100644
index 0000000..70cb45c
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTower-preview at 2x.png differ
diff --git a/share/hedgewars/Data/Forts/SteelTowerL.png b/share/hedgewars/Data/Forts/SteelTowerL.png
new file mode 100644
index 0000000..7f01d3b
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTowerL.png differ
diff --git a/share/hedgewars/Data/Forts/SteelTowerR.png b/share/hedgewars/Data/Forts/SteelTowerR.png
new file mode 100644
index 0000000..60036fe
Binary files /dev/null and b/share/hedgewars/Data/Forts/SteelTowerR.png differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png
index 4d8f1ec..053bb7b 100644
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png and b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos at 2x.png b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos at 2x.png
deleted file mode 100644
index c55dfa9..0000000
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos at 2x.png and /dev/null differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png
index 4e7b771..c8719ea 100644
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png and b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw at 2x.png b/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw at 2x.png
deleted file mode 100644
index ad53e24..0000000
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw at 2x.png and /dev/null differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png b/share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png
deleted file mode 100644
index 46fd446..0000000
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/BorderHorizontal.png and /dev/null differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png b/share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png
deleted file mode 100644
index 76a85d5..0000000
Binary files a/share/hedgewars/Data/Graphics/AmmoMenu/BorderVertical.png and /dev/null differ
diff --git a/share/hedgewars/Data/Graphics/AmmoMenu/CMakeLists.txt b/share/hedgewars/Data/Graphics/AmmoMenu/CMakeLists.txt
index ad5300c..32930b6 100644
--- a/share/hedgewars/Data/Graphics/AmmoMenu/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/AmmoMenu/CMakeLists.txt
@@ -1,6 +1,5 @@
file(GLOB AmmoMenuSprites *.png)
-list(REMOVE_ITEM AmmoMenuSprites *@2x.png Border*.png)
install(FILES
- ${AmmoMenuSprites}
- DESTINATION ${SHAREPATH}Data/Graphics/AmmoMenu)
+ ${AmmoMenuSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/AmmoMenu)
diff --git a/share/hedgewars/Data/Graphics/CMakeLists.txt b/share/hedgewars/Data/Graphics/CMakeLists.txt
index a17a68e..7fd527d 100644
--- a/share/hedgewars/Data/Graphics/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/CMakeLists.txt
@@ -6,9 +6,9 @@ add_subdirectory(Hedgehog)
add_subdirectory(SuddenDeath)
add_subdirectory(Missions)
-file(GLOB BaseSprites *.png)
+file(GLOB BaseSprites *.png)
list(REMOVE_ITEM BaseSprites *@2x.png)
install(FILES
- ${BaseSprites}
- DESTINATION ${SHAREPATH}Data/Graphics)
+ ${BaseSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics)
diff --git a/share/hedgewars/Data/Graphics/Flags/CMakeLists.txt b/share/hedgewars/Data/Graphics/Flags/CMakeLists.txt
index 5d5be92..58361a6 100644
--- a/share/hedgewars/Data/Graphics/Flags/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Flags/CMakeLists.txt
@@ -1,5 +1,5 @@
-file(GLOB FlagTemplates *.png)
+file(GLOB FlagTemplates *.png)
install(FILES
- ${FlagTemplates}
- DESTINATION ${SHAREPATH}Data/Graphics/Flags)
+ ${FlagTemplates}
+ DESTINATION ${SHAREPATH}Data/Graphics/Flags)
diff --git a/share/hedgewars/Data/Graphics/Flags/cm_belarus.png b/share/hedgewars/Data/Graphics/Flags/cm_belarus.png
new file mode 100644
index 0000000..0e1580a
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Flags/cm_belarus.png differ
diff --git a/share/hedgewars/Data/Graphics/Graves/CMakeLists.txt b/share/hedgewars/Data/Graphics/Graves/CMakeLists.txt
index cb71837..5fce39d 100644
--- a/share/hedgewars/Data/Graphics/Graves/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Graves/CMakeLists.txt
@@ -1,5 +1,5 @@
-file(GLOB GraveSprites *.png)
+file(GLOB GraveSprites *.png)
install(FILES
- ${GraveSprites}
- DESTINATION ${SHAREPATH}Data/Graphics/Graves)
+ ${GraveSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/Graves)
diff --git a/share/hedgewars/Data/Graphics/Hats/CMakeLists.txt b/share/hedgewars/Data/Graphics/Hats/CMakeLists.txt
index 2f7c7f1..efdbe10 100644
--- a/share/hedgewars/Data/Graphics/Hats/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Hats/CMakeLists.txt
@@ -3,5 +3,5 @@ add_subdirectory(Reserved)
file(GLOB HatSprites *.png)
install(FILES
- ${HatSprites}
- DESTINATION ${SHAREPATH}Data/Graphics/Hats)
+ ${HatSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/Hats)
diff --git a/share/hedgewars/Data/Graphics/Hats/Dan.png b/share/hedgewars/Data/Graphics/Hats/Dan.png
new file mode 100644
index 0000000..6c1a28e
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Dan.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Dauber.png b/share/hedgewars/Data/Graphics/Hats/Dauber.png
new file mode 100644
index 0000000..9b1fdbc
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Dauber.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/DayAndNight.png b/share/hedgewars/Data/Graphics/Hats/DayAndNight.png
new file mode 100644
index 0000000..5a1a80a
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/DayAndNight.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Evil.png b/share/hedgewars/Data/Graphics/Hats/Evil.png
new file mode 100644
index 0000000..9038d5d
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Evil.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Joker.png b/share/hedgewars/Data/Graphics/Hats/Joker.png
new file mode 100644
index 0000000..0a19d3f
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Joker.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Meteorhelmet.png b/share/hedgewars/Data/Graphics/Hats/Meteorhelmet.png
new file mode 100644
index 0000000..517d5c3
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Meteorhelmet.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Moustache.png b/share/hedgewars/Data/Graphics/Hats/Moustache.png
new file mode 100644
index 0000000..a37d7cd
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Moustache.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Moustache_glasses.png b/share/hedgewars/Data/Graphics/Hats/Moustache_glasses.png
new file mode 100644
index 0000000..6da9ab0
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/Moustache_glasses.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/Reserved/CMakeLists.txt b/share/hedgewars/Data/Graphics/Hats/Reserved/CMakeLists.txt
index efedb52..ec29e6a 100644
--- a/share/hedgewars/Data/Graphics/Hats/Reserved/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Hats/Reserved/CMakeLists.txt
@@ -1,5 +1,5 @@
file(GLOB HatSprites *.png)
install(FILES
- ${HatSprites}
- DESTINATION ${SHAREPATH}Data/Graphics/Hats/Reserved)
+ ${HatSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/Hats/Reserved)
diff --git a/share/hedgewars/Data/Graphics/Hats/SunWukong.png b/share/hedgewars/Data/Graphics/Hats/SunWukong.png
index e5693b9..2b3d7d5 100644
Binary files a/share/hedgewars/Data/Graphics/Hats/SunWukong.png and b/share/hedgewars/Data/Graphics/Hats/SunWukong.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/TeamWheatley.png b/share/hedgewars/Data/Graphics/Hats/TeamWheatley.png
new file mode 100644
index 0000000..4fbe369
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/TeamWheatley.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/bubble.png b/share/hedgewars/Data/Graphics/Hats/bubble.png
new file mode 100644
index 0000000..02da0f1
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/bubble.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/cap_thinking.png b/share/hedgewars/Data/Graphics/Hats/cap_thinking.png
new file mode 100644
index 0000000..30cc3c1
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/cap_thinking.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/car.png b/share/hedgewars/Data/Graphics/Hats/car.png
new file mode 100644
index 0000000..a3b93f6
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/car.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/flag_french.png b/share/hedgewars/Data/Graphics/Hats/flag_french.png
new file mode 100644
index 0000000..416943b
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/flag_french.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/flag_germany.png b/share/hedgewars/Data/Graphics/Hats/flag_germany.png
new file mode 100644
index 0000000..d11ff3f
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/flag_germany.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/flag_italy.png b/share/hedgewars/Data/Graphics/Hats/flag_italy.png
new file mode 100644
index 0000000..54044d1
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/flag_italy.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/flag_usa.png b/share/hedgewars/Data/Graphics/Hats/flag_usa.png
new file mode 100644
index 0000000..8ff044b
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/flag_usa.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/footballhelmet.png b/share/hedgewars/Data/Graphics/Hats/footballhelmet.png
new file mode 100644
index 0000000..b8788aa
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/footballhelmet.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/lamp.png b/share/hedgewars/Data/Graphics/Hats/lamp.png
new file mode 100644
index 0000000..8ada446
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/lamp.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/mechanicaltoy.png b/share/hedgewars/Data/Graphics/Hats/mechanicaltoy.png
new file mode 100644
index 0000000..ee2b5dc
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/mechanicaltoy.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/noface.png b/share/hedgewars/Data/Graphics/Hats/noface.png
new file mode 100644
index 0000000..4e10bef
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/noface.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper01.png b/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper01.png
new file mode 100644
index 0000000..5a1ae6e
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper01.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper02.png b/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper02.png
new file mode 100644
index 0000000..99a26cd
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_UNPeacekeeper02.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_airwarden02.png b/share/hedgewars/Data/Graphics/Hats/war_airwarden02.png
new file mode 100644
index 0000000..f6327cd
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_airwarden02.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_airwarden03.png b/share/hedgewars/Data/Graphics/Hats/war_airwarden03.png
new file mode 100644
index 0000000..e4d85e9
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_airwarden03.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_americanww2helmet.png b/share/hedgewars/Data/Graphics/Hats/war_americanww2helmet.png
new file mode 100644
index 0000000..99484a0
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_americanww2helmet.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_trenchfrench01.png b/share/hedgewars/Data/Graphics/Hats/war_trenchfrench01.png
new file mode 100644
index 0000000..f01a03b
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_trenchfrench01.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/war_trenchfrench02.png b/share/hedgewars/Data/Graphics/Hats/war_trenchfrench02.png
new file mode 100644
index 0000000..9310484
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/war_trenchfrench02.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_chicken.png b/share/hedgewars/Data/Graphics/Hats/zoo_chicken.png
new file mode 100644
index 0000000..b68b232
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_chicken.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_elephant.png b/share/hedgewars/Data/Graphics/Hats/zoo_elephant.png
new file mode 100644
index 0000000..f966705
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_elephant.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_fish.png b/share/hedgewars/Data/Graphics/Hats/zoo_fish.png
new file mode 100644
index 0000000..a5d9a6a
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_fish.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_frog.png b/share/hedgewars/Data/Graphics/Hats/zoo_frog.png
new file mode 100644
index 0000000..b9d99e1
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_frog.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_snail.png b/share/hedgewars/Data/Graphics/Hats/zoo_snail.png
new file mode 100644
index 0000000..08e7c2b
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_snail.png differ
diff --git a/share/hedgewars/Data/Graphics/Hats/zoo_turtle.png b/share/hedgewars/Data/Graphics/Hats/zoo_turtle.png
new file mode 100644
index 0000000..7fbb088
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hats/zoo_turtle.png differ
diff --git a/share/hedgewars/Data/Graphics/Hedgehog.png b/share/hedgewars/Data/Graphics/Hedgehog.png
index 32d18e2..3411846 100644
Binary files a/share/hedgewars/Data/Graphics/Hedgehog.png and b/share/hedgewars/Data/Graphics/Hedgehog.png differ
diff --git a/share/hedgewars/Data/Graphics/Hedgehog/CMakeLists.txt b/share/hedgewars/Data/Graphics/Hedgehog/CMakeLists.txt
index ca0cf1d..00558d8 100644
--- a/share/hedgewars/Data/Graphics/Hedgehog/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Hedgehog/CMakeLists.txt
@@ -1,5 +1,5 @@
file(GLOB HedgehogSprites *.png)
install(FILES
- ${HedgehogSprites}
- DESTINATION ${SHAREPATH}Data/Graphics/Hedgehog)
+ ${HedgehogSprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/Hedgehog)
diff --git a/share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png b/share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png
new file mode 100644
index 0000000..f1fb411
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png differ
diff --git a/share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png b/share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png
new file mode 100644
index 0000000..c886cec
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png differ
diff --git a/share/hedgewars/Data/Graphics/Missions/Training/CMakeLists.txt b/share/hedgewars/Data/Graphics/Missions/Training/CMakeLists.txt
index 7a66ed8..c7f0f27 100644
--- a/share/hedgewars/Data/Graphics/Missions/Training/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/Missions/Training/CMakeLists.txt
@@ -1,5 +1,5 @@
file(GLOB MissionPics *@2x.png)
install(FILES
- ${MissionPics}
- DESTINATION ${SHAREPATH}Data/Graphics/Missions/Training)
+ ${MissionPics}
+ DESTINATION ${SHAREPATH}Data/Graphics/Missions/Training)
diff --git a/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh.png b/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh.png
new file mode 100644
index 0000000..20bf0e4
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh.png differ
diff --git a/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh at 2x.png b/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh at 2x.png
new file mode 100644
index 0000000..c0cf3d9
Binary files /dev/null and b/share/hedgewars/Data/Graphics/Missions/Training/User_Mission_-_Nobody_Laugh at 2x.png differ
diff --git a/share/hedgewars/Data/Graphics/SuddenDeath/CMakeLists.txt b/share/hedgewars/Data/Graphics/SuddenDeath/CMakeLists.txt
index 136686e..90f6ab0 100644
--- a/share/hedgewars/Data/Graphics/SuddenDeath/CMakeLists.txt
+++ b/share/hedgewars/Data/Graphics/SuddenDeath/CMakeLists.txt
@@ -1,5 +1,5 @@
file(GLOB Sprites *.png)
install(FILES
- ${Sprites}
- DESTINATION ${SHAREPATH}Data/Graphics/SuddenDeath)
+ ${Sprites}
+ DESTINATION ${SHAREPATH}Data/Graphics/SuddenDeath)
diff --git a/share/hedgewars/Data/Graphics/icetexture.png b/share/hedgewars/Data/Graphics/icetexture.png
new file mode 100644
index 0000000..17a69b9
Binary files /dev/null and b/share/hedgewars/Data/Graphics/icetexture.png differ
diff --git a/share/hedgewars/Data/Locale/CMakeLists.txt b/share/hedgewars/Data/Locale/CMakeLists.txt
index 8df26dc..c3faeb5 100644
--- a/share/hedgewars/Data/Locale/CMakeLists.txt
+++ b/share/hedgewars/Data/Locale/CMakeLists.txt
@@ -6,17 +6,17 @@ file(GLOB missionfiles missions_*.txt)
QT4_ADD_TRANSLATION(QM ${tsfiles})
-add_custom_target (release-translation ALL
- DEPENDS ${QM}
- COMMENT "Compiling ts files"
+add_custom_target (release-translation ALL
+ DEPENDS ${QM}
+ COMMENT "Compiling ts files"
)
install(FILES
- ${txttrans2}
- ${txttrans5}
- ${QM}
- ${luafiles}
- ${missionfiles}
- DESTINATION ${SHAREPATH}Data/Locale
+ ${txttrans2}
+ ${txttrans5}
+ ${QM}
+ ${luafiles}
+ ${missionfiles}
+ DESTINATION ${SHAREPATH}Data/Locale
)
diff --git a/share/hedgewars/Data/Locale/ar.txt b/share/hedgewars/Data/Locale/ar.txt
index 5dd8fee..e0b2710 100644
--- a/share/hedgewars/Data/Locale/ar.txt
+++ b/share/hedgewars/Data/Locale/ar.txt
@@ -152,7 +152,6 @@
02:01=%1 wants to play Ecco the dolphin
02:01=%1 has gone to visit Aquaria
02:01=%1 has found the lost city of Atlantis
-02:01=%1 aims for the lead role in Bioshock 3
02:01=Your doggy paddle could use a little work, %1
02:01=%1 should have brought a jet ski
02:01=%1 doesn't like watersports
diff --git a/share/hedgewars/Data/Locale/cs.lua b/share/hedgewars/Data/Locale/cs.lua
index 99d3f1a..5d72f93 100644
--- a/share/hedgewars/Data/Locale/cs.lua
+++ b/share/hedgewars/Data/Locale/cs.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Nejrychlejšà kolo: ",
["Feeble Resistance"] = "Slabý odpor",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = "Nešťastný ježek odešel!",
["Hapless Hogs"] = "Nešťastný ježek",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurá!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Individuálnà munice",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "UmÃsti vÃce navigaÄnÃch bodů pomocà klávesy [enter]",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Výzva",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/cs.txt b/share/hedgewars/Data/Locale/cs.txt
index fa7e538..f8295cc 100644
--- a/share/hedgewars/Data/Locale/cs.txt
+++ b/share/hedgewars/Data/Locale/cs.txt
@@ -54,8 +54,8 @@
00:51=Hrouda bláta
00:52=Nenà vybrána žádná zbraÅ
00:53=TimeBox
-00:54=Struktura
-00:55=Pozemek s rozpraÅ¡ovaÄem
+; 00:54=Struktura
+00:54=Pozemek s rozpraÅ¡ovaÄem
01:00=Do boje!
01:01=Kolo nerozhodnÄ
@@ -175,7 +175,6 @@
02:01=%1 chce hrát delfÃna Ecca
02:01=%1 odeÅ¡el navÅ¡tÃvit akvárium
02:01=%1 naÅ¡el ztracené mÄsto Atlantidu
-02:01=%1 mÃÅà na hlavnà roli v Bioshocku 3
02:01=Na tvém stylu ÄubiÄka by jeÅ¡tÄ chtÄlo zapracovat, %1
02:01=%1 si nemÄl vozit vodnà lyže
02:01=%1 nemá rád vodnà sporty
@@ -447,8 +446,8 @@
03:51=Nalezeno na zemi
03:52=NEPOUŽITO
03:53=Typ 40
-03:54=VytvoÅit nÄco
-03:55=UžiteÄnost
+;03:54=VytvoÅit nÄco
+03:54=UžiteÄnost
; Weapon Descriptions (use | as line breaks)
04:00=ZaútoÄ na nepÅÃtele pomocà obyÄejného granátu.|Exploduje jakmile ÄasovaÄ dojde k nule.|1-5: Nastavuje ÄasovaÄ|Ãtok: Drž pro hozenà vÄtÅ¡Ã silou
@@ -506,8 +505,8 @@
04:51=ZÃskat ve volném zábÄru vrhá kouli bláta.|Žihadla bit, a srazà prasata zpÄt.
04:52=NEPOUŽITO
04:53=Vydejte se na dobrodružstvà v Äase a prostoru,|pÅiÄemž vaÅ¡i kamarádi bojovat dál sám.|Být pÅipraven vrátit kdykoliv,|nebo náhlé smrti nebo pokud jsou vÅ¡ichni poraženi.|ProhlášenÃ. Nefunguje v náhlé smrti,|Pokud jste sami, nebo jste-li král.
-04:54=NEÃPLNÃ
-04:55=Sprej proud lepkavými vloÄkami.|StavÄt mosty, pohÅbÃt nepÅátele, utÄsnÄnà tunely.|BuÄte opatrnÃ, nechcete dostat každý z vás!
+;04:54=NEÃPLNÃ
+04:54=Sprej proud lepkavými vloÄkami.|StavÄt mosty, pohÅbÃt nepÅátele, utÄsnÄnà tunely.|BuÄte opatrnÃ, nechcete dostat každý z vás!
; Game goal strings
05:00=Hernà módy
diff --git a/share/hedgewars/Data/Locale/da.lua b/share/hedgewars/Data/Locale/da.lua
index f4bda19..057f0c8 100644
--- a/share/hedgewars/Data/Locale/da.lua
+++ b/share/hedgewars/Data/Locale/da.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Hurtigste omgang: ",
["Feeble Resistance"] = "Sølle Modstand",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = " Uheldige Pindsvin gik!",
["Hapless Hogs"] = "Uheldige Pindsvin",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurra!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
["Pathetic Resistance"] = "Patetisk Modstand", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Ammunition Per Pindsvin",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Placer flere rutepunkter med [ENTER]",
+
["Place more waypoints using the 'Air Attack' weapon."] = "Placer flere rutepunkter med 'Luftangreb'-våbnet",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Brugerudfordring",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/da.txt b/share/hedgewars/Data/Locale/da.txt
index b1a0e05..5ceab4c 100644
--- a/share/hedgewars/Data/Locale/da.txt
+++ b/share/hedgewars/Data/Locale/da.txt
@@ -54,8 +54,8 @@
00:51=Mudderklat
00:52=Intet våben valgt
00:53=Tidsboks
-00:54=Struktur
-00:55=Jordspray
+; 00:54=Struktur
+00:54=Jordspray
01:00=Kæmp!
01:01=Runde uafgjort
@@ -175,7 +175,6 @@
02:01=%1 leger delfin
02:01=%1 er taget til Lalandia
02:01=%1 har fundet den forsvundne by Atlantis
-02:01=%1 håber på en hovedrolle i Bioshock 3
02:01=Du burde arbejde lidt med din hundesvømning, %1
02:01=%1 burde have medbragt jetski
02:01=%1 bryder sig ikke om vandsport
@@ -447,8 +446,8 @@
03:51=Lige til at samle op
03:52=UBRUGT
03:53=Ã
rgang 40
-03:54=Byg noget
-03:55=Værktøj
+;03:54=Byg noget
+03:54=Værktøj
; Weapon Descriptions (use |as line breaks)
04:00=Angrib dine fjender med en simpel granat.|Den eksploderer når uret når nul.|1-5: Indstil uret|Angrib: Hold knappen inde for at kaste hårdere
@@ -505,8 +504,8 @@
04:51=Få et skud lige ind med en Mudderklat.|Bider en smule og slår fjender omkuld.
04:52=UBRUGT
04:53=Tag på et eventyr gennem tid og rum,|mens du efterlader kampen til dine kammerater.|Vær klar til at vende tilbage når som helst,|eller hvis Pludselig Død indtræder|eller alle dine andre pindsvin dør.|Advarsel! Virker ikke under Pludselig Død,|hvis du er alene eller er Konge.
-04:54=UFÃRDIG
-04:55=Sprøjt rundt med klistrende flammer.|Byg broer, begrav fjender, luk tunneler af.|Pas på ikke selv at få noget på dig.
+;04:54=UFÃRDIG
+04:54=Sprøjt rundt med klistrende flammer.|Byg broer, begrav fjender, luk tunneler af.|Pas på ikke selv at få noget på dig.
; Game goal strings
05:00=Spilsystemer
diff --git a/share/hedgewars/Data/Locale/de.lua b/share/hedgewars/Data/Locale/de.lua
index b574d39..db65639 100644
--- a/share/hedgewars/Data/Locale/de.lua
+++ b/share/hedgewars/Data/Locale/de.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Schnellste Runde: ",
["Feeble Resistance"] = "Kraftloser Widerstand",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
["Hapless Hogs"] = "Glücklose Igel",
[" Hapless Hogs left!"] = " Glücklose Igel verbleibend!",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurra!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -565,11 +566,12 @@ locale = {
["Pathetic Resistance"] = "Erbärmlicher Widerstand", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Munition pro Igel",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Setze mehr Wegpunkte durch Drücken von [ENTER]",
+
["Place more waypoints using the 'Air Attack' weapon."] = "Platziere mehr Wegpunkte durch Verwenden der 'Luftangriff'-Waffe",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -823,7 +825,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/de.txt b/share/hedgewars/Data/Locale/de.txt
index 5523092..4ff1118 100644
--- a/share/hedgewars/Data/Locale/de.txt
+++ b/share/hedgewars/Data/Locale/de.txt
@@ -31,7 +31,7 @@
00:28=Bohrkopfrakete
00:29=Ballpistole
00:30=Napalm-Luftangriff
-00:31=RC-Flugzeug
+00:31=Funkflugzeug
00:32=Schwerkraft verringern
00:33=Zusatzschaden
00:34=Unverwundbarkeit
@@ -54,10 +54,10 @@
00:51=Schlammball
00:52=Keine Waffe ausgewählt
00:53=ZeitBox
-00:54=Bauwerk
-00:55=Landkanone
-00:56=Gefrierer
-00:57=Hackbeil
+; 00:54=Bauwerk
+00:54=Landkanone
+00:55=Gefrierer
+00:56=Hackebeil
01:00=Auf in die Schlacht!
@@ -69,7 +69,7 @@
01:06=Sudden Death!
01:07=%1 verbleibend
01:08=Treibstoff
-01:09=Synchronisiere ...
+01:09=Synchronisiere â¦
01:10=Benutzung beendet nicht die eigene Runde!
01:11=Waffe oder Werkzeug noch nicht verfügbar!
01:10=Benutzung beendet nicht die eigene Runde!
@@ -83,70 +83,66 @@
01:18=Hohe
01:19=Extreme
01:20=%1 Sprungkraft
-01:21=Audio Stumm
+01:21=Audio stumm
; Event messages
; Hog (%1) died
02:00=%1 hat den Löffel abgegeben!
02:00=%1 steht wohl nicht mehr auf!
-02:00=%1 hat's nicht geschafft!
+02:00=%1 hatâs nicht geschafft!
02:00=%1 stellt sich tot!
02:00=%1 hat schon bessere Tage gesehen!
02:00=%1 sieht tote Igel!
02:00=%1 hat ins Gras gebissen!
02:00=%1 ist Futter für die Würmer!
-02:00=Das war's wohl, %1!
-02:00=%1 hat's hinter sich!
+02:00=Das warâs wohl, %1!
+02:00=%1 hatâs hinter sich!
02:00=%1 kann schon das Licht sehen!
02:00=Für %1 gehen alle Lichter aus!
02:00=%1 kommt wieder!
02:00=%1 ist urlaubsreif!
-02:00=%1 trifft seine Ahnen.
02:00=%1 war nicht hartnäckig genug!
-02:00=%1 war einmal.
-02:00=%1 hat wohl versagt.
-02:00=Mach's gut, %1!
-02:00=%1 hinterlässt eine Frau und Kind
-02:00=%1 ins Leben gerufen hat seine letzte Panzerfaust
-02:00=%1 hat seine letzte Granate geworfen
-02:00=%1 hat seine letzte Kuchen gebacken
-02:00=%1 hat auf seiner letzten Seil schwangen
-02:00=%1 genannt hat seinen letzten Luftangriff
-02:00=%1 gepumpt hat seine letzte Schrotflinte
-02:00=%1 geworfen hat seine letzte Melone
-02:00=%1 gezogen hat seinen letzten deagle
+02:00=%1 war einmal
+02:00=%1 hat wohl versagt
+02:00=Machâs gut, %1!
+02:00=%1 hat die letzte Bazooka gefeuert
+02:00=%1 hat die letzte Granate geworfen
+02:00=%1 hat den letzten Kuchen gebacken
+02:00=%1 hat den letzten Luftangriff angefordert
+02:00=%1 hat die letzte Schrotflinte gepumpt
+02:00=%1 hat die letzte Melone geworfen
+02:00=%1 hat die letzte Deagle gezogen
02:00=%1 nahm einen Schuss zu viel
-02:00=%1 könnte wirklich eine gesundheitliche Kiste verwendet haben
-02:00=%1 gegangen ist, um ein besseres Spiel zu spielen
-02:00=%1 hat ragequit Leben
+02:00=%1 hätte wirklich ein Erste-Hilfe-Kit gebrauchen können
+02:00=%1 ist gegangen, um ein besseres Spiel zu spielen
+02:00=%1 will nicht mehr
02:00=%1 scheitert
-02:00=Schlecht schlecht %1...
-02:00=%1 lieber Warmux
-02:00=%1 wurde blockiert Schüsse mit seinem Gesicht
-02:00=%1 ist ein Held unter mir ... err ... Schweine
-02:00=%1 findet seinen Platz in der Walhalla
-02:00=%1 hat das Gebäude verlassen
+02:00=Schlecht, schlecht, %1 â¦
+02:00=%1 sollte lieber WarMUX spielen
+02:00=%1 hat versucht, die Kugeln mit den Zähnen zu fangen
+02:00=%1 findet seinen Platz in der Walhall
02:00=%1 geht den Weg der Dinosaurier
-02:00=%1 Igel bringt, einen Schritt näher zum Aussterben
-02:00=%1 bringt eine Träne zu mir ins Auge
-02:00=%1 ist ein Ex-Schwein
-02:00=%1 wird die Radieschen
-02:00=%1 hat aufgehört zu sein
+02:00=%1 bringt die Igelspezies einen Schritt näher zum Aussterben
+02:00=%1 wird vermisst werden
+02:00=%1 ist ab jetzt ein Ex-Igel
+02:00=%1 sieht sich die Radieschen von unten an
+02:00=%1 hat aufgehört, zu sein
02:00=Verabschieden Sie sich von %1
-02:00=Keine Hoffnung mehr für %1
-02:00=%1 steht vor der letzte Vorhang
-02:00=Rauchen, wenn du hast, %1
-02:00=%1 erleidet einen spontanen massiven Vorhandensein Ausfall
-02:00=%1 weitergegeben hat
+02:00=Für %1 gibt es keine Hoffnung mehr
+02:00=%1 trat von der Lebensbühne ab
+02:00=%1 erleidet ein spontanes multiples Organversagen
02:00=%1 ist mausetot
-02:00=%1 nicht mehr
-02:00=%1 abgelaufen
-02:00=Beraubt des Lebens, %1 ruht in Frieden
-02:00=%1 tritt der Chor unsichtbar
-02:00=Abschied %1, wussten wir kaum ye!
-02:00=%1 hatte eine geringe Toleranz für erschossen
-02:00=%1 hätte verwenden können ein zusätzliches Leben
-02:00=Gibt es einen Arzt im Haus?
+02:00=%1s Lebensuhr ist abgelaufen
+02:00=Beraubt des Lebens, ruht %1 in Frieden
+02:00=%1 hatte eine geringe Schadenstoleranz
+02:00=%1 hat all seine Extraleben aufgebraucht
+02:00=Ist ein Arzt im Haus?!
+02:00=%1 ist tot
+02:00=%1 ist hinüber
+02:00=%1 wurde in tausend Stücke zerfetzt
+02:00=Schade um %1
+02:00=Wir trauern um %1
+02:00=%1 beiÃt ins Gras
; Hog (%1) drowned
02:01=%1 geht auf Tauchstation!
@@ -157,97 +153,80 @@
02:01=%1 versagt beim Seepferdchen!
02:01=%1 ist ein Opfer der Gezeiten!
02:01=%1 findet Nemo!
-02:01=%1 taucht unter ...
+02:01=%1 taucht unter â¦
02:01=Atlantis wartet, %1!
02:01=%1 nimmt ein entspannendes Bad.
02:01=%1 hat nie das Seepferdchen gemacht!
02:01=%1 ist Fischfutter!
-02:01=%1 im Rausch der Tiefe!
+02:01=%1 ist im Rausch der Tiefe!
02:01=Was für ein feuchtes Erlebnis!
02:01=%1 geht unter die Perlentaucher!
02:01=%1 über Bord!
-02:01=%1 verlässt das sinkende Schiff.
+02:01=%1 verlässt das sinkende Schiff
02:01=%1 überschätzt seinen Auftrieb!
02:01=%1 erliegt dem Sog der Tiefe!
02:01=%1 geht der Sache auf den Grund!
02:01=%1 wäre fast verdurstet!
-02:01=%1 checkt das tiefe Ende
-02:01=%1 geht gluck gluck gluck
-02:01=%1 geht Spritzer
-02:01=%1 vergaà seine Armbinden
-02:01=%1 wirklich genommen haben sollte Schwimmunterricht
-02:01=%1 verlieà seinem Surfbrett zu Hause
-02:01=%1 wird gewaschen, bis
-02:01=%1 ist ein Schwein matschig
-02:01=%1 vergessen, sein Leben zu bringen Jacke
-02:01=%1 geht Splish Spritzer
-02:01=%1 wird mit den Fischen schlafen
-02:01=%1 denkt das Wasser saugen Physik in diesem Spiel
-02:01=%1 sieht durstig
-02:01=Das Meer behauptet %1
-02:01=%1 wird auf dem Meer verschollen
-02:01=%1 sollten mitgebracht haben seine Tauchausrüstung
-02:01=%1 bekommt eine Bestattung auf See
-02:01=%1 hat, dass die sinkenden Gefühl
-02:01=%1 übt seine Rückenschwimmen
+02:01=%1 macht »Gluck, gluck, gluck!«
+02:01=%1 macht »Platsch!«
+02:01=%1 vergaà seine Schwimmflügel
+02:01=%1 hätte Schwimmunterricht nehmen sollen
+02:01=%1 lieà sein Surfbrett zu Hause
+02:01=%1 wird gewaschen
+02:01=%1 ist ein nasser Igel
+02:01=%1 hat seine Schwimmweste vergessen
+02:01=%1 macht »Plitsch-platsch!«
+02:01=%1 sieht durstig aus
+02:01=%1 ist auf dem Meer verschollen
+02:01=%1 bekommt eine Seebestattung
+02:01=%1 übt sein Rückenschwimmen
02:01=%1 geht auf der Suche nach der Titanic
02:01=%1 ist nicht Jesus
-02:01=%1 wird Findet Nemo
-02:01=%1 ein Leck
-02:01=Du muÃt fragen, wie viele Schweine sind da unten
+02:01=%1 hat ein Leck
+02:01=Wie viele Igel wohl da unten liegen?
02:01=%1 macht das Meer etwas höher
-02:01=%1 nicht in der Marine zu gewinnen
-02:01=%1 tut sein Identitätswechsel von einem toten Fisch
-02:01=Zumindest ging nicht in die Toilette, %1
-02:01=Sonic nicht schwimmen konnte und kann weder %1
-02:01=%1 will spielen Ecco the Dolphin
-02:01=%1, Aquaria ist gegangen, um zu besuchen
-02:01=%1 hat festgestellt, die verlorene Stadt Atlantis
-02:01=%1 Ziele für die Hauptrolle in Bioshock 3
-02:01=Ihre doggy Paddel könnte ein wenig Arbeit, %1
-02:01=%1 sollten mitgebracht haben einen Jet-Ski
-02:01=%1 mag es nicht, Wassersport
-02:01=%1 wird forever blowing bubbles
-02:01=%1 ist kurz von einem FloÃ
-02:01=%1 denkt Salzwasser ist gut für die Haut
+02:01=%1 ist absolut nicht Marinetauglich
+02:01=%1 glaubt, er sei ein Fisch
+02:01=Wenigstens ging die Sache nicht ins Klo, %1!
+02:01=Sonic konnte nicht schwimmen, %1 auch nicht
+02:01=%1 spielt »Flipper der Delphin«
+02:01=%1 ist von uns gegangen, um Aquaria zu besuchen
+02:01=%1 hasst Wassersport
+02:01=%1 wird für immer Blasen machen
+02:01=%1 war ganz, ganz knapp vor einem FloÃ
+02:01=%1 dachte, Salzwasser sei gut für die Haut
02:01=%1 bekommt Salzwasser in seine Wunden
-02:01=%1 hat ging die Planke
-02:01=%1 verfügt über eine Badewanne
-02:01=%1 ist nass nass nass
-02:01=%1 bekommt seine Federkiele nass
-02:01=Es ist Davy Jones 'locker für %1
+02:01=%1 ging über die Planke
+02:01=%1 geht baden
+02:01=%1 ist nass, nass, nass
+02:01=%1 macht blubb
+02:01=%1, Igel, der mit dem Blubb
+02:01=Nächster Halt: Meeresgrund
+02:01=%1 hätte den Schwimmkurs nicht schwänzen sollen
; Round starts
02:02=Auf in die Schlacht!
02:02=Geladen und entsichert!
-02:02=Jetzt geht's rund!
-02:02=Los geht's!
+02:02=Jetzt gehtâs rund!
+02:02=Los gehtâs!
02:02=Alles angetreten!
02:02=Los, los, los!
-02:02=Lassen Sie uns dies Partei beginnen
-02:02=Letzte Schwein steht gewinnt
-02:02=Gehen wir!
+02:02=Der letzte Igel, der noch atmet, hat gewonnen
+02:02=Los gehtâs!
02:02=Lasst uns rocken!
-02:02=Lassen Sie uns jam!
-02:02=Es ist Anfang ...
+02:02=Lasst uns jammen!
+02:02=Das ist der Anfang â¦
02:02=Dies ist der Beginn von etwas GroÃem
02:02=Willkommen bei Hedgewars
-02:02=Willkommen auf der Front
-02:02=Crush deine Feinde!
-02:02=Mai die beste Schwein Sieg
+02:02=Willkommen an der Front
+02:02=Mögen die besten Igel gewinnen!
02:02=Sieg oder Tod
-02:02=Dem Sieger geht die Beute
-02:02=Verlieren ist keine Option
-02:02=Cry Havoc! Lassen Sie verlieren die Schweine des Krieges!
-02:02=Hedgewars, die Ihnen von Hedgewars.org
-02:02=GL HF
-02:02=Nur sich glücklich schätzen du bist nicht gegen Tiyuri
-02:02=Nur sich glücklich schätzen du bist nicht gegen unC0Rr
-02:02=Nur sich glücklich schätzen du bist nicht gegen Nemo
-02:02=Nur sich glücklich schätzen du bist nicht gegen Smaxx
-02:02=Nur sich glücklich schätzen du bist nicht gegen Jessor
+02:02=Dem Sieger gehört die Beute
+02:02=Diese Schlacht muss gewonnen werden!
+02:02=Hedgewars, präsentiert von hedgewars.org
+02:02=Sei froh, wenn du nicht gegen Nemo kämpfst
02:02=Gib alles!
-02:02=Die Verlierer machen die Reinigung auf!
+02:02=Die Verlierer müssen putzen!
02:02=Lassen Sie den Kampf des Jahrtausends beginnen
02:02=Lassen Sie den Kampf des Jahrhunderts beginnen
02:02=Lassen Sie den Kampf des Jahrzehnts beginnen
@@ -257,22 +236,18 @@
02:02=Lassen Sie den Kampf des Tages beginnen
02:02=Lassen Sie den Kampf der Stunde beginnen
02:02=Tun Sie Ihr Bestes!
-02:02=Zerstöre den Feind!
-02:02=Viel Glück
-02:02=Viel SpaÃ
-02:02=Kämpfe den guten Kampf
-02:02=Kampf schmutzig
+02:02=Zerstört den Feind!
+02:02=Viel Glück!
+02:02=Viel SpaÃ!
+02:02=Kampf im Schmutz
02:02=Kampf mit Ehre
-02:02=Gib nicht auf
-02:02=Never surrender
-02:02=Rock und Socke!
-02:02=Lassen Sie den fragfest beginnen!
-02:02=Ich hoffe du bist bereit für einen Kampf!
-02:02=Gehen gehen!
-02:02=Igel Voraus!
-02:02=Bringt es ihnen!
+02:02=Niemals aufgeben, niemals kapitulieren!
+02:02=Lassen Sie das Schlachtfest beginnen!
+02:02=Ich hoffe, du bist bereit für einen Kampf!
+02:02=Los, los!
+02:02=Igel voraus!
+02:02=Zeigtâs ihnen!
02:02=Habt keine Angst!
-02:02=Seien Sie mutig und erobern
; Round ends (win; unused atm)
02:03=...
@@ -288,14 +263,15 @@
02:05=Mit Liebe verpackt?
02:05=Frisches Pflaster!
02:05=So werden Sie sich besser fühlen
-02:05=Ein Hallo-Trank! Whoops falsche Spiel
-02:05=Ein wählen mir oben!
-02:05=Zugreifen
+02:05=Ein Hallo-Trank! Upps, falsches Spiel
+02:05=Zugreifen!
02:05=Ein gesunder Snack
-02:05=Ein Mittel, um Schmerzen
-02:05=Richtige Dosierung: so viele wie du finden kannst!
-02:05=Schnelle Lieferung
+02:05=Ein Mittel, um Schmerzen zu lindern
+02:05=Richtige Dosierung: so viele, wie du finden kannst!
+02:05=Express-Lieferung
02:05=Vorräte!
+02:05=Ein Erste-Hilfe-Koffer!
+02:05=Ein Grund zur Hoffnung!
; New ammo crate
02:06=Nachschub!
@@ -305,19 +281,19 @@
02:06=Tod aus der Luft!
02:06=Ein Geschenk!
02:06=Spezielle Lieferung!
-02:06=Es war ein Alptraum bekommen dies durch den Zoll
-02:06=Destruktive Spielzeug aus dem Himmel
-02:06=Warnung! Inhalt Flüchtige
-02:06=Wählen es oder blasen sie auf, ist Qual der Wahl
+02:06=Es war ein Alptraum, diese Kiste durch den Zoll zu kriegen â¦
+02:06=Destruktives Spielzeug aus dem Himmel
+02:06=Vorsicht! Inhalt leicht entzündlich
+02:06=Einsammeln oder sprengen, das ist die Frage
02:06=Extras!
-02:06=Mmm Munition
+02:06=M-M-M-Munition
02:06=Eine Schachtel zerstörerische Kraft
02:06=Luftpost!
-02:06=Was auch immer ist in diesem Feld ist es nicht Pizza
-02:06=Bekommen!
-02:06=Waffe fallen zu lassen eingehende
-02:06=Lassen Sie sich nicht, dass der Feind schnappen!
-02:06=Shiny neues Spielzeug!
+02:06=Was auch immer da drin ist, es ist bestimmt nicht Pizza
+02:06=Einsammlen!
+02:06=Eine Waffenkiste!
+02:06=Lassen Sie nicht zu, dass sich der Feind sie holt!
+02:06=Schönes neues Spielzeug!
02:06=Eine geheimnisvolle Kiste!
; New utility crate
@@ -330,91 +306,106 @@
02:07=Extras für Sie!
02:07=Dies sollte gut sein!
02:07=Verwenden Sie diese mit Bedacht
-02:07=Ooo diese Box ist schwer
-02:07=Möglicherweise müssen Sie diese
+02:07=Uff, diese Box ist schwer
; Hog (%1) skips his turn
-02:08=%1 ist so ein Langeweiler ...
-02:08=%1 denkt weiter nach ...
+02:08=%1 ist so ein Langeweiler â¦
+02:08=%1 denkt weiter nach â¦
+02:08=%1 schmiedet einen Plan â¦
02:08=Das war öde, %1!
02:08=%1 führt etwas im Schilde!
02:08=%1 setzt aus.
02:08=%1 ist ein Drückeberger.
02:08=%1 überdenkt die Situation.
02:08=%1 kann sich nicht entscheiden.
-02:08=%1 muss ein wenig mehr Motivation
+02:08=%1 ist unmotiviert
+02:08=%1 braucht etwas Motivation
02:08=%1 ist ein Pazifist
02:08=%1 hat eine Verschnaufpause
-02:08=%1 hat einen Rest
-02:08=%1 Schüttelfrost aus
-02:08=%1 hat kein Vertrauen in seine eigenen Fähigkeiten
+02:08=%1 nimmt sich eine Auszeit
+02:08=%1 hat kein Vertrauen in die eigenen Fähigkeiten
02:08=%1 beschlieÃt, nichts zu tun
-02:08=%1 lässt den Feind zu vernichten selbst
-02:08=%1 wäre bei Partys schrecklich
+02:08=%1 lässt den Feind sich selbst vernichten
+02:08=%1 wäre furchtbar auf Partys
02:08=%1 versteckt sich
-02:08=%1 hat sich entschlossen, diese Chance geben
-02:08=%1 entscheidet das Beste, was er tun kann, ist nichts ...
+02:08=%1 verpasst die Gelegenheit
+02:08=%1 verschenkt die Chance
+02:08=%1 meint Nichtstun sei der beste Plan â¦
02:08=%1 ist ein groÃes Weichei
-02:08=Bock bock bock, %1 ist ein Huhn
-02:08=%1 schaut ein wenig gelb
+02:08=%1 hat Angst â¦
02:08=%1 ist ein Feigling!
-02:08=%1 wird für den plötzlichen Tod wartet
-02:08=%1 ist wartet auf Sudden Death
-02:08=%1 ist nicht die Bekämpfung von Typ
-02:08=%1 überdenkt seinen Sinn im Leben
-02:08=%1 war nie viel von einem guten Schuss ohnehin
-02:08=%1 wollte nicht, dass die Armee in erster Linie verbinden
-02:08=Aufhören, unsere Zeit, %1
-02:08=Ich bin in dir enttäuscht, %1
-02:08=Los, können Sie es besser machen %1
-02:08=%1 wird gebrochen
+02:08=%1 wartet auf Sudden Death
+02:08=%1 ist nicht so der Kämpfertyp
+02:08=%1 denkt über den Sinn des Lebens nach
+02:08=%1 war noch nie so Recht in Schuss
+02:08=%1 wollte eigentlich niemals zur Armee
+02:08=Die Zeit ist um, %1!
+02:08=Ich bin von dir enttäuscht, %1
+02:08=Los, du kannst es besser, %1!
02:08=%1 hat anscheinend Besseres zu tun
-02:08=%1 ist zu Tode erschrocken
+02:08=%1 hat sich fast zu Tode erschrocken
02:08=%1 ist eingeschlafen
+02:08=%1 ist wohl nur aus Versehen hier
; Hog (%1) hurts himself only
-02:09=%1 sollte besser Zielen üben!
-02:09=%1 scheint sich zu hassen.
+02:09=%1 sollte lieber zielen üben!
+02:09=%1 scheint sich zu hassen
02:09=%1 steht auf der falschen Seite!
02:09=%1 lebt gefährlich!
-02:09=%1 hat keinen Instinkt der Selbsterhaltung
-02:09=%1 durcheinander
-02:09=%1 vermasselt
+02:09=%1 hat keinen Selbsterhaltungstrieb
+02:09=%1 ist durcheinander
+02:09=%1 vermasseltâs
02:09=Das war ein schlechter Schuss, %1
-02:09=%1 ist ein wenig zu sorglos mit gefährlichen Waffen
+02:09=%1 geht ein wenig zu sorglos mit gefährlichen Waffen um
02:09=%1 sollte eine Ãnderung der Laufbahn betrachten
-02:09=Schlechteste. Schuss. Je!
-02:09=Kein kein kein %1, Sie schieÃen auf den Feind!
-02:09=%1 sollte nur werden, den Feind zu vernichten
-02:09=%1 bewegt sich einen Schritt näher an Selbstmord
-02:09=%1, Hilfsmittel der Feind
-02:09=Das war dumm %1
-02:09=%1 Leben mit dem Mantra des "keine Schmerzen, keine gewinnen"
+02:09=Das. War. Schlecht!
+02:09=Nein, nein, nein, %1, Sie müssen auf den Feind schieÃen!
+02:09=%1 bewegt sich einen Schritt näher zum Selbstmord
+02:09=%1, Helfer des Feindes
+02:09=Das war dumm, %1
+02:09=%1 lebt nach dem Mantra des »Ohne Schmerz kein Sieg!«
02:09=%1 ist verwirrt
-02:09=%1 verletzen sich in seiner Verwirrung
-02:09=%1 hat ein Talent für sich zu blamieren
+02:09=%1 ist geistig verwirrt
+02:09=%1 verletzt sich selbst
+02:09=%1 blamiert sich!
02:09=%1 ist ein Trottel!
02:09=%1 ist ungeschickt
-02:09=%1 zeigt der Feind, wozu er fähig ist
-02:09=%1 kann nicht erwartet werden, perfekt zu sein werden die ganze Zeit
-02:09=Mach dir keine Sorgen %1, pobody die nerfect
-02:09=%1 völlig mit Absicht getan
-02:09=Ich werde niemandem sagen, wenn Sie nicht tun, %1
+02:09=%1 zeigt dem Feind, wozu er fähig ist
+02:09=%1 ist nicht perfekt
+02:09=Mach dir keine Sorgen, %1, piemand ist nerfekt
+02:09=%1 hat das mit Absicht getan
+02:09=Ich werd es auch niemandem verraten, mein Ehrenwort, %1!
02:09=Wie peinlich!
-02:09=Ich bin sicher, niemand sah, dass %1
-02:09=%1, Bedürfnisse, seine Field Manual überprüfen
-02:09=%1 Waffe eindeutig versagt
+02:09=Ich hoffe, dass das niemand gesehen hat, %1
+02:09=%1 sollte dringend die Gebrauchsanweisung noch einmal durchlesen
+02:09=%1s hat eindeutig versagt
+02:09=%1s Schuss ging nach hinten los!
; Hog (%1) shot an home run (using the bat and another hog)
02:10=Home Run!
-02:10=Ein Vogel, ein Flugzeug, ...
+02:10=Ein Vogel, ein Flugzeug, â¦
02:10=Der verleiht Flügel!
+02:10=%1 landet einen Home Run!
+02:10=%1 vor, noch ein Tor!
+02:10=Ausgezeichnet, %1!
+02:10=Bravo, %1!
; Hog (%1) has to leave (team is gone)
02:11=%1 muss ins Bett!
02:11=%1 scheint zu beschäftigt zu sein
02:11=Beam ihn hoch, Scotty!
02:11=%1 muss weg
+02:11=%1 verkrümelt sich
+02:11=%1 macht sich vom Acker
+02:11=%1 zieht den Schwanz ein
+02:11=%1 macht sich aus dem Staub
+02:11=%1 macht einen Rückzieher
+02:11=%1 zieht sich zurück
+02:11=%1 teleportiert sich in eine andere Dimension
+02:11=%1 teleportiert sich in ein Paralleluniversum
+02:11=%1 verschwindet
+02:11=%1 ist futsch
+02:11=%1 hat wohl besseres zu tun
; Weapon Categories
03:00=Zeitzünder-Granate
@@ -422,15 +413,15 @@
03:02=Ballistische Waffe
03:03=Vorsicht, sticht!
03:04=Gewehr (mehrere Schüsse)
-03:05=Grabwerkzeug
+03:05=Grabewerkzeug
03:06=Aktion
03:07=Fortbewegungsmittel
03:08=Annäherungsmine
03:09=Pistole (mehrere Schüsse)
-03:10=BOOM!
+03:10=BUMM!
03:11=Bonk!
03:12=Kampfkunst
-03:13=UNUSED
+03:13=NICHT IN VERWENDUNG
03:14=Fortbewegungsmittel
03:15=Luftschlag
03:16=Luftschlag
@@ -446,7 +437,7 @@
03:26=Saftige Granate
03:27=Feurige Granate
03:28=Ballistische Waffe
-03:29=Ballistische Waffe
+03:29=Ball-istische Waffe
03:30=Luftschlag
03:31=Ferngesteuerte Bombe
03:32=Temporärer Effekt
@@ -464,7 +455,7 @@
03:43=Spiele Beathovens tödliche Sonate!
03:44=Ziemlich alt und stinkig
03:45=Die Macht der Wissenschaft
-03:46=Heià heià heiÃ!
+03:46=HeiÃ, heiÃ, heiÃ!
03:47=Mach es weg!
03:48=Stop! Hammer time!
03:49=Tut, was man vermutet
@@ -472,8 +463,8 @@
03:51=Am Boden gefunden
03:52=NICHT IN VERWENDUNG
03:53=Typ 40
-03:54=Baue etwas
-03:55=Werkzeug
+;03:54=Baue etwas
+03:54=Werkzeug
; Weapon Descriptions (use | as line breaks)
04:00=Greife deine Feinde mit einfachen Granaten an.|Der Zeitzünder steuert den Explosionszeitpunkt.|1-5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen
@@ -499,7 +490,7 @@
04:20=Erlaubt es dir, den aktiven Igel zu wechseln|und mit einem anderen Igel fortzufahren.|Angriff: Wechsel aktivieren
04:21=Feuere ein granatenartiges Projektil in die|Richtung deines Gegners, das beim Aufschlag|mehrere kleine Bomben freisetzen wird.|Angriff: Mit voller Kraft feuern
04:22=Nicht nur etwas für Indiana Jones! Die Peitsche|eignet sich besonders gut, um ungezogene Igel|eine Klippe hinunter zu treiben.|Angriff: Alles vor dem Igel schlagen
-04:23=Wenn man nichts mehr zu verlieren hat ...|Opfere deinen Igel, indem du ihn in eine|festgelegte Richtung losstürmen lässt.|Er wird alles auf dem Weg treffen und am|Ende selbst explodieren.|Angriff: Tödlichen Angriff starten
+04:23=Wenn man nichts mehr zu verlieren hat â¦|Opfere deinen Igel, indem du ihn in eine|festgelegte Richtung losstürmen lässt.|Er wird alles auf dem Weg treffen und am|Ende selbst explodieren.|Angriff: Tödlichen Angriff starten
04:24=Alles Gute! Schick diesen Kuchen auf den Weg,|damit er deinen lieben Feinden eine explosive|Party beschert. Die Torte überwindet fast jedes|Terrain, verliert dabei aber an Laufzeit.|Angriff: Torte losschicken explodieren lassen
04:25=Benutze diese Verkleidung, um einen Feind blind|vor Liebe in deine Richtung (und damit in einen|Abgrund oder ähnliches) springen zu lassen.|Angriff: Verkleiden und verführen
04:26=Wirf diese saftige Wassermelone auf deine Feinde.|Sobald die Zeit abgelaufen ist, wird sie in|einzelne und explosive Stücke zerspringen.|Angriff: Halten, um mit mehr Kraft zu werfen
@@ -507,10 +498,10 @@
04:28=Kurz nach dem Start wird diese Rakete beginnen,|sich durch soliden Grund zu graben. Sobald sie|wieder austritt oder der Zeitzünder abläuft,|wird sie explodieren.|Angriff: Halten, um mit mehr Kraft zu feuern
04:29=Das ist nichts für kleine Kinder! Die Ballpistole|feuert Tonnen kleiner farbiger Bälle, die mit|Sprengstoff gefüllt sind.|Angriff: Mit voller Kraft feuern|Hoch/Runter: Im Feuern zielen
04:30=Rufe ein Flugzeug, um ein Areal gezielt mit|tödlichem Napalm einzudecken. Gut gezielt|lassen sich so groÃe Teile der Karte auslöschen.|Links/Rechts: Angriffsrichtung wählen|Cursor: Zielgebiet wählen und Angriff starten
-04:31=Das RC-Flugzeug kann Kisten einsammeln und weit|entfernte Igel angreifen. Steuere es direkt in|ein Opfer oder wirf erst einige Bomben ab.|Angriff: Flugzeug starten und Bomben abwerfen|Weiter Sprung: "Ritt der Walküren"|Hoch/Runter: Flugzeug lenken
+04:31=Das Funkflugzeug kann Kisten einsammeln und weit|entfernte Igel angreifen. Steuere es direkt in|ein Opfer oder wirf erst einige Bomben ab.|Angriff: Flugzeug starten und Bomben abwerfen|Weiter Sprung: "Ritt der Walküren"|Hoch/Runter: Flugzeug lenken
04:32=Niedrige Schwerkraft ist effektiver als jede|Diät! Springe höher und weiter oder lass|einfach deine Gegner noch weiter fliegen.|Angriff: Aktivieren
-04:33=Manchmal muss es eben doch ein bisschen|mehr sein ...|Angreifen: Aktivieren
-04:34=Can't touch me!|Angreifen: Aktivieren
+04:33=Manchmal muss es eben doch ein bisschen|mehr sein â¦|Angreifen: Aktivieren
+04:34=Canât touch me!|Angreifen: Aktivieren
04:35=Manchmal vergeht die Zeit einfach zu schnell.|Schnapp dir einige zusätzliche Sekunden, um|deinen Angriff abzuschlieÃen.|Angriff: Aktivieren
04:36=Nun, manchmal trifft man einfach nicht. In solchen|Fällen kann die moderne Technik natürlich nachhelfen.|Angriff: Aktivieren
04:37=Fürchte nicht das Tageslicht! Die Wirkung hält|nur eine Runde an, aber sie erlaubt es deinem|Igel, den Schaden, den er direkt verursacht|als Leben zu absorbieren.|Angreifen: Aktivieren
@@ -518,8 +509,8 @@
04:39=Fliege mit der fliegenden Untertasse in andere|Teile der Karte. Sie ist schwer zu beherrschen,|bringt dich aber an so gut wie jeden Ort.|Angriff: Aktivieren|Hoch/Links/Rechts: Beschleunigen|Weiter Sprung: Waffe benutzen
04:40=Entzünde einen Teil der Landschaft oder auch etwas|mehr mit dieser (schon bald) brennenden Flüssigkeit.|Angriff: Halten, um mit mehr Kraft zu werfen
04:41=Der Beweis, dass die Natur sogar die fliegende|Untertasse übertreffen könnte. Birdy kann|deinen Igel herumtragen und zudem Eier auf|deine Feinde fallen lassen.|Angriff: Aktivieren und Eier fallen lassen|Hoch/Links/Rechts: In eine Richtung flattern
-04:42=Das tragbare Portal Device ermöglicht es dir,|dich, deine Feinde oder Waffen direkt zwischen|zwei Punkten auf der Karte zu|teleportieren.|Benutze es weise und deine Kampagne wird ein...|RIESENERFOLG!|Angriff: Ãffnet ein Portal|Wechsel: Wechsle die Portalfarbe
-04:43=Lass dein musikalisches Debüt einschlagen wie eine Bombe!|Lass ein Piano vom Himmel fallen, aber pass auf...|jemand muss es spielen und das könnte dich |dein Leben kosten!|Cursor: Zielgebiet wählen und Angriff starten|F1-F9: Spiel das Piano
+04:42=Das tragbare Portal Device ermöglicht es dir,|dich, deine Feinde oder Waffen direkt zwischen|zwei Punkten auf der Karte zu|teleportieren.|Benutze es weise und deine Kampagne wird ein â¦|RIESENERFOLG!|Angriff: Ãffnet ein Portal|Wechsel: Wechsle die Portalfarbe
+04:43=Lass dein musikalisches Debüt einschlagen wie eine Bombe!|Lass ein Piano vom Himmel fallen, aber pass auf â¦|jemand muss es spielen und das könnte dich |dein Leben kosten!|Cursor: Zielgebiet wählen und Angriff starten|F1-F9: Spiel das Piano
04:44=Das ist nicht nur Käse, das ist biologische Kriegsführung!|Er wird nicht viel Schaden verursachen, sobald der Zünder|abgelaufen ist, aber er wird garantiert jeden in der Nähe|vergiften!|1-5: Zeitzünder einstellen|Angriff: Halten, um mit mehr Kraft zu werfen
04:45=All die Physikstunden haben sich endlich|bezahlt gemacht: Entfessle eine zerstörerische Sinuswelle|gegen deine Feinde.|Pass auf, die Waffe erzeugt einen ordentlichen RückstoÃ.|(Diese Waffe ist unvollständig)|Angriff: Sinuswellen erzeugen
04:46=Brutzle deine Feinde mit flieÃenden Flammen.|Herzerwärmend!|Angriff: Aktivieren|Hoch/Runter: Im Feuern zielen|Links/Rechts: Durchfluss ändern
@@ -530,8 +521,8 @@
04:51=Wirf mit Dreck um dich!|Schmerzt ein wenig und schubst Igel weg.
04:52=NICHT IN VERWENDUNG
04:53=Unternimm eine Reise durch Zeit und Raum,|während du deine Kameraden alleine am Schlachtfeld zurücklässt.|Sei darauf vorbereitet jederzeit wieder zurückzukommen,|oder auf Sudden Death wenn sie alle besiegt wurden.|Disclaimer: Nicht funktionstüchtig wenn in Sudden Death,|wenn du alleine bist - oder der König.
-04:54=IN ARBEIT
-04:55=Versprühe einen Strahl klebriger Flocken.|Baue Brücken, begrabe Gegner, versiegle Tunnel.|Pass auf, dass du selbst nichts abbekommst!
+;04:54=IN ARBEIT
+04:54=Versprühe einen Strahl klebriger Flocken.|Baue Brücken, begrabe Gegner, versiegle Tunnel.|Pass auf, dass du selbst nichts abbekommst!
; Game goal strings
05:00=Spielmodifikationen
@@ -548,7 +539,7 @@
05:11=Gemeinsames Arsenal: Alle Teams gleicher Farbe teilen sich ihr Arsenal
05:12=Minenzünder: Minen explodieren nach %1 Sekunde(n)
05:13=Minenzünder: Minen explodieren sofort
-05:14=Minenzünder: Minen explodieren nach 0 - 3 Sekunden
+05:14=Minenzünder: Minen explodieren nach 0-3 Sekunden
05:15=Prozentualer Schaden: Alle Waffen verursachen %1 % Schaden
05:16=Lebenspunkter aller Igel wird am Ende jeder Runde zurückgesetzt
05:17=Computergesteuerte Igel erscheinen nach dem Tod wieder
diff --git a/share/hedgewars/Data/Locale/el.txt b/share/hedgewars/Data/Locale/el.txt
index e028b99..d321474 100644
--- a/share/hedgewars/Data/Locale/el.txt
+++ b/share/hedgewars/Data/Locale/el.txt
@@ -1,4 +1,4 @@
-; Greek locale
+; Greek locale
00:00=ΧειÏοβομβίδα
00:01=ΧειÏοβομβίδα ÎιαÏÏοÏάÏ
@@ -164,7 +164,7 @@
02:01=Î %1 βÏήκε Ïην ÏαμÎνη ÏÏλη ÏÎ·Ï ÎÏλανÏίδαÏ!
02:01=Î %1 Îγινε ÏÏοÏή για Ïα ÏάÏια!
02:01=ΤοÏ
%1 δεν ÏοÏ
αÏÎÏοÏ
ν Ïα αθλήμαÏα ÏοÏ
νεÏοÏ!
-02:01=Î %1 ÎÏÏεÏε να ÏÎÏει Ïη ÏÏεδία ÏοÏ
!
+02:01=Î %1 ÎÏÏεÏε να ÏÎÏει Ïη ÏÏεδία ÏοÏ
!
02:01=Î %1 ÏιÏÏεÏει ÏÏι Ïο θαλαÏÏÎ¹Î½Ï Î½ÎµÏÏ ÎºÎ¬Î½ÎµÎ¹ ÎºÎ±Î»Ï ÏÏο δÎÏμα!
02:01=Î %1 βάζει αλάÏι ÏÏÎ¹Ï ÏληγÎÏ ÏοÏ
!
02:01=Î %1 Ïάει Ïαξίδι ÏÏην άβÏ
ÏÏο!
@@ -187,10 +187,10 @@
02:02=ΣÏ
νÎÏÏιÏε ÏοÏ
Ï ÎµÏθÏοÏÏ ÏοÏ
!
02:02=ÎÏ Î½Î¹ÎºÎ®Ïει ο καλÏÏεÏÎ¿Ï ÏκανÏζÏÏοιÏοÏ!
02:02=Îίκη ή θάναÏοÏ!
-02:02=Τα λάÏÏ
Ïα Ïάνε ÏÏο νικηÏή!
+02:02=Τα λάÏÏ
Ïα Ïάνε ÏÏο νικηÏή!
02:02=ΠήÏÏα δεν είναι εÏιλογή!
02:02=ΣκοÏÏίÏÏε Ïον ÏλεθÏο!
-02:02=ÎÏÎθηκαν ελεÏθεÏοι οι ÏκανÏζÏÏοιÏοι ÏοÏ
ÏολÎμοÏ
!
+02:02=ÎÏÎθηκαν ελεÏθεÏοι οι ÏκανÏζÏÏοιÏοι ÏοÏ
ÏολÎμοÏ
!
02:02=Hedgewars, ÏÎ±Ï ÏÏοÏÏÎÏεÏαι αÏÏ Ïο Hedgewars.org
02:02=ÎÎÎÎÎÎÎÎÎÎΡΡΡΡΡÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ.....
02:02=ÎίÏαι ÏÎ¿Î»Ï ÏÏ
ÏεÏÏÏ Î±Î½ δεν είÏαι ενανÏίÏν ÏοÏ
Tiyuri!
@@ -486,7 +486,7 @@
; Game goal strings
05:00=ÎανÏÎ½ÎµÏ Î Î±Î¹ÏνιδιοÏ
-05:01=ÎÏÏÏοÏ
ν οι ακÏλοÏ
θοι κανÏÎ½ÎµÏ :
+05:01=ÎÏÏÏοÏ
ν οι ακÏλοÏ
θοι κανÏÎ½ÎµÏ :
05:02=ΦÏοÏÏια : Î¥ÏεÏαÏÏιÏÏείÏε Ïο ÏÏοÏÏÎ¹Ï ÏαÏ, ÏÏ
νÏÏίÏÏε ÏοÏ
Ï ÎµÏθÏοÏÏ ÏαÏ!
05:03=ÎικÏοβαÏÏÏηÏα : Î ÏοÏÎξÏε ÏÎ¿Ï ÏαÏάÏε!
05:04=ÎÏÏίδα: Îι ÏκανÏζÏÏοιÏοι είναι (ÏÏεδÏν) άÏÏÏÏοι.
diff --git a/share/hedgewars/Data/Locale/en.txt b/share/hedgewars/Data/Locale/en.txt
index 763be41..fa1e441 100644
--- a/share/hedgewars/Data/Locale/en.txt
+++ b/share/hedgewars/Data/Locale/en.txt
@@ -45,7 +45,7 @@
00:42=Portable Portal Device
00:43=Piano Strike
00:44=Old Limburger
-00:45=Sine Gun (beta)
+00:45=Sine Gun
00:46=Flamethrower
00:47=Sticky Mine
00:48=Hammer
@@ -54,17 +54,17 @@
00:51=Mudball
00:52=No weapon selected
00:53=TimeBox
-00:54=Structure
-00:55=Land Spray
-00:56=Freezer
-00:57=Cleaver
+; 00:54=Structure
+00:54=Land Spray
+00:55=Freezer
+00:56=Cleaver
01:00=Let's fight!
01:01=Round draw
01:02=%1 wins!
01:03=Volume %1%
01:04=Paused
-01:05=Really quit (Y/Esc)?
+01:05=Really quit? (Y/Esc) (Click to resume)
01:06=Sudden Death!
01:07=%1 remaining
01:08=Fuel
@@ -178,7 +178,6 @@
02:01=%1 wants to play Ecco the dolphin
02:01=%1 has gone to visit Aquaria
02:01=%1 has found the lost city of Atlantis
-02:01=%1 aims for the lead role in Bioshock 3
02:01=Your doggy paddle could use a little work, %1
02:01=%1 should have brought a jet ski
02:01=%1 doesn't like watersports
@@ -445,13 +444,15 @@
03:46=Hot Hot Hot!
03:47=Stick these somewhere useful!
03:48=It's Hammer time!
-03:49=Does what you guess
+03:49=Bring back the dead TO hell!
03:50=Moles fan
03:51=Found on the ground
03:52=UNUSED
03:53=Type 40
-03:54=Build something
-03:55=Utility
+;03:54=Build something
+03:54=Utility
+03:55=It doesn't get cooler than this!
+03:56=Please use or misuse
; Weapon Descriptions (use | as line breaks)
04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power
@@ -504,12 +505,13 @@
04:47=Double the fun with two spiky, sneaky, sticky mines.|Set up a chain reaction or defend yourself (or both!)|Attack: Hold to shoot with more power (twice)
04:48=Why should the moles get all the abuse?|Wacking a hog can be just as fun! A good|blow from this hammer will shave off one|third of a hog's health and plunge them|underground.|Attack: Activate
04:49=Resurrect your friends!|But beware that this also resurrects your foes.|Attack: Keep attack pressed to resurrect slowly|Up: Accelerate resurrection
-04:50=Is someone hiding underground?|Dig them out with a drill strike!|Timer controls how far it will dig.
-04:51=Get in a free shot by hurling a ball of mud.|Stings a bit, and knocks hogs back.
+04:50=Is someone hiding underground?|Dig them out with a drill strike!|Timer controls how far it will dig.|Left/Right: Determine attack direction|Cursor: Select target region
+04:51=Get in a free shot by hurling a ball of mud.|Stings a bit, and knocks hogs back.|Attack: Hold to shoot with more power
04:52=UNUSED
-04:53=Take a trip through time and space,|while leaving your comrades to fight on alone.|Be prepared to return at any time,|or for Sudden Death or if they are all defeated.|Disclaimer. Does not function in Sudden Death,|if you are alone, or if you are a King.
-04:54=INCOMPLETE
-04:55=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!
+04:53=Take a trip through time and space,|while leaving your comrades to fight on alone.|Be prepared to return at any time,|or for Sudden Death or if they are all defeated.|Disclaimer. Does not function in Sudden Death,|if you are alone, or if you are a King.|Attack: Activate
+04:54=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!|Attack: Activate|Up/Down: Continue aiming|Left/Right: Modify spitting power
+04:55=Bring back the ice-age!|Freeze hedgehogs, make the floor slippery or|save yourself from drowning by freezing the water.|Attack: Shoot
+04:56=You can throw two cleavers at your enemy,|block passages and tunnels and even use them for climbing!|Be careful! Playing with knifes is dangerous.|Attack: Hold to shoot with more power (twice)
; Game goal strings
05:00=Game Modes
diff --git a/share/hedgewars/Data/Locale/es.lua b/share/hedgewars/Data/Locale/es.lua
index 638205d..4763eb3 100644
--- a/share/hedgewars/Data/Locale/es.lua
+++ b/share/hedgewars/Data/Locale/es.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Vuelta rápida: ",
["Feeble Resistance"] = "Resistencia Fútil",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = " pobres desgraciados restantes!",
["Hapless Hogs"] = "Pobres desgraciados",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "¡Hurra!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
["Pathetic Resistance"] = "Patética resistencia", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Armamento individualizado",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Coloca más balizas presionando [INTRO]",
+
["Place more waypoints using the 'Air Attack' weapon."] = "Coloca más balizas usando el 'Bombardeo aéreo'",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Reto personal",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/es.txt b/share/hedgewars/Data/Locale/es.txt
index 60a3cb9..8cef426 100644
--- a/share/hedgewars/Data/Locale/es.txt
+++ b/share/hedgewars/Data/Locale/es.txt
@@ -55,8 +55,8 @@
00:51=Bola de barro
00:52=No hay arma seleccionada
00:53=Cabina del tiempo
-00:54=Estructura
-00:55=Pistola de barro
+; 00:54=Estructura
+00:54=Pistola de barro
01:00=¡Luchad!
01:01=Empate
@@ -171,7 +171,6 @@
02:01=%1 prefiere jugar a Ecco the dolphin
02:01=%1 ha ido a visitar Aquaria
02:01=%1 ha encontrado la ciudad perdida de la Atlántida
-02:01=%1 hace audiciones para el personaje principal de Bioshock 3
02:01=Necesitas practicar más tu estilo perrito, %1
02:01=Necesitas practicar más tu brazada, %1
02:01=Necesitas practicar más tu estilo mariposa, %1
@@ -446,8 +445,8 @@
03:51=Me la encontré por el suelo
03:52=SIN USAR
03:53=Tipo 40
-03:54=Construye algo
-03:55=Herramienta
+;03:54=Construye algo
+03:54=Herramienta
; Descripciones de armamento ( lÃneas delimitadas con | )
04:00=Ataca a tus enemigos usando una sencilla granada.|Explotará una vez el temporizador llegue a cero.|1-5: ajustar temporizador.|Atacar: mantener presionado para lanzar más lejos.
@@ -504,8 +503,8 @@
04:51=¿Qué hay más barato que el barro?|Un tiro gratis gracias a la bola de barro.|Hará que el enemigo salga volando|y escuece un poco si te entra en los ojos.
04:52=SIN USAR
04:53=Vive una trepidante aventura a través del|espacio y el tiempo mientras tus compañeros|siguen luchando en tu lugar.|Estate preparado para volver en cualquier momento,|o al llegar la Muerte súbita si te has quedado solo.|Aviso: no funciona durante la Muerte súbita,|si estás solo o si eres el rey.
-04:54=INCOMPLETO
-04:55=Esparce un chorro de pegajoso barro.|Construye puentes, entierra enemigos o cierra túneles.|¡Ten especial cuidado de no mancharte!
+;04:54=INCOMPLETO
+04:54=Esparce un chorro de pegajoso barro.|Construye puentes, entierra enemigos o cierra túneles.|¡Ten especial cuidado de no mancharte!
; Game goal strings
05:00=Modos de juego
diff --git a/share/hedgewars/Data/Locale/fi.txt b/share/hedgewars/Data/Locale/fi.txt
index 01cd639..1f51991 100644
--- a/share/hedgewars/Data/Locale/fi.txt
+++ b/share/hedgewars/Data/Locale/fi.txt
@@ -159,7 +159,6 @@
02:01=%1 haluaa näytellä Ecco-delfiiniä
02:01=%1 lähti käymään Aquariassa
02:01=%1 löysi Atlantiksen kadonneen kaupungin
-02:01=%1 tähtää Bioshock 3:en päärooliin
02:01=%1:n olisi pitänyt ottaa vesiskootteri mukaan
02:01=%1 ei pidä vesiurheilusta
02:01=%1 puhaltaa ikuisesti kuplia
@@ -416,18 +415,18 @@
04:01=Hyökkää sirpalepommilla.|Se jakaantuu pienemmiksi pommeiksi ajan|loppuessa ajastimesta|1-5: Säädä kranaatin ajastin|Hyökkää: Pidä pohjassa lisätäksesi heittovoimaa
04:02=Hyökkää ballistisella ammuksella|johon tuuli saattaa vaikuttaa|Hyökkää: Pidä pohjassa lisätäksesi voimaa
04:03=Laukaise ohjattu mehiläinen joka lukittuu|valittuun kohteeseen. Ãlä ammu täydellä voimalla|lisätäksesi tarkkuutta|Kursori: Valitse kohde|Hyökkää: Pidä pohjassa lisätäksesi voimaa
-04:04=Ammu vihollisiasi kahdesti laukeavalla haulikolla.|Kiitos leviämisen sinun ei tarvitse tähdätä suoraan|vahingoittaeksi vihollisiasi.|Hyökkää: Ammu (useita kertoja)
+04:04=Ammu vihollisiasi kahdesti laukeavalla haulikolla.|Kiitos leviämisen sinun ei tarvitse tähdätä suoraan|vahingoittaeksi vihollisiasi.|Hyökkää: Ammu (useita kertoja)
04:05=Siirry maan alle! Käytä maaporaa porataksesi|reiän maahan päästäksesi muille alueille.|Hyökkää: Aloita ja lopeta kaivaminen
04:06=Tylsää? Ei mitään tapaa hyökätä? Säästät ammuksiasi?|Ei hätää! Jätä vuoro väliin, pelkuri!|Hyökkää: Jätä vuorosi väliin ilman tappelua
04:07=Ylitä pitkiä välimatkoja|hyvin ajoitetuilla laukauksilla ja köydellä.|Käytä momenttiasi liukuaksesi muiden siilien sekaan|tai pudota kranaatteja ja muita aseita niiden päälle.|Hyökkää: Ammu ja irroita köysi|Pitkä hyppy: Pudota kranaatteja ja vastaavia aseita
04:08=Pidä viholliset kaukana pudottamalla miina|kapeille käytäville tai suoraan niiden jalkojen juureen.|Pakene ennen kuin aktivoit sen itse!|Hyökkää: Pudota miina viereesi
04:09=Oletko epävarma tähtäyksestäsi? Käytä Desert|Eaglea hyökätäksesi neljällä laukauksella| Hyökkää: Ammu (useita kertoja)
-04:10=Raaka voima on aina vaihtoehto. Käytä tätä klassista|räjähdettä vihollisiis ja pakene.|Hyökkää: Pudota dynamiitti viereesi
+04:10=Raaka voima on aina vaihtoehto. Käytä tätä klassista|räjähdettä vihollisiis ja pakene.|Hyökkää: Pudota dynamiitti viereesi
04:11=Hankkiudu vihollissiileistä eroon lyömällä ne mailalla|kartan ulkopuolelle tai veteen. Tai miten olisi|muutaman miinan lyöminen kavereillesi?|Hyökkää: Lyö kaikkia edessä olevia
-04:12=Mene henkilökohtaisuuksiin vapauttamalla|tämän melkein tappavan kamppailulajitekniikan voimat.|Hyökkää: Suorita Fire Punch
-04:13=UNUSED
+04:12=Mene henkilökohtaisuuksiin vapauttamalla|tämän melkein tappavan kamppailulajitekniikan voimat.|Hyökkää: Suorita Fire Punch
+04:13=UNUSED
04:14=Korkean paikan kammo? Parempi ottaa laskuvarjo.|Se avautuu kun putoat liian kauas|ja pelastaa siilen putoamisvaurioilta.|Hyökkää: Avaa laskuvarjo
-04:15=Kutsu lentokone hyökkäämään vihollisiasi päin|pommituslennolla|Vasen/Oikea: Valitse suunta|Osoitin: Valitse kohdealue
+04:15=Kutsu lentokone hyökkäämään vihollisiasi päin|pommituslennolla|Vasen/Oikea: Valitse suunta|Osoitin: Valitse kohdealue
04:16=Kutsu lentokone pudottaaman useita miinoja kohdealueelle|Vasen/Oikea: Valitse hyökkäyssuunta|Osoitin: Valitse kohdealue
04:17=Tarvitsetko suojaa? Käytä puhalluslamppua kaivaaksesi|tunnelin maahan saadaksesi suojaa|Hyökkää: Aloita ja lopeta kaivaminen
04:18=Tarvitsetko suojaa vai haluatko ylittää|ylittämättömän maa-alueen? Sijoita muutamia palkkeja kuten haluat|Vasen/Oikea: Valitse asetettava palkki|Osoitin: Sijoita palkki sallittuun kohtaan
@@ -436,7 +435,7 @@
04:21=Ammu kranaatin kaltainen ammus|joka vapauttaa useita pommeja osuessaan|Hyökkää: Ammu täydellä voimalla
04:22=Ei vain Indiana Jonesille! Piiska on hyödyllinen ase|useissa tilanteissa. Erityisesti|jos haluat sysätä jonkun alas kielekkeeltä|Hyökkää: Iske kaikkea edessäsi olevaa
04:23=Jos sinulla ei ole mitään menettävää|tämä saattaa olla melko kätevä.|Uhraa siilesi laukaisemalla se|valittuun suuntan vahingottaen kaikkea tiellä olevaa räjähtäen lopussa|Hyökkää: Laukaise tuhoisa ja tappava hyökkäys
-04:24=Hyvää syntymäpäivää! Laukaise tämä kakku ja anna sen kävellä|vihollistesi viereen ja järjestä heille räjähtävät kekkerit.|Tämä kakku voi ylittää melkein minkä tahansa maaston|Mutta se saattaa räjähtää matkalla|Hyökkää: Laukaise kakku tai anna sen pysähtyä ja räjähtää
+04:24=Hyvää syntymäpäivää! Laukaise tämä kakku ja anna sen kävellä|vihollistesi viereen ja järjestä heille räjähtävät kekkerit.|Tämä kakku voi ylittää melkein minkä tahansa maaston|Mutta se saattaa räjähtää matkalla|Hyökkää: Laukaise kakku tai anna sen pysähtyä ja räjähtää
04:25=Käytä tätä naamioitumispakkausta saadaksesi vihollisesi|hyppäämään halatakseen (ja sitten putoamaan kuoppaan tai reikään).|Hyökkää: Käytä pakkausta ja yritä vietellä toinen siili
04:26=Heitä tämä mehukas vesimeloni vihollsiasi kohti|Kun ajastimesta loppuu aika, se hajoaa useiksi|räjähtäviksi palasiksi.|1-5: säädä vesimelonin ajastinta|Hyökkää: Pidä pohjassa lisätäksesi voimaa
04:27=Anna helvetin tulen sataa vihollistesi päälle käyttämällä tätä|pirullista räjähdettä. Ãlä mene liian lähelle tätä räjähdettä|koska pienemmät tulet saattavat kestää pitempään.|Hyökkää: Pidä pohjassa ampuaksesi voimakkaammin
diff --git a/share/hedgewars/Data/Locale/fr.lua b/share/hedgewars/Data/Locale/fr.lua
index f617a1e..0261317 100644
--- a/share/hedgewars/Data/Locale/fr.lua
+++ b/share/hedgewars/Data/Locale/fr.lua
@@ -1,51 +1,16 @@
locale = {
- ["???"] = "???",
- ["..."] = "...",
- ["..."] = "...",
+-- ["???"] = "",
+-- ["..."] = "",
-- [":("] = "",
-- ["!!!"] = "",
--- ["..."] = "",
- ["011101000"] = "",
- ["011101000"] = "",
- ["011101000"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "",
- ["011101001"] = "011101001",
+-- ["011101000"] = "",
+-- ["011101001"] = "",
["30 minutes later..."] = "30 minutes plus tard...",
["About a month ago, a cyborg came and told us that you're the cannibals!"] = "Il y a un moins, un cyborg est venu et nous a dit que vous étiez des cannibales !",
["Accuracy Bonus!"] = "Bonus précision",
-- ["Ace"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
["Achievement Unlocked"] = "Succes débloqué", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_That_Sinking_Feeling, Tumbler
--- a classic fairytale: backstab
--- a classic fairytale: dragon's lair
--- a classic fairytale: epilogue
--- a classic fairytale: family reunion
- -- a classic fairytale: first blood
--- a classic fairytale: long live the queen
--- a classic fairytale: the enemy of my enemy...
--- a classic fairytale: the journey back
--- a classic fairytale: the shadow falls
["A Classic Fairytale"] = "Un conte de fée classique",
--- a classic fairytale: united we stand
["Actually, you aren't worthy of life! Take this..."] = "En fait, tu n'es pas digne de vivre ! Prends ça....",
["A cy-what?"] = "Un cy-quoi ?",
["Adventurous"] = "Aventureux",
@@ -59,7 +24,6 @@ locale = {
["A leap in a leap"] = "Un bond dans un bond",
["A little gift from the cyborgs"] = "Un petit cadeau de la part des cyborgs",
["All gone...everything!"] = "évaporé...plus rien !",
- ["All right, we just need to get to the other side of the island!"] = "",
["All right, we just need to get to the other side of the island!"] = "Très bien, nous devons juste rejoindre l'autre côté de l'île !",
-- ["All walls touched!"] = "", -- WxW
["Ammo Depleted!"] = "Munitions épuisées !",
@@ -71,8 +35,6 @@ locale = {
["And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."] = "Et Leaks A Lot échoua à relever le défi ! Il atteri, honteux....",
["And so it began..."] = "Et c'est ainsi que ça a commencé...",
["...and so the cyborgs took over the world..."] = "...Et c'est ainsi que les cyborgs prirent le controle du monde...",
- ["And so they discovered that cyborgs weren't invulnerable..."] = "",
- ["And so they discovered that cyborgs weren't invulnerable..."] = "",
["And so they discovered that cyborgs weren't invulnerable..."] = "Et c'est ainsi qu'ils découvrirent que les cybords n'étaient pas invulnérables...",
["And where's all the weed?"] = "et où est toute l'herbe ?",
["And you believed me? Oh, god, that's cute!"] = "Et tu m'as cru ? Oh mon dieu, c'est mignon !",
@@ -81,25 +43,20 @@ locale = {
["Are we there yet?"] = "Somme nous toujours là ?",
["Are you accusing me of something?"] = "Es tu en train de m'accuser de quelque chose ? ",
["Are you saying that many of us have died for your entertainment?"] = "Etes vous en train de dire que beaucoup d'entre nous sont morts pour votre divertissement ? ",
- ["Artur Detour"] = "",
+-- ["Artur Detour"] = "",
["As a reward for your performance, here's some new technology!"] = "Comme récompence, voici quelques nouvelles technologie !",
-- ["a shoppa minigame"] = "", -- WxW
-- ["Asia"] = "", -- Continental_supplies
- ["Assault Team"] = "",
- ["Assault Team"] = "",
+-- ["Assault Team"] = "",
["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "Vu que les munitions sont éparpillées tu devrais re-lancer la corde en plein vol",
["As the challenge was completed, Leaks A Lot set foot on the ground..."] = "Le défi accompli, Leaks A Lot posa les pieds sur le sol...",
["As you can see, there is no way to get on the other side!"] = "Comme tu peux le voir, il n'y a pas de moyen d'atteindre l'autre côté !",
-- ["Attack From Rope"] = "", -- WxW
-- ["Australia"] = "", -- Continental_supplies
["Available points remaining: "] = "points restant disponibles", -- need the situation of when this sentence is used
- ["Back Breaker"] = "",
+-- ["Back Breaker"] = "",
["Back in the village, after telling the villagers about the threat..."] = "De retour au village, après avoir averti les villageois de la menace...",
-- ["[Backspace]"] = "effacement arrière", --maybe the original name is better...
- ["Backstab"] = "",
- ["Backstab"] = "",
- ["Backstab"] = "",
- ["Backstab"] = "",
["Backstab"] = "coup de poignard dans le dos",
-- ["Bad Team"] = "", -- User_Mission_-_The_Great_Escape
-- ["Bamboo Thicket"] = "", --really, i don't know the good translation for this
@@ -109,36 +66,29 @@ locale = {
["Bat balls at your enemies and|push them into the sea!"] = "Frappez vos ennemis à la batte|et envoyez-les à la mer !",
["Bat your opponents through the|baskets and out of the map!"] = "Frappez vos ennemis à la batte|, marquez des paniers ou envoyez-les à la mer !",
["Bazooka Training"] = "Entrainement au Bazooka",
- ["Beep Loopers"] = "",
- ["Beep Loopers"] = "",
+-- ["Beep Loopers"] = "",
["Best laps per team: "] = "Meilleur temps par équipe",
-- ["Best Team Times: "] = "",
["Beware, though! If you are slow, you die!"] = "Attention tout de meme ! si tu es lent, tu meurt !",
- ["Biomechanic Team"] = "",
- ["Biomechanic Team"] = "",
- ["Blender"] = "",
- ["Bloodpie"] = "",
- ["Bloodrocutor"] = "Bloodrocutor",
- ["Bloodsucker"] = "Bloodsucker",
+-- ["Biomechanic Team"] = "",
+-- ["Blender"] = "",
+-- ["Bloodpie"] = "",
+-- ["Bloodrocutor"] = "",
+-- ["Bloodsucker"] = "",
["Bloody Rookies"] = "Nouvelles recrues", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree
- ["Bone Jackson"] = "",
+-- ["Bone Jackson"] = "",
["Bonely"] = "Bonely",
- ["Boom!"] = "Boom!",
- ["BOOM!"] = "BOOM!",
+-- ["Boom!"] = "",
+-- ["BOOM!"] = "",
["Boss defeated!"] = "Boss vaincu",
["Boss Slayer!"] = "Tueur de Boss !",
- ["Brain Blower"] = "Brain Blower",
- ["Brainiac"] = "",
- ["Brainiac"] = "",
- ["Brainiac"] = "Brainiac",
- ["Brainiac"] = "Brainic",
- ["Brainila"] = "",
- ["Brain Stu"] = "",
- ["Brain Teaser"] = "",
- ["Brutal Lily"] = "",
- ["Brutal Lily"] = "Brutal Lily",
- ["Brutus"] = "",
- ["Brutus"] = "Brutus",
+-- ["Brain Blower"] = "",
+-- ["Brainiac"] = "",
+-- ["Brainila"] = "",
+-- ["Brain Stu"] = "",
+-- ["Brain Teaser"] = "",
+-- ["Brutal Lily"] = "",
+-- ["Brutus"] = "",
["Build a track and race."] = "construisez un parcours et faites la course.",
["Bullseye"] = "Dans le mille",
["But it proved to be no easy task!"] = "Mais cela ne s'avéra pas etre une tache facile !",
@@ -150,20 +100,12 @@ locale = {
["But you're cannibals. It's what you do."] = "Mais vous etes cannibales. C'est ce que vous faites.",
["But you said you'd let her go!"] = "Mais vous aviez dit que vous la laisseriez partir !",
["Call me Beep! Well, 'cause I'm such a nice...person!"] = "Appele moi Beep ! Hum, parce que je suis genre une personne sympa !",
- --CAMPAIGN MISSIONS TRANSLATION FRENCH--
- ["Cannibals"] = "",
- ["Cannibals"] = "",
- ["Cannibals"] = "",
- ["Cannibals"] = "",
["Cannibals"] = "Cannibales",
- ["Cannibals"] = "Cannibals",
- ["Cannibal Sentry"] = "",
- ["Cannibal Sentry"] = "",
["Cannibal Sentry"] = "Sentinelle cannibale",
["Cannibals?! You're the cannibals!"] = "Cannibales ? C'est vous les cannibales !",
["CAPTURE THE FLAG"] = "Capturez le drapeau !",
["Careless"] = "Imprudent",
- ["Carol"] = "",
+-- ["Carol"] = "",
-- ["CHALLENGE COMPLETE"] = "", -- User_Mission_-_RCPlane_Challenge
["Change Weapon"] = "changez d'arme",
["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "Choisis ton côté ! Si tu veux rejoindre l'étranger, marche vers lui. |Dans le cas contraire, éloigne toi de lui. Si tu décide de l'att...non laisse tomber...",
@@ -172,7 +114,6 @@ locale = {
-- ["Cluster Bomb Training"] = "", -- Basic_Training_-_Cluster_Bomb
["Codename: Teamwork"] = "Nom de code : Travail d'équipe",
["Collateral Damage"] = "Dommage collatéraux",
- ["Collateral Damage II"] = "",
["Collateral Damage II"] = "Dommage collatéraux II",
["Collect all the crates, but remember, our time in this life is limited!"] = "Collectes toutes les caisses mais souviens toi, notre temps dans cette vie est limité !",
-- ["Collect or destroy all the health crates."] = "", -- User_Mission_-_RCPlane_Challenge
@@ -190,41 +131,28 @@ locale = {
["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Félicitations ! Vous avez éliminé toutes les cibles|pendant le temps alloué.", --Bazooka, Shotgun, SniperRifle
-- ["Continental supplies"] = "", -- Continental_supplies
["Control pillars to score points."] = "Contrôlez les piliers pour marquer des points",
- ["Corporationals"] = "",
- ["Corporationals"] = "",
- ["Corpsemonger"] = "Corpsemonger",
- ["Corpse Thrower"] = "Corpse Thrower",
+-- ["Corporationals"] = "",
+-- ["Corpsemonger"] = "",
+-- ["Corpse Thrower"] = "",
-- ["Crates Left:"] = "", -- User_Mission_-_RCPlane_Challenge
["Cybernetic Empire"] = "Empire cybernétique",
["Cyborg. It's what the aliens call themselves."] = "Cyborg. C'est ainsi que s'appellent les aliens entre eux.",
- ["Dahmer"] = "",
+-- ["Dahmer"] = "",
["DAMMIT, ROOKIE!"] = "Et merde, recrue",
["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "Et merde, recrue ! Dégage de me tête !",
["Dangerous Ducklings"] = "Canetons dangereux",
-- ["Deadweight"] = "poids mort/boulet",
- ["Defeat the cannibals"] = "",
["Defeat the cannibals!|"] = "Bat les cannibales",
["Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "Bat les cannibales ! |Astuce Grenade : Règle le compte à rebour avec [1-5], vises avec [haut]/[bas] et maintient [Espace] pour la puissance",
["Defeat the cyborgs!"] = "Bats les cyborgs !",
["Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"] = "Défends toi ! |Conseil : Tu peux obtenir des astuces sur l'utilisation des armes en placant ta souris dessus dans le menu de séléction des armes",
["Demolition is fun!"] = "La démolition c'est cool",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "",
- ["Dense Cloud"] = "Dense Cloud",
+-- ["Dense Cloud"] = "",
["Dense Cloud must have already told them everything..."] = "Dense Cloud doit déjà leur avoir tout raconter...",
-- ["Depleted Kamikaze!"] = "Kamikaze ... !",
["Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"] = "Détruis le, Leaks A Lot ! Il est responsable de la mort de beaucoup d'entre nous !",
["Destroy invaders to score points."] = "Détruisez les envahisseur pour marquer des points",
["Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."] = "Détruis les cibles ! |Astuce : selectionne le Shoryuken et appuyez sur [Espace] |P.S. vous pouvez l'utilisez en plein vol",
- ["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "Détruis les cibles ! |Astuce : [haut], [bas] pour viser, [Espace] pour tirer",
["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "Détruis les cibles ! |Astuce : [haut], [bas] pour viser, [Espace] pour tirer",
["Did anyone follow you?"] = "As tu été suivis ? ",
["Did you see him coming?"] = "L'a tu vu venir ?",
@@ -239,11 +167,8 @@ locale = {
-- ["DOUBLE KILL"] = "", -- Mutant
["Do you have any idea how valuable grass is?"] = "Est ce que vous avez une idée de la valeur de votre herbe ?",
["Do you think you're some kind of god?"] = "Vous vous prenez pour un genre de dieu ?",
- ["Dragon's Lair"] = "",
- ["Dragon's Lair"] = "",
- ["Dragon's Lair"] = "",
["Dragon's Lair"] = "La tanière du dragon",
- ["Drills"] = "",
+-- ["Drills"] = "",
["Drone Hunter!"] = "Chasseur de drone",
-- ["Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"] = "", -- Continental_supplies
-- ["Drowner"] = "",-- can't have a good translation, think its a merge of drone and owner so if wanna translate it will be : tueur de drone, wich is like drone hunter...
@@ -253,16 +178,15 @@ locale = {
["Dude, we really need a new shaman..."] = "mec, on a vraiment besoin d'un nouveau Shaman...",
["Dude, what's this place?!"] = "Mec, quel est cet endroit?",
["Dude, where are we?"] = "Mec, où sommes nous ? ",
- -- ["Dude, wow! I just had the weirdest high!"] = "",
+-- ["Dude, wow! I just had the weirdest high!"] = "",
-- ["Duration"] = "", -- Continental_supplies
-- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "", -- Continental_supplies
["Each turn you get 1-3 random weapons"] = "A chaque tour, tu as 1 à 3 armes aléatoires",
["Each turn you get one random weapon"] = "A chaque tour, tu as une arme aléatoire",
- ["Eagle Eye"] = "",
+-- ["Eagle Eye"] = "",
-- ["Eagle Eye: [Blink to the impact ~ one shot]"] = "", -- Continental_supplies
- ["Ear Sniffer"] = "",
- ["Ear Sniffer"] = "Ear Sniffer",
- ["Elderbot"] = "",
+-- ["Ear Sniffer"] = "",
+-- ["Elderbot"] = "",
-- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape
["Eliminate all enemies"] = "Ãliminez tous les ennemis",
["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Ãliminez toutes les cibles avant d'être à cours de temps.|Vos munitions sont illimitées pour cette mission.", --Bazooka, Shotgun, SniperRifle
@@ -273,9 +197,7 @@ locale = {
["Eliminate the enemy hogs to win."] = "Eliminez les hérissons ennemis pour gagner",
["Eliminate the enemy specialists."] = "Eliminez les spécialists ennemis",
["- Eliminate Unit 3378 |- Feeble Resistance must survive"] = "Ãliminez l'unité 3378|- Résistance Futile doit survivre",
- ["Elmo"] = "",
- ["Elmo"] = "",
- ["Elmo"] = "",
+-- ["Elmo"] = "",
-- ["Energetic Engineer"] = "",
["Enjoy the swim..."] = "Profitez du bain ...",
-- ["[Enter]"] = "",
@@ -286,39 +208,17 @@ locale = {
["Everything looks OK..."] = "Tout à l'air d'être OK ...",
["Exactly, man! That was my dream."] = "Exactement, mec ! C'était mon rêve.",
["Eye Chewer"] = "Eye Chewer",
--- ["FAG"] = "", -- Mutant
- = "Fais sortir tes coéquipiers de leur prison naturelle et sauve la princesse ! |Percer des trous résoudrait tout. |ca serait une bonne idée de placer quelque poutres avant de commencer à percer. je dis ça, je dis rien. |Tous vos hérissons doivent être au dessus de la hauteur marquée ! | Leaks A Lot doit être très proche de la princesse ! ",
- ["Family Reunion"] = "",
+-- ["INSANITY"] = "", -- Mutant
+ ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"] = "Fais sortir tes coéquipiers de leur prison naturelle et sauve la princesse ! |Percer des trous résoudrait tout. |ca serait une bonne idée de placer quelque poutres avant de commencer à percer. je dis ça, je dis rien. |Tous vos hérissons doivent être au dessus de la hauteur marquée ! | Leaks A Lot doit être très proche de la princesse ! ",
["Family Reunion"] = "Réunion de famille ",
["Fastest lap: "] = "Meilleur tour : ",
["Feeble Resistance"] = "Résistance Futile",
- ["Fell From Grace"] = "",
- ["Fell From Grace"] = "",
- ["Fell From Grace"] = "",
- ["Fell From Grace"] = "",
- ["Fell From Grace"] = "",
- ["Fell From Grace"] = "Fell From Grace",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "",
- ["Fell From Heaven"] = "Fell From Heaven",
+-- ["Fell From Grace"] = "",
+-- ["Fell From Heaven"] = "",
["Fell From Heaven is the best! Fell From Heaven is the greatest!"] = "Fell From Heaven est la meilleure ! Fell From Heaven est la meilleure !",
- ["Femur Lover"] = "Femur Lover",
+-- ["Femur Lover"] = "",
-- ["Fierce Competition!"] = "", -- Space_Invasion
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "",
- ["Fiery Water"] = "Fiery Water",
+-- ["Fiery Water"] = "",
["Find your tribe!|Cross the lake!"] = "Trouves ta tribue ! |travers le lac !",
["Finish your training|Hint: Animations can be skipped with the [Precise] key."] = "Finis ton entraînement ! |Astuce : Les animations peuvent être passées en appuyant sur la touche [Precise]",
-- ["Fire"] = "",
@@ -326,15 +226,13 @@ locale = {
["First aid kits?!"] = "Des kits de premiers secours ?!",
-- ["FIRST BLOOD MUTATES"] = "", -- Mutant
["First Blood"] = "Premier sang",
- ["First Blood"] = "Premier sang",
- ["First Blood"] = "Premier sang",
["First Steps"] = "Premiers pas",
["Flag captured!"] = "Drapeau capturé !",
["Flag respawned!"] = "Drapeau réapparu",
["Flag returned!"] = "Drapeau récupéré",
["Flags, and their home base will be placed where each team ends their first turn."] = "Les drapeaux et leur base seront placés là où chaque équipe finit son premier tour",
-- ["Flamer"] = "",
- ["Flaming Worm"] = "",
+-- ["Flaming Worm"] = "",
-- ["Flare: [fire up some bombs depending on hogs depending on hogs in the circle"] = "", -- Continental_supplies
["Flesh for Brainz"] = "Flesh for Brainz",
-- ["For improved features/stability, play 0.9.18+"] = "", -- WxW
@@ -347,7 +245,7 @@ locale = {
["Game Started!"] = "Début du jeu ! ",
["Game? Was this a game to you?!"] = "Jeu ? Etais ce un jeu pour vous ?!",
-- ["GasBomb"] = "", -- Continental_supplies
- ["Gas Gargler"] = "",
+-- ["Gas Gargler"] = "",
["Get Dense Cloud out of the pit!"] = "Sortez Dense Cloud de la fosse",
["Get on over there and take him out!"] = "Viens par ici et débarrasse-toi de lui ! ",
["Get on the head of the mole"] = "Va sur la tête de la taupe",
@@ -355,17 +253,15 @@ locale = {
["Get that crate!"] = "Prends cette caisse",
["Get the crate on the other side of the island!|"] = "Prends la caisse de l'autre côté de l'île !",
-- ["Get to the target using your rope! |Controls: Left & Right to swing the rope - Up & Down to Contract and Expand!"] = "", -- Basic_Training_-_Rope
- ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.| Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"]
-- ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"] = "", -- A_Classic_Fairytale:family
-- ["GG!"] = "", -- User_Mission_-_Rope_Knock_Challenge
- ["Gimme Bones"] = "",
- ["Glark"] = "Glark",
+-- ["Gimme Bones"] = "",
+-- ["Glark"] = "",
-- ["Goal"] = "",
-- ["GO! GO! GO!"] = "",
["Good birdy......"] = "Gentil oiseau ...",
-- ["Good Dude"] = "", -- User_Mission_-_The_Great_Escape
["Good idea, they'll never find us there!"] = "Bonne idée, ils ne nous trouverons jamais là bas !",
- ["Good luck...or else!"] = "",
["Good luck...or else!"] = "Bonne chance.... ou pas !",
["Good luck out there!"] = "Bonne chance pour sortir d'ici",
-- ["Good so far!"] = "",
@@ -386,30 +282,27 @@ locale = {
-- ["Grenadiers"] = "", -- Basic_Training_-_Grenade
["Guys, do you think there's more of them?"] = "Les gars, vous pensez qu'ils y en plus encore ?",
-- ["Hahahaha!"] = "",
- ["Haha!"] = "Haha !",
- ["HAHA!"] = "HAHA !",
+-- ["Haha!"] = "",
+-- ["HAHA!"] = "",
["Haha, now THAT would be something!"] = "Haha, maintenant CA va être quelquechose !",
["Hannibal"] = "Hannibal",
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
- ["Hatless Jerry"] = "",
+-- [" HAS MUTATED"] = "", -- Mutant
+-- ["Hatless Jerry"] = "",
["Have no illusions, your tribe is dead, indifferent of your choice."] = "N'ai pas d'illusion, ta tribue est morte, quel que soit ton choix",
["Have we ever attacked you first?"] = "nous avons vous jamais attaqué en premier ? ",
["Health crates extend your time."] = "Les caisses de vie augmentent votre temps.",
-- ["Heavy"] = "",
- ["Heavy Cannfantry"] = "",
- ["Hedge-cogs"] = "",
- ["Hedge-cogs"] = "",
+-- ["Heavy Cannfantry"] = "",
+-- ["Hedge-cogs"] = "",
-- ["Hedgehog projectile: [fire your hog like a Sticky Bomb]"] = "", -- Continental_supplies
-- ["Hedgewars-Basketball"] = "",
-- ["Hedgewars-Knockball"] = "",
- ["Hedgibal Lecter"] = "",
+-- ["Hedgibal Lecter"] = "",
["Heh, it's not that bad."] = "Hé, c'est pas si mal.",
["Hello again, "] = "Re*bonjour,",
["Help me, Leaks!"] = "Aide moi, Leaks !",
- ["Help me, please!!!"] = "",
- ["Help me, please!"] = "",
["Help me, please!!!"] = "Aide moi, s'il te plait !!!",
["Help me, please!"] = "Aide moi, s'il te plaît !",
["He moves like an eagle in the sky."] = "Il se déplace comme un aigle dans le ciel",
@@ -420,9 +313,8 @@ locale = {
-- ["Hero Team"] = "", -- User_Mission_-_The_Great_Escape
["He's so brave..."] = "Il est si courageux",
["He won't be selling us out anymore!"] = "Il ne nous vendra plus !",
- ["Hey, guys!"] = "",
+-- ["Hey, guys!"] = "",
["Hey guys!"] = "Salut les gars !",
- ["Hey! This is cheating!"] = "",
["Hey! This is cheating!"] = "Hé ! C'est de la triche !",
-- ["HIGHLANDER"] = "", -- Highlander
["Hightime"] = "Meilleur temps",
@@ -437,19 +329,16 @@ locale = {
-- ["Hmmm, I'll have to find some way of moving him off this anti-portal surface..."] = "", -- portal
["Hmmm...it's a draw. How unfortunate!"] = "Hmmm... C'est un dessin. Pas de chance !",
["Hmmm...perhaps a little more time will help."] = "humm...Peut être qu'un peu plus de temps aiderait",
- ["Hogminator"] = "",
+-- ["Hogminator"] = "",
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
- ["Honest Lee"] = "",
+-- ["HOLY SHYTE!"] = "", -- Mutant
+-- ["Honest Lee"] = "",
["Hooray!"] = "Hourra ! ",
["Hostage Situation"] = "Situation d'otage",
- ["How can I ever repay you for saving my life?"] = "",
- ["How can I ever repay you for saving my life?"] = "",
["How can I ever repay you for saving my life?"] = "Comment pourrais-je jamais te remercier de m'avoir sauver la vie ?",
["How come in a village full of warriors, it's up to me to save it?"] = "Comment entrer dans un village plein de guerriers, c'est à moi de le sauver ?",
["How difficult would you like it to be?"] = "A quel point veut tu que ce soit difficile ?",
["HOW DO THEY KNOW WHERE WE ARE???"] = "COMMENT SAVENT-ILS OU NOUS SOMMES ?",
- ["However, if you fail to do so, she dies a most violent death, just like your friend! Muahahaha!"] = "",
["However, if you fail to do so, she dies a most violent death! Muahahaha!"] = "Cependant, si tu échoues, elle aura une mort encore plus violente ! Muahahaha!",
["However, my mates don't agree with me on letting you go..."] = "Mes amis ne sont pas d'accord pour vous laisser partit ...",
-- [" HP"] = "", -- Mutant
@@ -464,9 +353,7 @@ locale = {
["I'd better get going myself."] = "Je ferai mieux de rentrer.",
["I didn't until about a month ago."] = "Je ne savais pas jusqu'Ã il y a un mois",
-- ["I don't know how you did that.. But good work! |The next one should be easy as cake for you!"] = "", -- Basic_Training_-_Rope
- ["I feel something...a place! They will arrive near the circles!"] = "",
["I feel something...a place! They will arrive near the circles!"] = "Je sens quelque chose... une localisation ! Ils vont arriver près des cercles !",
- ["If only I had a way..."] = "",
["If only I had a way..."] = "Si seulement j'avais un moyen...",
["If only I were given a chance to explain my being here..."] = "Si seulement vous me laissiez une chance d'expliquer ce que je fais ici...",
["I forgot that she's the daughter of the chief, too..."] = "J'avais oublié qu'elle était aussi la fille du chef...",
@@ -477,7 +364,6 @@ locale = {
["If you get stuck, use your Desert Eagle or restart the mission!|"] = "Si vous êtes coincés, utiliser le Desert Eable, ou recommencez la missions",
["If you know what I mean..."] = "Si tu vois ce que je veux dire...",
["If you say so..."] = "Si tu le dis...",
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)!|"] = "Si tu soihaire recommencer la coursse, maintien [precise] quand ton tour se termine (avec [passe ton tour ] par exemple",
["I guess you'll have to kill them."] = "Je suppose que vous devrez les tuer",
["I have come to make you an offering..."] = "Je suis venu te faire une offre...",
@@ -498,7 +384,6 @@ locale = {
["I'm getting old for this!"] = "Je deviens vieux pour ça !",
["I'm getting thirsty..."] = "je deviens trentenaire",
["I'm here to help you rescue her."] = "Je suis ici pour t'aider à la secourir.",
- ["I'm not sure about that!"] = "",
["I'm not sure about that!"] = "Je n'en suis pas si sûr !",
["Impressive...you are still dry as the corpse of a hawk after a week in the desert..."] = "Impressionnant...tu es aussi sec que le cadavre d'un faucon après une semaine dans le désert...",
["I'm so scared!"] = "Je suis si effrayé !",
@@ -520,7 +405,6 @@ locale = {
["I see..."] = "Je vois...",
["I see you have already taken the leap of faith."] = "Je vois que tu as déjà fait le saut de la foi.",
["I see you would like his punishment to be more...personal..."] = "Je vois que tu voudrais que son châtiment soit plus...personnel...",
- ["I sense another wave of cannibals heading my way!"] = "",
["I sense another wave of cannibals heading our way!"] = "Je sens une autre vague de cannibale qui arrivent !",
["I shouldn't have drunk that last pint."] = "Je n'aurais pas du boire cette derniere pinte",
["Is this place in my head?"] = "est ce que cet endroit est dans ma tete ?",
@@ -544,21 +428,16 @@ locale = {
["It wants our brains!"] = "Ca veut nos cerveaux",
["It was not a dream, unwise one!"] = "Ce n'était pas un rêve, imprudent !",
["I've seen this before. They just appear out of thin air."] = "J'ai déjà vu ça. Ils apparaissent dans les airs",
- ["I want to play a game..."] = "",
["I want to play a game..."] = "Je veux faire un jeu...",
- ["I want to see how it handles this!"] = "",
["I want to see how it handles this!"] = "Je veux voir comment ils vont faire avec ça !",
["I wish to help you, "] = "Je souhaite t'aider,",
- ["I wonder where Dense Cloud is..."] = "Je me demande où est Dense Cloud... ",
["I wonder where Dense Cloud is..."] = "Je me demande où est Dense Cloud...",
["I wonder why I'm so angry all the time..."] = "Je me demande pourquoi je suis toujours tellement en colère",
["I won't let you kill her!"] = "Je ne te laisserai pas la tuer !",
- ["Jack"] = "",
- ["Jack"] = "",
- ["Jack"] = "",
- ["Jeremiah"] = "",
- ["John"] = "John",
- ["Judas"] = "Judas",
+-- ["Jack"] = "",
+-- ["Jeremiah"] = "",
+-- ["John"] = "",
+-- ["Judas"] = "",
["Jumping is disabled"] = "Le saut est désactivé",
["Just kidding, none of you have died!"] = "Je rigole, aucun d'entre vous n'est mort !",
["Just on a walk."] = "Je faisais juste une promenade",
@@ -567,52 +446,30 @@ locale = {
-- ["Keep it up!"] = "",
-- ["Kerguelen"] = "", -- Continental_supplies
["Killing spree!"] = "Massacre",
- ["KILL IT!"] = "Tue le",
["KILL IT!"] = "TUE LE !",
["KILLS"] = "Meurtres",
- ["Kill the aliens!"] = "",
+-- ["Kill the aliens!"] = "",
["Kill the cannibal!"] = "Tue le cannibale !",
- ["Kill the cannibal!"] = "Tue le cannibale",
["Kill the traitor...or spare his life!|Kill him or press [Precise]!"] = "Tue le traître... ou épargnes sa vie ! |Tue le ou appuies sur [Precise] !",
["Last Target!"] = "Dernière cible !",
- ["Leader"] = "",
- ["Leaderbot"] = "",
- ["Leaderbot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot"] = "",
- ["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "",
- ["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "",
+-- ["Leader"] = "",
+-- ["Leaderbot"] = "",
+-- ["Leaks A Lot"] = "",
["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "Leaks A Lot, déprimé d'avoir tué l'élue de son coeur, échoua à sauver le village...",
["Leaks A Lot gave his life for his tribe! He should have survived!"] = "Leaks A Lot à donné sa vie pour sa tribus ! Il aurait du survivre !",
- ["Leaks A Lot"] = "Leaks A Lot",
["Leaks A Lot must survive!"] = "Leaks A Lot doit survivre !",
- ["Led Heart"] = "",
- ["Lee"] = "",
- ["Lee"] = "",
- ["Lee"] = "",
+-- ["Led Heart"] = "",
+-- ["Lee"] = "",
-- ["[Left Shift]"] = "",-- touche majuscule gauche
-- ["Let a Continent provide your weapons!"] = "", -- Continental_supplies
- ["Let me test your skills a little, will you?"] = "",
["Let me test your skills a little, will you?"] = "Laisse moi te tester un peu, veux tu ?",
- ["Let's go home!"] = "",
- ["Let's go home!"] = "",
["Let's go home!"] = "Rentrons à la maison !",
["Let's head back to the village!"] = "Retournons au village !",
- ["Let's see what your comrade does now!"] = "",
["Let's see what your comrade does now!"] = "Voyons ce que fait ton camarade maintenant !",
- ["Let's show those cannibals what we're made of!"] = "",
["Let's show those cannibals what we're made of!"] = "Montrons à ces cannibales de quel bois on se chauffe !",
["Let them have a taste of my fury!"] = "Ils vont gouter de ma fureur !",
["Let us help, too!"] = "Allons aider nous aussi !",
- ["Light Cannfantry"] = "",
+-- ["Light Cannfantry"] = "",
["Listen up, maggot!!"] = "Ãcoutez, asticots",
["Little did they know that this hunt will mark them forever..."] = "Savait-il que cette chasse allait les marquer à jamais...",
-- ["Lively Lifeguard"] = "",
@@ -626,8 +483,8 @@ locale = {
["May the spirits aid you in all your quests!"] = "Puisse les esprits t'aider dans tes quêtes !",
-- ["Medicine: [Fire some exploding medicine that will heal all hogs effected by the explosion]"] = "", -- Continental_supplies
-- ["MEGA KILL"] = "", -- Mutant
- ["Meiwes"] = "",
- ["Mindy"] = "",
+-- ["Meiwes"] = "",
+-- ["Mindy"] = "",
-- ["Mine Deployer"] = "",
["Mine Eater!"] = "Mangeur de Mines",
-- ["|- Mines Time:"] = "", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
@@ -639,47 +496,14 @@ locale = {
["More Natives"] = "More Natives",
["Movement: [Up], [Down], [Left], [Right]"] = "Mouvement: [haut], [bas], [gauche], [droite]",
-- ["Multi-shot!"] = "",
- ["Muriel"] = "",
- ["Muriel"] = "",
- ["Muriel"] = "",
- ["Muriel"] = "",
+-- ["Muriel"] = "",
["Muscle Dissolver"] = "Muscle Dissolver",
-- ["-------"] = "", -- Mutant
-- ["Nade Boy"] = "", -- Basic_Training_-_Grenade
- ["Name"] = "",
+-- ["Name"] = "",
["Nameless Heroes"] = "Heros sans noms",
- ["Nancy Screw"] = "",
- ["Nancy Screw"] = "",
+-- ["Nancy Screw"] = "",
-- ["Napalm rocket: [Fire a bomb with napalm!]"] = "", -- Continental_supplies
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "",
- ["Natives"] = "Natives",
["Natives"] = "Natives",
["New Barrels Per Turn"] = "Nouveaux barrils par tour",
-- ["NEW CLAN RECORD: "] = "",
@@ -688,14 +512,13 @@ locale = {
["NEW RACE RECORD: "] = "NOUVEAU RECORD DE COURSE",
["Newton's Hammock"] = "Le hammac de Newton",
["Nicely done, meatbags!"] = "Bien joués, sac à viande !",
- ["Nice work!"] = "",
- ["Nice work, "] = "Beau boulot",
+ ["Nice work, "] = "Beau boulot, ",
["Nice work!"] = "Beau travail !",
- ["Nilarian"] = "",
+-- ["Nilarian"] = "",
["No, I came back to help you out..."] = "Non je suis revenu pour t'aider...",
["No...I wonder where they disappeared?!"] = "Non...Je me demande où ils ont disparu ?!",
- ["NomNom"] = "",
- ["Nom-Nom"] = "Nom-Nom",
+-- ["NomNom"] = "",
+-- ["Nom-Nom"] = "",
["Nope. It was one fast mole, that's for sure."] = "Non. C'était une taupe rapide, ça c'est certain.",
["No! Please, help me!"] = "Non ! S'il te plaît, aide moi !",
-- ["NORMAL"] = "", -- Continental_supplies
@@ -711,10 +534,9 @@ locale = {
["No. Where did he come from?"] = "Non. D'où est-il venu ?",
["Now how do I get on the other side?!"] = "Maintenant comme je me rends de l'autre coté ?",
["No. You and the rest of the tribe are safer there!"] = "Non, Toi et le reste de la tribue etes plus en sécurité ici ! ",
- ["Obliterate them!|Hint: You might want to take cover..."] = "",
+-- ["Obliterate them!|Hint: You might want to take cover..."] = "",
["Obstacle course"] = "Course d'obstacle",
["Of course I have to save her. What did I expect?!"] = "Bien sur je dois la sauver. Qu'est ce que j'imaginais ?",
- ["OH, COME ON!"] = "",
["OH, COME ON!"] = "OH, ALLEZ !",
["Oh, my!"] = "Oh mon dieu !",
["Oh, my! This is even more entertaining than I've expected!"] = "Oh mon dieu ! c'est meme plus amusant que ce que je pensais !",
@@ -722,10 +544,9 @@ locale = {
-- ["Oh no, not "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
["Oh no! Time's up! Just try again."] = "Eh non ! Temps écoulé ! Essayez encore ! ", --Bazooka, Shotgun, SniperRifle
-- ["Oh no! You failed! Just try again."] = "", -- Basic_Training_-_Cluster_Bomb
- ["Oh, silly me! I forgot that I'm the shaman."] = "",
["Oh, silly me! I forgot that I'm the shaman."] = "Oh suis je bête ! j'ai oublié que j'étais le shaman.",
- ["Olive"] = "",
- ["Omnivore"] = "Omnivore",
+-- ["Olive"] = "",
+-- ["Omnivore"] = "",
["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "Il était une fois, sur une île possédant de grandes ressources naturelles, vivait deux tribus en violent conflit...",
-- ["ONE HOG PER TEAM! KILLING EXCESS HEDGES"] = "", -- Mutant
["One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."] = "L'une des deux tribus était pacifique, passant son temps à chasser et à s'entraîner, appréciants les petits plaisirs de la vie",
@@ -733,7 +554,7 @@ locale = {
["Open that crate and we will continue!"] = "Ouvre cette caisse et nous pourrons continuer",
-- ["Operation Diver"] = "",
["Opposing Team: "] = "Ãquipe opposée",
- ["Orlando Boom!"] = "",
+-- ["Orlando Boom!"] = "",
-- ["Ouch!"] = "", -- User_Mission_-_Rope_Knock_Challenge
["Our tribe, our beautiful island!"] = "Notre tibue, notre belle ile !",
-- ["Parachute"] = "", -- Continental_supplies
@@ -741,12 +562,10 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
["Perfect! Now try to get the next crate without hurting yourself!"] = "Parfait, maintenant essaye d'avoir la prochaine caisse sans te blesser !",
["Per-Hog Ammo"] = "Munitions par hérissons",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
["Pfew! That was close!"] = "Ouf! C'est pas passé loin !",
- ["Pfew! That was close!"] = "Ouf ! C'étais pas loin !",
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Place plus de points de passage avec [enter]",
["Place more waypoints using the 'Air Attack' weapon."] = "Place plus de points de passage avec l'arme : attaque aérienne.",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -768,42 +587,19 @@ locale = {
["Protect yourselves!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "Protèges toi ! |Astuce Grenade : Règle le compte à rebour avec [1-5], vises avec [haut]/[bas] et maintient [Espace] pour la puissance",
-- ["Race complexity limit reached."] = "",
-- ["RACER"] = "",
- ["Rachel"] = "",
- ["Rachel"] = "",
- ["Rachel"] = "",
+-- ["Rachel"] = "",
-- ["Radar Ping"] = "", -- Space_Invasion
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "",
- ["Raging Buffalo"] = "Raging Buffalo",
- ["Ramon"] = "",
- ["Ramon"] = "",
- ["Ramon"] = "",
- ["Ramon"] = "Ramon",
- ["Ramon"] = "Ramon",
+-- ["Raging Buffalo"] = "",
+-- ["Ramon"] = "",
-- ["RC PLANE TRAINING"] = "", -- User_Mission_-_RCPlane_Challenge
["Really?! You thought you could harm me with your little toys?"] = "Vraiment ? tu pensais pouvoir me blesser avec tes petits jouets ?",
- ["Regurgitator"] = "",
- ["Reinforcements"] = "",
- ["Reinforcements"] = "",
+-- ["Regurgitator"] = "",
+-- ["Reinforcements"] = "",
-- ["Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!"] = "", -- Basic_Training_-_Rope
["Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"] = "Souviens toi, animal pathétique : quand le jour viendra, tu regrettera ton aveugle loyauté !",
[" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = "Ramenez le drapeau ennemi à votre base pour marquer | -La première équipe à 3 captures gagne | - Vous marquez uniquement si votre drapeau est dans votre base | - Les hérissons vont lâcher le drapeau s'ils sont tués ou noyés | - Les drapeaux lâchés peuvent être ramenés ou recapturés | - Les hérissons réapparaissent quand ils sont tués",
- ["Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"] = "",
["Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"] = "Retourne vers Leaks A Lot ! Si tu es bloqué, appuie sur [Precise] pour réessayer !",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "",
- ["Righteous Beard"] = "Righteous Beard",
+-- ["Righteous Beard"] = "Righteous Beard",
-- ["ROPE-KNOCKING"] = "", -- User_Mission_-_Rope_Knock_Challenge
-- ["Rope Training"] = "", -- Basic_Training_-_Rope
["Rot Molester"] = "Rot Molester",
@@ -812,19 +608,18 @@ locale = {
-- ["Rounds Complete: "] = "",
-- ["Rounds Complete"] = "",
["RULES OF THE GAME [Press ESC to view]"] = "RÃGLES DU JEU | [Appuyez Ãchap pour voir]",
- ["Rusty Joe"] = "",
+-- ["Rusty Joe"] = "",
-- ["s|"] = "",
-- ["Sabotage: [Sabotage all hogs in the circle and deal ~10 dmg]"] = "", -- Continental_supplies
- ["Salivaslurper"] = "",
+-- ["Salivaslurper"] = "",
["Salvation"] = "Le salut",
["Salvation was one step closer now..."] = "Le salut était tout proche...",
-- ["Save as many hapless hogs as possible!"] = "",
- ["Save Fell From Heaven!"] = "",
["Save Fell From Heaven!"] = "Sauve Fell From Heaven ! ",
["Save Leaks A Lot!|Hint: The Switch utility might be of help to you."] = "Sauve Leaks A Lot ! |L'outil changer de hérisson pourrait aider",
["Save the princess! All your hogs must survive!|Hint: Kill the cyborgs first! Use the ammo very carefully!|Hint: You might want to spare a girder for cover!"] = "Sauve la princesse, tous vos hérissons doivent survivre ! |tue les cyborgs en premier ! utilise les munitions très prudemment ! |Tu voudras peut etre garder une poutre pour te couvrir !",
["Save the princess by collecting the crate in under 12 turns!"] = "Sauve la princesse en collectant la caisse en moins de 3 tours !",
- ["Scalp Muncher"] = "",
+-- ["Scalp Muncher"] = "",
-- ["SCORE"] = "",
-- ["Score"] = "", -- Mutant
-- ["Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"] = "", -- Continental_supplies
@@ -833,7 +628,7 @@ locale = {
-- ["Seems like every time you take a \"walk\", the enemy find us!"] = "", -- A_Classic_Fairytale:backstab
["See that crate farther on the right?"] = "Tu vois cette caisse plus loin sur la droite ? ",
["See ya!"] = "Bye bye",
- ["Segmentation Paul"] = "",
+-- ["Segmentation Paul"] = "",
-- ["Select continent!"] = "", -- Continental_supplies
["Select difficulty: [Left] - easier or [Right] - harder"] = "Choisis la difficulté : [Gauche] : plus facile, ou [Droite] : plus dur",
-- ["selected!"] = "",
@@ -844,7 +639,7 @@ locale = {
["Shield Depleted"] = "Bouclier épuisé",
["Shield is fully recharged!"] = "bouclier chargé à fond!",
["Shield Master!"] = "Bouclier master",
- ["Shield Miser!"] = "",
+-- ["Shield Miser!"] = "",
["Shield OFF:"] = "bouclier OFF",
["Shield ON:"] = "Bouclier ON",
-- ["Shield Seeker!"] = "",
@@ -854,16 +649,16 @@ locale = {
["shots remaining."] = "tirs restants",
-- ["Silly"] = "",
-- ["Sinky"] = "",
- ["Sirius Lee"] = "",
+-- ["Sirius Lee"] = "",
["%s is out and Team %d|scored a penalty!| |Score:"] = "%s est dehors et l'équipe %d| reçoit une pénalité ! | |Score : ", -- Basketball, Knockball
["%s is out and Team %d|scored a point!| |Score:"] = "%s est dehors et l'équipe %d| reçoit un point ! | |Score : ", -- Basketball, Knockball
["Slippery"] = "Glissant",
- ["Smith 0.97"] = "",
- ["Smith 0.98"] = "",
- ["Smith 0.99a"] = "",
- ["Smith 0.99b"] = "",
- ["Smith 0.99f"] = "",
- ["Smith 1.0"] = "",
+-- ["Smith 0.97"] = "",
+-- ["Smith 0.98"] = "",
+-- ["Smith 0.99a"] = "",
+-- ["Smith 0.99b"] = "",
+-- ["Smith 0.99f"] = "",
+-- ["Smith 1.0"] = "",
-- ["Sniper Rifle"] = "", -- Continental_supplies
-- ["Sniper!"] = "", -- Space_Invasion
["Sniper Training"] = "Entrainement au fusil de sniper",
@@ -873,22 +668,16 @@ locale = {
["So? What will it be?"] = "Alors ? Qu'est ce que ce sera ?",
-- ["Spawn the crate, and attack!"] = "", -- WxW
-- ["Special Weapons:"] = "", -- Continental_supplies
- ["Spiky Cheese"] = "",
- ["Spiky Cheese"] = "",
- ["Spiky Cheese"] = "",
- ["Spiky Cheese"] = "Spiky cheese",
- ["Spiky Cheese"] = "Spiky Cheese",
- ["Spleenlover"] = "",
+-- ["Spiky Cheese"] = "",
+-- ["Spleenlover"] = "",
-- ["Sponge"] = "éponde",--??
["Spooky Tree"] = "Arbre fantomatique",
-- ["STATUS UPDATE"] = "", -- GaudyRacer, Space_Invasion
- ["Steel Eye"] = "",
+-- ["Steel Eye"] = "",
["Step By Step"] = "Pas à Pas",
- ["Steve"] = "",
- ["Steve"] = "",
- ["Steve"] = "",
+-- ["Steve"] = "",
-- ["Sticky Mine"] = "", -- Continental_supplies
- ["Stronglings"] = "Stronglings",
+-- ["Stronglings"] = "",
-- ["Structure"] = "", -- Continental_supplies
-- ["Super Weapons"] = "", -- WxW
-- ["Surf Before Crate"] = "", -- WxW
@@ -897,7 +686,7 @@ locale = {
["Survive!|Hint: Cinematics can be skipped with the [Precise] key."] = "Survis ! Les cinématique peuvent être passées avec la touche [Precise]. ",
["Swing, Leaks A Lot, on the wings of the wind!"] = "Balances toi Leaks a Lot, sur les ailes du vent",
-- ["Switched to "] = "",
- ["Syntax Errol"] = "",
+-- ["Syntax Errol"] = "",
["Talk about mixed signals..."] = "Parlons des signaux mélangés",
["Team %d: "] = "Ãquipe %d : ",
-- ["Team Scores"] = "", -- Control, Space_Invasion
@@ -905,7 +694,6 @@ locale = {
["Thanks!"] = "Merci !",
["Thank you, my hero!"] = "Merci, mon héro !",
["Thank you, oh, thank you, Leaks A Lot!"] = "Merci, oh, Merci, Leaks A Lot !",
- ["Thank you, oh, thank you, my heroes!"] = "",
["Thank you, oh, thank you, my heroes!"] = "Merci, oh, merci mes héros !",
["That is, indeed, very weird..."] = "c'est ça, en effet, très étrange...",
["That makes it almost invaluable!"] = "Ca la rends presque inestimable !",
@@ -926,7 +714,6 @@ locale = {
["The enemy can't move but it might be a good idea to stay out of sight!|"] = "les ennemis ne peuvent pas bouger mais ce serait une bonne idée de rester hors de vue",
["The enemy is hiding out on yonder ducky!"] = "L'ennemi se cache là -bas sur le canard !",
["The Enemy Of My Enemy"] = "Les ennemis de mes ennemis",
- ["The First Blood"] = "Le premier sang",
["The First Blood"] = "Le premier sang",
["The First Encounter"] = "La première rencontre",
["The flag will respawn next round."] = "Le drapeau va réapparaitre au prochain tour",
@@ -936,14 +723,6 @@ locale = {
["The guardian"] = "Le gardien",
["The Individualist"] = "L'individualiste",
["Their buildings were very primitive back then, even for an uncivilised island."] = "Leurs batiments étaient très primitif à l'époque, même pour une ile non civilisée.",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
- ["The Journey Back"] = "",
["The Journey Back"] = "Le voyage de retour",
["The Leap of Faith"] = "Le saut de la foi",
["The Moonwalk"] = "Le Moonwalk",
@@ -953,52 +732,37 @@ locale = {
["The other one were all cannibals, spending their time eating the organs of fellow hedgehogs..."] = "L'autre était une tribus de cannibales, ils passaient leur temps à manger les organes d'autres hérissons...",
["There must be a spy among us!"] = "Il doit y avoir un espion parmi nous",
["There's more of them? When did they become so hungry?"] = "Il y en encore ? Quand sont-ils devenu si affamés ?",
- ["There's more of them? When did they become so hungry?"] = "Il y en encore ? Quand sont-ils devenu si affamés ?",
["There's nothing more satisfying for me than seeing you share your beauty with the world every morning, my princess!"] = "Il n'y a rien de plus satisfaisant pour moi que de te voir partager ta beauté avec le monde chaque matin, ma princesse !",
["There's nothing more satisfying to us than seeing you share your beauty..."] = "Il n'y a rien de plus satisfaisant pour moi que de te voir partager ta beauté...",
- ["There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"] = "",
+-- ["There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"] = "",
["The Rising"] = "L'ascension",
["The Savior"] = "Le sauveur",
["These primitive people are so funny!"] = "Ces primitis sont si amusants !",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
- ["The Shadow Falls"] = "",
["The Shadow Falls"] = "La chute des ombres",
["The Showdown"] = "La confrontation",
- ["The Slaughter"] = "",
["The Slaughter"] = "Le massacre",
-- ["THE SPECIALISTS"] = "",
["The spirits of the ancerstors are surely pleased, Leaks A Lot."] = "Les esprits des ancêtres sont sûrement ravis, Leaks A Lot.",
["The Torment"] = "Le supplice",
["The Tunnel Maker"] = "Le creuseur de tunnel",
- ["The Ultimate Weapon"] = "L'arme ultime",
["The Ultimate Weapon"] = "L'arme ultime",
["The Union"] = "L'union",
- ["The village, unprepared, was destroyed by the cyborgs..."] = "",
["The village, unprepared, was destroyed by the cyborgs..."] = "Le village, pas préparé, fut détruit par les cyborgs...",
- ["The walk of Fame"] = "",
["The walk of Fame"] = "La marche d'honneur",
["The wasted youth"] = "Une jeunesse ruinée",
["The weapon in that last crate was bestowed upon us by the ancients!"] = "L'arme dans cette dernière caisse nous a été conféré par les ancients",
- ["The what?!"] = "",
+-- ["The what?!"] = "",
["The wind whispers that you are ready to become familiar with tools, now..."] = "Le vent me murmure que tu es maintenant prêt à te familiariser avec les outils ...",
["They are all waiting back in the village, haha."] = "Ils attendent tous au village, haha.",
-- ["They Call Me Bullseye!"] = "", -- Space_Invasion
- ["They have weapons we've never seen before!"] = "",
["They have weapons we've never seen before!"] = "Ils ont des armes que nous n'avons jamais vu avant !",
- ["They keep appearing like this. It's weird!"] = "",
+-- ["They keep appearing like this. It's weird!"] = "",
-- ["They killed "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
["They must be trying to weaken us!"] = "Ils doivent essayer de nous affaiblir !",
["They never learn"] = "Ils n'apprennent jamais",
["They told us to wear these clothes. They said that this is the newest trend."] = "Ils nous ont dit de porter ces vêtements. Ils nous ont dit que c'était la nouvelle mode.",
["They've been manipulating us all this time!"] = "Ils nous ont tous manipulé cette fois !",
- ["Thighlicker"] = "",
+-- ["Thighlicker"] = "",
["This is it! It's time to make Fell From Heaven fall for me..."] = "Ca y est ! il est temps d'impressionner Fell From Heaven ",
["This island is the only place left on Earth with grass on it!"] = "Cette ile est le dernier endroit sur terre avec de l'herbe dessus !",
["This is typical!"] = "C'est typique !",
@@ -1024,33 +788,23 @@ locale = {
["TRACK FAILED!"] = "COURSE RATEE",
-- ["training"] = "", -- portal
["Traitors"] = "Traitors",
- ["Tribe"] = "",
- ["Tribe"] = "",
- ["Tribe"] = "",
- ["Tribe"] = "",
- ["Tribe"] = "",
+-- ["Tribe"] = "",
-- ["TrophyRace"] = "",
["Try to protect the chief! You won't lose if he dies, but it is advised that he survives."] = "Essaie de protéger le chef ! Tu ne perdras pas s'il meurt, mais il serait avisé qu'il survive",
-- ["T_T"] = "",
-- ["Tumbling Time Extended!"] = "",
- ["Turns until Sudden Death: "] = "",
+-- ["Turns until Sudden Death: "] = "",
[" turns until Sudden Death! Better hurry!"] = "tours avant la mort subite ! tu ferais mieux de te dépecher !",
-- ["Turn Time"] = "",
- ["Two little hogs cooperating, getting past obstacles..."] = "",
["Two little hogs cooperating, getting past obstacles..."] = "Deux petits hérissons coopérant à passer les obstacles...",
["Uhm...I met one of them and took his weapons."] = "hum... J'ai rencontré l'un d'entre eux et j'ai pris ses armes.",
["Uhmm...ok no."] = "Humm... ok non.",
-- ["ULTRA KILL"] = "", -- Mutant
["Under Construction"] = "En construction",
- ["Unexpected Igor"] = "",
+-- ["Unexpected Igor"] = "",
-- ["Unit"] = "",
- ["Unit 0x0007"] = "",
- ["Unit 334a$7%;.*"] = "",
- ["Unit 334a$7%;.*"] = "",
- ["Unit 334a$7%;.*"] = "",
- ["Unit 334a$7%;.*"] = "",
- ["Unit 334a$7%;.*"] = "",
- ["Unit 334a$7%;.*"] = "",
+-- ["Unit 0x0007"] = "",
+-- ["Unit 334a$7%;.*"] = "",
["Unit 3378"] = "Unité 3378",
-- ["Unit 835"] = "",
["United We Stand"] = "Nous restons unis",
@@ -1062,14 +816,13 @@ locale = {
["Use it wisely!"] = "a utiliser intelligemment",
["Use it with precaution!"] = "Utilise la avec prudence",
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
["Use the parachute ([Space] while in air) to get the next crate"] = "utilisez le parachute ([Espace] en vol) pour atteindre la prochaine caisse ",
["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "Utilise le fusil à portail pour atteindre la prochaine caisse, puis utilise le nouveau fusil pour atteindre la destination finale",
["Use the rope to get on the head of the mole, young one!"] = "Utilise la corde pour atteindre la tête de la taupe, l'apprenti !",
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
["Use your rope to get from start to finish as fast as you can!"] = "Utilisez votre Corde Ninja pour aller du début à la fin aussi vite que vous pouvez !",
["Vedgies"] = "Vedgies",
- ["Vegan Jack"] = "",
+-- ["Vegan Jack"] = "",
-- ["Victory!"] = "", -- Basic_Training_-_Rope
["Victory for the "] = "Victoire pour ", -- CTF_Blizzard, Capture_the_Flag
["Violence is not the answer to your problems!"] = "La violence n'est pas la réponse à tes problèmes !",
@@ -1082,7 +835,6 @@ locale = {
["Waypoint placed."] = "Point de passage placé.",
["Way-Points Remaining"] = "Points de passage restants",
["Weaklings"] = "Weaklings",
- ["Weaklings"] = "Weaklings",
["We all know what happens when you get frightened..."] = "Nous savons tous ce qui arrive quand tu es effrayé",
["Weapons Reset"] = "Armes réinitialisées",
-- ["Weapons reset."] = "", -- Highlander
@@ -1094,13 +846,11 @@ locale = {
["We have nowhere else to live!"] = "Nous n'avons nul part autre ou vivre !",
["We have to protect the village!"] = "Nous devons protéger le village !",
["We have to unite and defeat those cylergs!"] = "nous devons nous unir et battre ces cyborgs !",
- ["Welcome, Leaks A Lot!"] = "",
["Welcome, Leaks A Lot!"] = "Bienvenue, Leaks A Lot !",
-- ["Well done."] = "",
["We'll give you a problem then!"] = "Nous allons vous donner des problèmes alors !",
["We'll spare your life for now!"] = "Nous t'épargnons la vie pour le moment !",
["Well, that was a waste of time."] = "Bien, c'était une perte de temps.",
- ["Well, well! Isn't that the cutest thing you've ever seen?"] = "",
["Well, well! Isn't that the cutest thing you've ever seen?"] = "Bien, Bien ! N'est pas la chose la plus mignonne que tu aies jamais vu ? ",
["Well, yes. This was a cyborg television show."] = "Bien, oui. c'est une émission de télévision cyborg.",
["We made sure noone followed us!"] = "Nous nous sommes assurés que personne ne nous as suivis !",
@@ -1109,26 +859,20 @@ locale = {
["We need to warn the village."] = "Nous devons avertir le village",
["We should head back to the village now."] = "Nous devrions retourner au village maintenant.",
["We were trying to save her and we got lost."] = "On essayait de la sauver et on s'est perdu.",
- ["We won't let you hurt her!"] = "",
["We won't let you hurt her!"] = "Nous ne te laisserons pas la blesser !",
["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "Quoi ?! Un cannibale ? Ici ? Il n'y a pas de temps à perdre ! Viens, tu es préparé.",
["What a douche!"] = "Quelle douche !",
- ["What am I gonna...eat, yo?"] = "",
["What are you doing at a distance so great, young one?"] = "Qu'est ce que tu fais si loin, l'apprenti ? ",
- ["What are you doing? Let her go!"] = "",
["What are you doing? Let her go!"] = "Que fais tu ? Laisses la partir ! ",
["What a ride!"] = "Quel voyage !",
["What a strange cave!"] = "quelle etrange caverne",
- ["What a strange feeling!"] = "",
["What a strange feeling!"] = "Quel étrange sentiment !",
["What do my faulty eyes observe? A spy!"] = "Que voient mes vieux yeux ? Un espion !",
--["Whatever floats your boat..."] = "Comme tu veux...",
-- [" What !! For all of this struggle i just win some ... TIME o0"] = "", -- portal
-- ["What has "] = "", -- A_Classic_Fairytale:backstab
["What? Here? How did they find us?!"] = "Quoi ? ici ? Comment nous ont ils trouvés ?",
- ["What is this place?"] = "quel est cet endroit ,",
["What is this place?"] = "Quel est cet endroit ? ",
- ["What shall we do with the traitor?"] = "",
["What shall we do with the traitor?"] = "Que devons nous faire avec le traître ? ",
["WHAT?! You're the ones attacking us!"] = "Quoi ?! C'est vous qui nous attaquez !",
["When I find it..."] = "Quand je vais le trouver...",
@@ -1146,7 +890,6 @@ locale = {
-- ["? Why?"] = "", -- A_Classic_Fairytale:backstab
-- ["Why "] = "", -- A_Classic_Fairytale:backstab
-- ["! Why?!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
- ["Why are you doing this?"] = "",
["Why are you doing this?"] = "Pourquoi fais tu ça ? ",
["Why are you helping us, uhm...?"] = "Pourquoi nous aidez vous, hum ...?",
["Why can't he just let her go?!"] = "Pourquoi ne peut-il pas juste la laisser partit ?!",
@@ -1161,25 +904,17 @@ locale = {
-- ["Will this ever end?"] = "",
-- ["WINNER IS "] = "", -- Mutant
["WINNING TIME: "] = "Temps gagnant : ",
- ["Wise Oak"] = "",
- ["Wise Oak"] = "",
- ["Wise Oak"] = "",
- ["Wise Oak"] = "",
- ["Wise Oak"] = "",
["Wise Oak"] = "Wise Oak",
["With Dense Cloud on the land of shadows, I'm the village's only hope..."] = "Avec Dense Cloud dans le territoire des ombres, je suis le seul espoir du village...",
["With the rest of the tribe gone, it was up to "] = "Avec le reste de la tribue partie, il était temps de ",
["Worry not, for it is a peaceful animal! There is no reason to be afraid..."] = "Pas d'inquiétude, c'est un animal pacifique ! il n'y a pas de raison d'avoir peur...",
["Wow, what a dream!"] = "Wow, quel rêve !",
["Y3K1337"] = "Y3K1337",
- ["Y3K1337"] = "Y3K1337",
- ["Yay, we won!"] = "",
["Yay, we won!"] = "Ouais, on a gagné !",
- ["Y Chwiliad"] = "",
+-- ["Y Chwiliad"] = "",
["Yeah...I think it's a 'he', lol."] = "Ouais... Je crois que c'est un 'homme', lol.",
["Yeah, sure! I died. Hillarious!"] = "Ouais, sûr ! il est mort. Hillarant !",
["Yeah, take that!"] = "Ouais, prends ça !",
- ["Yeah? Watcha gonna do? Cry?"] = "",
["Yeah? Watcha gonna do? Cry?"] = "Ouais? Qu'est ce que tu vas faire ? Pleurer ? ",
["Yes!"] = "Oui !",
["Yes, yeees! You are now ready to enter the real world!"] = "Oui, Ouiii ! Maintenant tu es prêt à entrer dans le monde réel !",
@@ -1221,7 +956,6 @@ locale = {
["You might want to find a way to instantly kill arriving cannibals!"] = "tu aimerais surement trouver un moyen de tuer instantanément les cannibales qui arrivent !",
["Young one, you are telling us that they can instantly change location without a shaman?"] = "L'apprenti, tu es en train de nous dire qu'ils peuvent changer de place sans shaman ?",
["You probably know what to do next..."] = "Tu sais probablement ce que tu dois faire ensuite....",
- ["Your deaths will be avenged, cannibals!"] = "",
["Your deaths will be avenged, cannibals!"] = "Vos morts seront vengées, cannibales !",
["Your death will not be in vain, Dense Cloud!"] = "Tu ne seras pas mort en vain, Dense Cloud !",
["You're...alive!? But we saw you die!"] = "Tu es...vivant ? Mais nous t'avons vu mourrir !",
@@ -1242,7 +976,5 @@ locale = {
["Yuck! I bet they'll keep worshipping her even after I save the village!"] = "beurck ! je parie qu'ils continueront à l'adorer meme après que j'ai sauvé le village !",
-- ["Zealandia"] = "", -- Continental_supplies
-- ["'Zooka Team"] = "",
- ["Zork"] = "",
- ["Zork"] = "",
- ["Zork"] = "",
+-- ["Zork"] = "",
}
diff --git a/share/hedgewars/Data/Locale/fr.txt b/share/hedgewars/Data/Locale/fr.txt
index 8522e05..98e8e3a 100644
--- a/share/hedgewars/Data/Locale/fr.txt
+++ b/share/hedgewars/Data/Locale/fr.txt
@@ -3,22 +3,22 @@
00:00=Grenade
00:01=Grenade à fragmentation
00:02=Bazooka
-00:03=Abeille Missile
+00:03=Abeille à tête chercheuse
00:04=Fusil
00:05=Marteau-piqueur
00:06=Passer
-00:07=Corde ninja
+00:07=Grappin
00:08=Mine
-00:09=Révolver
+00:09=Pistolet
00:10=Dynamite
00:11=Batte de baseball
00:12=Shoryuken
00:13=sec
00:14=Parachute
-00:15=Attaque aérienne
-00:16=Lancer de mines
+00:15=Frappe aérienne
+00:16=Pluie de mines
00:17=Chalumeau
-00:18=Poutre
+00:18=Construction
00:19=Téléportation
00:20=Changer de hérisson
00:21=Mortier
@@ -29,39 +29,44 @@
00:26=Bombe pastèque
00:27=Grenade infernale
00:28=Roquette perforante
-00:29=Canon à billes
+00:29=Mitrailleuse à balles
00:30=Napalm
00:31=Avion télécommandé
00:32=Faible gravité
-00:33=Plus de dégâts
+00:33=Dégats supplémentaires
00:34=Invulnérable
00:35=Temps supplémentaire
00:36=Visée laser
00:37=Vampirisme
-00:38=Fusil de sniper
+00:38=Sniper
00:39=Soucoupe Volante
00:40=Cocktail Molotov
00:41=Piaf
-00:42=Fusil à portails
-00:43=Attaque du Piano
+00:42=Générateur de portails
+00:43=Chute de Piano
00:44=Vieux Limburger
-00:45=Fusil Sinus (bêta)
+00:45=Fusil Sinusoidale
00:46=Lance-flammes
00:47=Mines adhésives
00:48=Marteau
00:49=Resurrecteur
00:50=Attaque perforante
00:51=Boule de terre
+00:52=Aucune arme sélectionnée
+00:53=Boîte temporelle
+00:54=Aéro-Sol
+00:55=Congélateur
+00:56=Hachoir
01:00=C'est parti !
01:01=Round ex-aequo
01:02=%1 gagne !
01:03=Volume %1%
01:04=Pause
-01:05=Quitter (Y/Esc) ?
+01:05=Quitter? (Y/Esc) (Clique pour reprendre)
01:06=Mort subite !
01:07=%1 Restantes
-01:08=Essence
+01:08=Carburant
; Event messages
; Hog (%1) died
@@ -78,41 +83,42 @@
02:00=%1 fait l'ultime sacrifice !
02:00=%1 sera profondément regretté !
02:00=%1 a un anévrisme !
-02:00=%1 s'en va, laissant sa femme et ses enfants
-02:00=%1 a lancé sa dernière roquette
-02:00=%1 a jeté sa dernière grenade
-02:00=%1 a fait cuire son dernier gâteau
-02:00=%1 s'est balancé sur sa dernière corde
-02:00=%1 a appelé son dernier raid aérien
-02:00=%1 a rechargé son dernier fusil de chasse
-02:00=%1 a envoyé son dernier melon
-02:00=%1 a tiré sa dernière balle
-02:00=%1 aurait vraiment dû utiliser une caisse de vie
-02:00=%1 est parti pour jouer à un meilleur jeu
+02:00=%1 s'en va, laissant sa femme et ses enfants !
+02:00=%1 a lancé sa dernière roquette !
+02:00=%1 a jeté sa dernière grenade !
+02:00=%1 a fait cuire son dernier gâteau !
+02:00=%1 s'est balancé sur sa dernière corde !
+02:00=%1 a appelé son dernier raid aérien !
+02:00=%1 a rechargé son dernier fusil de chasse !
+02:00=%1 a envoyé son dernier melon !
+02:00=%1 a tiré sa dernière balle !
+02:00=%1 aurait vraiment dû utiliser une caisse de vie !
+02:00=%1 est parti pour jouer à un meilleur jeu !
02:00=%1 est mauvais joueur !
-02:00=%1 a échoué
+02:00=%1 a échoué !
02:00=Pauvre %1...
-02:00=%1 préfère Warmux
-02:00=%1 a bloqué les balles avec sa tête
-02:00=%1 s'en va à la façon des dinosaures
-02:00=%1 fait avancer les hérissons d'un pas vers l'extinction
-02:00=%1 me fait pleurer une larme
-02:00=%1 a cessé d'être
-02:00=Dites au revoir à %1
-02:00=Plus d'espoir restant pour %1
-02:00=%1 ferme le rideau final
-02:00=%1 souffre d'Ãchec Spontané et Massif d'Existence
-02:00=%1 est mort
-02:00=%1 est raide mort
-02:00=%1 n'existe plus
-02:00=%1 est périmé
-02:00=Privé de la vie, %1, reste en paix
-02:00=%1 rejoins le chÅur invisible
+02:00=%1 préfère Warmux !
+02:00=%1 a bloqué les balles avec sa tête !
+02:00=%1 s'en va à la façon des dinosaures !
+02:00=%1 fait avancer les hérissons d'un pas vers l'extinction !
+02:00=%1 me fait pleurer une larme !
+02:00=%1 a cessé d'être !
+02:00=Dites au revoir à %1 !
+02:00=Plus d'espoir restant pour %1 !
+02:00=%1 ferme le rideau final !
+02:00=%1 souffre d'Ãchec Spontané et Massif d'Existence !
+02:00=%1 est mort !
+02:00=%1 est raide mort !
+02:00=%1 n'existe plus !
+02:00=%1 est périmé !
+02:00=Privé de la vie, %1, reste en paix !
+02:00=%1 rejoins le chÅur invisible !
02:00=Adieu %1, nous tenions beaucoup a toi !
-02:00=%1 avait une faible tolérance aux coups à balles
-02:00=%1 aurait dû utiliser une vie supplémentaire
-02:00=%1 rejoint ses ancêtres
+02:00=%1 avait une faible tolérance aux coups à balles !
+02:00=%1 aurait dû utiliser une vie supplémentaire !
+02:00=%1 rejoint ses ancêtres !
02:00=%1 sera muet comme une tombe
+
; Hog (%1) drowned
02:01=%1 joue au sous-marin !
02:01=%1 imite le Titanic !
@@ -148,7 +154,6 @@
02:01=%1 veut jouer à Ecco the Dolphin
02:01=%1 est parti visiter l'aquarium
02:01=%1 a trouvé la cité perdue d'Atlantide
-02:01=%1 se propose pour le rôle principal de Bioshock 3
02:01=Ta pagaie pour chiens aurait pû servir, %1
02:01=%1 aurait dû acheter un jet ski
02:01=%1 n'aime pas les sports aquatiques
@@ -162,6 +167,7 @@
02:01=%1 flotte comme une enclume
02:01=%1 a oublié son masque et ses palmes
02:01=%1 a vu une sirène !
+
; Match starts
02:02=Aux armes !
02:02=Prêts à combattre !
@@ -210,10 +216,13 @@
02:02=Ave Caesar, Morituri te salutant !
02:02=Combattez jusqu'Ã la fin !
02:02=Que la force soit avec vous !
+
; Round ends (win; unused atm)
02:03=...
+
; Round ends (draw; unused atm)
02:04=...
+
; New health crate
02:05=Pharmacie !
02:05=De l'aide !
@@ -232,6 +241,7 @@
02:05=Voilà la Croix Rouge !
02:05=Médecin Sans Frontière à votre service !
02:05=Hausse de l'espérance de vie en vue
+
; New ammo crate
02:06=Plus d'armes !
02:06=Du renfort !
@@ -256,6 +266,7 @@
02:06=L'espoir fait vivre
02:06=Surement quelquechose d'utile
02:06=Que la chance soit avec vous !
+
; New utility crate
02:07=Boite à outils !
02:07=Ãa peut être pratique...
@@ -269,6 +280,7 @@
02:07=Elle s'est peut être blessée en tombant, vous devriez aller la voir
02:07=Bob le bricoleur sait être généreux
02:07=Le moment donné par le hasard vaut mieux que le moment choisi
+
; Hog (%1) skips his turn
02:08=%1 est une lopette...
02:08=%1 est trooooop rasant...
@@ -310,6 +322,7 @@
02:08=Les gens heureux n'ont pas besoin de se presser selon %1
02:08=Ne crains pas d'avancer lentement, crains seulement de t'arrêter %1
02:08=Patience ! Avec le temps, l'herbe devient du lait
+
; Hog (%1) hurts himself only
02:09=%1 devrait apprendre à viser !
02:09=%1 s'en veut
@@ -345,123 +358,160 @@
02:09=%1 ne peut pas échapper à son destin
02:09=%1 a pris son arme dans le mauvais sens
02:09=%1 est surement daltonien
+
; Hog shot an home run (using the bat and another hog)
02:10=Home Run !
02:10=C'est un oiseau ! C'est un avion ! ...
02:10=Hors du parc !
02:10=Coup gagnant !
02:10=I believe I can FLY ! I believe I can... *boum*
-; Weapon Categories
-03:00=Grenade à retardement
-03:01=Grenade à retardement
-03:02=Arme balistique
-03:03=Arme téléguidée
-03:04=Fusil (plusieurs coups)
-03:05=Engin excavateur
-03:06=Action
-03:07=Véhicule utilitaire
-03:08=Bombe de proximité
-03:09=Révolver (à plusieurs coups)
-03:10=BOUM!
-03:11=Bonk!
-03:12=Arts martiaux
-03:13=Non Utilisé
-03:14=Véhicule utilitaire
-03:15=Attaque aéroportée
-03:16=Attaque aéroportée
-03:17=Engin excavateur
-03:18=Utilitaire
-03:19=Véhicule utilitaire
-03:20=Action
-03:21=Engin balistique
-03:22=Appelez-moi Indiana !
-03:23=Arts (vraiment) martiaux !
-03:24=Le gâteau n'est PAS un mensonge !
-03:25=Déguisement
-03:26=Grenade à fragmentation
-03:27=Grenade infernale
-03:28=Missile balistique
-03:29=Missile balistique
-03:30=Attaque aéroportée
-03:31=Bombe à déclenchement télécommandé
-03:32=Effet temporaire
-03:33=Effet temporaire
-03:34=Effet temporaire
-03:35=Effet temporaire
-03:36=Effet temporaire
-03:37=Effet temporaire
-03:38=Fusil (Ã coups multiples)
-03:39=Moyen de transport
-03:40=Grenade incendiaire
+
+; Hog (%1) Has to leave (team is gone)
+02:11=%1 a du aller se coucher!
+02:11=%1 est trop occupé pour jouer
+02:11=%1 a du partir
+
+; Weapon Categories
+03:00=Grenade à retardement
+03:01=Grenade à retardement
+03:02=Arme balistique
+03:03=Arme téléguidée
+03:04=Fusil (plusieurs coups)
+03:05=Outil de creusage
+03:06=Action
+03:07=Moyen de transport
+03:08=Bombe de proximité
+03:09=Révolver (à plusieurs coups)
+03:10=BOUM!
+03:11=Bonk!
+03:12=Arts martiaux
+03:13=Non Utilisé
+03:14=Moyen de transport
+03:15=Attaque aéroportée
+03:16=Attaque aéroportée
+03:17=Outil de creusage
+03:18=Utilitaire
+03:19=Moyen de transport
+03:20=Action
+03:21=Engin balistique
+03:22=Appelez-moi Indiana !
+03:23=Arts (vraiment) martiaux !
+03:24=Le gâteau n'est PAS un mensonge !
+03:25=Déguisement
+03:26=Grenade juteuse
+03:27=Grenade enflammée
+03:28=Arme balistique
+03:29=Arme balistique
+03:30=Attaque aéroportée
+03:31=Bombe à déclenchement télécommandé
+03:32=Effet temporaire
+03:33=Effet temporaire
+03:34=Effet temporaire
+03:35=Effet temporaire
+03:36=Effet temporaire
+03:37=Effet temporaire
+03:38=Fusil (Ã coups multiples)
+03:39=Moyen de transport
+03:40=Grenade incendiaire
03:41=Un supporter enragé de Squawks
+; they wont get the original joke the song is in english so Ill use "for science" instead since its said a lot in the game
+03:42=Pour la science ...
+03:43=Joue la douloureuse sonate de Beethoven
+03:44=A consommer de préference avant : 1923
+03:45=La puissance de la science
+03:46=Chaud ! Chaud ! Chaud!
+03:47=Colle ça là où ce sera utile!
+03:48=C'est l'heure de marteler !
+03:49=Ramène les morts en ENFER !!!
+03:50=Un fan de taupes
+03:51=Trouvé par terre
+03:52=UNUSED
+03:53=Type 40
+03:54=Trace ta route
+03:55=Qui a commandé un herisson-glacé?
+03:56=Grand couteau, Multi-fonctions !
-; Weapon Descriptions (use | as line breaks)
-04:00=Attaquez vos ennemis en utilisant une simple grenade.|Elle explosera une fois que le compte à rebours atteindra zéro.|1-5: Lancez le minuteur de la grenade|Attaque : maintenez pour la lancer avec plus de force
-04:01=Attaquez vos ennemis en utilisant une bombe à retardement.|Elle se désintégrera en de multiples petites bombes |quand le compte à rebours atteindra zéro|1-5 : Lancez le minuteur de la grenade|Attaque : maintenez pour la lancer avec plus de force
-04:02=Attaquez vos ennemis en utilisant un missile balistique|subissant l'influence du vent.|Attaque : maintenez pour tirer avec plus de force
-04:03=Lancez une bombe téléguidée qui se verrouillera|sur la cible choisie. Ne tirez pas à pleine puissance|pour une meilleure précision.|Curseur : choix de la cible|Attaque : maintenez pour tirer avec plus de force
-04:04=Attaquez votre ennemi en utilisant un fusil à deux coups.|Grâce à son pouvoir de dispersion vous n'avez pas besoin de frapper directement sur la cible|pour toucher votre ennemi.|Attaque : tirez (coups multiples)
-04:05=Descendez sous terre ! Utilisez le marteau-piqueur pour creuser un trou|dans le sol et atteindre d'autres zones.|Attaque : commencez/achevez de creuser
-04:06=Vous en avez marre ? Pas moyen d'attaquer ? Vous économisez vos munitions ?|Pas de problèmes ! Passez simplement votre tour, espèce de lâche !|Attaque : Passez votre tour sans combattre
-04:07=Franchissez les grandes distances en utilisant par intervalles la |corde ninja. Utilisez votre élan pour vous lancer contre les autres hérissons,|balancez leurs des grenades ou d'autres armes explosives.|Attaque : Tirer ou lâchez la corde ninja|Saut longue distance : jetez des grenades ou des armes similaires
+; Weapon Descriptions (use | as line breaks)
+04:00=Attaquez vos ennemis en utilisant une simple grenade.|Elle explosera une fois que le compte à rebours atteindra zéro.|1-5: Réglez le minuteur de la grenade|Attaque : maintenez pour la lancer avec plus de force
+04:01=Attaquez vos ennemis en utilisant une grenade a fragmentation.|Elle se désintégrera en de multiples petits fragements explosifs |quand le compte à rebours atteindra zéro|1-5 : Réglez le minuteur de la grenade|Attaque : maintenez pour la lancer avec plus de force
+04:02=Attaquez vos ennemis en utilisant un bazooka dont la roquette|subira l'influence du vent.|Attaque : maintenez pour tirer avec plus de force
+04:03=Lancez une abeille à tête chercheuse qui se verrouillera|sur la cible choisie. Ne tirez pas à pleine puissance|pour une meilleure précision.|Curseur : choix de la cible|Attaque : maintenez pour tirer avec plus de force
+04:04=Attaquez votre ennemi en utilisant un fusil à deux coups.|Grâce à son pouvoir de dispersion vous n'avez pas besoin de frapper directement sur la cible|pour toucher votre ennemi.|Attaque : tirez (coups multiples)
+04:05=Descendez sous terre ! Utilisez le marteau-piqueur pour creuser un trou|dans le sol et atteindre d'autres zones.|Attaque : commencez/achevez de creuser
+04:06=Vous en avez marre ? Pas moyen d'attaquer ? Vous économisez vos munitions ?|Pas de problèmes ! Passez simplement votre tour, espèce de lâche !|Attaque : Passez votre tour sans combattre
+04:07=Franchissez les grandes distances en utilisant par intervalles le |Grappin. Utilisez votre élan pour vous lancer contre les autres hérissons,|leur balancer des grenades ou d'autres armes explosives.|Attaque : Tirer ou lâchez la corde ninja|Saut longue distance : jetez des grenades ou des armes similaires
04:08=Maintenez vos ennemis à distance en laissant une mine|dans les passages étroits ou juste sous leurs pieds. Assurez-vous|que vous pouvez vous sauver avant son déclenchement !|Attaque : lâchez la mine à vos pieds
-04:09=Vous n'êtes pas sûr de ce que vous voulez ? Utilisez l'Aigle| du Désert pour attaquer en utilisant vos quatre coups. Poussez dans l'eau vos ennemis ou transpercez leur défense|Attaque : tirez (coups multiples)
-04:10=La force brute est toujours une possibilité. Lancez cet explosif|classique sur vos ennemis et prenez le temps de vous retirer.|Attaque : Lâchez la dynamite à vos pieds
-04:11=Débarrassez-vous des hérissons ennemis en leur donnant des coups pour les chasser |vers d'autres horizons ou en les jetant à l'eau. Ou bien préférez-vous|envoyer quelques tonneaux ou mines sur vos ennemis ?|Attaque : frappez un bon coup sur tout ce qui bouge.
-04:12=Allez au combat rapproché corps à corps pour utiliser toute la force presque mortelle de ces arts martiaux.|Attaque : lancez un coup de poing fulgurant
+04:09=Vous n'êtes pas sûr de ce que vous voulez ? Utilisez le| pistolet pour attaquer en utilisant vos quatre coups. Poussez dans l'eau vos ennemis ou transpercez leur défense|Attaque : tirez (coups multiples)
+04:10=La force brute est toujours une possibilité. Lancez cet explosif|classique sur vos ennemis et prenez le temps de vous retirer.|Attaque : Lâchez la dynamite à vos pieds
+04:11=Débarrassez-vous des hérissons ennemis en leur donnant des coups pour les éjecter |vers d'autres horizons ou en les jetant à l'eau. Ou bien préférez-vous|envoyer quelques tonneaux ou mines sur vos ennemis ?|Attaque : frappez un bon coup sur tout ce qui bouge.
+04:12=Allez au corps-Ã -corps pour utiliser toute la force presque mortelle de ces arts martiaux.|Attaque : lancez un coup de poing fulgurant
04:13=non-utilisé
04:14=Vous avez le vertige ? Prenez donc un parachute.|Il se déploiera lorsque|vous serez tombé trop loin|et épargnera le choc de la chute à votre hérisson.|Attaque: Dépliez le parachute
04:15=Appelez le 3615 BOMBE pour commander une frappe aérienne dévastatrice sur vos ennemis.|Gauche/Droite : Déterminez la direction de l'attaque|Curseur : Choisissez la zone cible
04:16=Appelez un avion qui enverra plusieurs mines|sur la zone cible.|Gauche/Droite : Détermine la direction de l'attaque|Curseur : Sélectionnez la zone cible
-04:17=vous avez besoin d'un abri ? de pousser quelques ennemis dans l'eau ? Utilisez le chalumeau| pour creuser un tunnel dans le sol, vous protéger ou faire de nouvelles victimes.|Attaque : Commencez/cessez de creuser.
-04:18=Vous avez besoin de vous protéger davantage ou de passer un |obstacle infranchissable ? Placez quelques poutrelles|où vous voulez .|Gauche/Droite : Choisissez la poutrelle à placer|Curseur : Placez la poutrelle dans la bonne position
+04:17=vous avez besoin d'un abri ? de pousser quelques ennemis dans l'eau ? Utilisez le chalumeau| pour creuser un tunnel dans le sol, vous protéger ou faire de nouvelles victimes.|Attaque : Commencez/cessez de creuser.
+04:18=Vous avez besoin de vous protéger davantage ou de passer un |obstacle infranchissable ? Placez quelques poutrelles|où vous voulez .|Gauche/Droite : Choisissez la poutrelle à placer|Curseur : Placez la poutrelle dans la bonne position
04:19=La téléportation utilisée au bon moment|peut être bien plus efficace|que la plupart des autres armes|car elle vous permet de sauver des hérissons de situations dangereuses|en quelques secondes.|Curseur : Choisissez la zone cible
-04:20=Vous permet de jouer la partie en cours avec|un hérisson différent.|Attaque : Activez le changement de hérisson
+04:20=Vous permet de changer de herisson|pendant votre tour.|Attaque : Activez le changement de hérisson
04:21=Tirez un missile balistique qui va|envoyer de multiples bombes au point d'impact.|Attaque : Tirez à pleine puissance
-04:22=Ce n'est pas réservé à Indiana Jones ! Le fouet est une|arme bien utile dans plusieurs situations. Particulièrement|quand vous devez hisser quelqu'un en haut d'une falaise.|Attaque : Frappez tout ce qui bouge devant vous
-04:23=Si vous n'avez rien à perdre, voilà qui peut être |bien pratique. Sacrifiez votre hérisson en le lançant dans une direction| particulière. Il heurtera tout sur son passage avant |d'exploser finalement.|Attaque : Lancer l'attaque mortelle et dévastatrice
-04:24=Joyeux anniversaire ! Lancez ce gâteau, faites-le atterrir|tout près de vos ennemis et offrez-leur une fête explosive.|Le gâteau peut franchir presque tous les environnements mais|il se peut qu'il explose à mi-chemin.|Attaque : Lancez le gâteau ou bien faites-le s'arrêter et exploser
-04:25=Arme de séduction massive ! Utilisez le déguisement pour amener vos ennemis| à sauter vers votre hérisson (et donc vers un piège ou un trou).|Attaque : Utilisez le déguisement et tentez de séduire un autre hérisson
-04:26=Envoyez cette pastèque explosive à la tête de vos ennemis. Une fois le compte-à -rebours achevé, elle se désintégrera en de multiples fragments explosifs|1-5 : Lancer le compte à rebours|Attaque : Maintenez pour tirer avec plus de puissance
-04:27=Faites tomber un déluge de feu sur vos adversaires en utilisant|cet explosif dévastateur.|Ne vous tenez pas trop prêt|de l'impact car les flammes peuvent durer longtemps|Attaque : Maintenez pour tirer avec plus de puissance
-04:28=Peu après le lancement de ce missile, il va se mettre|à creuser le sol le plus résistant et explosera|une fois son détonateur amorcé ou une fois atteint l'air libre.|Attaque : Maintenez pour tirer avec plus de puissance
+04:22=Ce n'est pas réservé à Indiana Jones ! Le fouet est une|arme bien utile dans plusieurs situations. Particulièrement|quand vous devez hisser quelqu'un en haut d'une falaise.|Attaque : Frappez tout ce qui bouge devant vous
+04:23=Si vous n'avez rien à perdre, voilà qui peut être |bien pratique. Sacrifiez votre hérisson en le lançant dans une direction| particulière. Il heurtera tout sur son passage avant |d'exploser.|Attaque : Lancer l'attaque mortelle et dévastatrice
+04:24=Joyeux anniversaire ! Lancez ce gâteau, et déposez-le|tout près de vos ennemis et offrez-leur une fête explosive.|Le gâteau peut franchir presque tous les environnements mais|il se peut qu'il explose à mi-chemin ou apès votre cible.|Attaque : Lancez le gâteau ou bien faites-le s'arrêter et exploser
+04:25=Arme de séduction massive ! Utilisez le déguisement pour ammener vos ennemis| à sauter vers votre hérisson (et donc vers un piège ou un trou).|Attaque : Utilisez le déguisement et tentez de séduire un autre hérisson
+04:26=Envoyez cette pastèque explosive à la tête de vos ennemis. Une fois le compte-à -rebours achevé, elle se désintégrera en de multiples tranches explosives|1-5 : Régler le compte à rebours|Attaque : Maintenez pour tirer avec plus de puissance
+04:27=Faites tomber un déluge de feu sur vos adversaires en utilisant|cet explosif diabolique et dévastateur.|Ne vous tenez pas trop prêt|de l'impact car les flammes peuvent durer longtemps|Attaque : Maintenez pour tirer avec plus de puissance
+04:28=Peu après le lancement de cette roquette, elle va se mettre|à creuser le sol le plus résistant et explosera|une fois son compte à rebours ou une fois atteint l'air libre.|Attaque : Maintenez pour tirer avec plus de puissance
04:29=Ce n'est pas un jouet pour les enfants ! La mitrailleuse envoie|des centaines de petites balles colorées explosives.|Attaque : Tirez à pleine puissance|Haut/Bas : Continuez à tirer
-04:30=Appelez un avion pour larguer une puissante giclée de napalm.|En la menant correctement cette attaque peut éradiquer|des zones entières du paysage, et notamment les hérissons qui auraient la malchance de se trouver là .|Gauche/Droite: Déterminez la direction de l'attaque|Curseur : Choisissez la zone cible
-04:31=L'avion télécommandé est l'arme idéale pour récolter des boites ou|attaquer des hérissons très éloignés. Une fois vos ennemis bombardés, vous pourrez lancer votre avion sur l'ennemi dans une explosion incendiaire.|Attaque : Lancez l'avion ou larguez des bombes|Saut longue distance : laissez les valkyries entrer dans la danse guerrière|Haut/Bas : Pilotez l'avion
-04:32=La fable gravité est plus efficace que n'importe quel régime ! Sautez|plus haut et franchissez de plus grandes distances ou bien faites voltiger vos ennemis |encore plus loin.|Attaque : Activez
-04:33=Parfois vous avez besoin d'un petit coup de pouce supplémentaire|pour gérer les dégâts.|Attaque : Activez
+04:30=Appelez un avion pour larguer une pluie de napalm soumise à la force du vent.|En la menant correctement cette attaque peut éradiquer|des zones entières du paysage, et notamment les hérissons qui auraient la malchance de se trouver là .|Gauche/Droite: Déterminez la direction de l'attaque|Curseur : Choisissez la zone cible
+04:31=L'avion télécommandé est l'arme idéale pour récolter des boites ou|attaquer des hérissons très éloignés. Une fois vos ennemis bombardés, vous pourrez lancer votre avion sur l'ennemi dans une explosion incendiaire.|Attaque : Lancez l'avion ou larguez des bombes|Saut longue distance : laissez les valkyries entrer dans la danse guerrière|Haut/Bas : Pilotez l'avion
+04:32=La faible gravité est plus efficace que n'importe quel régime ! Sautez|plus haut et franchissez de plus grandes distances ou bien faites voltiger vos ennemis |encore plus loin.|Attaque : Activez
+04:33=Parfois vous avez besoin d'un petit coup de pouce supplémentaire|pour gérer les dégâts.|Attaque : Activez
04:34=Personne ne peut me toucher !|Attaque : Activez
04:35=Parfois le temps passe trop vite. Grappillez quelques secondes de plus pour terminer votre attaque|Attaque : Activez
-04:36=Eh bien, parfois vous ratez complètement la cible. Demandez plutôt de l'aide|à la technologie de pointe actuelle pour bien viser.|Attaque : Activez
+04:36=Eh bien, parfois vous ratez complètement la cible. Demandez plutôt de l'aide|à la technologie de pointe pour bien viser.|Attaque : Activez
04:37=Ne craignez pas la lumière du jour. Rafraichissez vous |d'un peu de sang en récupérant des points de vie sur les dégats faits aux ennemis.|Attaque : Activez
-04:38= Le fusil à lunette peut être une des armes les plus dévastatrices|de tout votre arsenal, toutefois il est totalement inefficace|en combat rapproché. Les dommages qu'il cause augmentent suivant|la distance de la cible.|Attaque : Tirez (deux fois)
-04:39=Volez vers d'autres secteurs de la carte en utilisant une soucoupe|volante. Ce moyen de transport, pas facile à dompter, vous|emportera vers presque tous les horizons du champ de bataille|Attaque : Activer|Haut/Gauche/Droite : Prenez de l'altitude et controllez votre direction
-04:40=Mettez le feu à un territoire en utilisant cette bouteille remplie|de liquide inflammable.|Attaque : maintenez pour tirer avec plus de force
+04:38= Le sniper peut être une des armes les plus dévastatrices|de tout votre arsenal, toutefois il est totalement inefficace|en combat rapproché. Les dommages qu'il cause augmentent suivant|la distance de la cible.|Attaque : Tirez (deux fois)
+04:39=Volez vers d'autres secteurs de la carte en utilisant une soucoupe|volante. Ce moyen de transport, pas facile à dompter, vous|emportera vers presque tous les horizons du champ de bataille mais attention au carburant!|Attaque : Activer|Haut/Gauche/Droite : Prenez de l'altitude et controllez votre direction
+04:40=Mettez le feu à un territoire en utilisant cette bouteille remplie|de liquide inflammable.|Attaque : maintenez pour tirer avec plus de force
04:41=Une arme naturelle qui peut suffire à remplacer la soucoupe volante.|Cet oiseau a du manger un vieux fromage pourri (du Limburger vous dites ?)|car ses oeufs ont comme quelquechose de ... toxique.|Le piaf peut donc transporter votre hérisson et balancer des Åufs|sur vos ennemis !|Attaque : Activez et larguez des Åufs|Haut/Gauche/Droite: voltigez vers une direction.
-04:42=Ce fusil à portails est capable de transporter instantanément hérissons,|tonneaux ou mines entre deux points du terrain. |Utilisez-le intelligemment et votre campagne sera un ... GRAND SUCCÃS !|Attaque : Crée un portail|Modificateur : Change la couleur du portail
+04:42=Ce générateur de portails est capable de transporter instantanément hérissons,|tonneaux ou mines entre deux points du terrain. |Utilisez-le intelligemment et votre campagne sera un ... GRAND SUCCÃS !|Attaque : Crée un portail|Modificateur : Change la couleur du portail
04:43=Faites de vos débuts musicaux un succès explosif !| Lâchez un piano depuis les cieux, mais attention ... si quelqu'un doit|jouer dessus, cela pourrait lui coûter la vie !|Curseur : Choix de la cible|F1-F9 : Jouer du piano
-04:44=Ce n'est pas juste un fromage, c'est une arme bactériologique !|Si il ne provoque que de faibles dommages, sa puissance se|trouve dans sa durée. Il empoisonnera tous les malchanceux|touchés par l'odeur et réduira leur vie à l'agonie !|1-5 : Lancez le minuteur de la grenade|Attaque : maintenez pour la lancer avec plus de force
-04:45=Tous ces cours de physique ont finalement payé,|lancez une onde Sinus dévastatrice sur vos ennemis.|Attention au recul ! (cette arme est incomplète)|Attaque : Activez
+04:44=Ce n'est pas juste un fromage, c'est une arme bactériologique !|Si il ne provoque que de faibles dommages, sa puissance se|trouve dans sa durée. Il empoisonnera tous les malchanceux|touchés par l'odeur et réduira leur vie à l'agonie !|1-5 : Réglez le minuteur de l'arme|Attaque : maintenez pour la lancer avec plus de force
+04:45=Tous ces cours de physique ont finalement payé,|lancez une onde Sinusoidale dévastatrice sur vos ennemis.|Attention au recul ! |Attaque : Activez
04:46=Aspergez vos ennemis de flammes liquides ou creusez vous un passage dans le sol.|Hardi !|Attaque : Activez|Haut/Bas : Continuez à viser|Droite/Gauche : Changer la puissance de tir
04:47=Doublez le fun avec deux mines, piquantes, furtives et collantes.|Provoquez une réaction en chaine dévastatrice et/ou défendez-vous ! |Attaque : maintenez pour tirer avec plus de force (deux fois)
04:48=Outre une bonne bosse, un bon coup de ce marteau enlèvera un tiers de la santé |du hérisson ennemi et l'enfoncera dans le sol ou dans l'eau comme un vulgaire asticot !|Attaque : Activez
04:49=Ressuscite vos amis oubliés six pieds sous terre ! Mais méfiez-vous, ressuscite également vos ennemis. |Attaque : Maintenez attaque pressée pour ressusciter lentement|Haut : Accélérer la résurrection
+04:50=Un ennemi se cache sous terre ?|Faîtes le sortir avec l'attaque perforante! |Un avion vous délivrera des roquettes perforantes qui creuseront vers le bas jusqu'a la fin du compte a rebours|ou du contact a l'air libre où elles exploseront|1-5 : Réglez le minuteur des roquettes|Gauche/Droite: Déterminez la direction de l'attaque|Curseur : Choisissez la zone cible
+04:51=Gagnez un tir gratuit en lançant une boule de terre sur vos ennemis.|Elle poussera les herissons dans l'eau ou dans un trou afin d'utiliser votre deuxième arme pour l'achever|Attaque : Maintenez pour tirer avec plus de puissance
+04:52=UNUSED
+04:53=Faîtes un voyage dans le temps et l'espace en|laissant vos camarades se battre seuls!|Soyez préparé à revenir a n'importequel moment|ou lors d'une mort subite ou encore si tout vos camarades sont morts|Attention ne marche pas pendant la mort subite, si vous êtes le dernier survivant ou le roi.|Attaque : Activer
+04:54=Et voici le nouveau sol en bouteille! Ce spray produit des flocon collants sur lesquels vous pouvez marchez!|Construisez des pont,enterrez vos ennemis, scellez des tunnels.|Attention à ne pas en mettre sur vous!|Attaque : Activez|Haut/Bas : Continuez à viser|Droite/Gauche : Changer la puissance de tir
+04:55=Apportez l'ère glacière sur vos ennemis!|Avec le congélateur gelez les herissons rendez le sol glissant|et sauvez vous de la noyade en gelant l'eau!!|Attaque : Tirez
+04:56=Un couteau mais bien plus,|ce hachoir se lance sur les ennemis, bloc les passages et tunnels et|peut même servir d'appui pour gravir une montagne!|Mais attention à ne pas vous blesser.|Attaque : maintenez pour la lancer avec plus de force (deux fois)
+
-; Game goal strings
-05:00=Modes de jeu
-05:01=Les règles suivantes s'appliquent
-05:02=Forts : Défendez votre forteresse ; exterminez vos ennemis !
-05:03=Faible gravité : Attention à vos mouvements
-05:04=Invulnérabilité : Les hérissons sont (presque) invulnérables
-05:05=Vampirisme : Les hérissons récupèrent des points de vie par les dégats qu'ils infligent
+; Game goal strings
+05:00=Modes de jeu
+05:01=Les règles suivantes s'appliquent
+05:02=Forts : Défendez votre forteresse ; exterminez vos ennemis !
+05:03=Faible gravité : Attention à vos mouvements
+05:04=Invulnérabilité : Les hérissons sont (presque) invulnérables
+05:05=Vampirisme : Les hérissons récupèrent des points de vie par les dégats qu'ils infligent
05:06=Karma: Les hérissons sont victimes des blessures qu'ils infligent
-05:07=Protégez le roi : Ne laissez pas mourir le roi !|Placez le roi : Choisissez un point de départ sécurisé pour le roi
-05:08=Placez les hérissons : Placez vos hérissons avant le début de la partie
-05:09=Artillerie : Les hérissons ne peuvent pas se déplacer pour changer de place
+05:07=Protégez le roi : Ne laissez pas mourir le roi !|Placez le roi : Choisissez un point de départ sécurisé pour le roi
+05:08=Placez les hérissons : Placez vos hérissons avant le début de la partie
+05:09=Artillerie : Les hérissons ne peuvent pas se déplacer pour changer de place
05:10=Terrain indestructible : La plupart des armes sont incapables de modifier le terrain
05:11=Munitions partagées : Toutes les équipes de la même couleur partagent leurs munitions
05:12=Mines à retardement : Les mines exploseront après %1 seconde(s)
-05:13=Mines à retardement : Les mines explosent immédiatement
+05:13=Mines à retardement : Les mines explosent instentanément
05:14=Mines à retardement : Les mines exploseront dans un délai compris entre 0 et 3 secondes
05:15=Modificateur de dégâts : Toutes les armes feront %1% de dégâts
+05:16=La vie de tout les hérissons est restaurée à la fin du tour
+05:17=Les hérissons IA réapparaissent lorsqu'ils meurent
+05:18=Attaques illimitées
+05:19=Les armes sont réinitialisées à la fin du tour
+05:20=Les armes ne sont pas partagées entre les hérissons
+05:21=Relais: Des équipes sous la même couleur partagent le tour|Temps partagé: Dès que l'un à fini son action il passe la main à sont camarade pour qu'il agisse|avant la fin du tour
diff --git a/share/hedgewars/Data/Locale/hedgewars_ar.ts b/share/hedgewars/Data/Locale/hedgewars_ar.ts
index 2d10c61..458a63f 100644
--- a/share/hedgewars/Data/Locale/hedgewars_ar.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_ar.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="fr">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,11 +141,68 @@
<translation>Edit schemes</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">خارطة</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Cannot create directory %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -103,7 +256,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -140,27 +301,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
+ <translation type="unfinished">اسÙ
اÙÙاعب</translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">اسÙ
اÙÙاعب</translation>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -178,18 +385,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>خارطة</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>ÙÙ
Ø·</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>ÙÙÙر</translation>
- </message>
- <message>
<source>All</source>
<translation>ÙÙ</translation>
</message>
@@ -214,10 +409,6 @@ Please pick another nickname:</source>
<translation>تعباÙ</translation>
</message>
<message>
- <source>Type</source>
- <translation type="unfinished">ÙÙع</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation type="unfinished">اÙÙا٠صغÙرة</translation>
</message>
@@ -226,27 +417,95 @@ Please pick another nickname:</source>
<translation type="unfinished">اÙÙا٠Ù
تÙسطة</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation type="unfinished">اÙÙا٠ÙبÙرة</translation>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation type="unfinished">جزر طائÙØ© صغÙرة</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation type="unfinished">جزر طائÙØ© Ù
تÙسطة</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation type="unfinished">جزر طائÙØ© ÙبÙرة</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">عشÙائÙ</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -293,7 +552,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 اÙضÙ
</translation>
+ <translation type="obsolete">%1 *** %2 اÙضÙ
</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -319,8 +578,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">ÙÙÙ
Ø© اÙسر</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -335,6 +609,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -342,7 +638,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -360,6 +663,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -391,6 +705,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">عاÙ
</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -400,6 +746,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -445,8 +802,40 @@ Please pick another nickname:</source>
<translation>عاÙ
</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Ù
تÙدÙ
</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">اسÙ
</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">ÙرÙ٠عشÙائÙ</translation>
</message>
</context>
<context>
@@ -509,310 +898,85 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -822,38 +986,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>ابدا</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>تØÙÙ
</translation>
+ <translation type="obsolete">تØÙÙ
</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">ابدا</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Ùعبة شبÙÙØ©</translation>
+ <source>Update</source>
+ <translation type="unfinished">تØدÙØ«</translation>
</message>
<message>
- <source>Official server</source>
- <translation>اÙخادÙ
اÙرسÙ
Ù</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -900,10 +1068,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">عاÙ
</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Ù
تÙدÙ
</translation>
</message>
@@ -943,6 +1107,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">ÙرÙ</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">اسÙØØ©</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -959,11 +1211,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>اصÙع</translation>
+ <translation type="obsolete">اصÙع</translation>
</message>
<message>
<source>Join</source>
- <translation>اÙضÙ
</translation>
+ <translation type="obsolete">اÙضÙ
</translation>
</message>
<message>
<source>Admin features</source>
@@ -971,7 +1223,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation type="unfinished">رÙÙ
اÙغرÙØ©</translation>
+ <translation type="obsolete">رÙÙ
اÙغرÙØ©</translation>
</message>
<message>
<source>Rules:</source>
@@ -981,14 +1233,6 @@ Please pick another nickname:</source>
<source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Search:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Clear</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%1 players online</source>
<translation type="unfinished">
@@ -996,6 +1240,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1142,18 +1410,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1162,26 +1422,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">تØÙ
ÙÙ</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1227,19 +1475,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1254,10 +1504,6 @@ Please pick another nickname:</source>
<translation>Ù
عÙÙÙ
ات</translation>
</message>
<message>
- <source>Start</source>
- <translation>ابدا</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>اÙ
Ùع اÙاÙضÙ
اÙ
</translation>
</message>
@@ -1291,7 +1537,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">تØدÙØ«</translation>
+ <translation type="obsolete">تØدÙØ«</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1305,18 +1563,6 @@ Please pick another nickname:</source>
<translation type="unfinished">Ù
ÙØ¡ اÙشاشة</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>شاشة اÙÙائÙ
Ø© Ù
ÙØ¡ اÙعرض</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Ùع٠اÙصÙت</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Ùع٠اÙÙ
ÙسÙÙÙ</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>اضÙر عدد اÙاطارات Ù٠اÙثاÙÙØ©</translation>
</message>
@@ -1333,18 +1579,6 @@ Please pick another nickname:</source>
<translation>اضÙر ÙÙائÙ
ÙÙعتاد</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Ùع٠اصÙات شاشة اÙÙ
ÙدÙ
Ø©</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Ùع٠Ù
ÙسÙÙ٠شاشة اÙÙ
ÙدÙ
Ø©</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>تأثÙرات اÙÙ
ÙدÙ
Ø©</translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1364,51 +1598,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation type="unfinished">ÙÙد خارطة</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>اÙساÙ</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation type="unfinished">Ù
رØÙØ©</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
- <translation>ÙÙ
Ø· اÙÙظاÙ
</translation>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
- <translation>Ù
ÙÙ
Ø©</translation>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
- <translation type="unfinished">ÙÙد Ù
تاÙØ©</translation>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>اÙساÙ</translation>
</message>
<message>
- <source>In lobby</source>
- <translation type="unfinished"></translation>
+ <source>Level</source>
+ <translation type="unfinished">Ù
رØÙØ©</translation>
</message>
<message>
- <source>In progress</source>
+ <source>(System default)</source>
+ <translation>ÙÙ
Ø· اÙÙظاÙ
</translation>
+ </message>
+ <message>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1448,10 +1686,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1487,18 +1721,6 @@ Please pick another nickname:</source>
<translation>ØصÙ</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>ربط اÙÙ
ÙاتÙج</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>ÙرÙ</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>ÙÙائÙ
اÙصÙتÙات ٠اÙÙ
رئÙات</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Ùعبة شبÙÙØ©</translation>
</message>
@@ -1507,36 +1729,16 @@ Please pick another nickname:</source>
<translation>Ùر٠اÙÙعب</translation>
</message>
<message>
- <source>Game Modifiers</source>
- <translation>Ù
غÙرات اÙÙعبة</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>اعدادات اÙاساسÙØ©</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>اعدادات اÙÙرÙÙ</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Ù
تÙÙعة</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <source>Game Modifiers</source>
+ <translation>Ù
غÙرات اÙÙعبة</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>اعدادات اÙاساسÙØ©</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>اعدادات اÙÙرÙÙ</translation>
</message>
<message>
<source>Videos</source>
@@ -1546,10 +1748,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1563,27 +1761,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Ùسخة</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation type="unfinished">اÙÙ
Ø·ÙرÙÙ</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation type="unfinished">ÙÙÙÙ</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation type="unfinished">اÙاصÙات</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation type="unfinished">اÙÙ
ترجÙ
ÙÙ</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation type="unfinished">Ø´Ùر خاص</translation>
+ <translation type="obsolete">Ùسخة</translation>
</message>
<message>
<source>Weapons</source>
@@ -1642,10 +1820,6 @@ Please pick another nickname:</source>
<translation>اÙÙ
ساعدات</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>ÙÙ
Ø· اÙÙعبة</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% اÙغاÙ
</translation>
</message>
@@ -1682,10 +1856,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1726,10 +1896,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1760,10 +1926,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1791,6 +1953,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Ù
ÙØ¡ اÙشاشة</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1813,6 +2019,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1829,10 +2039,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1879,47 +2085,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Cannot create directory %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Cannot create directory %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Unable to start the server: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Unable to start the server: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2037,16 +2208,42 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>اسÙ
اÙÙاعب</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ادØ٠اسÙ
اÙÙاعب</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2104,47 +2301,86 @@ Do you still want to join the room?</source>
<translation>تØÙ
ÙÙ</translation>
</message>
<message>
- <source>Setup</source>
- <translation>تÙصÙب</translation>
+ <source>Associate file extensions</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ready</source>
- <translation>ابدا</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation>ÙرÙ٠عشÙائÙ</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
+ <source>Open videos directory</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>More info</source>
+ <source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default options</source>
+ <source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Open videos directory</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Upload to YouTube</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cancel uploading</source>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
+ </message>
+ <message>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2196,6 +2432,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2223,105 +2478,43 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>TCPBase</name>
<message>
- <source>Vampirism</source>
- <translation>Ù
صاص دÙ
اء</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>ÙارÙ
ا</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Ù
دÙعÙØ©</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation type="unfinished">طرÙÙØ© اÙØصÙ</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>ÙسÙ
اÙÙرÙ</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>ارض صÙبة</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>اض٠اطار</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>جاذبÙØ© ÙÙÙÙØ©</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Ù
Ùظار ÙÙزرÙ</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>غÙر Ùاب٠ÙÙتدÙ
Ùر</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>تÙزÙع عشÙائÙ</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Ù
ÙÙ</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>ضع اÙاعبÙÙ</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>اÙÙرÙÙ Ùتشار٠باÙعتاد</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>ابطا٠اÙبÙاء</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation type="unfinished">ابطا٠اÙاجساÙ
اÙارضÙØ©</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">اÙغاء</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2456,12 +2649,6 @@ Do you still want to join the room?</source>
<translation>capture</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>hedgehogs
-info</translation>
- </message>
- <message>
<source>quit</source>
<translation>quit</translation>
</message>
@@ -2497,33 +2684,33 @@ info</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>اÙاسÙØØ© اÙاÙÙÙØ©</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>اÙسÙطرة عÙ٠اÙاسÙØØ©</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">اسÙØØ©</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation type="unfinished">اÙسÙطرة عÙ٠اÙÙاÙ
رة ٠اÙÙ
ؤشر</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>اخرÙ</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished">تØرÙ٠اÙÙاعب ٠اÙتصÙÙب</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished">ÙÙز ÙÙ٠اÙØÙاجز</translation>
</message>
@@ -2587,6 +2774,10 @@ info</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_bg.ts b/share/hedgewars/Data/Locale/hedgewars_bg.ts
index d94944e..1a08fd2 100644
--- a/share/hedgewars/Data/Locale/hedgewars_bg.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_bg.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="bg">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,11 +140,68 @@
<translation>РедакÑиÑане на оÑÑжиÑÑа</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>ÐогаÑо Ñази наÑÑÑойка е вклÑÑена, пÑи избиÑанеÑо на игÑова ÑÑ
ема авÑомаÑиÑно Ñе Ñе избеÑе оÑÑжие</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">ÐаÑÑа</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Ðе може да Ñе ÑÑздаде папка %1</translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -102,7 +255,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +300,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">ÐÑÑкоÑÑÑ Ð²Ð¸ %1 е
-ÑегиÑÑÑиÑан на Hedgewars.org
-ÐÐ¾Ð»Ñ Ð²ÑдеÑе паÑолаÑа Ñи по-долÑ
-или избеÑеÑе дÑÑг пÑÑÐºÐ¾Ñ Ð² наÑÑÑойкиÑе на игÑаÑа:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">ÐÑÑкоÑ</translation>
</message>
@@ -165,6 +312,63 @@ or pick another nickname in game config:</source>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,18 +384,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>ÐаÑÑа</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Тема</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>ФилÑÑÑ</translation>
- </message>
- <message>
<source>All</source>
<translation>ÐÑиÑки</translation>
</message>
@@ -216,10 +408,6 @@ Please pick another nickname:</source>
<translation>ЩÑÑа</translation>
</message>
<message>
- <source>Type</source>
- <translation>Тип</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Ðалки ÑÑнели</translation>
</message>
@@ -228,27 +416,95 @@ Please pick another nickname:</source>
<translation>СÑедни ÑÑнели</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Ðолеми ÑÑнели</translation>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Ðалки плаваÑи оÑÑÑови</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>СÑедни плаваÑи оÑÑÑови</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Ðолеми плаваÑи оÑÑÑови</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">ÐаÑеждане на наÑеÑÑана каÑÑа</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -295,7 +551,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 Ñе пÑиÑÑедини</translation>
+ <translation type="obsolete">%1 *** %2 Ñе пÑиÑÑедини</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +577,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">ÐаÑола</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -337,6 +608,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +637,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +662,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +704,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Ðадаване на данни</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">ÐбÑи</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +745,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +801,40 @@ Please pick another nickname:</source>
<translation>ÐбÑи</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Ðа напÑеднали</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Ðме</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">СлÑÑаен оÑбоÑ</translation>
</message>
</context>
<context>
@@ -498,323 +884,98 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Save</source>
+ <translation type="unfinished">Ðапазване</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -824,38 +985,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>СÑаÑÑ</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>ÐонÑÑол</translation>
+ <translation type="obsolete">ÐонÑÑол</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">СÑаÑÑ</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>ÐгÑа по локална мÑежа</translation>
+ <source>Update</source>
+ <translation type="unfinished">ÐкÑÑализиÑане</translation>
</message>
<message>
- <source>Official server</source>
- <translation>ÐÑиÑиален ÑÑÑвÑÑ</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -902,10 +1067,6 @@ Please pick another nickname:</source>
<translation>ÐзÑÑиване на комплекÑа оÑÑжиÑ</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">ÐбÑи</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Ðа напÑеднали</translation>
</message>
@@ -945,6 +1106,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">ÐÑбоÑи</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">ÐÑÑжиÑ</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -961,11 +1210,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>СÑздаване</translation>
+ <translation type="obsolete">СÑздаване</translation>
</message>
<message>
<source>Join</source>
- <translation>ÐÑиÑÑединÑване</translation>
+ <translation type="obsolete">ÐÑиÑÑединÑване</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1222,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Ðме на ÑÑаÑÑа:</translation>
+ <translation type="obsolete">Ðме на ÑÑаÑÑа:</translation>
</message>
<message>
<source>Rules:</source>
@@ -985,11 +1234,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>ТÑÑÑене:</translation>
+ <translation type="obsolete">ТÑÑÑене:</translation>
</message>
<message>
<source>Clear</source>
- <translation>ÐзÑиÑÑване</translation>
+ <translation type="obsolete">ÐзÑиÑÑване</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1247,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1417,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1164,26 +1429,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">ÐаÑеждане</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1229,19 +1482,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1256,10 +1511,6 @@ Please pick another nickname:</source>
<translation>ÐабÑанÑване</translation>
</message>
<message>
- <source>Start</source>
- <translation>СÑаÑÑ</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>ÐгÑаниÑи пÑиÑÑединÑване</translation>
</message>
@@ -1293,7 +1544,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">ÐкÑÑализиÑане</translation>
+ <translation type="obsolete">ÐкÑÑализиÑане</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1303,10 +1566,6 @@ Please pick another nickname:</source>
<translation>ÐÑовеÑÑване за Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñи ÑÑаÑÑиÑане</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>ÐклÑÑване на звÑка</translation>
- </message>
- <message>
<source>Fullscreen</source>
<translation>ÐÑлен екÑан</translation>
</message>
@@ -1319,14 +1578,6 @@ Please pick another nickname:</source>
<translation>Ðоказване на алÑеÑнаÑивен Ñежим на ÑеÑиÑе</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>ÐклÑÑване на мÑзикаÑа</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>ÐÑлен екÑан</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Ðобави даÑа и ÑÐ°Ñ ÐºÑм имеÑо на запиÑаноÑо демо</translation>
</message>
@@ -1335,45 +1586,57 @@ Please pick another nickname:</source>
<translation>Ðоказване на подÑказки за боепÑипаÑиÑе</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>ÐклÑÑване на звÑÑи</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>ÐклÑÑване на мÑзика</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>ÐÑекÑи</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>СлÑÑайна каÑÑа...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Човек</translation>
</message>
@@ -1386,14 +1649,6 @@ Please pick another nickname:</source>
<translation>(СÑандаÑÑно за ÑиÑÑемаÑа)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>генеÑиÑан лабиÑинÑ...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>ÐиÑиÑ</translation>
- </message>
- <message>
<source>Community</source>
<translation>ÐбÑноÑÑ</translation>
</message>
@@ -1403,15 +1658,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>Рлоби</translation>
+ <translation type="obsolete">Рлоби</translation>
</message>
<message>
<source>In progress</source>
- <translation>РпÑогÑеÑ</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>Ð ÑÑно наÑиÑÑвана каÑÑа...</translation>
+ <translation type="obsolete">РпÑогÑеÑ</translation>
</message>
<message>
<source>Disabled</source>
@@ -1450,10 +1701,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1497,48 +1744,16 @@ Please pick another nickname:</source>
<translation>ФоÑÑ</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>ÐлавиÑи</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>ÐÑбоÑи</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>ÐаÑÑÑойки на ÐвÑк/ÐÑаÑика</translation>
- </message>
- <message>
- <source>Playing teams</source>
- <translation>ÐгÑаеÑи оÑбоÑи</translation>
- </message>
- <message>
- <source>Net game</source>
- <translation>ÐÑежова игÑа</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>ÐаÑÑÑойки на оÑбоÑиÑе</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Разни</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>СÑ
еми и оÑÑжиÑ</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <source>Playing teams</source>
+ <translation>ÐгÑаеÑи оÑбоÑи</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Net game</source>
+ <translation>ÐÑежова игÑа</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>ÐаÑÑÑойки на оÑбоÑиÑе</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,18 +1763,10 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Game scheme</source>
- <translation>ÐгÑови ÑÑ
еми</translation>
- </message>
- <message>
<source>Damage Modifier</source>
<translation>ÐодиÑикаÑÐ¾Ñ Ð½Ð° ÑеÑиÑе</translation>
</message>
@@ -1600,22 +1807,6 @@ Please pick another nickname:</source>
<translation>ÐгÑаниÑение на бÑой кадÑи за ÑекÑнда</translation>
</message>
<message>
- <source>Developers:</source>
- <translation>РазÑабоÑÑиÑи:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>ÐÑаÑика:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>ÐÑеводи:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>СпеÑиални благодаÑноÑÑи на:</translation>
- </message>
- <message>
<source>Server name:</source>
<translation>Ðме на ÑÑÑвÑÑа:</translation>
</message>
@@ -1637,11 +1828,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>ÐеÑÑиÑ</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>ÐвÑÑи:</translation>
+ <translation type="obsolete">ÐеÑÑиÑ</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1684,10 +1871,6 @@ Please pick another nickname:</source>
<translation>СÑвеÑ:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation>ÐаÑеÑÑво</translation>
</message>
@@ -1728,10 +1911,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1762,10 +1941,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1793,6 +1968,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">ÐÑлен екÑан</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1815,6 +2034,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>ТаÑалежови войни %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1831,10 +2054,6 @@ Do you really want to quit?</source>
<translation>ФайловаÑа аÑоÑиаÑÐ¸Ñ Ñе пÑовали.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1881,47 +2100,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Ðе може да Ñе ÑÑздаде папка %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ðе може да Ñе ÑÑздаде папка %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">ÐÑеÑка пÑи ÑÑаÑÑиÑане на ÑÑÑвÑÑа: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ÐÑеÑка пÑи ÑÑаÑÑиÑане на ÑÑÑвÑÑа: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2040,25 +2224,47 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>ÐÑÑкоÑ</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ÐÐ¾Ð»Ñ Ð²ÑведеÑе пÑÑкоÑÑÑ Ñи</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <source>Setup</source>
- <translation>ÐаÑÑÑойки</translation>
- </message>
- <message>
<source>Play demo</source>
<translation>ÐÑÑкане на демо</translation>
</message>
@@ -2111,22 +2317,10 @@ Do you still want to join the room?</source>
<translation>ÐзÑÑиване</translation>
</message>
<message>
- <source>Ready</source>
- <translation>ÐоÑово</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>СлÑÑаен оÑбоÑ</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>ÐÑоÑииÑане на Ñайлови ÑазÑиÑениÑ</translation>
</message>
<message>
- <source>more</source>
- <translation>повеÑе</translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2150,6 +2344,61 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2199,6 +2448,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2226,105 +2494,43 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Fort Mode</source>
- <translation>Режим на ÑоÑÑове</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>РазделÑне на оÑбоÑиÑе</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>ТвÑÑда земÑ</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Ðобави гÑаниÑна ивиÑа</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>ÐиÑка гÑавиÑаÑиÑ</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>ÐазеÑен меÑник</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>ÐеÑÑзвимоÑÑ</translation>
- </message>
- <message>
- <source>Vampirism</source>
- <translation>ÐампиÑизÑм</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>ÐаÑма</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>ÐÑÑилеÑиÑ</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>ÐÑоизволен Ñед</translation>
- </message>
- <message>
- <source>King</source>
- <translation>ÐÑал</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>ÐоÑÑавÑне на ÑаÑалежи</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>ÐланÑÑ ÑÐ¿Ð¾Ð´ÐµÐ»Ñ Ð¾ÑÑжиÑÑа</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>ÐзкбÑÑване на гÑеди</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>ÐзклÑÑване на обекÑи по земÑÑа</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Режим ÐРоÑелÑване</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>ÐзÑиÑÑване на здÑанеÑо</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>ÐеогÑаниÑени аÑаки</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>ÐзÑиÑÑване на оÑÑжиÑÑа</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>ÐоепÑипаÑи за вÑеки ÑаÑалеж пооÑделно</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>ÐзклÑÑване на вÑÑÑÑа</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>ÐÑе вÑÑÑÑ</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">ÐÑказ</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2447,12 +2653,6 @@ Do you still want to join the room?</source>
<translation>Ð¡Ð»Ð¾Ñ 9</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>ÐнÑоÑмаÑиÑ
-за игÑаÑа</translation>
- </message>
- <message>
<source>chat</source>
<translation>ЧаÑ</translation>
</message>
@@ -2500,33 +2700,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>ÐÑновни конÑÑоли</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>ÐонÑÑоли за оÑÑжиÑÑа</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ÐÑÑжиÑ</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>ÐонÑÑоли за камеÑаÑа и показалеÑа</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>ÐÑÑго</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>ÐÑемеÑÑеÑе ÑаÑалежиÑе Ñи и Ñе пÑиÑелеÑе:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>ÐÑеодолÑвайÑе пÑазнини и пÑепÑÑÑÑÐ²Ð¸Ñ ÑÑез ÑкаÑане:</translation>
</message>
@@ -2590,6 +2790,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_cs.ts b/share/hedgewars/Data/Locale/hedgewars_cs.ts
index fb3ef4b..cc06fa6 100644
--- a/share/hedgewars/Data/Locale/hedgewars_cs.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_cs.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="cs">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,11 +141,73 @@
<translation>Editovat schémata</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Pokud je tato volba aktivována, výbÄr hernÃho schématu vybere automaticky i zbraÅové schéma</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Nemohu vytvoÅit adresáŠ%1</translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -103,7 +261,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -140,20 +306,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Tvoje pÅezdÃvka %1 je
-registrovaná na Hedgewars.org
-ProsÃm, zadej své heslo
-nebo si v konfiguraci vyber jinou pÅezdÃvku:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">PÅezdÃvka</translation>
</message>
@@ -166,6 +318,63 @@ nebo si v konfiguraci vyber jinou pÅezdÃvku:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -181,18 +390,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Témata</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtr</translation>
- </message>
- <message>
<source>All</source>
<translation>VÅ¡e</translation>
</message>
@@ -217,10 +414,6 @@ Please pick another nickname:</source>
<translation>Å Ãlená</translation>
</message>
<message>
- <source>Type</source>
- <translation>Typ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Malé tunely</translation>
</message>
@@ -229,28 +422,96 @@ Please pick another nickname:</source>
<translation>StÅednà tunely</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Velké tunely</translation>
+ <source>Seed</source>
+ <translation>SemÃnko</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Malé plovoucà ostrovy</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>StÅednà plovoucà ostrovy</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Velké plovoucà ostrovy</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>SemÃnko</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Náhodné</translation>
</message>
<message>
- <source>Set</source>
- <translation>Sada</translation>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Nahrát nakreslenou mapu</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -296,7 +557,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 se pÅipojil</translation>
+ <translation type="obsolete">%1 *** %2 se pÅipojil</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -322,8 +583,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Heslo</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -338,6 +614,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -345,7 +643,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -363,6 +668,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -394,6 +710,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Nastavit data</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Obecné</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -403,6 +751,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -448,8 +807,40 @@ Please pick another nickname:</source>
<translation>Obecné</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>RozÅ¡ÃÅené</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">KlobouÄek</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Jméno</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Náhodný tým</translation>
</message>
</context>
<context>
@@ -506,322 +897,97 @@ Please pick another nickname:</source>
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation>
<numerusform><b>%1</b> zabil <b>%2</b> vlastnÃho ježka.</numerusform>
- <numerusform><b>%1</b> zabil <b>%2</b> vlastnà ježky.</numerusform>
- <numerusform><b>%1</b> zabil <b>%2</b> vlastnÃch ježků.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
- <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
- <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>JednoduÅ¡e zvol stejnou barvu jako spoluhráÄ, abys hrál ve stejném týmu. Každý z vás bude mÃt kontrolu nad svými vlastnÃmi ježky, ale vyhraje nebo prohraje spoleÄnÄ.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>NÄkteré zbranÄ mohou způsobovat jen malé poÅ¡kozenÃ, ale mohou být devastujÃcà v pravé chvÃli. Zkus použÃt pistoli Desert Eagle ke sraženà nÄkolika nepÅátelských ježků do vody.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Pokud si nejsi jistý, co dÄlat a nechceÅ¡ plýtvat municÃ, pÅeskoÄ tah. Ale nenech ubÄhnout moc Äasu, protože pak pÅijde Náhlá smrt!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Pokud chceÅ¡ zabránit ostatnÃm, aby použÃvali tvoji oblÃbenou pÅezdÃvku na oficiálnÃm serveru, zaregistruj se na http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Jsi znudÄn standardnà hrou? VyzkouÅ¡ej nÄkterou misi - nabÃdnou jiný hernà zážitek v závislosti na tom, kterou si vybereÅ¡.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>StandardnÄ hra vždycky nahrává poslednà odehraný zápas jako ukázku. Vyber si 'MÃstnà hru' a zvol tlaÄÃtko 'Ukázky' v pravém spodnÃm rohu k jejich pÅehrávánà a správÄ.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, který jsme vytvoÅili v naÅ¡em volném Äase. Pokud máš problémy, zeptej se na naÅ¡em fóru, ale neoÄekávej prosÃm nonstop podporu!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, který jsme vytvoÅili v naÅ¡em volném Äase. Pokud se ti lÃbÃ, pomož nám malým pÅÃspÄvkem, nebo se podÃlej na práci!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, který jsme vytvoÅili v naÅ¡em volném Äase. SdÃlej ho se svoji rodinou a pÅáteli dle libosti!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Äas od Äasu se konajà oficiálnà turnaje. NadcházejÃcà události budou publikovány na http://www.hedgewars.org/ s nÄkolika dennÃm pÅedstihem.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je k dispozici v mnoha jazycÃch. Pokud pÅeklad do tvého jazyka vypadá zastaralý nebo chybÃ, neváhej nás kontaktovat!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars může být spuÅ¡tÄno na mnoha různých operaÄnÃch systémech vÄetnÄ Microsoft Windows, Mac OS X a Linuxu.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Vždycky si pamatuj, že můžeÅ¡ vytvoÅit vlastnà hru na mÃstnà sÃti i internetu. Nejsi odkázán jen na možnost 'Prostá hra'.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>BÄhem hranà bys mÄl dÄlat krátké pÅestávky alespoÅ jednou za hodinu.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Pokud tvoje grafická karta nepodporuje hardwarovou akceleraci OpenGL, zkus zapnout nÃzkou kvalitu pro zlepÅ¡enà výkonu.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Jsme otevÅeni návrhům a konstruktivnà kritice. Pokud se ti nÄco nelÃbÃ, nebo máš skvÄlý nápad, dej nám vÄdÄt!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>ObzvláštÄ pÅi hÅe online buÄ sluÅ¡ný a vždy pamatuj na to, že s tebou nebo proti tobÄ může hrát nÄkdo z nÄjaké menÅ¡iny!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Speciálnà hernà módy jako tÅeba 'Vampyrismus' nebo 'Karma' ti dovolujà vymýšlet úplnÄ jiné hernà taktiky. VyzkouÅ¡ej je v nÄjaké hÅe!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Nikdy bys nemÄl instalovat Hedgewars na poÄÃtaÄi, který ti nepatÅà (Å¡kola, univerzita, práce a jiné). ProsÃm, zeptej se nejprve zodpovÄdné osoby!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars mohou být perfektnà pro krátkou hru bÄhem pauzy. Jen se ujisti, že jsi nepÅidal pÅÃliÅ¡ mnoho ježků nebo nezvolil velkou mapu. ZmenÅ¡it Äas nebo zdravà také urychlà hru.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Žádný ježek nebyl zranÄn bÄhem vytváÅenà této hry.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, který jsme vytvoÅili v naÅ¡em volném Äase. Pokud ti tuto hru nÄkdo prodal, mÄl bys chtÃt vrátit penÃze!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>PÅipojenim jednoho nebo vÃce gamepadů pÅed zaÄátkem hry ti umožnà nastavit je jako ovladaÄ pro tvé týmy.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>VytvoÅ si úÄet na %1, abys zabránil ostatnÃm použÃvat tvoji oblÃbenou pÅezdÃvku na oficiálnÃm serveru.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Pokud tvoje grafická karta nepodporuje hardwarovou akceleraci OpenGL, zkus aktualizovat ovladaÄe.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished">K dispozici jsou tÅi různé druhy skoků. ZmáÄkni [Vysoký skok] dvakrát, abys udÄlal skok do vÄtÅ¡Ã výšky a dozadu.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished">BojÃÅ¡ se pádu z útesu? Stiskni [pÅesnost], aby ses otoÄil [vlevo], Äi [vpravo] bez jakéhokoliv pohybu.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>NÄkteré zbranÄ vyžadujà speciálnà strategii, nebo jen spoustu cviÄenÃ. Nezavrhuj hned nÄkterou zbraÅ, pokud jednou mineÅ¡ cÃl.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>VÄtÅ¡ina zbranà nefunguje, jakmile se ponoÅà do vody. NavádÄná vÄela nebo dort jsou vyjÃmka z tohoto pravidla.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Olomoucké tvarůžky vybuchujà jen málo, ale vÃtr ovlivÅuje oblak smradu, který může nakazit mnoho ježků najednou.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Ãtok pianem je nejniÄivÄjÅ¡Ã letecký útok. Na druhé stranÄ ale ztratÃÅ¡ ježka, který tento útok vykoná.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>PÅisavné miny jsou perfektnà nástroj na vytváÅenà malých ÅetÄzových reakcÃ, které mohou nepÅátelské ježky dostat do divokých situacà ... nebo vody.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Kladivo je nejefektivnÄjÅ¡Ã pÅi použitÇ na mostech a traverzách. Zasažený ježek prostÄ prorazà skrz zem.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Pokud jsi zaseklý za nepÅátelským ježkem, použij kladivo, aby ses osvobodil a nemusel riskovat zranÄnà z exploze.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Maximálnà vzdálenost, do které dort dojde, je ovlivnÄna terénem, kterým musà jÃt. Použij [útok] k dÅÃvÄjÅ¡Ã explozi.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Plamenomet je zbraÅ, ale dá se použÃt i pro kopánà tunelů.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>ChceÅ¡ vÄdÄt, kdo stojà za touto hrou? Klikni na logo Hedgewars v hlavnÃm menu a podÃvej se.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>LÃbà se ti Hedgewars? StaÅ se fanouÅ¡kem na %1 nebo nás sleduj na %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Neboj se kreslit vlastnà hroby, Äepice, vlajky nebo mapy a témata! Ale pamatuj, že je musÃÅ¡ nÄkde sdÃlet, abys je mohl použÃvat online.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Opravdu chceÅ¡ nosit specifickou Äepici? Daruj nám nÄco a dostaneÅ¡ exklusivnà Äepici dle svého výbÄru!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Udržuj ovladaÄe grafické karty aktuálnÃ, aby ses vyhnul problémům pÅi hÅe.</translation>
+ <numerusform><b>%1</b> zabil <b>%2</b> vlastnà ježky.</numerusform>
+ <numerusform><b>%1</b> zabil <b>%2</b> vlastnÃch ježků.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Své nastavenà Hedgewars najdeÅ¡ v "Dokumenty\Hedgewars". VytvoÅ si zálohu nebo si je pÅenášej s sebou, ale needituj je ruÄnÄ.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
+ <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
+ <numerusform><b>%1</b> byl vystraÅ¡ený a pÅeskoÄil tah <b>%2</b> krát.</numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>MůžeÅ¡ si asociovat Hedgewars soubory (uložené hry a nahrávky) tak, abys je mohl ihned spouÅ¡tÄt z internetového prohlÞeÄe nebo prúzkumnÃka souborů.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>ChceÅ¡ uÅ¡etÅit lana? Uvolni ho ve vzduchu a vystÅel znovu. Dokud se nedotkneÅ¡ zemÄ, využÃváš ho bez plýtvánà munice!</translation>
+ <source>Save</source>
+ <translation type="unfinished">Uložit</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Konfigurace Hedgewars je k nalezenà ve tvém domovském adresáÅi pod "Library/Application Support/Hedgewars". VytvoÅ si zálohu, pÅenášej ho s sebou, ale nemÄÅ ho ruÄnÄ.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Konfigurace Hedgewars je k nalezenà ve tvém domovském adresáÅi pod ".hedgewars". VytvoÅ si zálohu, pÅenášej ho s sebou, ale nemÄÅ ho ruÄnÄ.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Windows verze Hedgewars podporuje Xfire. PÅidej si Hedgewars do jeho seznamu her, abys vidÄl pÅátele, kteÅà ho hrajÃ.</translation>
+ <source>Downloadable Content</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Použij Molotov nebo plamenomet, abys doÄasnÄ zamezil ježkům v pÅechodu terénu jako jsou tunely nebo ploÅ¡iny.</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -831,38 +997,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Start</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>OvládánÃ</translation>
+ <translation type="obsolete">OvládánÃ</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Hra po mÃstnà sÃti</translation>
+ <source>Update</source>
+ <translation type="unfinished">Obnovit</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Oficiálnà server</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -909,10 +1079,6 @@ Please pick another nickname:</source>
<translation>Smazat sadu zbranÃ</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Obecné</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">RozÅ¡ÃÅené</translation>
</message>
@@ -952,6 +1118,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Týmy</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">ZbranÄ</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -968,11 +1222,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>VytvoÅit</translation>
+ <translation type="obsolete">VytvoÅit</translation>
</message>
<message>
<source>Join</source>
- <translation>PÅipojit se</translation>
+ <translation type="obsolete">PÅipojit se</translation>
</message>
<message>
<source>Admin features</source>
@@ -980,7 +1234,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Jméno mÃstnosti:</translation>
+ <translation type="obsolete">Jméno mÃstnosti:</translation>
</message>
<message>
<source>Rules:</source>
@@ -992,11 +1246,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Hledej:</translation>
+ <translation type="obsolete">Hledej:</translation>
</message>
<message>
<source>Clear</source>
- <translation>VyÄisti</translation>
+ <translation type="obsolete">VyÄisti</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1006,6 +1260,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1152,18 +1430,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1172,26 +1442,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Nahrát</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1238,19 +1496,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1265,10 +1525,6 @@ Please pick another nickname:</source>
<translation>Info</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Omezit pÅipojenÃ</translation>
</message>
@@ -1302,7 +1558,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Obnovit</translation>
+ <translation type="obsolete">Obnovit</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1316,18 +1584,6 @@ Please pick another nickname:</source>
<translation>Celá obrazovka</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Celá obrazovka v menu</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Zapnout zvuky</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Zapnout hudbu</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Zobrazovat FPS</translation>
</message>
@@ -1344,45 +1600,57 @@ Please pick another nickname:</source>
<translation>Ukazovat tipy ke zbranÃm</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Zapnout zvuky v menu</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Zapnout hudbu v menu</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Efekty v menu</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>generovaná mapa...</translation>
- </message>
- <message>
<source>Human</source>
<translation>ÄlovÄk</translation>
</message>
@@ -1395,14 +1663,6 @@ Please pick another nickname:</source>
<translation>(Podle systému)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>generovaný labyrint...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Mise</translation>
- </message>
- <message>
<source>Community</source>
<translation>Komunita</translation>
</message>
@@ -1412,15 +1672,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>V ÄekárnÄ</translation>
+ <translation type="obsolete">V ÄekárnÄ</translation>
</message>
<message>
<source>In progress</source>
- <translation>ProbÃhá</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>ruÄnÄ kreslená mapa...</translation>
+ <translation type="obsolete">ProbÃhá</translation>
</message>
<message>
<source>Disabled</source>
@@ -1459,10 +1715,6 @@ Please pick another nickname:</source>
<translation type="unfinished">Shora-Dolu</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished">Kývat se</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1498,18 +1750,6 @@ Please pick another nickname:</source>
<translation>Pevnost</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Nastavenà kláves</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Týmy</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Nastavenà audio/video</translation>
- </message>
- <message>
<source>Net game</source>
<translation>SÃÅ¥ová hra</translation>
</message>
@@ -1517,37 +1757,17 @@ Please pick another nickname:</source>
<source>Playing teams</source>
<translation>HrajÃcà týmy</translation>
</message>
- <message>
- <source>Game Modifiers</source>
- <translation>Hernà modifikátory</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Základnà nastavenÃ</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Týmová nastavenÃ</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>OstatnÃ</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Schémata a zbranÄ</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <message>
+ <source>Game Modifiers</source>
+ <translation>Hernà modifikátory</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Základnà nastavenÃ</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Týmová nastavenÃ</translation>
</message>
<message>
<source>Videos</source>
@@ -1557,36 +1777,12 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
<source>Version</source>
- <translation>Verze</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>VývojáÅi:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafika:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Zvuky:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>PÅeklady:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Speciálnà podÄkovánÃ:</translation>
+ <translation type="obsolete">Verze</translation>
</message>
<message>
<source>Weapons</source>
@@ -1653,10 +1849,6 @@ Please pick another nickname:</source>
<translation>Shazovánà beden</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Hernà schéma</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% falešných min</translation>
</message>
@@ -1693,10 +1885,6 @@ Please pick another nickname:</source>
<translation>Tip: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Tato vývojová verze je 'v průbÄhu práce' a může být kompatibilnà s jinými verzemi hry. NÄkteré možnosti mohou být rozbité nebo nekompletnÃ. PoužÃvej na vlastnà riziko!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Kvalita</translation>
</message>
@@ -1737,10 +1925,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1771,10 +1955,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1802,6 +1982,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Celá obrazovka</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1824,6 +2048,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1840,10 +2068,6 @@ Do you really want to quit?</source>
<translation>Asociace souborů selhala.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1890,47 +2114,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Nemohu vytvoÅit adresáŠ%1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nemohu vytvoÅit adresáŠ%1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Nemohu spustit server: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nemohu spustit server: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2050,16 +2239,42 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>PÅezdÃvka</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ProsÃm zadej svou pÅezdÃvku</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2097,10 +2312,6 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
<translation>Start</translation>
</message>
<message>
- <source>Ready</source>
- <translation>PÅipraven</translation>
- </message>
- <message>
<source>Go!</source>
<translation>Jedem!</translation>
</message>
@@ -2121,22 +2332,10 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
<translation>Nahrát</translation>
</message>
<message>
- <source>Setup</source>
- <translation>NastavenÃ</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Náhodný tým</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Asociovat pÅÃpony souborů</translation>
</message>
<message>
- <source>more</source>
- <translation>vÃce</translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2160,6 +2359,61 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2209,6 +2463,25 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2236,105 +2509,43 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampyrismus</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>DÄlostÅelectvo</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Pevnosti</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>RozdÄl týmy</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Pevná zem</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>PÅidej hranice</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>NÃzká gravitace</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Laserové zamÄÅovánÃ</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Nesmrtelnost</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Náhodné poÅadÃ</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Král</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>UmÃsti ježky</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Klan sdÃlà munici</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Vypni traverzy</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Vypni terénà objekty</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation type="unfinished">Mód 'PoÄÃtaÄ pÅežÃvá'</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>Obnova zdravÃ</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>NeomezenÄ Ãºtoků</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Obnova zbranÃ</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Individuálnà munice</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Vypni vÃtr</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>VÃce vÄtru</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušit</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2469,11 +2680,6 @@ JeÅ¡tÄ stále se chceÅ¡ pÅipojit do mÃstosti?</translation>
<translation>sejmout</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>info o ježkovi</translation>
- </message>
- <message>
<source>quit</source>
<translation>ukonÄit</translation>
</message>
@@ -2509,33 +2715,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Základnà ovládánÃ</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Ovládánà zbranÃ</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ZbranÄ</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Ovládánà kamery a kurzoru</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>OstatnÃ</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Pohybuj ježkem a miÅ:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>PÅekonej mezery a pÅekážky skokem:</translation>
</message>
@@ -2599,6 +2805,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_da.ts b/share/hedgewars/Data/Locale/hedgewars_da.ts
index 01dda1c..50b9101 100644
--- a/share/hedgewars/Data/Locale/hedgewars_da.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_da.ts
@@ -2,6 +2,20 @@
<!DOCTYPE TS>
<TS version="2.0" language="da">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AbstractPage</name>
+ <message>
+ <source>Go back</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AmmoSchemeModel</name>
<message>
<source>new</source>
@@ -13,18 +27,92 @@
</message>
</context>
<context>
- <name>DrawMapWidget</name>
+ <name>BanDialog</name>
<message>
- <source>File error</source>
- <translation>Fejl i fil</translation>
+ <source>IP</source>
+ <translation type="unfinished">Ip</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot open file '%1' for writing</source>
- <translation>Kan ikke åbne filen '%1' til skrivning</translation>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot read file '%1'</source>
- <translation>Kan ikke læse filen '%1'</translation>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -48,44 +136,88 @@
<translation>Rediger våben</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Edit schemes</source>
+ <translation>Rediger spilsystemer</translation>
</message>
<message>
- <source>Illegal ammo scheme</source>
- <translation>Ugyldig ammunitionssystem</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Spilindstillinger</translation>
</message>
<message>
- <source>Edit schemes</source>
- <translation>Rediger spilsystemer</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Når denne indstilling er aktiveret vælges automatisk et våben når et spilsystem vælges</translation>
+ <source>Map</source>
+ <translation type="unfinished">Bane</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Spilindstillinger</translation>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>HWChatWidget</name>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>%1 *** %2 has been removed from your ignore list</source>
- <translation>%1 *** %2 er blevet fjernet fra din ignoreringsliste</translation>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has been added to your ignore list</source>
- <translation>%1 *** %2 er blevet tilføjet til din ignoreringsliste</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Kan ikke oprette mappe %1</translation>
</message>
<message>
- <source>%1 *** %2 has been removed from your friends list</source>
- <translation>%1 *** %2 er blevet fjernet fra din venneliste</translation>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWAskQuitDialog</name>
<message>
- <source>%1 *** %2 has been added to your friends list</source>
- <translation>%1 *** %2 er blevet tilføjet til din venneliste</translation>
+ <source>Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWChatWidget</name>
<message>
<source>%1 has been removed from your ignore list</source>
<translation>%1 er blevet fjernet fra din ignoreringsliste</translation>
@@ -127,41 +259,25 @@
<translation>Mislykkedes at gemme typografiark til %1</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 er ikke en gyldig kommando!</translation>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Kicking %1 ...</source>
- <translation>Smider %1 ud...</translation>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HWForm</name>
<message>
- <source>new</source>
- <translation>ny</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>OK</translation>
- </message>
- <message>
- <source>Unable to start the server</source>
- <translation>Ude af stand til at starte serveren</translation>
- </message>
- <message>
<source>Cannot save record to file %1</source>
<translation>Kan ikke gemme optagelse til fil %1</translation>
</message>
<message>
- <source>Please select record from the list above</source>
- <translation>Vælg venligst en optagelse fra den ovenstående liste</translation>
- </message>
- <message>
<source>DefaultTeam</source>
<translation>StandardHold</translation>
</message>
@@ -188,40 +304,74 @@
<translation>Spil afbrudt</translation>
</message>
<message>
- <source>Password</source>
- <translation>Kodeord</translation>
+ <source>Nickname</source>
+ <translation>Brugernavn</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>Dit brugernavn %1 er
-registreret på Hedgewars.org
-Indtast venligst dit kodeord nedenfor
-eller vælg et andet brugernavn under spilkonfigurationen:</translation>
+ <source>No nickname supplied.</source>
+ <translation>Intet brugernavn indtastet.</translation>
</message>
<message>
- <source>No password supplied.</source>
- <translation>Intet kodeord indtastet.</translation>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation>Brugernavn</translation>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Some one already uses
- your nickname %1
-on the server.
-Please pick another nickname:</source>
- <translation>En eller anden bruger allerede
-dit brugernavn %1
-på serveren.
-Vælg venligst et andet brugernavn:</translation>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
- <translation>Intet brugernavn indtastet.</translation>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -238,18 +388,6 @@ Vælg venligst et andet brugernavn:</translation>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Bane</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temaer</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>Alle</translation>
</message>
@@ -274,10 +412,6 @@ Vælg venligst et andet brugernavn:</translation>
<translation>Skør</translation>
</message>
<message>
- <source>Type</source>
- <translation>Type</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Små tunneler</translation>
</message>
@@ -286,28 +420,96 @@ Vælg venligst et andet brugernavn:</translation>
<translation>Mellemstore tunneler</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Store tunneler</translation>
+ <source>Seed</source>
+ <translation>Spire</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Små svævende øer</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Mellemstore svævende øer</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Store svævende øer</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>Spire</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Tilfældig</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
- <translation>Indstil</translation>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Indlæs tegnet bane</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished">Tegnede Baner</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished">Alle filer</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -348,26 +550,12 @@ Vælg venligst et andet brugernavn:</translation>
<translation>Du blev smidt ud</translation>
</message>
<message>
- <source>Password</source>
- <translation>Kodeord</translation>
- </message>
- <message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</source>
- <translation type="obsolete">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</translation>
- </message>
- <message>
<source>%1 *** %2 has joined the room</source>
<translation>%1 *** %2 har tilsluttet sig til rummet</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 har tilsluttet sig</translation>
+ <translation type="obsolete">%1 *** %2 har tilsluttet sig</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -378,22 +566,71 @@ or pick another nickname:</translation>
<translation>%1 *** %2 har forladt</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="obsolete">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</translation>
+ <source>User quit</source>
+ <translation>En bruger forlod</translation>
</message>
<message>
- <source>Nickname</source>
- <translation>Brugernavn</translation>
+ <source>Remote host has closed connection</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>User quit</source>
- <translation>En bruger forlod</translation>
+ <source>The server is too old. Disconnecting now.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWPasswordDialog</name>
+ <message>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWUploadVideoDialog</name>
+ <message>
+ <source>Upload video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -404,16 +641,46 @@ or pick another nickname in game config:</translation>
</message>
</context>
<context>
- <name>PageAdmin</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <source>Duration: %1m %2s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video: %1x%2, </source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <source>Server message:</source>
- <translation>Serverbesked:</translation>
+ <source>%1 fps, </source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set message</source>
- <translation>Indstil besked</translation>
+ <source>Audio: </source>
+ <translation type="unfinished"></translation>
</message>
<message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageAdmin</name>
+ <message>
<source>Clear Accounts Cache</source>
<translation>Ryd Bruger-cache</translation>
</message>
@@ -441,6 +708,38 @@ or pick another nickname in game config:</translation>
<source>Set data</source>
<translation>Indstil data</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Generelt</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished">Opdater</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -448,9 +747,16 @@ or pick another nickname in game config:</translation>
<source>Connecting...</source>
<translation>Opretter forbindelse...</translation>
</message>
+</context>
+<context>
+ <name>PageDataDownload</name>
<message>
- <source>Cancel</source>
- <translation>Annuler</translation>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -487,6 +793,10 @@ or pick another nickname in game config:</translation>
<source>All files</source>
<translation>Alle filer</translation>
</message>
+ <message>
+ <source>Eraser</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageEditTeam</name>
@@ -495,31 +805,45 @@ or pick another nickname in game config:</translation>
<translation>Generelt</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Advanceret</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageGameStats</name>
<message>
- <source><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></source>
- <translation><p>Prisen for det bedste skud gik til <b>%1</b> med <b>%2</b> point.</p></translation>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></source>
- <translation type="obsolete">
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kill in a turn.</p></numerusform>
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></numerusform>
- </translation>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>A total of <b>%1</b> hedgehog(s) were killed during this round.</p></source>
- <translation type="obsolete">
- <numerusform><p>A total of <b>%1</b> hedgehog was killed during this round.</p></numerusform>
- <numerusform><p>A total of <b>%1</b> hedgehogs were killed during this round.</p></numerusform>
- </translation>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Hat</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Navn</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Tilfældige Hold</translation>
+ </message>
+</context>
+<context>
+ <name>PageGameStats</name>
+ <message>
<source>Details</source>
<translation>Detaljer</translation>
</message>
@@ -565,284 +889,98 @@ or pick another nickname in game config:</translation>
</message>
<message numerus="yes">
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation>
- <numerusform><b>%1</b> dræbte <b>%2</b> af sine egne pindsvin.</numerusform>
- <numerusform><b>%1</b> dræbte <b>%2</b> af sine egne pindsvin.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> blev bange og sprang over sin tur <b>%2</b> gang.</numerusform>
- <numerusform><b>%1</b> blev bange og sprang over sin tur <b>%2</b> gange.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation>I spillet...</translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Local Game (Play a game on a single computer)</source>
- <translation>Lokalt spil (Spil et spil på én enkelt computer)</translation>
- </message>
- <message>
- <source>Network Game (Play a game across a network)</source>
- <translation>Netværksspil (Spil et spil over et netværk)</translation>
- </message>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Bare vælg samme farve som en ven for at spille sammen som et hold. Hver af jer vil stadig kontrollere sine egne pindsvin, men vil vinde eller tabe sammen.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Nogle våben giver måske ikke særlig meget skade, men de kan være meget mere farlige i de rigtige situationer. Prøv at bruge Desert Eagle-pistolen til at skubbe flere pindsvin i vandet.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Hvis du er usikker på hvad du skal gøre og ikke vil spilde ammunition, kan du springe en runde over. Men lad der ikke gå alt for meget tid, for ellers indtræffer Pludselig Død!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server, kan du registrere en bruger på http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Er du træt af den almindelige måde at spille på? Prøv en af missionerne - de tilbyder forskellige måder at spille på afhængigt af hvilken en du vælger.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Som standard optager spillet altid det sidste spil du har spillet som en demo. Tryk på 'Lokalt spil' og vælg 'Demoer'-knappen i nederste højre hjørne for at afspille eller administrere dem.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du har problemer er du velkommen til at spørge på forummet, men forvent ikke at få hjælp 24 timer i døgnet!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis du holder af det, kan du hjælpe os med en lille donation eller ved at indsende dine egne modifikationer!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Del det med dine venner og din familie som du ønsker!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Fra tid til anden er der officielle turneringer. Kommende begivenheder vil blive annonceret på http://www.hedgewars.org/ et par dage i forvejen.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars er tilgængeligt på mange sprog. Hvis oversættelsen på dit sprog mangler noget eller er uddateret, skal du være velkommen til at kontakte os!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars kan køre på mange forskellige operativsystemer, herunder Microsoft Windows, Mac OS X og Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Husk altid at du kan sætte dine egne spil op under lokale-, netværks- og online-spil. Du er ikke begrænset til kun at bruge 'Simpelt spil'-muligheden.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Mens du spiller bør du tage en kort pause mindst en gang i timen.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Hvis dit grafikkort ikke understøtter hardware-accelereret OpenGL, kan du prøve at slå indstillingen 'Reduceret kvalitet' til for at forbedre ydelsen.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Vi er åbne over for foreslag og konstruktive tilbagemeldinger. Fortæl os det hvis der er noget du ikke kan lide eller hvis du har en god idé!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Specielt når du spiller online bør du være venlig og altid huske at du måske også spiller med eller mod børn!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Specielle måder at spille på som f.eks. 'Varmpyr' eller 'Karma' tillader dig at udvikle helt nye taktikker. Prøv dem i et brugerdefineret spil!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Du bør aldrig installere Hedgewars på computere du ikke ejer (skole, universitet, arbejde,e.l.). Spørg venligst den ansvarlige person i stedet!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars er perfekt til korte spil under pauser. Bare par på du ikke tilføjer for mange pindsvin eller bruger en kæmpe bane. Det kan også hjælpe at reducere tid og liv.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Ingen pindsvin kom til skade under produktionen af dette spil.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars er Open Source og et gratis spil vi laver i vores fritid. Hvis nogen solgte dig spiller skal du bede om at få pengene tilbage!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Tilslut en eller flere gamepads før du starter spiller for at kunne tildele dem til dit hold.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Opret en bruger på %1 hvis du ikke vil have at andre anvender dit foretrukne brugernavn på den officielle server.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Hvis du ikke er i stand til at slå hardware-accelereret OpenGL til, bør du prøve at opdatere dine grafikkort-drivere.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Der er tre forskellige typer hop tilgængelige. Tryk hurtigt på [hight jump] to gange i træk for at lave et højt, baglæns hop.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Er du bange for at falde ned fra en skrænt? Hold [precise] nede for at vende dig mod [left] eller [right] uden at bevæge dig.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Nogle våben kræver specielle strategier eller bare masser af træning, så undlad ikke at bruge et bestemt våben bare fordi du rammer ved siden af én gang.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>De fleste våben virker ikke så snart de har rørt vandet. Den Målsøgende Bi og Kagen er de eneste undtagelser.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Gamle Ole laver kun en lille eksplosion. Til gengæld kan den stænkende sky den udsender føres rundt af vinden og ramme mange pindsvin på én gang.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Klaveranslaget er det luftvåben der giver allermest skade. Til gengæld mister du det pindsvin som bruger angrebet, så der er også en bagside af medaljen.</translation>
+ <translation>
+ <numerusform><b>%1</b> dræbte <b>%2</b> af sine egne pindsvin.</numerusform>
+ <numerusform><b>%1</b> dræbte <b>%2</b> af sine egne pindsvin.</numerusform>
+ </translation>
</message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Klæbrige Miner er det perfekte værktøj til at lave små kædereaktioner og smide pindsvin ud i faretruende situationer... eller bare direkte i vandet.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> blev bange og sprang over sin tur <b>%2</b> gang.</numerusform>
+ <numerusform><b>%1</b> blev bange og sprang over sin tur <b>%2</b> gange.</numerusform>
+ </translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Hammeren er mest effektiv når den bruges enten på broer eller bærebjælker. Sigter du mod pindsvin med den, laver du bare huller i jorden.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Hvis du sidder fast bag en af modstanderens pindsvin, kan du bruge Hammeren til at slå dig fri uden at tage skade under en eksplosion.</translation>
+ <source>Save</source>
+ <translation type="unfinished">Gem</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Kagen kan gå kortere eller længere, afhængig af hvad den skal over på vejen. Du kan brrug [attack] til at detonere den før den når sin destination.</translation>
+ <source>In game...</source>
+ <translation>I spillet...</translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Flammekasteren er et våben, men den kan også bruges til hurtigt at grave tunneler.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Vil du vide hvem der står bag spillet? Klik på Hedgewars-logoet i hovedmenuen for at se rulleteksterne.</translation>
+ <source>Downloadable Content</source>
+ <translation>Indhold der kan Downloades</translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Er du glad for Hedgewars? Bliv fan på %1 eller følge vores opdateringer på %2!</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Du skal være velkommen til at tegne dine egne gravsten, hatte, flag eller endda baner og temaer! Men læg mærke til at du bliver nød til at dele dem med andre hvis du vil spille med dem online.</translation>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Vil du virkelig gerne have en specifik hat? Send os en donation, så kvitterer vi med en eksklusiv hat efter eget valg!</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Hold dine grafikkortdrivere opdaterede for at undgå problemmer i spillet.</translation>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen "(Mine) Dokumenter\Hedgewars". Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+ <source>Access the user created content downloadable from our website</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Du kan indstille Hedgewars-filer (gemte spil og demooptagelser) til automatisk at åbne når du trykker på dem eller åbner dem i din internet-browser.</translation>
+ <source>Exit game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Vil du gerne spare på dine reb? Slip rebet midt i luften og skyd straks igen. Så længe du ikke rører jorden bruger du ikke noget ammunition!</translation>
+ <source>Manage videos recorded from game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen "Bibliotek/Application Support/Hedgewars" i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan finde konfigurationsfilerne til Hedgewars under mappen ".hedgewars" i din hjemmemappe. Opret gerne en back-up eller tag filerne med dig, men lad være med selv at ændre i dem.</translation>
+ <source>Play a game across a local area network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Windows-versionen af Hedgewars understøtter integrering med Xfire. Husk at tilføje Hedgewars til din liste med spil så dine venner kan se hvornår du spiller.</translation>
+ <source>Play a game on an official server</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Brug en Molotovcocktail eller Flammekasteren til midlertidigt at forhindre pindsvin i at passere et område, f.eks. en tunnel eller platform.</translation>
+ <source>Feedback</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>Den Målsøgende Bi kan være svær at bruge. Den vender lettere hvis den ikke flyver alt for hurtigt, så prøv at spare på kraften når du affyrer den.</translation>
+ <source>Play local network game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Indhold der kan Downloades</translation>
+ <source>Play official network game</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -851,46 +989,43 @@ or pick another nickname in game config:</translation>
<source>Start</source>
<translation>Start</translation>
</message>
-</context>
-<context>
- <name>PageNet</name>
- <message>
- <source>Error</source>
- <translation>Fejl</translation>
- </message>
<message>
- <source>Please select server from the list above</source>
- <translation>Vælg venligst en server fra den ovenstående liste</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Kontrol</translation>
+ <translation type="obsolete">Kontrol</translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter room name</source>
- <translation>Indtast venligst navnet på rummet</translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
<message>
- <source>OK</source>
- <translation>OK</translation>
+ <source>Update</source>
+ <translation type="unfinished">Opdater</translation>
+ </message>
+ <message>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageNetType</name>
+ <name>PageNetServer</name>
<message>
- <source>LAN game</source>
- <translation>Netværksspil</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
- <translation>Officiel server</translation>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -908,18 +1043,6 @@ or pick another nickname in game config:</translation>
<translation>Slet hold</translation>
</message>
<message>
- <source>New weapon scheme</source>
- <translation>Nyt våbensystem</translation>
- </message>
- <message>
- <source>Edit weapon scheme</source>
- <translation>Rediger våbensystem</translation>
- </message>
- <message>
- <source>Delete weapon scheme</source>
- <translation>Slet våbensystem</translation>
- </message>
- <message>
<source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation>Du kan ikke ændre på holdene fra holdvalgsskærmen. Gå tilbage til hovedmenuen for at tilføje, redigere og slette hold.</translation>
</message>
@@ -947,125 +1070,163 @@ or pick another nickname in game config:</translation>
<source>Delete weapon set</source>
<translation>Slet våbensæt</translation>
</message>
-</context>
-<context>
- <name>PagePlayDemo</name>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Advanced</source>
+ <translation type="unfinished">Advanceret</translation>
</message>
<message>
- <source>OK</source>
- <translation>OK</translation>
+ <source>Reset to default colors</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rename dialog</source>
- <translation>Dialogboks til omdøbelse</translation>
+ <source>Proxy host</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enter new file name:</source>
- <translation>Indtast nyt filnavn:</translation>
+ <source>Proxy port</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot rename to</source>
- <translation>Kan ikke omdøbe til</translation>
+ <source>Proxy login</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot delete file</source>
- <translation>Kan ikke slette fil</translation>
+ <source>Proxy password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please select record from the list</source>
- <translation>Vælg venligst en optagelse fra listen</translation>
+ <source>No proxy</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageRoomsList</name>
<message>
- <source>Create</source>
- <translation>Opret</translation>
+ <source>System proxy settings</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join</source>
- <translation>Tilslut</translation>
+ <source>Socks5 proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Refresh</source>
- <translation>Opdater</translation>
+ <source>HTTP proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation>OK</translation>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Admin features</source>
- <translation>Administratorfunktioner</translation>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Room Name:</source>
- <translation>Navn på Rum:</translation>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>This game is in lobby.
-You may join and start playing once the game starts.</source>
- <translation>Dette spil er i lobbyen.
-Du kan tilslutte dig og spille med når spillet starter.</translation>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>This game is in progress.
-You may join and spectate now but you'll have to wait for the game to end to start playing.</source>
- <translation>Dette spil er i gang.
-Du kan tilslutte dig og kigge med med det samme, men du må vente på at spillet slutter med selv at kunne spille med.</translation>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is the host. He may adjust settings and start the game.</source>
- <translation>%1 er værten. Han kan ændre indstillingerne og starte spillet.</translation>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
- <translation>Tilfældig Bane</translation>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Games may be played on precreated or randomized maps.</source>
- <translation>Man kan spille enten på allerede lavede eller tilfældigt genererede baner.</translation>
+ <source>Network</source>
+ <translation type="unfinished">Netværk</translation>
</message>
<message>
- <source>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</source>
- <translation>Spilsystemet definerer generelle indstillinger og præferencer, så som rundelængden, Pludselig Død og Vampyr.</translation>
+ <source>Teams</source>
+ <translation type="unfinished">Hold</translation>
</message>
<message>
- <source>The Weapon Scheme defines available weapons and their ammunition count.</source>
- <translation>Våbensystemet definere hvilke våben der er tilgængelige og hvor meget ammunition de har.</translation>
+ <source>Schemes</source>
+ <translation type="unfinished">Spilsystemer</translation>
</message>
- <message numerus="yes">
- <source>There are %1 clients connected to this room.</source>
- <translation>
- <numerusform>Der er %1 klient forbundet til dette rum.</numerusform>
- <numerusform>Der er %1 klienter forbundet til dette rum.</numerusform>
- </translation>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">VÃ¥ben</translation>
</message>
- <message numerus="yes">
- <source>There are %1 teams participating in this room.</source>
- <translation>
- <numerusform>Der deltager %1 hold i dette rum.</numerusform>
- <numerusform>Der deltager %1 hold i dette rum.</numerusform>
- </translation>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter room name</source>
- <translation>Indtast venligst rummets navn</translation>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please select room from the list</source>
- <translation>Vælg venligst et rum fra listen</translation>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
- <translation>Tilfældig Labyrint</translation>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PagePlayDemo</name>
+ <message>
+ <source>Rename dialog</source>
+ <translation>Dialogboks til omdøbelse</translation>
+ </message>
+ <message>
+ <source>Enter new file name:</source>
+ <translation>Indtast nyt filnavn:</translation>
+ </message>
+</context>
+<context>
+ <name>PageRoomsList</name>
+ <message>
+ <source>Create</source>
+ <translation type="obsolete">Opret</translation>
+ </message>
+ <message>
+ <source>Join</source>
+ <translation type="obsolete">Tilslut</translation>
+ </message>
+ <message>
+ <source>Admin features</source>
+ <translation>Administratorfunktioner</translation>
+ </message>
+ <message>
+ <source>Room Name:</source>
+ <translation type="obsolete">Navn på Rum:</translation>
</message>
<message>
<source>Rules:</source>
@@ -1077,21 +1238,11 @@ Du kan tilslutte dig og kigge med med det samme, men du må vente på at spillet
</message>
<message>
<source>Search:</source>
- <translation>Søg:</translation>
+ <translation type="obsolete">Søg:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Ryd</translation>
- </message>
- <message>
- <source>Warning</source>
- <translation>Advarsel</translation>
- </message>
- <message>
- <source>The game you are trying to join has started.
-Do you still want to join the room?</source>
- <translation>Det spil du forsøge at tilslutte dig er allerede startet.
-Har du stadig lyst til at tilslutte dig rummet?</translation>
+ <translation type="obsolete">Ryd</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1100,6 +1251,30 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<numerusform>%1 spillere er online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1116,10 +1291,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Landmassen kan ikke ødelægges!</translation>
</message>
<message>
- <source>Add an indestructable border around the terrain</source>
- <translation>Tilføj en kant rundt om banen som ikke kan destrueres</translation>
- </message>
- <message>
<source>Lower gravity</source>
<translation>Svagere tyngdekraft</translation>
</message>
@@ -1132,10 +1303,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Alle pindsvin har deres eget personlige kraftfelt</translation>
</message>
<message>
- <source>Enable random mines</source>
- <translation>Aktiver tilfældige miner</translation>
- </message>
- <message>
<source>Gain 80% of the damage you do back in health</source>
<translation>FÃ¥ 80% af den skade du giver tilbage som liv</translation>
</message>
@@ -1254,28 +1421,28 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game (a quick game against the computer, settings are chosen for you)</source>
- <translation>Simpelt spil (et hurtigt spil mod computeren, hvor indstillingerne er valgt på forhånd)</translation>
+ <source>Play a quick game against the computer with random settings</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer (play a hotseat game against your friends, or AI teams)</source>
- <translation>Multiplayer (spil mod flere venner eller AI hold ved samme computer)</translation>
+ <source>Play a hotseat game against your friends, or AI teams</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode (Practice your skills in a range of training missions)</source>
- <translation>Træningsspil (Rafiner dine evner i en række forskellige træningsmissioner)</translation>
+ <source>Campaign Mode</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Demos (Watch recorded demos)</source>
- <translation>Demoer (Afspil optagede demoer)</translation>
+ <source>Practice your skills in a range of training missions</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Load (Load a previously saved game)</source>
- <translation>Indlæs (Indlæs et tidligere gemt spil)</translation>
+ <source>Watch recorded demos</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Campaign Mode (...)</source>
- <translation>Kampagnespil (...)</translation>
+ <source>Load a previously saved game</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1288,6 +1455,54 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<source>Select a mission!</source>
<translation>Vælg en mission!</translation>
</message>
+ <message>
+ <source>Pick the mission or training to play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start fighting</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageVideos</name>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Navn</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 bytes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>(in progress...)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>encoding</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1300,10 +1515,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Info</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Begræns tilslutninger</translation>
</message>
@@ -1337,7 +1548,19 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
</message>
<message>
<source>Update</source>
- <translation>Opdater</translation>
+ <translation type="obsolete">Opdater</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1351,18 +1574,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Fuldskærm</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Fullskærm (frontend)</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Aktiver lyd</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Aktiver musik</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Fremvis antal billeder vist per sekund</translation>
</message>
@@ -1375,33 +1586,61 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Tilføj dato og tidspunkt til filnavnet for optagelser</translation>
</message>
<message>
- <source>Reduced quality</source>
- <translation>Reduceret kvalitet</translation>
- </message>
- <message>
<source>Show ammo menu tooltips</source>
<translation>Vis værktøjstip i ammunitionsmenuer</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Aktiver lyd (frontend)</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Record audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use game resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Aktiver musik (frontend)</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Effekter (frontend)</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>genereret bane...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Menneske</translation>
</message>
@@ -1414,14 +1653,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>(Systemstandard)</translation>
</message>
<message>
- <source>Mission</source>
- <translation>Mission</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation>genereret labyrint...</translation>
- </message>
- <message>
<source>Community</source>
<translation>Fællesskab</translation>
</message>
@@ -1431,19 +1662,11 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
</message>
<message>
<source>In lobby</source>
- <translation>I lobbyen</translation>
+ <translation type="obsolete">I lobbyen</translation>
</message>
<message>
<source>In progress</source>
- <translation>I gang</translation>
- </message>
- <message>
- <source>Default</source>
- <translation>Standard</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>håndtegnet bane...</translation>
+ <translation type="obsolete">I gang</translation>
</message>
<message>
<source>Disabled</source>
@@ -1482,10 +1705,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Top-Bund</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Vrikke</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Rød/Cyan gråskala</translation>
</message>
@@ -1521,22 +1740,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Fort</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Tasteindstillinger</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Hold</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation>VÃ¥ben</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Lyd-/Grafikindstillinger</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Netspil</translation>
</message>
@@ -1557,12 +1760,12 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Holdindstillinger</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Diverse</translation>
+ <source>Videos</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Schemes and Weapons</source>
- <translation>Spilsystemer og VÃ¥ben</translation>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1577,31 +1780,7 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>This program is distributed under the GNU General Public License</source>
- <translation>Dette program distribueres under GNU General Public License</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Udviklere:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafik:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Lyde:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Oversættelser:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Særlig tak til:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Weapons</source>
@@ -1616,10 +1795,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Port:</translation>
</message>
<message>
- <source>Net nick</source>
- <translation>Brugernavn</translation>
- </message>
- <message>
<source>Resolution</source>
<translation>Opløsning</translation>
</message>
@@ -1664,10 +1839,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Antal Kasser</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Spilsystem</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Miner er Fusere</translation>
</message>
@@ -1696,10 +1867,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Lokalitet</translation>
</message>
<message>
- <source>Restart game to apply</source>
- <translation>Genstart spil for at anvende</translation>
- </message>
- <message>
<source>Explosives</source>
<translation>Eksplosiver</translation>
</message>
@@ -1708,10 +1875,6 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Tip:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Denne udviklerversion er under konstruktion og er ikke nødvendigvis kompatibel med andre versioner af spillet. Nogle funktioner er måske i stykker eller ukomplette. Brug er på eget ansvar!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Kvalitet</translation>
</message>
@@ -1748,16 +1911,114 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Spilsystem</translation>
</message>
<message>
- <source>Password</source>
- <translation>Kodeord</translation>
- </message>
- <message>
<source>% Get Away Time</source>
<translation>% Tid til at Løbe Væk</translation>
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>Dette program distribueres under GNU General Public License v2</translation>
+ <translation type="obsolete">Dette program distribueres under GNU General Public License v2</translation>
+ </message>
+ <message>
+ <source>There are videos that are currently being processed.
+Exiting now will abort them.
+Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account name (or email): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video title: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video description: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Tags (comma separated): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation type="unfinished">Brugernavn</translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Fuldskærm</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1770,6 +2031,10 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<source>hedgehog %1</source>
<translation>pindsvin %1</translation>
</message>
+ <message>
+ <source>anonymous</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMainWindow</name>
@@ -1777,14 +2042,14 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
<message>
- <source>Network</source>
- <translation>Netværk</translation>
- </message>
- <message>
<source>Connection to server is lost</source>
<translation>Forbindelse til serveren er gået tabt</translation>
</message>
@@ -1793,87 +2058,216 @@ Har du stadig lyst til at tilslutte dig rummet?</translation>
<translation>Fejl</translation>
</message>
<message>
- <source>Failed to open data directory:
-%1
-Please check your installation</source>
- <translation>Det mislykkedes at åbne data mappen:
-%1
-Tjek venligst om spillet er installeret korrekt</translation>
+ <source>File association failed.</source>
+ <translation>Filtilknytninger mislykkedes.</translation>
</message>
<message>
- <source>Weapons</source>
- <translation>VÃ¥ben</translation>
+ <source>Teams - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not edit default weapon set</source>
- <translation>Kan ikke ændre standardvåbensæt</translation>
+ <source>Do you really want to delete the team '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default weapon set</source>
- <translation>Kan ikke slette standardvåbensæt</translation>
+ <source>Cannot delete default scheme '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this weapon set?</source>
- <translation>Vil du virkelig slette dette våbensæt?</translation>
+ <source>Please select a record from the list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not overwrite default weapon set '%1'!</source>
- <translation>Kan ikke overskrive standardvåbensættet '%1'!</translation>
+ <source>Unable to start server</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>All file associations have been set.</source>
- <translation>Alle filtilknytninger er blevet indstillede.</translation>
+ <source>Hedgewars - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>File association failed.</source>
- <translation>Filtilknytninger mislykkedes.</translation>
+ <source>Hedgewars - Success</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Teams</source>
- <translation>Hold</translation>
+ <source>All file associations have been set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this team?</source>
- <translation>Vil du virkelig slette dette hold?</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="obsolete">Kan ikke oprette mappe %1</translation>
</message>
<message>
- <source>Schemes</source>
- <translation>Spilsystemer</translation>
+ <source>Unable to start the server: %1.</source>
+ <translation type="obsolete">Ude af stand til at starte serveren: %1.</translation>
</message>
<message>
- <source>Can not delete default scheme '%1'!</source>
- <translation>Kan ikke slette standardspilsystemet '%1'!</translation>
+ <source>Error while authenticating at google.com:
+</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this game scheme?</source>
- <translation>Vil du virkelig slette dette spilsystem?</translation>
+ <source>Login or password is incorrect</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default weapon set '%1'!</source>
- <translation>Kan ikke slette standardvåbensættet '%1'!</translation>
+ <source>Video upload - Error</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Error while sending metadata to youtube.com:
+</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot create directory %1</source>
- <translation>Kan ikke oprette mappe %1</translation>
+ <source>Netgame - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation>OK</translation>
+ <source>Please select a server from the list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation>Brugernavn</translation>
+ <source>Please enter room name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Record Play - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select record from the list</source>
+ <translation type="unfinished">Vælg venligst en optagelse fra listen</translation>
+ </message>
+ <message>
+ <source>Cannot rename to </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot delete file </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room Name - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select room from the list</source>
+ <translation type="unfinished">Vælg venligst et rum fra listen</translation>
+ </message>
+ <message>
+ <source>Room Name - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+ <translation type="unfinished">Det spil du forsøge at tilslutte dig er allerede startet.
+Har du stadig lyst til at tilslutte dig rummet?</translation>
+ </message>
+ <message>
+ <source>Schemes - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Schemes - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the game scheme '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Videos - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the video '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to remove %1 file(s)?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Do you really want to cancel uploading %1?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File error</source>
+ <translation type="unfinished">Fejl i fil</translation>
+ </message>
+ <message>
+ <source>Cannot open '%1' for writing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot open '%1' for reading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot use the ammo '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot overwrite default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot delete default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the weapon set '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Indtast venligst dit brugernavn</translation>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1931,204 +2325,221 @@ Tjek venligst om spillet er installeret korrekt</translation>
<translation>Indlæs</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Indstillinger</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Klar</translation>
+ <source>Associate file extensions</source>
+ <translation>Tilknyt filtyper</translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Tilfældige Hold</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
- <translation>Tilknyt filtyper</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation>mere</translation>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QTableWidget</name>
<message>
- <source>Room Name</source>
- <translation>Navn på Rum</translation>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
- <translation>C</translation>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
- <translation>T</translation>
+ <source>Play</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
- <translation>Ejer</translation>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation>Bane</translation>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
- <translation>Regler</translation>
+ <source>Upload to YouTube</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation>VÃ¥ben</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>SelWeaponWidget</name>
<message>
- <source>Weapon set</source>
- <translation>Våbensæt</translation>
+ <source>Cancel uploading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation>Sandsynligheder</translation>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ammo in boxes</source>
- <translation>Ammunition i bokse</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delays</source>
- <translation>Forsinkelser</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
- <translation>ny</translation>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
- <translation>kopi af</translation>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>TCPBase</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Error</source>
- <translation>Fejl</translation>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server: %1.</source>
- <translation>Ude af stand til at starte serveren: %1.</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
</message>
<message>
- <source>Unable to run engine: %1 (</source>
- <translation>Ude af stand til at starte spilmotoren: %1 (</translation>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>RoomsListModel</name>
+ <message>
+ <source>In progress</source>
+ <translation type="unfinished">I gang</translation>
+ </message>
+ <message>
+ <source>Room Name</source>
+ <translation type="unfinished">Navn på Rum</translation>
+ </message>
<message>
- <source>Vampirism</source>
- <translation>Vampyr</translation>
+ <source>C</source>
+ <translation type="unfinished">C</translation>
</message>
<message>
- <source>Karma</source>
- <translation>Karma</translation>
+ <source>T</source>
+ <translation type="unfinished">T</translation>
</message>
<message>
- <source>Artillery</source>
- <translation>Artilleri</translation>
+ <source>Owner</source>
+ <translation type="unfinished">Ejer</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>Brug Forter</translation>
+ <source>Map</source>
+ <translation type="unfinished">Bane</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>Opdel Hold</translation>
+ <source>Rules</source>
+ <translation type="unfinished">Regler</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>Fastland</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">VÃ¥ben</translation>
</message>
<message>
- <source>Add Border</source>
- <translation>Tilføj Kant</translation>
+ <source>Random Map</source>
+ <translation type="unfinished">Tilfældig Bane</translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>Svag Tyngdekraft</translation>
+ <source>Random Maze</source>
+ <translation type="unfinished">Tilfældig Labyrint</translation>
</message>
<message>
- <source>Laser Sight</source>
- <translation>Lasersigte</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Invulnerable</source>
- <translation>Udødelighed</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Mines</source>
- <translation>Tilføj Miner</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
</message>
<message>
- <source>Random Order</source>
- <translation>Tilfældig Rækkefølge</translation>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
- <translation>Konge</translation>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
- <translation>Placer Pindsvin</translation>
+ <source>Weapon set</source>
+ <translation>Våbensæt</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation>Klan Deler Ammunition</translation>
+ <source>Probabilities</source>
+ <translation>Sandsynligheder</translation>
</message>
<message>
- <source>Disable Girders</source>
- <translation>Deaktiver Bærebjælker</translation>
+ <source>Ammo in boxes</source>
+ <translation>Ammunition i bokse</translation>
</message>
<message>
- <source>Disable Land Objects</source>
- <translation>Deaktiver Overfladeobjekter</translation>
+ <source>Delays</source>
+ <translation>Forsinkelser</translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation>AI Overlevelse</translation>
+ <source>new</source>
+ <translation>ny</translation>
</message>
<message>
- <source>Reset Health</source>
- <translation>Nulstil Liv</translation>
+ <source>copy of</source>
+ <translation>kopi af</translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>Uendelige Angreb</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Nulstil VÃ¥ben</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Indivuel Ammunition per Pindsvin</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Deaktiver Vind</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Mere Vind</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Annuler</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tagteam</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Tilføj Kant i Bunden</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2262,12 +2673,6 @@ Tjek venligst om spillet er installeret korrekt</translation>
<translation>fang</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>pindsvin
-info</translation>
- </message>
- <message>
<source>quit</source>
<translation>afslut</translation>
</message>
@@ -2295,33 +2700,41 @@ info</translation>
<source>slot 10</source>
<translation>Ã¥bning 10</translation>
</message>
+ <message>
+ <source>mute audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>record</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Grundlæggende styring</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>VÃ¥benstyring</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">VÃ¥ben</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kamera og musestyring</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Andet</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Bevæg dine pindsvin og sigt:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Hop over sprækker og forhinderinger:</translation>
</message>
@@ -2381,6 +2794,14 @@ info</translation>
<source>Toggle labels above hedgehogs:</source>
<translation>Slå mærkater over pindsvin fra og til:</translation>
</message>
+ <message>
+ <source>Record video:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_de.ts b/share/hedgewars/Data/Locale/hedgewars_de.ts
index 6a841d7..3d4e05f 100644
--- a/share/hedgewars/Data/Locale/hedgewars_de.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_de.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="de">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,12 +140,76 @@
<translation>Spielprofile bearbeiten</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Wenn diese Option aktiviert ist, wird durch Auswählen eines Spielprofils auch automatisch Waffen ausgewählt</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Spieloptionen</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Spieloptionen</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Karte</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Verzeichnis %1 konnte nicht angelegt werden</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished">Konnte Daten-Verzeichnis nicht öffnen:
+%1
+
+Bitte überprüfe deine Installation!</translation>
</message>
</context>
<context>
@@ -102,8 +262,16 @@
<translation>Style-Sheet konnte nich nach %1 gesichert werden</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 ist kein gültiger Befehl!</translation>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -139,22 +307,6 @@
<translation>Spiel abgebrochen</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>Dein Spitzname '%1' wurde
-auf Hedgewars.org registriert.
-
-Bitte gib dein Passwort ein oder
-wähle einen anderen Spitznamen
-in den Spieloptionen:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>Kein Passwort</translation>
- </message>
- <message>
<source>Nickname</source>
<translation>Spitzname</translation>
</message>
@@ -167,6 +319,63 @@ in den Spieloptionen:</translation>
Please pick another nickname:</source>
<translation>Dein Spitzname '%1' ist bereits in Verwendung. Bitte wähle einen anderen Spitznamen:</translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -182,18 +391,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Karte</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Motiv</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>Alles</translation>
</message>
@@ -218,10 +415,6 @@ Please pick another nickname:</source>
<translation>Verrückt</translation>
</message>
<message>
- <source>Type</source>
- <translation>Typ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Kleine Tunnel</translation>
</message>
@@ -230,28 +423,96 @@ Please pick another nickname:</source>
<translation>Mittlere Tunnel</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>GroÃe Tunnel</translation>
+ <source>Seed</source>
+ <translation>Seed</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Kleine schwebende Inseln</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Mittlere schwebende Inseln</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>GroÃe schwebende Inseln</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>Seed</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished">Handgemalt</translation>
</message>
<message>
- <source>Set</source>
- <translation>Setzen</translation>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Zufall</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Gezeichnete Karte laden</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished">Gezeichnete Karten</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished">Alle Dateien</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -297,7 +558,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 ist beigetreten</translation>
+ <translation type="obsolete">%1 *** %2 ist beigetreten</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -323,8 +584,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation>Passwort</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -339,6 +615,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -346,23 +644,41 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
- <translation>Dauer: %1m %2s</translation>
+ <translation type="unfinished">Dauer: %1m %2s</translation>
</message>
<message>
<source>Video: %1x%2, </source>
- <translation>Video: %1x%2, </translation>
+ <translation type="unfinished">Video: %1x%2, </translation>
</message>
<message>
<source>%1 fps, </source>
- <translation>%1 fps, </translation>
+ <translation type="unfinished">%1 fps, </translation>
</message>
<message>
<source>Audio: </source>
- <translation>Audio: </translation>
+ <translation type="unfinished">Audio: </translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -395,6 +711,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Speichere Daten</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Allgemein</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -404,6 +752,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -449,349 +808,136 @@ Please pick another nickname:</source>
<translation>Allgemein</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Erweitert</translation>
- </message>
-</context>
-<context>
- <name>PageGameStats</name>
- <message>
- <source>Details</source>
- <translation>Details</translation>
- </message>
- <message>
- <source>Health graph</source>
- <translation>Lebenspunkteverlauf</translation>
- </message>
- <message>
- <source>Ranking</source>
- <translation>Ranking</translation>
- </message>
- <message>
- <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
- <translation>Der beste Schuss geht an <br>%1</b> mit <b>%2</b> Schadenspunkten.</translation>
- </message>
- <message numerus="yes">
- <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
- <translation>
- <numerusform>Der blutigste Kämpfer ist <b>%1</b> mit <b>%2</b> Opfer in einer Runde.</numerusform>
- <numerusform>Der blutigste Kämpfer ist <b>%1</b> mit <b>%2</b> Opfern in einer Runde.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
- <translation>
- <numerusform>Insgesamt fand <b>%1</b> Igel ein trauriges Ende in dieser Runde.</numerusform>
- <numerusform>Insgesamt fanden <b>%1</b> Igel ein trauriges Ende in dieser Runde.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>(%1 kill)</source>
- <translation>
- <numerusform>(%1 Opfer)</numerusform>
- <numerusform>(%1 Opfer)</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
- <translation>
- <numerusform><b>%1</b> dachte es ist gut seinen eigenen Igel mit <b>%2</b> Punkten zu verletzen.</numerusform>
- <numerusform><b>%1</b> dachte es ist gut seine eigenen Igel mit <b>%2</b> Punkten zu verletzen.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation>
- <numerusform><b>%1</b> erledigte <b>%2</b> seiner eigenen Igel.</numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> hatte Angst und übersprang <b>%2</b> Runde.</numerusform>
- <numerusform><b>%1</b> hatte Angst und übersprang <b>%2</b> Runden.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation>Im Spiel...</translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation>Schnappschuss-Ordner öffnen</translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Wähle einfach die gleiche Farbe wie dein Freund um als ein Team zu spielen. Jeder von euch wird trotzdem seine eigenen Igel kontrollieren, aber sie gewinnen oder verlieren zusammen.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Manche Waffen richten nur einen geringen Schaden an, können aber in der richtigen Situation sehr nützlich sein. Benutze die Desert Eagle um mehrere Igel ins Wasser zu schieÃen.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Wenn du dir nicht sicher bist was du tun sollst und keine Munition verschwenden willst, überspringe eine Runde. Aber lass nicht zu viele Runden verstreichen, denn später kommt es zum Sudden Death!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Wenn du andere daran hindern willst deinen bevorzugten Nickname auf dem offiziellen Server zu nutzen, registriere dich auf http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Du bist von dem Standardspiel gelangweilt? Probiere die Missionen aus - sie ermöglichen dir verschiedene Spielarten je nachdem welche du wählst.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Das Spiel wird automatisch das letzte Spiel als Demo aufnehmen. Wähle 'Lokales Spiel' und wähle den 'Demos'-Knopf in der unteren rechten Ecke um sie zu spielen oder zu verwalten.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist freie und kostenlose Software, die wir in unserer Freizeit entwickeln. Wenn du Probleme hast, frag in unseren Foren, aber erwarte bitte keinen 24/7-Support!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist freie und kostenlose Software, die wir in unserer Freizeit entwickeln. Wenn du es magst, hilf uns mit einer kleinen Spende oder trage deine eigene Arbeit bei!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist freie und kostenlose Software, die wir in unserer Freizeit entwickeln. Teile es mit deiner Familie und deinen Freunden!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Von Zeit zu Zeit wird es offizielle Turniere geben. Anstehede Events werden frühzeitig auf http://www.hedgewars.org/ bekannt gegeben.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist in vielen Sprachen verfügbar. Wenn die Ãbersetzung in deiner Sprache fehlt oder veraltet ist scheue dich nicht uns zu kontaktieren!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars läuft auf vielen verschiedenen Betriebssystemen wie Microsoft Windows, Mac OS X und Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Bedenke immer, dass du auch eigene Spiele im lokalen und Netzwerk/Online-Spiel erstellen kannst. Du bist nicht an die 'Einfaches Spiel'-Option gebunden.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Du solltest dir wenigstens einmal pro Stunde eine Pause gönnen.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Wenn deine Grafikkarte keine hardwarebeschleunigtes OpenGL unterstützt, versuche die Qualtität in den Einstellungen runterzuschrauben.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Wir sind offen für Vorschläge oder konstruktive Rückmeldungen. Wenn dir etwas nicht gefällt oder du eine gute Idee hat, lass es uns wissen!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Sei gerade beim Spielen in Internet höflich und vergiss nie, dass eventuell auch Kinder mit dir oder gegen dich spielen!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Spezielle Spielmodi wie 'Vampirismus' oder 'Karma' erlauben es dir völlig neue Taktiken zu entwickeln. Probier sie einem eigenen Spiel aus!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Du solltest nie Hedgewars auf einem Computer installieren, der dir nicht gehört (Schule, Universität, Arbeit, etc.). Frag bitte stattdessen die verantwortliche Person!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist perfekt für kurze Spielchen zwischendurch. Schaue nur, dass du nicht zu viele Igel oder eine zu groÃe Karte nimmst. Das Verringern der Zeit oder Lebenspunkte kann auch helfen.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Bei der Erstellung des Spiels wurden keine Igel verletzt.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars ist freie und kostenlose Software, die wir in unserer Freizeit entwickeln. Wenn dir jemand das Spiel verkauft hat, solltest du versuchen es dir erstatten zu lassen!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Verbinde ein oder mehrere Gamepads bevor du das Spiel startest um damit deine Teams kontrollieren zu können.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Erstellen einen Account auf %1 um andere daran zu deinen favorisierten Benutzernamen zu benutzen, wenn du auf dem offiziellen Server spielst.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Wenn deine Grafikkarte kein hardwarebeschleunigtes OpenGL bietet, versuche die entsprechenden Treiber zu aktualisieren.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Es gibt drei Arten von Sprüngen: Drücke zweimal die Taste zum Hochspringen, um noch höher/rückwärts zu springen.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Angst eine Klippe herunterzufallen? Halte [Umschalt] um dich nach links oder rechts zu drehen, ohne dich wirklich zu bewegen.</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Manche Waffen brauchen spezielle Strategieren oder einfach nur eine Menge Ãbung, also gib eine Waffe nicht direkt auf wenn du deinen Gegner einmal verfehlst.</translation>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>Die meisten Waffen funktionieren nicht mehr, sobald sie das Wasser berühren. Die zielsuchende Biene oder die Torte sind Ausnahmen hierfür.</translation>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Der Alte Limburger versucht nur einen kleinen Schaden. Die durch den Wind beeinflussbare Stinkwolke jedoch kann viele Igel auf einmal vergiften.</translation>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Der Piano-Angriff ist der verheerenste Luftangriff. Du verlierst allerdings den Igel der ihn vollführt, er hat also auch seine Schattenseite.</translation>
+ <source>Hat</source>
+ <translation type="unfinished">Cooliehat</translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Haftminen sind perfekte Werkzeuge um Kettenreaktionen auszulösen oder Igel in die gewünschte Richtung zu lenken ... oder ins Wasser.</translation>
+ <source>Name</source>
+ <translation type="unfinished">Name</translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Der Hammer ist die effektivste Waffe auf Brücken oder Klippen. Getroffene Igel fallen einfach durch den Boden.</translation>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Wenn du hinter einem Igel feststeckst, benutze den Hammer um dich zu befreien ohne durch eine Explosion verletzt zu werden.</translation>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Die maximale Laufdistanz der Torte hängt vom abzulaufenden Untergrund ab. Benutze [Angriff] um sie früher zu zünden.</translation>
+ <source>Random Team</source>
+ <translation type="unfinished">Zufallsteam</translation>
</message>
+</context>
+<context>
+ <name>PageGameStats</name>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Der Flammenwerfer ist zwar eine Waffe, kann aber auch zum Tunnelgraben genutzt werden.</translation>
+ <source>Details</source>
+ <translation>Details</translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Du willst wissen wer hinter Hedgewars steckt? Klicke auf das Hedgewars-Logo im Hauptmenü um die Credits zu sehen.</translation>
+ <source>Health graph</source>
+ <translation>Lebenspunkteverlauf</translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Du magst Hedgewars? Werde ein Fan auf %1 oder folge uns auf %2!</translation>
+ <source>Ranking</source>
+ <translation>Ranking</translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Du kannst gerne deine eigenen Grabsteine, Hüte, Flaggen oder sogar Karten und Themes erstellen! Aber vergiss nicht, dass du sie auch verteilen musst um sie online zu nutzen.</translation>
+ <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
+ <translation>Der beste Schuss geht an <br>%1</b> mit <b>%2</b> Schadenspunkten.</translation>
</message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Du willst einen besonderen Hut tragen? Spende etwas an uns und du kriegst einen exklusiven Hut deiner Wahl!</translation>
+ <message numerus="yes">
+ <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
+ <translation>
+ <numerusform>Der blutigste Kämpfer ist <b>%1</b> mit <b>%2</b> Opfer in einer Runde.</numerusform>
+ <numerusform>Der blutigste Kämpfer ist <b>%1</b> mit <b>%2</b> Opfern in einer Runde.</numerusform>
+ </translation>
</message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Halte deine Grafiktreiber aktuell um Probleme beim Spielen zu vermeiden.</translation>
+ <message numerus="yes">
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation>
+ <numerusform>Insgesamt fand <b>%1</b> Igel ein trauriges Ende in dieser Runde.</numerusform>
+ <numerusform>Insgesamt fanden <b>%1</b> Igel ein trauriges Ende in dieser Runde.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du findest deine Hedgewars Konfigurationsdateien unter "Eigene Dateien\Hedgewars". Erstelle Backups oder kopiere deine Dateien, aber editiere sie besser nicht selbst.</translation>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation>
+ <numerusform>(%1 Opfer)</numerusform>
+ <numerusform>(%1 Opfer)</numerusform>
+ </translation>
</message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Du kannst Dateien wie Speicherstände oder Demos mit Hedgewars verknüpfen um sie so direkt mit deinem Datei- oder Internetbrowser zu öffnen.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation>
+ <numerusform><b>%1</b> dachte es ist gut seinen eigenen Igel mit <b>%2</b> Punkten zu verletzen.</numerusform>
+ <numerusform><b>%1</b> dachte es ist gut seine eigenen Igel mit <b>%2</b> Punkten zu verletzen.</numerusform>
+ </translation>
</message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Du willst Seile sparen? Lass das Seil in der Luft los und schieà nochmal. Solange du nicht den Boden berührst kannst du es wiederverwenden ohne Munition zu verschwenden!</translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation>
+ <numerusform><b>%1</b> erledigte <b>%2</b> seiner eigenen Igel.</numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du findest die Hedgewars Konfigurationsdateien unter "Library/Application Support/Hedgewars" in deinem Home-Verzeichnis. Erstelle Backups oder kopiere deine Dateien, aber editiere sie besser nicht selbst.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> hatte Angst und übersprang <b>%2</b> Runde.</numerusform>
+ <numerusform><b>%1</b> hatte Angst und übersprang <b>%2</b> Runden.</numerusform>
+ </translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du findest die Hedgewars Konfigurationsdateien unter ".hedgewars" in deinem Home-Verzeichnis. Erstelle Backups oder kopiere deine Dateien, aber editiere sie besser nicht selbst.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Die Windows version von Hedgewars unterstützt Xfire. Füge Hedgewars zu deiner Spieleliste hinzu damit deine Freunde dich spielen sehen können.</translation>
+ <source>Save</source>
+ <translation type="unfinished">Sichern</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Benutze den Molotov-Cocktail oder den Flammenwerfer um Igel vorübergehend am passieren von Gelände wie z.B. Tunnels oder Platformen zu hindern.</translation>
+ <source>In game...</source>
+ <translation>Im Spiel...</translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>Die Verwendung der Zielsuchende Biene ist ein bisschen knifflig. Ihr Wenderadius hängt von der Geschwindigkeit ab, versuche sie also nicht mit voller Stärke wegzuschieÃen.</translation>
+ <source>Open the snapshot folder</source>
+ <translation>Schnappschuss-Ordner öffnen</translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
<source>Downloadable Content</source>
<translation>Herunterladbare Inhalte</translation>
</message>
<message>
- <source>Local Game</source>
- <translation>Lokales Spiel</translation>
- </message>
- <message>
<source>Play a game on a single computer</source>
<translation>Spiele auf einem einzelnen PC</translation>
</message>
<message>
- <source>Network Game</source>
- <translation>Netzwerkspiel</translation>
- </message>
- <message>
<source>Play a game across a network</source>
<translation>Spiele über ein Netwerk</translation>
</message>
@@ -819,6 +965,26 @@ Please pick another nickname:</source>
<source>Edit game preferences</source>
<translation>Bearbeite Spieleinstellungen</translation>
</message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play local network game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play official network game</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageMultiplayer</name>
@@ -826,39 +992,43 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Start</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished">Bearbeite Spieleinstellungen</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Steuerung</translation>
+ <translation type="obsolete">Steuerung</translation>
</message>
<message>
- <source>DLC</source>
- <translation>DLC</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished">Bearbeite Spieleinstellungen</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Herunterladbare Inhalte</translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Eigener Server (LAN oder Internet)</translation>
+ <source>Update</source>
+ <translation type="unfinished">Aktualisieren</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Offizieller Server</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
- <translation>Treffe hunderte Spieler online!</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation>Erstelle einen eigenen Spiel-Server oder verbinde dich zu einem bestehenden Server im Netzwerk.</translation>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -904,10 +1074,6 @@ Please pick another nickname:</source>
<translation>Waffenprofil löschen</translation>
</message>
<message>
- <source>General</source>
- <translation>Allgemein</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Erweitert</translation>
</message>
@@ -947,6 +1113,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation>Betriebsystem Proxy-Einstellungen</translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Teams</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Waffen</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished">Benutzerdefinierte Farben</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished">Proxy-Einstellungen</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished">Verschiedenes</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished">Videoaufnahmeoptionen</translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -963,11 +1217,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Erstellen</translation>
+ <translation type="obsolete">Erstellen</translation>
</message>
<message>
<source>Join</source>
- <translation>Betreten</translation>
+ <translation type="obsolete">Betreten</translation>
</message>
<message>
<source>Admin features</source>
@@ -975,7 +1229,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Raumname:</translation>
+ <translation type="obsolete">Raumname:</translation>
</message>
<message>
<source>Rules:</source>
@@ -987,11 +1241,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Suche:</translation>
+ <translation type="obsolete">Suche:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Leeren</translation>
+ <translation type="obsolete">Leeren</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1000,6 +1254,30 @@ Please pick another nickname:</source>
<numerusform>%1 Spieler online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1146,18 +1424,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation>Einfaches Spiel</translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation>Spiele ein schnelles Spiel gegen den Computer - mit Zufallseinstellungen</translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation>Multiplayer</translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation>Spiele gegen deine Freunde oder Computer-Teams.</translation>
</message>
@@ -1166,26 +1436,14 @@ Please pick another nickname:</source>
<translation>Kampagnenmodus</translation>
</message>
<message>
- <source>Training Mode</source>
- <translation>Trainingsmodus</translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation>Verbessere deine Fähigkeiten in verschiedenen Trainingsmissionen</translation>
</message>
<message>
- <source>Demos</source>
- <translation>Demos</translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation>Sehe aufgenommene Demos an</translation>
</message>
<message>
- <source>Load</source>
- <translation>Laden</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation>Lade ein vormals gespeichtes Spiel</translation>
</message>
@@ -1231,14 +1489,6 @@ Please pick another nickname:</source>
<translation>(in Bearbeitung...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation>Datum: </translation>
- </message>
- <message>
- <source>Size: </source>
- <translation>GröÃe: </translation>
- </message>
- <message>
<source>encoding</source>
<translation>encoden</translation>
</message>
@@ -1246,6 +1496,16 @@ Please pick another nickname:</source>
<source>uploading</source>
<translation>hochladen</translation>
</message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1254,10 +1514,6 @@ Please pick another nickname:</source>
<translation>Rauswerfen</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Zugang beschränken</translation>
</message>
@@ -1295,7 +1551,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>Aktualisieren</translation>
+ <translation type="obsolete">Aktualisieren</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1305,10 +1573,6 @@ Please pick another nickname:</source>
<translation>Vollbild</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Klänge im Spiel</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>FPS anzeigen</translation>
</message>
@@ -1317,14 +1581,6 @@ Please pick another nickname:</source>
<translation>Alternativen Schaden anzeigen</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Musik im Spiel</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Frontend im Vollbild</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Datum und Uhrzeit an Aufnahmedatei anhängen</translation>
</message>
@@ -1337,18 +1593,6 @@ Please pick another nickname:</source>
<translation>Kurzinfos für Waffen anzeigen</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Klänge im Frontend</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Musik im Frontend</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Animationen im Frontend</translation>
- </message>
- <message>
<source>Save password</source>
<translation>Passwort speichern</translation>
</message>
@@ -1368,14 +1612,38 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation>Spielauflösung verwenden</translation>
</message>
+ <message>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>Zufallskarte...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Mensch</translation>
</message>
@@ -1388,14 +1656,6 @@ Please pick another nickname:</source>
<translation>(Systemstandard)</translation>
</message>
<message>
- <source>Mission</source>
- <translation>Mission</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation>Zufallslabyrinth...</translation>
- </message>
- <message>
<source>Community</source>
<translation></translation>
</message>
@@ -1405,15 +1665,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>In Lobby</translation>
+ <translation type="obsolete">In Lobby</translation>
</message>
<message>
<source>In progress</source>
- <translation>Im Spiel</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>Handgezeichnete Karte</translation>
+ <translation type="obsolete">Im Spiel</translation>
</message>
<message>
<source>Disabled</source>
@@ -1452,10 +1708,6 @@ Please pick another nickname:</source>
<translation>Ãbereinander</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Wackeln</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Rot/Türkis Graustufen</translation>
</message>
@@ -1487,22 +1739,10 @@ Please pick another nickname:</source>
<translation>Teammitglieder</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Tastenkombinationen</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Festung</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Teams</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Audio-/Grafik-Einstellungen</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Netzwerkspiel</translation>
</message>
@@ -1523,26 +1763,6 @@ Please pick another nickname:</source>
<translation>Teameinstellungen</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Verschiedenes</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Spielprofile und Waffen</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation>Benutzerdefinierte Farben</translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation>Verschiedenes</translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation>Videoaufnahmeoptionen</translation>
- </message>
- <message>
<source>Videos</source>
<translation>Videos</translation>
</message>
@@ -1550,30 +1770,10 @@ Please pick another nickname:</source>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation>Proxy-Einstellungen</translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Developers:</source>
- <translation>Entwickler:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafiken:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Ãbersetzer:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Besonderer Dank geht an:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Waffen</translation>
</message>
@@ -1603,11 +1803,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sounds:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1646,10 +1842,6 @@ Please pick another nickname:</source>
<translation>Kistenabwurf</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Spielprofil</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Blindgänger</translation>
</message>
@@ -1686,10 +1878,6 @@ Please pick another nickname:</source>
<translation>Tipp:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Dieser Entwicklungsbuild ist 'in Arbeit' und kann inkompatibel zu anderen Versionen des Spiels sein. Manche Funktionen könnten unbrauchbar oder unvollständig sein. Benutzung auf eigene Gefahr!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Qualität</translation>
</message>
@@ -1731,7 +1919,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>Dieses Spiel wird unter den Bedingungen der GNU General Public License v2 verbreitet</translation>
+ <translation type="obsolete">Dieses Spiel wird unter den Bedingungen der GNU General Public License v2 verbreitet</translation>
</message>
<message>
<source>There are videos that are currently being processed.
@@ -1766,10 +1954,6 @@ Willst du wirklich verlassen?</translation>
<translation>Tags (durch Beistriche getrennt)</translation>
</message>
<message>
- <source>Summary </source>
- <translation>Zusammenfassung </translation>
- </message>
- <message>
<source>Description</source>
<translation>Beschreibung</translation>
</message>
@@ -1797,6 +1981,50 @@ Willst du wirklich verlassen?</translation>
<source>Bitrate (Kbps)</source>
<translation>Bitrate (Kbps)</translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Vollbild</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1819,6 +2047,10 @@ Willst du wirklich verlassen?</translation>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1835,10 +2067,6 @@ Willst du wirklich verlassen?</translation>
<translation>Dateizuordnung fehlgeschlagen.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation>Bitte fülle alle Felder aus</translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation>Fehler während Authentifizierung auf google.com:
@@ -1887,50 +2115,38 @@ Willst du wirklich verlassen?</translation>
<translation>Alle Dateizuordnungen wurden gesetzt</translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Main - Error</source>
- <translation>Hedgewars - Fehler</translation>
+ <translation type="obsolete">Hedgewars - Fehler</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation>Verzeichnis %1 konnte nicht angelegt werden</translation>
+ <translation type="obsolete">Verzeichnis %1 konnte nicht angelegt werden</translation>
</message>
<message>
<source>Failed to open data directory:
%1
Please check your installation!</source>
- <translation>Konnte Daten-Verzeichnis nicht öffnen:
+ <translation type="obsolete">Konnte Daten-Verzeichnis nicht öffnen:
%1
Bitte überprüfe deine Installation!</translation>
</message>
<message>
<source>TCP - Error</source>
- <translation>TCP - Fehler</translation>
+ <translation type="obsolete">TCP - Fehler</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation>Server %1 konnte nicht gestartet werden.</translation>
+ <translation type="obsolete">Server %1 konnte nicht gestartet werden.</translation>
</message>
<message>
<source>Unable to run engine at </source>
- <translation>Konnte Engine nicht starten: </translation>
+ <translation type="obsolete">Konnte Engine nicht starten: </translation>
</message>
<message>
<source>Error code: %1</source>
- <translation>Fehler-Code: %1</translation>
+ <translation type="obsolete">Fehler-Code: %1</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2049,16 +2265,42 @@ Willst du trotzdem den Raum betreten?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation>Willst du das Waffenprofil '%1' wirklich löschen?</translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Spitzname</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Bitte gib deinen Spitznamen ein</translation>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2116,26 +2358,10 @@ Willst du trotzdem den Raum betreten?</translation>
<translation>Laden</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Einstellungen</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Bereit</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Zufallsteam</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Ordne Dateitypen zu</translation>
</message>
<message>
- <source>more</source>
- <translation>mehr</translation>
- </message>
- <message>
<source>More info</source>
<translation>Mehr Info</translation>
</message>
@@ -2159,6 +2385,61 @@ Willst du trotzdem den Raum betreten?</translation>
<source>Cancel uploading</source>
<translation>Hochladen abbrechen</translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2208,6 +2489,25 @@ Willst du trotzdem den Raum betreten?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2235,106 +2535,44 @@ Willst du trotzdem den Raum betreten?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>TCPBase</name>
<message>
- <source>Vampirism</source>
- <translation>Vampirismus</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artillerie</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Festungs-Modus</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Teams getrennt aufstellen</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Unzerstörbares Terrain</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Randbegrenzung einfügen</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Verringerte Schwerkraft</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Laservisier</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Unverwundbarkeit</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Zufällige Reihenfolge</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Schützt den König</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Igel platzieren</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Gemeinsames Arsenal</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Keine Bauträger</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Deaktivere Landschaftsobjekte</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>KI Ãberlebensmodus</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>Gesundheit zurücksetzen</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>Unbegrenzte Angriffe</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Waffen zurücksetzen</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Waffen pro Igel</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Kein Wind</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Mehr Wind</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Abbrechen</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tag Team</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Untere Randbegrenzung hinzufügen</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2452,12 +2690,6 @@ Willst du trotzdem den Raum betreten?</translation>
<translation>Bildschirmfoto</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>Igel
-Statistik</translation>
- </message>
- <message>
<source>quit</source>
<translation>Beenden</translation>
</message>
@@ -2509,33 +2741,33 @@ Statistik</translation>
<source>record</source>
<translation>aufnehmen</translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Grundsteuerung</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Waffensteuerung</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Waffen</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kamera- und Zeigersteuerung</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Andere</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished">Verschiedenes</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Bewege und ziele mit deinen Igeln:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Ãberwinde Abgründe und Hindernisse mit Sprüngen:</translation>
</message>
@@ -2599,6 +2831,10 @@ Statistik</translation>
<source>Record video:</source>
<translation>Video aufnehmen:</translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_el.ts b/share/hedgewars/Data/Locale/hedgewars_el.ts
index ca88746..53bfc34 100644
--- a/share/hedgewars/Data/Locale/hedgewars_el.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_el.ts
@@ -2,11 +2,118 @@
<!DOCTYPE TS>
<TS version="2.0" language="el">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AbstractPage</name>
+ <message>
+ <source>Go back</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AmmoSchemeModel</name>
<message>
<source>new</source>
<translation type="unfinished">ÎÎο</translation>
</message>
+ <message>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>FreqSpinBox</name>
@@ -29,66 +136,142 @@
<translation type="unfinished">ÎÏεξεÏγαÏία ÏÏλÏν</translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Edit schemes</source>
+ <translation type="unfinished">ÎÏεξεÏγαÏία ÏÏεδιαÏμÏν</translation>
</message>
<message>
- <source>Illegal ammo scheme</source>
- <translation type="unfinished">ÎÏÏμβαÏÎ¿Ï ÏÏεδιαÏμÏÏ ÏÏλÏν</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Edit schemes</source>
- <translation type="unfinished">ÎÏεξεÏγαÏία ÏÏεδιαÏμÏν</translation>
+ <source>Map</source>
+ <translation type="unfinished">ΧάÏÏηÏ</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon (and viceversa)</source>
- <translation type="unfinished">ÎÏαν αÏ
Ïή η εÏιλογη είναι ενεÏγοÏοιημÎνη, εÏιλÎγονÏÎ±Ï Îνα ÏÏεδιαÏÎ¼Ï ÏαιÏÎ½Î¹Î´Î¹Î¿Ï Î¸Î± εÏιλÎγεÏαι αÏ
ÏομάÏÏÏ Îνα ÏÏλο (και ανÏιÏÏÏÏÏÏÏ)</translation>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>HWChatWidget</name>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>%1 *** %2 has been removed from your ignore list</source>
- <translation type="unfinished">%1 *** %2 αÏαιÏÎθηκε αÏÏ Ïη "μαÏÏη" λίÏÏα</translation>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has been added to your ignore list</source>
- <translation type="unfinished">%1 *** %2 ÏÏοÏÏÎθηκε ÏÏη "μαÏÏη" λίÏÏα</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Îεν μÏοÏεί να δημιοÏ
Ïγηθεί ο καÏÎ¬Î»Î¿Î³Î¿Ï %1</translation>
</message>
<message>
- <source>%1 *** %2 has been removed from your friends list</source>
- <translation type="unfinished">%1 *** %2 αÏαιÏÎθηκε αÏÏ Ïη λίÏÏα ÏίλÏν</translation>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWAskQuitDialog</name>
<message>
- <source>%1 *** %2 has been added to your friends list</source>
- <translation type="unfinished">%1 *** %2 ÏÏοÏÏÎθηκε ÏÏη λίÏÏα ÏίλÏν</translation>
+ <source>Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>HWForm</name>
+ <name>HWChatWidget</name>
<message>
- <source>new</source>
- <translation type="unfinished">ÎÎο</translation>
+ <source>%1 has been removed from your ignore list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>%1 has been added to your ignore list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation type="unfinished">ÎνÏάξει</translation>
+ <source>%1 has been removed from your friends list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server</source>
- <translation type="unfinished">Îεν είναι δÏ
ναÏÏν να ξεκινήÏει ο εξÏ
ÏηÏεÏηÏήÏ</translation>
+ <source>%1 has been added to your friends list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot save record to file %1</source>
- <translation type="unfinished">Îεν μÏοÏεί να ÏÏθεί η εγγÏαÏή ÏÏο αÏÏείο %1</translation>
+ <source>Stylesheet imported from %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Couldn't read %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>StyleSheet discarded</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>StyleSheet saved to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to save StyleSheet to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWForm</name>
<message>
- <source>Please select record from the list above</source>
- <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏÎλεξε εγγÏαÏή αÏÏ Ïην ÏαÏαÏÎ¬Î½Ï Î»Î¯ÏÏα</translation>
+ <source>Cannot save record to file %1</source>
+ <translation type="unfinished">Îεν μÏοÏεί να ÏÏθεί η εγγÏαÏή ÏÏο αÏÏείο %1</translation>
</message>
<message>
<source>DefaultTeam</source>
@@ -106,33 +289,103 @@
<translatorcomment>ΤÏÏÎ¿Ï ÎÏÏείÏν</translatorcomment>
<translation type="unfinished">ÎÏÏείο ÎÏοθήκεÏ
ÏÎ·Ï Hedgewars</translation>
</message>
-</context>
-<context>
- <name>HWGame</name>
<message>
- <source>el.txt</source>
- <translation>el.txt</translation>
+ <source>Game aborted</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot open demofile %1</source>
- <translation type="unfinished">Îεν μÏοÏεί να ÏοÏÏÏθεί Ïο αÏÏείο εÏιδείξεÏν %1</translation>
+ <source>Nickname</source>
+ <translation type="unfinished">ΨεÏ
δÏνÏ
μο</translation>
</message>
-</context>
-<context>
- <name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation type="unfinished">ΧάÏÏηÏ</translation>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Demo name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Demo name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Themes</source>
- <translation type="unfinished">ÎÎμαÏα</translation>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Filter</source>
- <translation type="unfinished">ΦίλÏÏο</translation>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWGame</name>
+ <message>
+ <source>Cannot open demofile %1</source>
+ <translation type="unfinished">Îεν μÏοÏεί να ÏοÏÏÏθεί Ïο αÏÏείο εÏιδείξεÏν %1</translation>
+ </message>
+ <message>
+ <source>en.txt</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWMapContainer</name>
+ <message>
<source>All</source>
<translation type="unfinished">Îλα</translation>
</message>
@@ -157,10 +410,6 @@
<translation type="unfinished">ÎξÏÏÏενικÏ</translation>
</message>
<message>
- <source>Type</source>
- <translation type="unfinished">ΤÏÏοÏ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation type="unfinished">ÎικÏÎÏ ÏήÏαγγεÏ</translation>
</message>
@@ -169,20 +418,96 @@
<translation type="unfinished">ÎÎÏÏÎ¹ÎµÏ ÏήÏαγγεÏ</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation type="unfinished">ÎÎµÎ³Î¬Î»ÎµÏ ÏήÏαγγεÏ</translation>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">ΤÏ
Ïαίο</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation type="unfinished">ÎικÏά εÏιÏλÎονÏα νηÏιά</translation>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation type="unfinished">ÎÎÏÏια εÏιÏλÎονÏα νηÏιά</translation>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation type="unfinished">Îεγάλα εÏιÏλÎονÏα νηÏιά</translation>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -223,26 +548,12 @@
<translation type="unfinished">Σε ÏÎÏαξαν ÎξÏ</translation>
</message>
<message>
- <source>Password</source>
- <translation type="unfinished">ÎÏδικÏÏ</translation>
- </message>
- <message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</source>
- <translation type="obsolete">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</translation>
- </message>
- <message>
<source>%1 *** %2 has joined the room</source>
<translation type="unfinished">%1 *** %2 ειÏήλθε ÏÏο δÏμάÏιο</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation type="unfinished">%1 *** %2 ειÏήλθε</translation>
+ <translation type="obsolete">%1 *** %2 ειÏήλθε</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -253,62 +564,180 @@ or pick another nickname:</translation>
<translation type="unfinished">%1 *** %2 εγκαÏÎλειÏε</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Το ÏεÏ
δÏνÏ
μο %1 είναι ήδη
-καÏαÏÏÏημÎνο ÏÏο Hedgewars.org
-ΠαÏÎ±ÎºÎ±Î»Ï ÎµÎ¹ÏάγεÏε Ïον κÏÎ´Î¹ÎºÏ ÏαÏ
-ή εÏιλÎξÏε άλλο ÏεÏ
δÏνÏ
μο αÏÏ ÏιÏ
-ÏÏ
θμίÏÎµÎ¹Ï ÏοÏ
ÏαιÏνιδιοÏ:</translation>
+ <source>User quit</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>KB</name>
<message>
- <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
- <translation type="unfinished">Το SDL_ttf εÏÎÏÏÏεÏε ÏÏάλμα καθÏÏ Î´Î¹ÎµÏμήνεÏ
Ïε κείμενο. Το Ïιο ÏÎ¹Î¸Î±Î½Ï ÎµÎ¯Î½Î±Î¹ αÏ
ÏÏ Î½Î± ÏÏεÏίζεÏαι με Ïο ÏÏάλμα ÏÏο freetype2. Î ÏοÏείνεÏαι να αναβαθμίÏεÏε Ïο freetype lib.</translation>
+ <source>Remote host has closed connection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The server is too old. Disconnecting now.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageAdmin</name>
+ <name>HWPasswordDialog</name>
<message>
- <source>Server message:</source>
- <translation type="obsolete">Server message:</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set message</source>
- <translation type="obsolete">Set message</translation>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Clear Accounts Cache</source>
- <translation type="unfinished">ÎαθαÏιÏμÏÏ Î¼Î½Î®Î¼Î·Ï Î»Î¿Î³Î±ÏιαÏμÏν</translation>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Fetch data</source>
- <translation type="unfinished">Î ÏοÏκομιδή δεδομÎνÏν</translation>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWUploadVideoDialog</name>
<message>
- <source>Server message for latest version:</source>
- <translation type="unfinished">ÎήνÏ
μα εξηÏηÏεÏηÏή για Ïην ÏελεÏ
Ïαία ÎκδοÏη:</translation>
+ <source>Upload video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Server message for previous versions:</source>
- <translation type="unfinished">ÎήνÏ
μα εξηÏηÏεÏηÏή για ÏÏοηγοÏÎ¼ÎµÎ½ÎµÏ ÎµÎºÎ´ÏÏειÏ:</translation>
+ <source>Upload</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HatButton</name>
<message>
- <source>Latest version protocol number:</source>
- <translation type="unfinished">ÎÏιθμÏÏ ÏÏÏÏοκÏλλοÏ
ÏελεÏ
ÏÎ±Î¯Î±Ï ÎκδοÏÎ·Ï :</translation>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HatPrompt</name>
<message>
- <source>MOTD preview:</source>
- <translation type="unfinished">Î ÏοεÏιÏκÏÏηÏη MOTD :</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KB</name>
+ <message>
+ <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
+ <translation type="unfinished">Το SDL_ttf εÏÎÏÏÏεÏε ÏÏάλμα καθÏÏ Î´Î¹ÎµÏμήνεÏ
Ïε κείμενο. Το Ïιο ÏÎ¹Î¸Î±Î½Ï ÎµÎ¯Î½Î±Î¹ αÏ
ÏÏ Î½Î± ÏÏεÏίζεÏαι με Ïο ÏÏάλμα ÏÏο freetype2. Î ÏοÏείνεÏαι να αναβαθμίÏεÏε Ïο freetype lib.</translation>
+ </message>
+</context>
+<context>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <source>Duration: %1m %2s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video: %1x%2, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 fps, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageAdmin</name>
+ <message>
+ <source>Clear Accounts Cache</source>
+ <translation type="unfinished">ÎαθαÏιÏμÏÏ Î¼Î½Î®Î¼Î·Ï Î»Î¿Î³Î±ÏιαÏμÏν</translation>
+ </message>
+ <message>
+ <source>Fetch data</source>
+ <translation type="unfinished">Î ÏοÏκομιδή δεδομÎνÏν</translation>
+ </message>
+ <message>
+ <source>Server message for latest version:</source>
+ <translation type="unfinished">ÎήνÏ
μα εξηÏηÏεÏηÏή για Ïην ÏελεÏ
Ïαία ÎκδοÏη:</translation>
+ </message>
+ <message>
+ <source>Server message for previous versions:</source>
+ <translation type="unfinished">ÎήνÏ
μα εξηÏηÏεÏηÏή για ÏÏοηγοÏÎ¼ÎµÎ½ÎµÏ ÎµÎºÎ´ÏÏειÏ:</translation>
+ </message>
+ <message>
+ <source>Latest version protocol number:</source>
+ <translation type="unfinished">ÎÏιθμÏÏ ÏÏÏÏοκÏλλοÏ
ÏελεÏ
ÏÎ±Î¯Î±Ï ÎκδοÏÎ·Ï :</translation>
+ </message>
+ <message>
+ <source>MOTD preview:</source>
+ <translation type="unfinished">Î ÏοεÏιÏκÏÏηÏη MOTD :</translation>
</message>
<message>
<source>Set data</source>
<translation type="unfinished">ΤοÏοθÎÏηÏη δεδομÎνÏν</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Îενικά</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished">ÎνανÎÏÏη</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -318,37 +747,101 @@ or pick another nickname in game config:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageDrawMap</name>
+ <message>
+ <source>Eraser</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load</source>
+ <translation type="unfinished">ΦÏÏÏÏÏη</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageEditTeam</name>
<message>
<source>General</source>
<translation type="unfinished">Îενικά</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">Îια ÏÏοÏÏÏημÎνοÏ
Ï</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageGameStats</name>
<message>
- <source><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></source>
- <translation type="obsolete"><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></translation>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></source>
- <translation type="obsolete">
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kill in a turn.</p></numerusform>
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></numerusform>
- </translation>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>A total of <b>%1</b> hedgehog(s) were killed during this round.</p></source>
- <translation type="obsolete">
- <numerusform><p>A total of <b>%1</b> hedgehog was killed during this round.</p></numerusform>
- <numerusform><p>A total of <b>%1</b> hedgehogs were killed during this round.</p></numerusform>
- </translation>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">ÎαÏÎλο</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Îνομα</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">ΤÏ
Ïαία Îμάδα</translation>
+ </message>
+</context>
+<context>
+ <name>PageGameStats</name>
+ <message>
<source>Details</source>
<translation type="unfinished">ÎεÏÏομÎÏειεÏ</translation>
</message>
@@ -406,478 +899,379 @@ or pick another nickname in game config:</source>
<numerusform>Î <b>%1</b> Ïοβήθηκε και ÏαÏαÏÏÏηÏε Ïη ÏειÏά ÏοÏ
<b>%2</b> ÏοÏÎÏ.</numerusform>
</translation>
</message>
-</context>
-<context>
- <name>PageMain</name>
<message>
- <source>Local Game (Play a game on a single computer)</source>
- <translation type="unfinished">ΤοÏÎ¹ÎºÏ Î Î±Î¹Ïνίδι (Παίξιμο ÏαιÏÎ½Î¹Î´Î¹Î¿Ï Ïε Îνα Ï
ÏολογιÏÏή)</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game (Play a game across a network)</source>
- <translation type="unfinished">ÎικÏÏ
Î±ÎºÏ Î Î±Î¹Ïνίδι (Παίξιμο ÏαιÏÎ½Î¹Î´Î¹Î¿Ï Ïε δίκÏÏ
ο)</translation>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏλÏÏ ÎµÏιλÎξÏε Ïο ίδιο ÏÏÏμα με Ïο Ïίλο ÏÎ±Ï Î³Î¹Î± να ÏαίξεÏε μαζί Ïαν ομάδα. ΠκαθÎÎ½Î±Ï Î±ÏÏ ÏÎ±Ï Î¸Î± μÏοÏεί ακÏμα να ελÎγÏει ÏοÏ
Ï Î´Î¹ÎºÎ¿ÏÏ ÏοÏ
ή ÏοÏ
Ï Î´Î¹ÎºÎ¿ÏÏ ÏÎ·Ï ÏκαÏζÏÏοιÏοÏ
Ï, αλλά ÏάνεÏε ή κεÏδίζεÏε μαζί.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎεÏικά ÏÏλα μÏοÏεί να κάνοÏ
ν μÏνο λίγη ζημιά αλλά μÏοÏεί να είναι ÏÎ¿Î»Ï Ïιο καÏαÏÏÏεÏÏικά ÏÏην καÏάλληλη ÏεÏίÏÏαÏη. ÎοκιμάÏÏε να ÏÏηÏιμοÏοιήÏεÏε Ïο Desert Eagle για να ÏίξεÏε ÏολλαÏλοÏÏ ÏκαÏζÏÏοιÏοÏ
Ï ÏÏο νεÏÏ.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îαν δεν ξÎÏεÏε Ïι να κάνεÏε και δεν θÎλεÏε να ÏÏαÏαλήÏεÏε ÏÏ
ÏομαÏικά, "ÏηδήξÏε" Îνα γÏÏο. Îλλά μην αÏήÏεÏε ÏÎ¿Î»Ï ÏÏα να ÏεÏάÏει διÏÏι θα εÏÎλθει ÎαÏνικÏÏ ÎάναÏοÏ!</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îαν θα θÎλαÏε να αÏοÏÏÎÏεÏε ÏÏίÏοÏ
Ï Î±ÏÏ Ïο να ÏÏηÏιμοÏοιοÏν Ïο ÏεÏ
δÏνÏ
Î¼Ï ÏÎ±Ï ÏÏον εÏίÏημο εξÏ
ÏηÏεÏηÏή, ÏÏιάξÏε Îνα λογαÏιαÏÎ¼Ï ÏÏην ιÏÏοÏελίδα : http://www.hedgewars.org/.</translation>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎαÏιÎÏÏε Ïο ÏαÏαδοÏÎ¹Î±ÎºÏ Ïαίξιμο; ÎοκιμάÏÏε μια αÏÏ ÏÎ¹Ï Î±ÏοÏÏολÎÏ! Îα ÏÎ±Ï ÏÏοÏÏÎÏοÏ
ν Îνα διαÏοÏεÏÎ¹ÎºÏ ÏÏÏÏο ÏαιÏνιδιοÏ, αναλÏγÏÏ Ïην αÏοÏÏολή.</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îξ'οÏιÏÎ¼Î¿Ï Ïο ÏαιÏνίδι ÏάνÏα θα καÏαγÏάÏει Ïην Ïιο ÏÏÏÏÏαÏη ÏαÏÏίδα Ïαν εÏίδειξη. ÎÏιλÎξÏε "ΤοÏÎ¹ÎºÏ Î Î±Î¹Ïνίδι" και καÏÏÏιν εÏιλÎξÏε "ÎÏιδείξειÏ" ÏÏην κάÏÏ Î´ÎµÎ¾Î¹Î¬ γÏνία για να ÏÎ¹Ï Î±Î½Î±ÏαÏάγεÏε ή να ÏÎ¹Ï Î´Î¹Î±ÏειÏιÏÏείÏε.</translation>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι λογιÏÎ¼Î¹ÎºÏ ÎνοικÏÎ¿Ï ÎÏδικα (Open Source) και ÎλεÏθεÏο ÎογιÏÎ¼Î¹ÎºÏ (Free Software) Ïο οÏοίο δημιοÏ
ÏγοÏμε ÏÏον ελεÏθεÏο ÏÏÏνο μαÏ. Îν ÎÏεÏε ÏÏοβλήμαÏα ÏÏÏήÏÏε ÏÏο forum αλλά ÏαÏÎ±ÎºÎ±Î»Ï Î¼Î·Î½ ÏεÏιμÎνεÏε Ï
ÏοÏÏήÏιξη 24/7!</translation>
+ <source>Downloadable Content</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι λογιÏÎ¼Î¹ÎºÏ ÎνοικÏÎ¿Ï ÎÏδικα (Open Source) και ÎλεÏθεÏο ÎογιÏÎ¼Î¹ÎºÏ (Free Software) Ïο οÏοίο δημιοÏ
ÏγοÏμε ÏÏον ελεÏθεÏο ÏÏÏνο μαÏ. Îν ÏÎ±Ï Î±ÏÎÏει βοηθήÏÏε Î¼Î±Ï Î¼Îµ μια μικÏή δÏÏεά ή ÏÏ
νειÏÏÎÏεÏε Ïην δική ÏÎ±Ï Î´Î¿Ï
λειά!</translation>
+ <source>Access the user created content downloadable from our website</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι λογιÏÎ¼Î¹ÎºÏ ÎνοικÏÎ¿Ï ÎÏδικα (Open Source) και ÎλεÏθεÏο ÎογιÏÎ¼Î¹ÎºÏ (Free Software) Ïο οÏοίο δημιοÏ
ÏγοÏμε ÏÏον ελεÏθεÏο ÏÏÏνο μαÏ. ÎοιÏαÏÏείÏε Ïο με Ïην οικογÎνειά ÏÎ±Ï ÎºÎ±Î¹ ÏοÏ
Ï ÏίλοÏ
Ï ÏÎ±Ï ÏÏÏÏ ÎµÏÎµÎ¯Ï ÎµÏιθÏ
μείÏε!</translation>
+ <source>Exit game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΣÏ
Ïνά-ÏÏ
κνά θα Ï
ÏάÏÏοÏ
ν εÏίÏημα ÏÏÏÏαθλήμαÏα. Τα εÏικείμενα γεγονÏÏα θα ανακοινÏνονÏαι ÏÏην ιÏÏοÏελίδα : http://www.hedgewars.org/ μεÏικÎÏ Î·Î¼ÎÏÎµÏ Î½ÏÏίÏεÏα.</translation>
+ <source>Manage videos recorded from game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι διαθÎÏιμο Ïε ÏολλÎÏ Î³Î»ÏÏÏεÏ. Îάν η μεÏάÏÏαÏη για Ïη γλÏÏÏα ÏÎ±Ï Î¼Î¿Î¹Î¬Î¶ÎµÎ¹ αÏαÏÏαιÏμÎνη ή λείÏει, μην διÏÏάÏεÏε να εÏικοινÏνίÏεÏε μαζί μαÏ!</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars μÏοÏεί να ÏÏÎξει Ïε μια μεγάλη Ïοικιλία λειÏοÏ
ÏγικÏν ÏÏ
ÏÏημάÏÏν εκ ÏÏν οÏοίÏν ÏÏ
μÏεÏιλαμβάνονÏαι Ïα Microsoft Windows, Mac OS X και Ïο GNU/Linux.</translation>
+ <source>Play a game across a local area network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îην ξεÏνάÏε ÏÏι ÎÏεÏε Ïη δÏ
ναÏÏÏηÏα να "ÏÏήÏεÏε" Ïα δικά ÏÎ±Ï ÏενάÏια ÏαιÏÎ½Î¹Î´Î¹Î¿Ï Ïε ÏοÏÎ¹ÎºÏ ÎºÎ±Î¹ δικÏÏ
ακÏ/διαδικÏÏ
Î±ÎºÏ ÏαιÏνίδι. Îεν είÏÏε ÏεÏιοÏιÏμÎνοι ÏÏην εÏιλογή "ÎÏÎ»Ï Î Î±Î¹Ïνίδι".</translation>
+ <source>Play a game on an official server</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎνÏÏÏ ÏαίζεÏε ÏÏÎÏει να κάνεÏε ÏακÏικά διαλείμμαÏα, ÏοÏ
λάÏιÏÏον κάθε μία ÏÏα.</translation>
+ <source>Feedback</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îαν η κάÏÏα γÏαÏικÏν ÏÎ±Ï Î´ÎµÎ½ μÏοÏεί να ÏαÏÎÏει εÏιÏάÏÏ
νÏη Ï
Î»Î¹ÎºÎ¿Ï Î³Î¹Î± Ïο OpenGL (hardware accelerated OpenGL) ÏÏοÏÏαθήÏÏε να ενεÏγοÏοιήÏεÏε Ïην εÏιλογή ÏÎ±Î¼Î·Î»Î®Ï ÏοιÏÏηÏÎ±Ï ÎÏÏι ÏÏÏε να βελÏιÏθεί η αÏÏδοÏη ÏοÏ
ÏαιÏνιδιοÏ.</translation>
+ <source>Play local network game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎίμαÏÏε ανοικÏοί Ïε ÏÏ
μβοÏ
λÎÏ ÎºÎ±Î¹ εÏοικοδομηÏÎ¹ÎºÏ Î´Î¹Î¬Î»Î¿Î³Î¿. Îαν δεν ÏÎ±Ï Î±ÏÎÏει κάÏι ή ÎÏεÏε μια ÏÏομεÏή ιδÎα, ÏÏÏε ενημεÏÏÏÏε μαÏ!</translation>
+ <source>Play official network game</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎιδικÏÏ ÏÏαν ÏαίζεÏε ÏÏο διαδίκÏÏ
ο, να είÏÏε εÏ
γενικοί και να θÏ
μάÏÏε ÏάνÏα οÏι μÏοÏεί να ÏαίζοÏ
ν ανήλικοι, είÏε μαζί ÏÎ±Ï Î® ενανÏίον ÏαÏ!</translation>
+ <source>Start</source>
+ <translation type="unfinished">ÎκκίνηÏη</translation>
</message>
<message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îιδικοί ÏÏÏÏοι ÏαιÏÎ½Î¹Î´Î¹Î¿Ï ÏÏÏÏ Ïο "ÎαμÏιÏιÏμÏÏ" ή Ïο "ÎοίÏα" ÏÎ±Ï ÎµÏιÏÏÎÏοÏ
ν να αναÏÏÏξεÏε ενÏελÏÏ Î½ÎÎµÏ ÏακÏικÎÏ. ÎοκιμάÏÏε ÏοÏ
Ï Ïε Îνα ÏÏοÏαÏμÏÏιμο ÏαιÏνίδι!</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgwars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Î ÎκδοÏη Hedgewars για Windows Ï
ÏοÏÏηÏίζει Xfire. ΣιγοÏ
ÏεÏ
ÏείÏε οÏι ÏÏοÏθÎÏαÏε Ïο Hedgewars ÏÏη λίÏÏα ÏαιÏνιδιÏν ÏοÏ
, ÏÏÏε οι Ïίλοι ÏÎ±Ï Î½Î± μÏοÏοÏν να ÏÎ±Ï Î´Î¿Ï
ν ÏÏαν εÏÎµÎ¯Ï ÏαίζεÏε.</translation>
+ <source>Control</source>
+ <translation type="obsolete">ÎλεγÏοÏ</translation>
</message>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îεν ÏÏÎÏει ÏοÏΠνα εγκαÏαÏÏήÏεÏε Ïο Hedgewars Ïε Ï
ÏολογιÏÏÎÏ ÏοÏ
δεν ÏÎ±Ï Î±Î½Î®ÎºÎ¿Ï
ν (ÏÏολείο, ÏανεÏιÏÏήμιο, εÏγαÏία, κ.λÏ.). ÎÎ½Ï 'αÏ
ÏοÏ, ζηÏήÏÏε Ïο αÏÏ Ïον Ï
ÏεÏθÏ
νο!</translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι Î¹Î´Î±Î½Î¹ÎºÏ Î³Î¹Î± ÏÏνÏομα ÏαιÏνίδια καÏά Ïη διάÏκεια ÏοÏ
διαλείμμαÏοÏ. ÎÏλά βεβαιÏθείÏε ÏÏι δεν ÏÏοÏθÎÏαÏε ÏολλοÏÏ ÏκανÏζÏÏοιÏοÏ
Ï Î® ÏÏηÏιμοÏοιείÏε Îνα ÏεÏάÏÏιο ÏάÏÏη. ÎείÏÏη ÏοÏ
ÏÏÏνοÏ
και ÏÎ·Ï Ï
Î³ÎµÎ¯Î±Ï Î¼ÏοÏεί να βοηθήÏει εÏίÏηÏ.</translation>
+ <source>Start</source>
+ <translation type="unfinished">ÎκκίνηÏη</translation>
</message>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎανÎÎ½Î±Ï ÏκαÏζÏÏοιÏÎ¿Ï Î´ÎµÎ½ βλάÏÏηκε ÏÏην δημιοÏ
Ïγία αÏ
ÏÎ¿Ï ÏοÏ
ÏαιÏνιδιοÏ.</translation>
+ <source>Update</source>
+ <translation type="unfinished">ÎναβάθμιÏη</translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Hedgewars είναι λογιÏÎ¼Î¹ÎºÏ ÎνοικÏÎ¿Ï ÎÏδικα (Open Source) και ÎλεÏθεÏο ÎογιÏÎ¼Î¹ÎºÏ (Free Software) Ïο οÏοίο δημιοÏ
ÏγοÏμε ÏÏον ελεÏθεÏο ÏÏÏνο μαÏ. Îαν κάÏÎ¿Î¹Î¿Ï ÏÎ±Ï ÏοÏληÏε Ïο ÏαιÏνίδι, ÏÏÎÏει να διεκδικήÏεÏε αÏοζημίÏÏη!</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΣÏ
νδÎÏÏε Îνα ή ÏεÏιÏÏÏÏεÏα gamepad ÏÏιν αÏÏ Ïην ÎναÏξη ÏοÏ
ÏαιÏÎ½Î¹Î´Î¹Î¿Ï ÎÏÏι ÏÏÏε να είναι Ïε θÎÏη να αναθÎÏει ÏοÏ
Ï ÏειÏιÏμοÏÏ ÏοÏ
ÏÏÎ¹Ï Î¿Î¼Î¬Î´ÎµÏ ÏαÏ.</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎημιοÏ
ÏγήÏÏε Îναν λογαÏιαÏÎ¼Ï ÏÏο %1 για να αÏοÏÏÎÏεÏε ÏοÏ
Ï Î¬Î»Î»Î¿Ï
Ï Î±ÏÏ Ïο να ÏÏηÏιμοÏοιοÏν Ïο ÏεÏ
δÏνÏ
Î¼Ï ÏÎ±Ï ÎµÎ½ÏÏÏ ÏαίζεÏε ÏÏον εÏίÏημο εξÏ
ÏηÏεÏηÏή.</translation>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îαν η κάÏÏα γÏαÏικÏν ÏÎ±Ï Î´ÎµÎ½ μÏοÏεί να ÏαÏÎÏει εÏιÏάÏÏ
νÏη Ï
Î»Î¹ÎºÎ¿Ï Î³Î¹Î± Ïο OpenGL (hardware accelerated OpenGL) ÏÏοÏÏαθήÏÏε να αναβαθμίÏεÏε ÏοÏ
Ï Î±Î½ÏίÏÏοιÏοÏ
Ï Î¿Î´Î·Î³Î¿ÏÏ Ï
λικοÏ.</translation>
+ <source>New team</source>
+ <translation type="unfinished">ÎÎα ομάδα</translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Î¥ÏάÏÏοÏ
ν ÏÏία διαÏοÏεÏικά άλμαÏα διαθÎÏιμα. Îλμα ÎµÎ¹Ï Î¼Î®ÎºÎ¿Ï, άλμα ÎµÎ¹Ï ÏÏÎ¿Ï [με Îνα ÏάÏημα],ÏÎ¿Î»Ï Ï
ÏÎ·Î»Ï / οÏίÏθιο άλμα [με δÏο ÏαÏήμαÏα].</translation>
+ <source>Edit team</source>
+ <translation type="unfinished">ÎÏεξεÏγαÏία ομάδαÏ</translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΦοβάÏÏε μήÏÏÏ ÏÎÏεÏε ÏÏο γκÏεμÏ; ÎÏαÏήÏÏε ÏαÏημÎνο Ïο ÏλήκÏÏο ακÏÎ¯Î²ÎµÎ¹Î±Ï [Left Shift] και ÎÏειÏα αÏιÏÏεÏά ή δεξιά ÏÏÏÎ¯Ï Î½Î± κινήÏÏε ÏÏην ÏÏαγμαÏικÏÏηÏα.</translation>
+ <source>Delete team</source>
+ <translation type="unfinished">ÎιαγÏαÏή ομάδαÏ</translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏιÏμÎνα ÏÏλα αÏαιÏοÏν ειδικÎÏ ÏÏÏαÏηγικÎÏ Î® αÏλÏÏ ÏÎ¿Î»Ï ÎµÎºÏαίδεÏ
Ïη, γι 'αÏ
ÏÏ Î¼Î·Î½ εγκαÏαλείÏεÏε Îνα ÏÏ
γκεκÏιμÎνο εÏγαλείο, εάν αÏÏοÏήÏεÏε μια ÏοÏά Ïε Îναν εÏθÏÏ.</translation>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <translation type="unfinished">Îεν μÏοÏείÏε να εÏεξεÏγαÏÏείÏε ÏÎ¹Ï Î¿Î¼Î¬Î´ÎµÏ Î±ÏÏ Ïην εÏιλογή ομάδÏν. ΠηγαίνεÏε ÏίÏÏ ÏÏην κÏÏια Ïελίδα για να ÏÏοÏθÎÏεÏε, να εÏεξεÏγαÏÏείÏε ή να διαγÏάÏεÏε ομάδεÏ.</translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Τα ÏεÏιÏÏÏÏεÏα ÏÏλα δεν λειÏοÏ
ÏγοÏν μÏÎ»Î¹Ï Î±Î³Î³Î¯Î¶Î¿Ï
ν Ïο νεÏÏ. Î ÎÏ
ÏοκαθοδηγοÏμενη ÎÎλιÏÏα καθÏÏ ÎºÎ±Î¹ η ΤοÏÏÏα αÏοÏελοÏν εξαιÏÎÏÎµÎ¹Ï Ïε αÏ
ÏÏ.</translation>
+ <source>Advanced</source>
+ <translation type="unfinished">Îια ÏÏοÏÏÏημÎνοÏ
Ï</translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΠΧαλαÏμÎνη ΦÎÏα ÏÏοκαλεί μÏνο μια μικÏή ÎκÏηξη. ΩÏÏÏÏο, Ïο δÏÏοÏμο ÏÏννεÏο Ïο οÏοίο εÏιÏÏεάζεÏαι αÏÏ Ïον άνεμο μÏοÏεί να δηληÏηÏιάÏει ÏολλοÏÏ ÏκαÏζÏÏοιÏοÏ
Ï Î¼Îµ Ïη μία.</translation>
+ <source>New scheme</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το Πιάνο είναι η Ïιο εÏιζήμια αεÏοÏοÏική εÏίθεÏη. Îα ÏάÏεÏε Ïο ÏκανÏζÏÏοιÏο ο οÏÎ¿Î¯Î¿Ï Ïην εκÏελεί, ÎÏÏι Ï
ÏάÏÏει Îνα ÏεÏάÏÏιο μειονÎκÏημα εÏίÏηÏ.</translation>
+ <source>Edit scheme</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. It's turn radius depends on it's velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Î ÎÏ
ÏοκαθοδηγοÏμενη ÎÎλιÏÏα μÏοÏεί να είναι δÏÏκολη ÏÏη ÏÏήÏη. ΠακÏίνα καμÏÏ
λÏÏηÏÎ¬Ï ÏÎ·Ï ÎµÎ¾Î±ÏÏάÏαι αÏÏ Ïην ÏαÏÏÏηÏά ÏηÏ, εÏομÎνÏÏ ÏÏοÏÏαθήÏÏε να μην ÏÏηÏιμοÏοιείÏε Ïην ÏλήÏη ιÏÏÏ.</translation>
+ <source>Delete scheme</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îι ÎÏ
ÏοκÏλληÏÎµÏ ÎάÏÎºÎµÏ ÎµÎ¯Î½Î±Î¹ Îνα ÏÎλειο εÏγαλείο για να δημιοÏ
ÏγηθοÏν μικÏÎÏ Î±Î»Ï
ÏιδÏÏÎÏ Î±Î½ÏιδÏάÏÎµÎ¹Ï ÏοÏ
βάζοÏ
ν ÏοÏ
Ï Î±Î½ÏίÏαλοÏ
Ï ÏκανÏζÏÏοιÏοÏ
Ï Ïε ÎνÏÎ¿Î½ÎµÏ ÎºÎ±ÏαÏÏάÏÎµÎ¹Ï ... ή ÏÏο νεÏÏ.</translation>
+ <source>New weapon set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το ΣÏÏ
Ïί είναι Ïιο αÏοÏελεÏμαÏÎ¹ÎºÏ ÏÏαν ÏÏηÏιμοÏοιείÏαι Ïε γÎÏÏ
ÏÎµÏ Î® δοκοÏÏ. Îι ÏκαÏζÏÏοιÏοι αÏλÏÏ Î¸Î± "ÏÏ
ÏεÏ
θοÏν" ÏÏο ÎδαÏοÏ.</translation>
+ <source>Edit weapon set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Îάν είÏÏε κολλημÎνοι ÏίÏÏ Î±ÏÏ Îναν εÏθÏÎ¹ÎºÏ ÏκανÏζÏÏοιÏο, ÏÏηÏιμοÏοιήÏÏε Ïο ΣÏÏ
Ïί για να ελεÏ
θεÏÏÏεÏε Ïον εαÏ
ÏÏ ÏÎ±Ï ÏÏÏÎ¯Ï Î½Î± ÏάθεÏε ζημιÎÏ Î±ÏÏ ÎκÏηξη.</translation>
+ <source>Delete weapon set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΠμÎγιÏÏη αÏÏÏÏαÏη ÏοÏ
διανÏει η ΤοÏÏÏα εξαÏÏάÏαι αÏÏ Ïο ÎδαÏÎ¿Ï Ïο οÏοίο ÏÏÎÏει να διαβεί. ΧÏηÏιμοÏοιήÏÏε Ïο κοÏ
μÏί ÏÎ·Ï ÎµÏίθεÏÎ·Ï Î³Î¹Î± ÏÏοκαλÎÏεÏε Ïην ÎκÏηξη νÏÏίÏεÏα.</translation>
+ <source>Reset to default colors</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Το ÏλογοβÏλο είναι ÏÏλο μεν, αλλά μÏοÏεί να ÏÏηÏιμοÏοιηθεί εξίÏοÏ
καλά για ÏκάÏιμο ÏήÏαγγαÏ.</translation>
+ <source>Proxy host</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Incinerating Grenade to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ΧÏηÏιμοÏοιήÏÏε Ïην ÎαÏ
ÏÏική ΧειÏοβομβίδα για να εμÏοδίÏεÏε ÏÏοÏÏÏινÏÏ ÏοÏ
Ï ÏκαÏζÏÏοιÏοÏ
Ï Î±ÏÏ Ïο να διαÏÏίÏοÏ
ν ÎδαÏοÏ, ÏÏÏÏ ÏήÏÎ±Î³Î³ÎµÏ Î® εξÎδÏεÏ.</translation>
+ <source>Proxy port</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÎλεÏε να μάθεÏε ÏοιÏÏ ÎµÎ¯Î½Î±Î¹ ÏίÏÏ Î±ÏÏ Ïο ÏαιÏνίδι; ΠαÏήÏÏε Ïο λογÏÏÏ
Ïο Hedgewars ÏÏο κÏ
ÏίÏÏ Î¼ÎµÎ½Î¿Ï
για να δείÏε Ïα credits.</translation>
+ <source>Proxy login</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Î£Î±Ï Î±ÏÎÏει Ïο Hedgewars; ÎίνεÏε οÏαδÏÏ ÏÏο %1 ή ακολοÏ
θήÏÏε Î¼Î±Ï ÏÏο %2!</translation>
+ <source>Proxy password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎημιοÏ
ÏγήÏÏε ελεÏθεÏα ÏοÏ
Ï Î´Î¹ÎºÎ¿ÏÏ ÏÎ±Ï ÏÏμβοÏ
Ï, Ïα καÏÎλα ÏαÏ, ÏÎ·Î¼Î±Î¯ÎµÏ Î® ακÏμα ÏάÏÏÎµÏ ÎºÎ±Î¹ θÎμαÏα! ΣημειÏÏÏε ÏμÏÏ ÏÏι θα ÏÏÎÏει να Ïα μοιÏαÏÏείÏε κάÏοÏ
για να Ïα ÏÏηÏιμοÏοιήÏεÏε Ïε διαδικÏÏ
Î±ÎºÏ ÏαιÏνίδι.</translation>
+ <source>No proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation type="unfinished">Î£Î±Ï Î±ÏÎÏει ÏÏαγμαÏικά να ÏοÏάÏε Îνα ÏÏ
γκεκÏιμÎνο καÏÎλο; ÎάνÏε μια δÏÏεά Ïε Î¼Î±Ï ÎºÎ±Î¹ λάβεÏε Îνα αÏοκλειÏÏÎ¹ÎºÏ ÎºÎ±ÏÎλο ÏÎ·Ï ÎµÏÎ¹Î»Î¿Î³Î®Ï ÏαÏ!</translation>
+ <source>System proxy settings</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎναβαθμίÏÏε ÏοÏ
Ï Î¿Î´Î·Î³Î¿ÏÏ ÏÎ·Ï ÎºÎ¬ÏÏÎ±Ï Î³ÏαÏικÏν ÏÎ±Ï Î³Î¹Î± να αÏοÏÏγεÏε ÏÏ
ÏÏν ÏÏοβλήμαÏα ÏαίζονÏÎ±Ï Ïο ÏαιÏνίδι.</translation>
+ <source>Socks5 proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏοÏείÏε να βÏείÏε Ïα αÏÏεία ÏÏ
θμίÏεÏν ÏοÏ
Hedgewars ÏÏο "My Documents\Hedgewars". ÎημιοÏ
ÏγήÏÏε ανÏίγÏαÏα αÏÏÎ±Î»ÎµÎ¯Î±Ï Î® ÏάÏÏε Ïα αÏÏεία μαζί ÏαÏ, αλλά μην Ïα εÏεξεÏγαÏÏείÏε ÏειÏοκίνηÏα.</translation>
+ <source>HTTP proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏοÏείÏε να ανÏιÏÏοιÏίÏεÏε Ïα ανÏίÏÏοιÏα αÏÏεία ÏοÏ
Hedgewars (ÏÏÏμÎνα ÏαιÏνίδια και εγγÏαÏÎÏ ÎµÏίδειξηÏ) με Ïο ÏαιÏνίδι, ÎÏÏι ÏÏÏε να Ïα ÏÏÎÏεÏε αÏεÏ
Î¸ÎµÎ¯Î±Ï Î±ÏÏ Ïον αγαÏημÎνο ÏÎ±Ï ÏεÏιηγηÏή αÏÏείÏν ή διαδικÏÏοÏ
.</translation>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÎλεÏε να κάνεÏε οικονομία ÏÏα ÏÏοινιά; ÎÏήÏÏε Ïο ÏÏοινί ενÏÏο βÏίÏκεÏÏε ÏÏον αÎÏα και ÏÏη ÏÏ
νÎÏεια ÏÏ
ÏοβολήÏÏε ξανά. ÎÏο δεν αγγίζεÏε Ïο ÎδαÏÎ¿Ï Î¸Î± εÏαναÏÏηÏιμοÏοιείÏε Ïο ÏÏοινί ÏÎ±Ï ÏÏÏÎ¯Ï ÏÏαÏάλη ÏÏ
ÏομαÏικÏν!</translation>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏοÏείÏε να βÏείÏε Ïα αÏÏεία ÏÏ
θμίÏεÏν ÏοÏ
Hedgewars ÏÏο "Library/Application Support/Hedgewars" ÏÏον ÏÏοÏÏÏÎ¹ÎºÏ ÏÎ±Ï Ïάκελο. ÎημιοÏ
ÏγήÏÏε ανÏίγÏαÏα αÏÏÎ±Î»ÎµÎ¯Î±Ï Î® ÏάÏÏε Ïα αÏÏεία μαζί ÏαÏ, αλλά μην Ïα εÏεξεÏγαÏÏείÏε ÏειÏοκίνηÏα.</translation>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">ÎÏοÏείÏε να βÏείÏε Ïα αÏÏεία ÏÏ
θμίÏεÏν ÏοÏ
Hedgewars ÏÏο ".hedgewars" ÏÏον ÏÏοÏÏÏÎ¹ÎºÏ ÏÎ±Ï Ïάκελο. ÎημιοÏ
ÏγήÏÏε ανÏίγÏαÏα αÏÏÎ±Î»ÎµÎ¯Î±Ï Î® ÏάÏÏε Ïα αÏÏεία μαζί ÏαÏ, αλλά μην Ïα εÏεξεÏγαÏÏείÏε ÏειÏοκίνηÏα.</translation>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <source>Start</source>
- <translation type="unfinished">ÎκκίνηÏη</translation>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNet</name>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please select server from the list above</source>
- <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏιλÎξÏε εξÏ
ÏηÏεÏηÏή αÏÏ Ïην ÏαÏακάÏÏ Î»Î¯ÏÏα</translation>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <source>Control</source>
- <translation type="unfinished">ÎλεγÏοÏ</translation>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation type="unfinished">ΠαιÏνίδι Ïε δίκÏÏ
ο (LAN)</translation>
+ <source>Network</source>
+ <translation type="unfinished">ÎίκÏÏ
ο</translation>
</message>
<message>
- <source>Official server</source>
- <translation type="unfinished">ÎÏίÏÎ·Î¼Î¿Ï ÎµÎ¾Ï
ÏηÏεÏηÏήÏ</translation>
+ <source>Teams</source>
+ <translation type="unfinished">ÎμάδεÏ</translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
- <translation type="unfinished">ÎÎα ομάδα</translation>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Edit team</source>
- <translation type="unfinished">ÎÏεξεÏγαÏία ομάδαÏ</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ÎÏλα</translation>
</message>
<message>
- <source>Delete team</source>
- <translation type="unfinished">ÎιαγÏαÏή ομάδαÏ</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon scheme</source>
- <translation type="unfinished">ÎÎÎ¿Ï ÏÏεδιαÏμÏÏ ÏÏλÏν</translation>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon scheme</source>
- <translation type="unfinished">ÎÏεξεÏγαÏία ÏÏεδιαÏÎ¼Î¿Ï ÏÏλÏν</translation>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delete weapon scheme</source>
- <translation type="unfinished">ÎιαγÏαÏή ÏÏεδιαÏÎ¼Î¿Ï ÏÏλÏν</translation>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
- <translation type="unfinished">Îεν μÏοÏείÏε να εÏεξεÏγαÏÏείÏε ÏÎ¹Ï Î¿Î¼Î¬Î´ÎµÏ Î±ÏÏ Ïην εÏιλογή ομάδÏν. ΠηγαίνεÏε ÏίÏÏ ÏÏην κÏÏια Ïελίδα για να ÏÏοÏθÎÏεÏε, να εÏεξεÏγαÏÏείÏε ή να διαγÏάÏεÏε ομάδεÏ.</translation>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PagePlayDemo</name>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation type="unfinished">ÎνÏάξει</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rename dialog</source>
- <translation type="unfinished">ÎεÏονομαÏία διαλÏγοÏ
</translation>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enter new file name:</source>
- <translation type="unfinished">ÎιÏάγεÏε Ïο Ïνομα ÏοÏ
νÎοÏ
αÏÏείοÏ
:</translation>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot rename to</source>
- <translation type="unfinished">Îεν μÏοÏεί να γίνει μεÏονομαÏία Ïε</translation>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PagePlayDemo</name>
<message>
- <source>Cannot delete file</source>
- <translation type="unfinished">Îεν μÏοÏεί να διαγÏαÏεί Ïο αÏÏείο</translation>
+ <source>Rename dialog</source>
+ <translation type="unfinished">ÎεÏονομαÏία διαλÏγοÏ
</translation>
</message>
<message>
- <source>Please select record from the list</source>
- <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏιλÎξÏε εγγÏαÏή αÏÏ Ïην λίÏÏα</translation>
+ <source>Enter new file name:</source>
+ <translation type="unfinished">ÎιÏάγεÏε Ïο Ïνομα ÏοÏ
νÎοÏ
αÏÏείοÏ
:</translation>
</message>
</context>
<context>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation type="unfinished">ÎημιοÏ
Ïγία</translation>
+ <translation type="obsolete">ÎημιοÏ
Ïγία</translation>
</message>
<message>
<source>Join</source>
- <translation type="unfinished">ΣÏνδεÏη</translation>
+ <translation type="obsolete">ΣÏνδεÏη</translation>
</message>
<message>
- <source>Refresh</source>
- <translation type="unfinished">ÎνανÎÏÏη</translation>
+ <source>Admin features</source>
+ <translation type="unfinished">ΧαÏακÏηÏιÏÏικά διαÏειÏιÏÏή</translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Room Name:</source>
+ <translation type="obsolete">Îνομα δÏμαÏίοÏ
:</translation>
</message>
<message>
- <source>OK</source>
- <translation type="unfinished">ÎνÏάξει</translation>
+ <source>Rules:</source>
+ <translation type="unfinished">ÎανÏÎ½ÎµÏ :</translation>
</message>
<message>
- <source>Admin features</source>
- <translation type="unfinished">ΧαÏακÏηÏιÏÏικά διαÏειÏιÏÏή</translation>
+ <source>Weapons:</source>
+ <translation type="unfinished">ÎÏλα :</translation>
</message>
<message>
- <source>Room Name:</source>
- <translation type="unfinished">Îνομα δÏμαÏίοÏ
:</translation>
+ <source>Search:</source>
+ <translation type="obsolete">ÎναζήÏηÏη :</translation>
</message>
<message>
- <source>This game is in lobby.
-You may join and start playing once the game starts.</source>
- <translation type="unfinished">ÎÏ
ÏÏ Ïο ÏαιÏνίδι είναι Ïε αναμονή.
-ÎÏοÏείÏε να ÏÏ
νδεθείÏε και να ÏαίξεÏε μÏÎ»Î¹Ï Ïο ÏαιÏνίδι ξεκινήÏει.</translation>
+ <source>Clear</source>
+ <translation type="obsolete">ÎαθαÏιÏμÏÏ</translation>
</message>
- <message>
- <source>This game is in progress.
-You may join and spectate now but you'll have to wait for the game to end to start playing.</source>
- <translation type="unfinished">ÎÏ
ÏÏ Ïο ÏαιÏνίδι είναι Ïε εξÎλιξη.
-ÎÏοÏείÏε να ÏÏ
νδεθείÏε και να ÏαÏακολοÏ
θείÏε Ïην εξÎλιξη αλλά θα ÏÏÎÏει να ÏεÏιμÎνεÏε να ÏελειÏÏει Ïο ÏαιÏνίδι για να ξεκινήÏεÏε να ÏαίζεÏε.</translation>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>%1 is the host. He may adjust settings and start the game.</source>
- <translation type="unfinished">%1 είναι ο οικοδεÏÏÏÏηÏ. ÎÏοÏεί να ÏÏοÏαÏμÏζει ÏÎ¹Ï ÏÏ
θμίÏÎµÎ¹Ï ÎºÎ±Î¹ να ξεκινά Ïο ÏαιÏνίδι.</translation>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
- <translation type="unfinished">ΤÏ
ÏÎ±Î¯Î¿Ï ÏάÏÏηÏ</translation>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Games may be played on precreated or randomized maps.</source>
- <translation type="unfinished">Τα ÏαιÏνίδια μÏοÏοÏν να ÏαίζονÏαι Ïε ÏÏοκαÏαÏκεÏ
αÏμÎνοÏ
Ï Î® ÏÏ
ÏαιοÏοιημÎνοÏ
Ï ÏάÏÏεÏ.</translation>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</source>
- <translation type="unfinished">Î ÏÏεδιαÏμÏÏ ÏοÏ
ÏαιÏÎ½Î¹Î´Î¹Î¿Ï ÎºÎ±Î¸Î¿Ïίζει ÏÎ¹Ï Î³ÎµÎ½Î¹ÎºÎÏ ÎµÏιλογÎÏ ÎºÎ±Î¹ ÏÎ¹Ï ÏÏοÏιμήÏÎµÎ¹Ï ÏÏÏÏ Ïον ΧÏÏνο ÏοÏ
ÎÏÏοÏ
, Ïον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο ή Ïον ÎαμÏιÏιÏμÏ.</translation>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Weapon Scheme defines available weapons and their ammunition count.</source>
- <translation type="unfinished">ΠΣÏεδιαÏμÏÏ ÏÏν ÎÏλÏν καθοÏίζει Ïα διαθÎÏιμα ÏÏλα και Ïο ÏοÏÏ ÏÏν ÏÏ
ÏομαÏικÏν.</translation>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>There are %1 clients connected to this room.</source>
- <translation type="unfinished">
- <numerusform>Î¥ÏάÏÏει %1 ÏÏήÏÏÎ·Ï ÏÏ
νδεδεμÎÎ½Î¿Ï Ïε αÏ
ÏÏ Ïο δÏμάÏιο.</numerusform>
- <numerusform>Î¥ÏάÏÏοÏ
ν %1 ÏÏήÏÏÎµÏ ÏÏ
νδεδεμÎνοι Ïε αÏ
ÏÏ Ïο δÏμάÏιο.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>There are %1 teams participating in this room.</source>
- <translation type="unfinished">
- <numerusform>%1 ομάδα ÏÏ
μμεÏÎÏει Ïε αÏ
ÏÏ Ïο δÏμάÏιο.</numerusform>
- <numerusform>%1 Î¿Î¼Î¬Î´ÎµÏ ÏÏ
μμεÏÎÏοÏ
ν Ïε αÏ
ÏÏ Ïο δÏμάÏιο.</numerusform>
- </translation>
- </message>
- <message>
- <source>Please enter room name</source>
- <translation type="unfinished">ÎιÏάγεÏε Ïο Ïνομα ÏοÏ
δÏμαÏίοÏ
</translation>
- </message>
- <message>
- <source>Please select room from the list</source>
- <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏιλÎξÏε δÏμάÏιο αÏÏ Ïη λίÏÏα</translation>
- </message>
- <message>
- <source>Random Maze</source>
- <translation type="unfinished">ΤÏ
ÏÎ±Î¯Î¿Ï ÎαβÏÏινθοÏ</translation>
- </message>
- <message>
- <source>State:</source>
- <translation type="unfinished">ÎαÏάÏÏαÏη :</translation>
- </message>
- <message>
- <source>Rules:</source>
- <translation type="unfinished">ÎανÏÎ½ÎµÏ :</translation>
- </message>
- <message>
- <source>Weapons:</source>
- <translation type="unfinished">ÎÏλα :</translation>
- </message>
- <message>
- <source>Search:</source>
- <translation type="unfinished">ÎναζήÏηÏη :</translation>
- </message>
- <message>
- <source>Clear</source>
- <translation type="unfinished">ÎαθαÏιÏμÏÏ</translation>
- </message>
- <message>
- <source>Warning</source>
- <translation type="unfinished">Î ÏοÏοÏή</translation>
- </message>
- <message>
- <source>The game you are trying to join has started.
-Do you still want to join the room?</source>
- <translation type="unfinished">Το ÏαιÏνίδι ÏÏο οÏοίο ÏÏοÏÏαθείÏε να ÏÏ
νδεθείÏε ÎÏει ήδη ξεκινήÏει.
-ÎÎλεÏε ακÏμα να ÏÏ
νδεθείÏε με Ïο δÏμάÏιο;</translation>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -895,10 +1289,6 @@ Do you still want to join the room?</source>
<translation type="unfinished">Το ÎδαÏÎ¿Ï Î´ÎµÎ½ μÏοÏεί να καÏαÏÏÏαÏεί!</translation>
</message>
<message>
- <source>Add an indestructable border around the terrain</source>
- <translation type="unfinished">Î ÏοÏθήκη ενÏÏ Î¬ÏθαÏÏοÏ
ÏÏ
νÏÏοÏ
γÏÏÏ Î±ÏÏ Ïην ÏίÏÏα</translation>
- </message>
- <message>
<source>Lower gravity</source>
<translation type="unfinished">ÎικÏοβαÏÏÏηÏα</translation>
</message>
@@ -911,10 +1301,6 @@ Do you still want to join the room?</source>
<translation type="unfinished">Îλοιοι ÏκαÏζÏÏοιÏοι ÎÏοÏ
ν αÏÎ¿Î¼Î¹ÎºÏ Ïεδίο δÏ
νάμεÏν</translation>
</message>
<message>
- <source>Enable random mines</source>
- <translation type="obsolete">Enable random mines</translation>
- </message>
- <message>
<source>Gain 80% of the damage you do back in health</source>
<translation type="unfinished">ÎεÏδίÏÏε Ïο 80% ÏÎ·Ï Î¶Î·Î¼Î¹Î¬Ï ÏοÏ
ÏÏοκαλείÏε Ïε Ï
γεία</translation>
</message>
@@ -986,6 +1372,30 @@ Do you still want to join the room?</source>
<source>Each hedgehog has its own ammo. It does not share with the team.</source>
<translation type="unfinished">Îάθε ÏκαÏζÏÏοιÏÎ¿Ï ÎÏει Ïα δικά ÏοÏ
ÏÏ
ÏομαÏικά. Îεν Ïα μοιÏάζεÏαι με Ïην ομάδα.</translation>
</message>
+ <message>
+ <source>Add an indestructible border around the terrain</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You will not have to worry about wind anymore.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Wind will affect almost everything.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams in each clan take successive turns sharing their turn time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add an indestructible border along the bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageSelectWeapon</name>
@@ -997,32 +1407,99 @@ Do you still want to join the room?</source>
<source>Delete</source>
<translation type="unfinished">ÎιαγÏαÏή</translation>
</message>
+ <message>
+ <source>New</source>
+ <translation type="unfinished">ÎÎο</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game (a quick game against the computer, settings are chosen for you)</source>
- <translation type="unfinished">ÎÏÎ»Ï Î Î±Î¹Ïνίδι (Îνα γÏήγοÏο ÏαιÏνίδι ενανÏίον ÏοÏ
Ï
ÏολογιÏÏή, οι ÏÏ
θμίÏÎµÎ¹Ï ÎµÎ¯Î½Î±Î¹ ÏÏοεÏιλεγμÎνεs)</translation>
+ <source>Play a quick game against the computer with random settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a hotseat game against your friends, or AI teams</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Campaign Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Practice your skills in a range of training missions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Watch recorded demos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load a previously saved game</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageTraining</name>
+ <message>
+ <source>Pick the mission or training to play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start fighting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No description available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a mission!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageVideos</name>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Îνομα</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 bytes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>Multiplayer (play a hotseat game against your friends, or AI teams)</source>
- <translation type="unfinished">Πολλοί ΠαίÏÏÎµÏ (Îνα ÏαιÏνίδι ενανÏίον ÏÏν ÏίλÏν ÏÎ±Ï Î® ÏοÏ
Ï
ÏολογιÏÏή)</translation>
+ <source>(in progress...)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode (Practice your skills in a range of training missions). IN DEVELOPMENT</source>
- <translation type="unfinished">ÎξάÏκηÏη (ÎξαÏκήÏÏε ÏÎ¹Ï Î´ÎµÎ¾Î¹ÏÏηÏÎÏ ÏÎ±Ï Ïε Îνα εÏÏÎ¿Ï ÎµÎºÏαιδεÏ
ÏικÏν αÏοÏÏολÏν). ΣΠÎÎÎÎÎÎÎ</translation>
+ <source>encoding</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Demos (Watch recorded demos)</source>
- <translation type="unfinished">ÎÏÎ¹Î´ÎµÎ¯Î¾ÎµÎ¹Ï (ΠαÏακολοÏ
θήÏÏε καÏαγεγÏαμμÎÎ½ÎµÏ ÎµÏιδείξειÏ)</translation>
+ <source>uploading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Load (Load a previously saved game)</source>
- <translation type="unfinished">ΦÏÏÏÏÏη ΣÏÏμÎνοÏ
ΠαιÏÎ½Î¹Î´Î¹Î¿Ï (ΦοÏÏÏÏÏε Îνα ÏÏÏμÎνο ÏαιÏνίδι)</translation>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Campaign Mode (...). IN DEVELOPMENT</source>
- <translation type="unfinished">ÎκÏÏÏαÏεία ΣΠÎÎÎÎÎÎÎ</translation>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1036,10 +1513,6 @@ Do you still want to join the room?</source>
<translation type="unfinished">ΠληÏοÏοÏίεÏ</translation>
</message>
<message>
- <source>Start</source>
- <translation type="unfinished">ÎναÏξη</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation type="unfinished">ΠεÏιοÏιÏμÏÏ ÏÏ
νδÎÏεÏν</translation>
</message>
@@ -1071,6 +1544,22 @@ Do you still want to join the room?</source>
<source>Remove friend</source>
<translation type="unfinished">ÎÏαίÏεÏη ÏίλοÏ
</translation>
</message>
+ <message>
+ <source>Update</source>
+ <translation type="obsolete">ÎναβάθμιÏη</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QCheckBox</name>
@@ -1083,18 +1572,6 @@ Do you still want to join the room?</source>
<translation type="unfinished">ΠλήÏÎ·Ï Î¿Î¸Ïνη</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation type="unfinished">ÎιεÏαÏή Ïε ÏλήÏη οθÏνη</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation type="unfinished">ÎνεÏγοÏοίηÏη ήÏοÏ
</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation type="unfinished">ÎνεÏγοÏοίηÏη μοÏ
ÏικήÏ</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation type="unfinished">Î Ïοβολή FPS</translation>
</message>
@@ -1107,33 +1584,61 @@ Do you still want to join the room?</source>
<translation type="unfinished">Î ÏοÏάÏÏηÏη ημεÏÎ¿Î¼Î·Î½Î¯Î±Ï ÎºÎ±Î¹ ÏÏÎ±Ï ÏÏην εγγÏαÏή ÏοÏ
ονÏμαÏÎ¿Ï Î±ÏÏείοÏ
</translation>
</message>
<message>
- <source>Reduced quality</source>
- <translation type="obsolete">Reduced quality</translation>
- </message>
- <message>
<source>Show ammo menu tooltips</source>
<translation type="unfinished">Î Ïοβολή ÏÏ
μβοÏ
λÏν ÏÏον καÏάλογο ÏÏν ÏÏ
ÏομαÏικÏν</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished">ÎνεÏγοÏοίηÏη ήÏÏν διεÏαÏήÏ</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Record audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use game resolution</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation type="unfinished">ÎνεÏγοÏοίηÏη μοÏ
ÏÎ¹ÎºÎ®Ï Î´Î¹ÎµÏαÏήÏ</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation type="unfinished">ÎνεÏγοÏοίηÏη εÏε διεÏαÏήÏ</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation type="unfinished">ÎημιοÏ
ÏγημÎÎ½Î¿Ï ÏάÏÏηÏ...</translation>
- </message>
- <message>
<source>Human</source>
<translation type="unfinished">ÎνθÏÏÏοÏ</translation>
</message>
@@ -1146,14 +1651,6 @@ Do you still want to join the room?</source>
<translation type="unfinished">(Îξ'οÏιÏÎ¼Î¿Ï ÏÏ
ÏÏήμαÏοÏ)</translation>
</message>
<message>
- <source>Mission</source>
- <translation type="unfinished">ÎÏοÏÏολή</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation type="unfinished">ÎημιοÏ
ÏγημÎÎ½Î¿Ï Î»Î±Î²ÏÏινθοÏ...</translation>
- </message>
- <message>
<source>Community</source>
<translation type="unfinished">ÎοινÏÏηÏα</translation>
</message>
@@ -1163,15 +1660,71 @@ Do you still want to join the room?</source>
</message>
<message>
<source>In lobby</source>
- <translation type="unfinished">Σε αναμονή</translation>
+ <translation type="obsolete">Σε αναμονή</translation>
</message>
<message>
<source>In progress</source>
- <translation type="unfinished">Σε εξÎλιξη</translation>
+ <translation type="obsolete">Σε εξÎλιξη</translation>
</message>
<message>
- <source>Default</source>
- <translation type="obsolete">Default</translation>
+ <source>Disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Cyan</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cyan/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Blue</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Blue/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Green</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Green/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Side-by-side</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Top-Bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Cyan grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cyan/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Blue grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Blue/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Green grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Green/Red grayscale</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1185,303 +1738,530 @@ Do you still want to join the room?</source>
<translation type="unfinished">ΦÏοÏÏιο</translation>
</message>
<message>
- <source>Key binds</source>
- <translation type="unfinished">ÎεÏμεÏÏÎµÎ¹Ï ÎºÎ¿Ï
μÏιÏν</translation>
+ <source>Net game</source>
+ <translation type="unfinished">ÎικÏÏ
Î±ÎºÏ ÏαιÏνίδι</translation>
+ </message>
+ <message>
+ <source>Playing teams</source>
+ <translation type="unfinished">ÎÎ¼Î¬Î´ÎµÏ ÏοÏ
ÏαίζοÏ
ν</translation>
</message>
<message>
- <source>Teams</source>
- <translation type="unfinished">ÎμάδεÏ</translation>
+ <source>Game Modifiers</source>
+ <translation type="unfinished">ΤÏοÏοÏοιηÏÎÏ ÏαιÏνιδιοÏ</translation>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation type="unfinished">ÎαÏικÎÏ ÏÏ
θμίÏειÏ</translation>
+ </message>
+ <message>
+ <source>Team Settings</source>
+ <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï Î¿Î¼Î¬Î´Î±Ï</translation>
+ </message>
+ <message>
+ <source>Videos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLabel</name>
+ <message>
+ <source>Mines Time</source>
+ <translation type="unfinished">ΦÏ
Ïίλι ÎάÏκηÏ</translation>
+ </message>
+ <message>
+ <source>Mines</source>
+ <translation type="unfinished">ÎάÏκεÏ</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation type="obsolete">ÎκδοÏη</translation>
</message>
<message>
<source>Weapons</source>
<translation type="unfinished">ÎÏλα</translation>
</message>
<message>
- <source>Audio/Graphic options</source>
- <translation type="unfinished">ÎÏιλογÎÏ ÎÏοÏ
/ÎÏαÏικÏν</translation>
+ <source>Host:</source>
+ <translation type="unfinished">ÎÏοδÎκÏÎ·Ï (host):</translation>
</message>
<message>
- <source>Net game</source>
- <translation type="unfinished">ÎικÏÏ
Î±ÎºÏ ÏαιÏνίδι</translation>
+ <source>Port:</source>
+ <translation type="unfinished">ÎÏÏα :</translation>
</message>
<message>
- <source>Playing teams</source>
- <translation type="unfinished">ÎÎ¼Î¬Î´ÎµÏ ÏοÏ
ÏαίζοÏ
ν</translation>
+ <source>Resolution</source>
+ <translation type="unfinished">ÎνάλÏ
Ïη</translation>
</message>
<message>
- <source>Game Modifiers</source>
- <translation type="unfinished">ΤÏοÏοÏοιηÏÎÏ ÏαιÏνιδιοÏ</translation>
+ <source>FPS limit</source>
+ <translation type="unfinished">ÎÏιο FPS</translation>
+ </message>
+ <message>
+ <source>Server name:</source>
+ <translation type="unfinished">Îνομα εξÏ
ÏηÏεÏηÏή :</translation>
+ </message>
+ <message>
+ <source>Server port:</source>
+ <translation type="unfinished">ÎÏÏα εξÏ
ÏηÏεÏηÏή :</translation>
+ </message>
+ <message>
+ <source>Initial sound volume</source>
+ <translation type="unfinished">ÎÏÏική ÎνÏαÏη ήÏοÏ
</translation>
+ </message>
+ <message>
+ <source>Damage Modifier</source>
+ <translation type="unfinished">ΤÏοÏοÏοιηÏÎ®Ï Î¶Î·Î¼Î¹Î¬Ï</translation>
+ </message>
+ <message>
+ <source>Turn Time</source>
+ <translation type="unfinished">ΧÏÏÎ½Î¿Ï ÎÏÏοÏ
</translation>
+ </message>
+ <message>
+ <source>Initial Health</source>
+ <translation type="unfinished">ÎÏÏική Υγεία</translation>
+ </message>
+ <message>
+ <source>Sudden Death Timeout</source>
+ <translation type="unfinished">ΧÏÏÎ½Î¿Ï Î¼ÎÏÏι Ïον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ </message>
+ <message>
+ <source>Scheme Name:</source>
+ <translation type="unfinished">Îνομα ΣÏεδιαÏÎ¼Î¿Ï :</translation>
+ </message>
+ <message>
+ <source>Crate Drops</source>
+ <translation type="unfinished">ΡίÏÎµÎ¹Ï ÎºÎ¹Î²ÏÏίÏν</translation>
+ </message>
+ <message>
+ <source>% Dud Mines</source>
+ <translation type="unfinished">% ΤζοÏÏÎ¹ÎµÏ ÎάÏκεÏ</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Îνομα</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">ΤÏÏοÏ</translation>
+ </message>
+ <message>
+ <source>Grave</source>
+ <translation type="unfinished">ΤÏμβοÏ</translation>
+ </message>
+ <message>
+ <source>Flag</source>
+ <translation type="unfinished">Σημαία</translation>
+ </message>
+ <message>
+ <source>Voice</source>
+ <translation type="unfinished">ΦÏνή</translation>
+ </message>
+ <message>
+ <source>Locale</source>
+ <translation type="unfinished">ÎλÏÏÏα</translation>
+ </message>
+ <message>
+ <source>Explosives</source>
+ <translation type="unfinished">ÎκÏηκÏικά</translation>
+ </message>
+ <message>
+ <source>Tip: </source>
+ <translation type="unfinished">ΣÏ
μβοÏ
λή : </translation>
+ </message>
+ <message>
+ <source>Quality</source>
+ <translation type="unfinished">ΠοιÏÏηÏα</translation>
+ </message>
+ <message>
+ <source>% Health Crates</source>
+ <translation type="unfinished">% ÎιβÏÏια ΥγείαÏ</translation>
+ </message>
+ <message>
+ <source>Health in Crates</source>
+ <translation type="unfinished">Υγεία ÏÏα κιβÏÏια</translation>
+ </message>
+ <message>
+ <source>Sudden Death Water Rise</source>
+ <translation type="unfinished">ÎÎ½Î¿Î´Î¿Ï ÏÏÎ¬Î¸Î¼Î·Ï Î½ÎµÏÎ¿Ï ÏÏον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ </message>
+ <message>
+ <source>Sudden Death Health Decrease</source>
+ <translation type="unfinished">ÎείÏÏη Î¥Î³ÎµÎ¯Î±Ï ÏÏον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ </message>
+ <message>
+ <source>There are videos that are currently being processed.
+Exiting now will abort them.
+Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account name (or email): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video title: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video description: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Tags (comma separated): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation type="unfinished">ΨεÏ
δÏνÏ
μο</translation>
+ </message>
+ <message>
+ <source>Stereo rendering</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Rope Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Get Away Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Style</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">ΠλήÏÎ·Ï Î¿Î¸Ïνη</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Basic Settings</source>
- <translation type="unfinished">ÎαÏικÎÏ ÏÏ
θμίÏειÏ</translation>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Team Settings</source>
- <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï Î¿Î¼Î¬Î´Î±Ï</translation>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Misc</source>
- <translation type="unfinished">ÎιάÏοÏα</translation>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QLabel</name>
<message>
- <source>Mines Time</source>
- <translation type="unfinished">ΦÏ
Ïίλι ÎάÏκηÏ</translation>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Mines</source>
- <translation type="unfinished">ÎάÏκεÏ</translation>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Version</source>
- <translation type="unfinished">ÎκδοÏη</translation>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QLineEdit</name>
<message>
- <source>This program is distributed under the GNU General Public License</source>
- <translation type="unfinished">Το ÏÏÏγÏαμμα αÏ
ÏÏ Î´Î¹Î±Î½ÎμεÏαι κάÏÏ Î±ÏÏ Ïην GNU General Public License</translation>
+ <source>unnamed</source>
+ <translation type="unfinished">ÎνÏνÏ
μο</translation>
</message>
<message>
- <source>Developers:</source>
- <translation type="unfinished">Î ÏογÏαμμαÏιÏÏÎÏ :</translation>
+ <source>hedgehog %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Art:</source>
- <translation type="unfinished">ÎÏαÏικά:</translation>
+ <source>anonymous</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMainWindow</name>
<message>
- <source>Sounds:</source>
- <translation type="unfinished">ÎÏοι:</translation>
+ <source>Hedgewars %1</source>
+ <translation>Hedgewars %1</translation>
</message>
<message>
- <source>Translations:</source>
- <translation type="unfinished">ÎεÏαγλÏÏÏίÏειÏ:</translation>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMessageBox</name>
<message>
- <source>Special thanks:</source>
- <translation type="unfinished">ÎιδικÎÏ ÎµÏ
ÏαÏιÏÏίεÏ:</translation>
+ <source>Connection to server is lost</source>
+ <translation type="unfinished">Î ÏÏνδεÏη με Ïον εξÏ
ÏηÏεÏηÏή διακÏÏηκε</translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">ÎÏλα</translation>
+ <source>Error</source>
+ <translation type="unfinished">ΣÏάλμα</translation>
</message>
<message>
- <source>Host:</source>
- <translation type="unfinished">ÎÏοδÎκÏÎ·Ï (host):</translation>
+ <source>File association failed.</source>
+ <translation type="unfinished">ΠανÏιÏÏοίÏιÏη ÏοÏ
αÏÏείοÏ
αÏÎÏÏ
Ïε.</translation>
</message>
<message>
- <source>Port:</source>
- <translation type="unfinished">ÎÏÏα :</translation>
+ <source>Teams - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Net nick</source>
- <translation type="unfinished">ΨεÏ
δÏνÏ
μο</translation>
+ <source>Do you really want to delete the team '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Resolution</source>
- <translation type="unfinished">ÎνάλÏ
Ïη</translation>
+ <source>Cannot delete default scheme '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>FPS limit</source>
- <translation type="unfinished">ÎÏιο FPS</translation>
+ <source>Please select a record from the list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Server name:</source>
- <translation type="unfinished">Îνομα εξÏ
ÏηÏεÏηÏή :</translation>
+ <source>Unable to start server</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Server port:</source>
- <translation type="unfinished">ÎÏÏα εξÏ
ÏηÏεÏηÏή :</translation>
+ <source>Hedgewars - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Initial sound volume</source>
- <translation type="unfinished">ÎÏÏική ÎνÏαÏη ήÏοÏ
</translation>
+ <source>Hedgewars - Success</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Damage Modifier</source>
- <translation type="unfinished">ΤÏοÏοÏοιηÏÎ®Ï Î¶Î·Î¼Î¹Î¬Ï</translation>
+ <source>All file associations have been set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Turn Time</source>
- <translation type="unfinished">ΧÏÏÎ½Î¿Ï ÎÏÏοÏ
</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="obsolete">Îεν μÏοÏεί να δημιοÏ
Ïγηθεί ο καÏÎ¬Î»Î¿Î³Î¿Ï %1</translation>
</message>
<message>
- <source>Initial Health</source>
- <translation type="unfinished">ÎÏÏική Υγεία</translation>
+ <source>Unable to start the server: %1.</source>
+ <translation type="obsolete">Îεν είναι δÏ
ναÏÏν να ξεκινήÏει ο εξÏ
ÏηÏεÏηÏÎ®Ï : %1.</translation>
</message>
<message>
- <source>Sudden Death Timeout</source>
- <translation type="unfinished">ΧÏÏÎ½Î¿Ï Î¼ÎÏÏι Ïον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ <source>Error while authenticating at google.com:
+</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Scheme Name:</source>
- <translation type="unfinished">Îνομα ΣÏεδιαÏÎ¼Î¿Ï :</translation>
+ <source>Login or password is incorrect</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Crate Drops</source>
- <translation type="unfinished">ΡίÏÎµÎ¹Ï ÎºÎ¹Î²ÏÏίÏν</translation>
+ <source>Video upload - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Game scheme</source>
- <translation type="unfinished">ΣÏεδιαÏμÏÏ Î Î±Î¹ÏνιδιοÏ</translation>
+ <source>Error while sending metadata to youtube.com:
+</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>% Dud Mines</source>
- <translation type="unfinished">% ΤζοÏÏÎ¹ÎµÏ ÎάÏκεÏ</translation>
+ <source>Netgame - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Name</source>
- <translation type="unfinished">Îνομα</translation>
+ <source>Please select a server from the list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
- <translation type="unfinished">ΤÏÏοÏ</translation>
+ <source>Please enter room name</source>
+ <translation type="unfinished">ÎιÏάγεÏε Ïο Ïνομα ÏοÏ
δÏμαÏίοÏ
</translation>
</message>
<message>
- <source>Grave</source>
- <translation type="unfinished">ΤÏμβοÏ</translation>
+ <source>Record Play - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Flag</source>
- <translation type="unfinished">Σημαία</translation>
+ <source>Please select record from the list</source>
+ <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏιλÎξÏε εγγÏαÏή αÏÏ Ïην λίÏÏα</translation>
</message>
<message>
- <source>Voice</source>
- <translation type="unfinished">ΦÏνή</translation>
+ <source>Cannot rename to </source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Locale</source>
- <translation type="unfinished">ÎλÏÏÏα</translation>
+ <source>Cannot delete file </source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Restart game to apply</source>
- <translation type="unfinished">ÎÏανεκκινήÏÏε Ïο ÏαιÏνίδι για εÏαÏμογή ÏÏν αλλαγÏν</translation>
+ <source>Room Name - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Explosives</source>
- <translation type="unfinished">ÎκÏηκÏικά</translation>
+ <source>Please select room from the list</source>
+ <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÏιλÎξÏε δÏμάÏιο αÏÏ Ïη λίÏÏα</translation>
</message>
<message>
- <source>Tip: </source>
- <translation type="unfinished">ΣÏ
μβοÏ
λή : </translation>
+ <source>Room Name - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished">ÎÏ
Ïή η διανομή είναι «ÎÏγο Ïε εξÎλιξη» και μÏοÏεί να μην είναι ÏÏ
μβαÏή με Î¬Î»Î»ÎµÏ ÎµÎºÎ´ÏÏÎµÎ¹Ï ÏοÏ
ÏαιÏνιδιοÏ. ÎÏιÏμÎÎ½ÎµÏ Î»ÎµÎ¹ÏοÏ
ÏÎ³Î¯ÎµÏ Î¼ÏοÏεί να μη δοÏ
λεÏοÏ
ν ή να είναι ελλιÏείÏ. ΧÏηÏιμοÏοιήÏÏε Ïην με δική ÏÎ±Ï ÎµÏ
θÏνη!</translation>
+ <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+ <translation type="unfinished">Το ÏαιÏνίδι ÏÏο οÏοίο ÏÏοÏÏαθείÏε να ÏÏ
νδεθείÏε ÎÏει ήδη ξεκινήÏει.
+ÎÎλεÏε ακÏμα να ÏÏ
νδεθείÏε με Ïο δÏμάÏιο;</translation>
</message>
<message>
- <source>Quality</source>
- <translation type="unfinished">ΠοιÏÏηÏα</translation>
+ <source>Schemes - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>% Health Crates</source>
- <translation type="unfinished">% ÎιβÏÏια ΥγείαÏ</translation>
+ <source>Schemes - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Health in Crates</source>
- <translation type="unfinished">Υγεία ÏÏα κιβÏÏια</translation>
+ <source>Do you really want to delete the game scheme '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Sudden Death Water Rise</source>
- <translation type="unfinished">ÎÎ½Î¿Î´Î¿Ï ÏÏÎ¬Î¸Î¼Î·Ï Î½ÎµÏÎ¿Ï ÏÏον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ <source>Videos - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Sudden Death Health Decrease</source>
- <translation type="unfinished">ÎείÏÏη Î¥Î³ÎµÎ¯Î±Ï ÏÏον ÎαÏÎ½Î¹ÎºÏ ÎάναÏο</translation>
+ <source>Do you really want to delete the video '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to remove %1 file(s)?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>Bind schemes and weapons</source>
- <translation type="unfinished">ΣÏζεÏ
ξη ÏÏεδιαÏμÏν και ÏÏλÏν</translation>
+ <source>Do you really want to cancel uploading %1?</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QLineEdit</name>
<message>
- <source>unnamed</source>
- <translation type="unfinished">ÎνÏνÏ
μο</translation>
+ <source>File error</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMainWindow</name>
<message>
- <source>Hedgewars %1</source>
- <translation>Hedgewars %1</translation>
+ <source>Cannot open '%1' for writing</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMessageBox</name>
<message>
- <source>Network</source>
- <translation type="unfinished">ÎίκÏÏ
ο</translation>
+ <source>Cannot open '%1' for reading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Connection to server is lost</source>
- <translation type="unfinished">Î ÏÏνδεÏη με Ïον εξÏ
ÏηÏεÏηÏή διακÏÏηκε</translation>
+ <source>Cannot use the ammo '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Weapons - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Failed to open data directory:
-%1
-Please check your installation</source>
- <translation type="unfinished">ÎÏοÏÏ
Ïία ανοίγμαÏÎ¿Ï ÏακÎλοÏ
δεδομÎνÏν :
- %1
-ΠαÏÎ±ÎºÎ±Î»Ï ÎµÎ»ÎγξÏε Ïην εγκαÏάÏÏαÏή ÏαÏ</translation>
+ <source>Cannot overwrite default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">ÎÏλα</translation>
+ <source>Cannot delete default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not edit default weapon set</source>
- <translation type="obsolete">Can not edit default weapon set</translation>
+ <source>Weapons - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default weapon set</source>
- <translation type="unfinished">Îεν μÏοÏεί να διαγÏαÏεί η βαÏική ÏειÏά ÏÏλÏν</translation>
+ <source>Do you really want to delete the weapon set '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this weapon set?</source>
- <translation type="unfinished">ΣίγοÏ
Ïα να διαγÏαÏεί αÏ
Ïή η ÏειÏά ÏÏλÏν ;</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not overwrite default weapon set '%1'!</source>
- <translation type="unfinished">Îεν μÏοÏεί να ανÏικαÏαÏÏαθεί η βαÏική ÏειÏά ÏÏλÏν '%1'!</translation>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>All file associations have been set.</source>
- <translation type="unfinished">ÎÎ»ÎµÏ Î¿Î¹ ανÏιÏÏοιÏίÏÎµÎ¹Ï Î±ÏÏείÏν ÎÏοÏ
ν Ïεθεί.</translation>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>File association failed.</source>
- <translation type="unfinished">ΠανÏιÏÏοίÏιÏη ÏοÏ
αÏÏείοÏ
αÏÎÏÏ
Ïε.</translation>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot create directory %1</source>
- <translation type="unfinished">Îεν μÏοÏεί να δημιοÏ
Ïγηθεί ο καÏÎ¬Î»Î¿Î³Î¿Ï %1</translation>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation type="unfinished">ÎνÏάξει</translation>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">ΨεÏ
δÏνÏ
μο</translation>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation type="unfinished">ΠαÏÎ±ÎºÎ±Î»Ï ÎµÎ¹ÏάγεÏε Ïο ÏεÏ
δÏνÏ
Î¼Ï ÏαÏ</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1539,176 +2319,221 @@ Please check your installation</source>
<translation type="unfinished">ΦÏÏÏÏÏη</translation>
</message>
<message>
- <source>Setup</source>
- <translation type="unfinished">ΡÏθμιÏη</translation>
+ <source>Associate file extensions</source>
+ <translation type="unfinished">ÎνÏιÏÏοίÏηÏη εÏεκÏάÏεÏν αÏÏείÏν</translation>
</message>
<message>
- <source>Ready</source>
- <translation type="unfinished">ÎÏοιμο</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation type="unfinished">ΤÏ
Ïαία Îμάδα</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
- <translation type="unfinished">ÎνÏιÏÏοίÏηÏη εÏεκÏάÏεÏν αÏÏείÏν</translation>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QTableWidget</name>
<message>
- <source>Room Name</source>
- <translation type="unfinished">Îνομα ÎÏμαÏίοÏ
</translation>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
- <translation>C</translation>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
- <translation>T</translation>
+ <source>Play</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
- <translation type="unfinished">ÎδιοκÏήÏηÏ</translation>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">ΧάÏÏηÏ</translation>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
- <translation type="unfinished">ÎανÏνεÏ</translation>
+ <source>Upload to YouTube</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">ÎÏλα</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>SelWeaponWidget</name>
<message>
- <source>Weapon set</source>
- <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï ÎÏλÏν</translation>
+ <source>Cancel uploading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation type="unfinished">ΠιθανÏÏηÏεÏ</translation>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ammo in boxes</source>
- <translation type="unfinished">Î Ï
ÏομαÏικά ÏÏα κιβÏÏια</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delays</source>
- <translation type="unfinished">ÎαθÏ
ÏÏεÏήÏειÏ</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>TCPBase</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Error</source>
- <translation type="unfinished">ΣÏάλμα</translation>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server: %1.</source>
- <translation type="unfinished">Îεν είναι δÏ
ναÏÏν να ξεκινήÏει ο εξÏ
ÏηÏεÏηÏÎ®Ï : %1.</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
</message>
<message>
- <source>Unable to run engine: %1 (</source>
- <translation type="unfinished">Îεν είναι δÏ
ναÏÏν να ÏÏÎξει η μηÏανή : %1 (</translation>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>RoomsListModel</name>
+ <message>
+ <source>In progress</source>
+ <translation type="unfinished">Σε εξÎλιξη</translation>
+ </message>
+ <message>
+ <source>Room Name</source>
+ <translation type="unfinished">Îνομα ÎÏμαÏίοÏ
</translation>
+ </message>
+ <message>
+ <source>C</source>
+ <translation type="unfinished">C</translation>
+ </message>
+ <message>
+ <source>T</source>
+ <translation type="unfinished">T</translation>
+ </message>
+ <message>
+ <source>Owner</source>
+ <translation type="unfinished">ÎδιοκÏήÏηÏ</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">ΧάÏÏηÏ</translation>
+ </message>
<message>
- <source>Vampirism</source>
- <translation type="unfinished">ÎαμÏιÏιÏμÏÏ</translation>
+ <source>Rules</source>
+ <translation type="unfinished">ÎανÏνεÏ</translation>
</message>
<message>
- <source>Karma</source>
- <translation type="unfinished">ÎοίÏα</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ÎÏλα</translation>
</message>
<message>
- <source>Artillery</source>
- <translation type="unfinished">Î Ï
ÏοβολικÏ</translation>
+ <source>Random Map</source>
+ <translation type="unfinished">ΤÏ
ÏÎ±Î¯Î¿Ï ÏάÏÏηÏ</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation type="unfinished">ÎειÏοÏ
Ïγία ΦÏοÏÏιοÏ
</translation>
+ <source>Random Maze</source>
+ <translation type="unfinished">ΤÏ
ÏÎ±Î¯Î¿Ï ÎαβÏÏινθοÏ</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation type="unfinished">ÎιαίÏεÏη ÎμάδÏν</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Solid Land</source>
- <translation type="unfinished">ΣÏεÏÎµÏ ÎδαÏοÏ</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Border</source>
- <translation type="unfinished">Î ÏοÏθήκη ΣÏ
νÏÏοÏ
</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation type="unfinished">ÎικÏοβαÏÏÏηÏα</translation>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Laser Sight</source>
- <translation type="unfinished">ÎιÏÏÏÏα Laser</translation>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Invulnerable</source>
- <translation type="unfinished">ÎÏÏÏÏοÏ</translation>
+ <source>Weapon set</source>
+ <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï ÎÏλÏν</translation>
</message>
<message>
- <source>Add Mines</source>
- <translation type="obsolete">Add Mines</translation>
+ <source>Probabilities</source>
+ <translation type="unfinished">ΠιθανÏÏηÏεÏ</translation>
</message>
<message>
- <source>Random Order</source>
- <translation type="unfinished">ΤÏ
Ïαία ΣειÏά</translation>
+ <source>Ammo in boxes</source>
+ <translation type="unfinished">Î Ï
ÏομαÏικά ÏÏα κιβÏÏια</translation>
</message>
<message>
- <source>King</source>
- <translation type="unfinished">ÎαÏιλÎαÏ</translation>
+ <source>Delays</source>
+ <translation type="unfinished">ÎαθÏ
ÏÏεÏήÏειÏ</translation>
</message>
<message>
- <source>Place Hedgehogs</source>
- <translation type="unfinished">ΤοÏοθÎÏηÏη ÏκαÏζÏÏοιÏÏν</translation>
+ <source>new</source>
+ <translation type="unfinished">ÎÎο</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation type="unfinished">Î ÏÏ
μμοÏία μοιÏάζεÏαι Ïα ÏÏ
ÏομαÏικά</translation>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Disable Girders</source>
- <translation type="unfinished">ÎÏενεÏγοÏοίηÏη δοκÏν</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
- <translation type="unfinished">ÎÏενεÏγοÏοίηÏη ÎνÏικειμÎνÏν ÎδάÏοÏ
Ï</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished">ÎειÏοÏ
Ïγία ÎÏιβίÏÏÎ·Ï Î³Î¹Î± Ïον Ï
ÏολογιÏÏή</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Reset Health</source>
- <translation type="unfinished">ÎÏαναÏοÏά ΥγείαÏ</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>Unlimited Attacks</source>
- <translation type="unfinished">ÎÏεÏιÏÏιÏÏÎµÏ ÎÏιθÎÏειÏ</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">ÎκÏ
Ïο</translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation type="unfinished">ÎÏαναÏοÏά ÎÏλÏν</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation type="unfinished">Î Ï
ÏομαÏικά ανά ÏκαÏζÏÏοιÏο</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1842,12 +2667,6 @@ Please check your installation</source>
<translation type="unfinished">αιÏμαλÏÏιÏη</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation type="unfinished">ÏληÏοÏοÏίεÏ
-ÏκαÏζÏÏοιÏοÏ
</translation>
- </message>
- <message>
<source>quit</source>
<translation type="unfinished">ÎξοδοÏ</translation>
</message>
@@ -1875,33 +2694,41 @@ info</source>
<source>slot 10</source>
<translation type="unfinished">θÎÏη 10</translation>
</message>
+ <message>
+ <source>mute audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>record</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation type="unfinished">ÎαÏικÎÏ Î¡Ï
θμίÏειÏ</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï ÎÏλÏν</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ÎÏλα</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation type="unfinished">ΡÏ
θμίÏÎµÎ¹Ï ÎºÎ¬Î¼ÎµÏÎ±Ï ÎºÎ±Î¹ δείκÏη ÏονÏικιοÏ</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation type="unfinished">ÎιάÏοÏα</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished">ÎεÏακινήÏÏε ÏοÏ
Ï ÏκαÏζÏÏοιÏοÏÏ ÏÎ±Ï ÎºÎ±Î¹ ÏημαδÎÏÏε :</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished">ÎιαÏÏίÏÏε κενά και εμÏÏδια ÏηδÏνÏÎ±Ï :</translation>
</message>
@@ -1961,6 +2788,14 @@ info</source>
<source>Toggle labels above hedgehogs:</source>
<translation type="unfinished">ÎναλλάξÏε ÏÎ¹Ï ÎµÏιγÏαÏÎÏ ÏÎ¬Î½Ï Î±ÏÏ ÏοÏ
Ï ÏκαÏζÏÏοιÏοÏ
Ï :</translation>
</message>
+ <message>
+ <source>Record video:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_en.ts b/share/hedgewars/Data/Locale/hedgewars_en.ts
index cae9431..e36c631 100644
--- a/share/hedgewars/Data/Locale/hedgewars_en.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_en.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="en">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,11 +140,68 @@
<translation>Edit schemes</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">Map</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Cannot create directory %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -102,7 +255,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +300,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">Nickname</translation>
</message>
@@ -165,6 +312,63 @@ or pick another nickname in game config:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,18 +384,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Map</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Themes</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>All</translation>
</message>
@@ -216,10 +408,6 @@ Please pick another nickname:</source>
<translation>Wacky</translation>
</message>
<message>
- <source>Type</source>
- <translation>Type</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation type="unfinished"></translation>
</message>
@@ -228,27 +416,95 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Random</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -295,7 +551,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 has joined</translation>
+ <translation type="obsolete">%1 *** %2 has joined</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +577,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Password</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -337,6 +608,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +637,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +662,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +704,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">General</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +745,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +801,40 @@ Please pick another nickname:</source>
<translation>General</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Advanced</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Name</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Random Team</translation>
</message>
</context>
<context>
@@ -509,312 +895,87 @@ Please pick another nickname:</source>
<translation>
<numerusform><b>%1</b> was scared and skipped turn <b>%2</b> time.</numerusform>
<numerusform><b>%1</b> was scared and skipped turn <b>%2</b> times.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -824,38 +985,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Start</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Control</translation>
+ <translation type="obsolete">Control</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>LAN game</translation>
+ <source>Update</source>
+ <translation type="unfinished">Update</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Official server</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -902,10 +1067,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">General</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Advanced</translation>
</message>
@@ -945,6 +1106,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Teams</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Weapons</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -961,11 +1210,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Create</translation>
+ <translation type="obsolete">Create</translation>
</message>
<message>
<source>Join</source>
- <translation>Join</translation>
+ <translation type="obsolete">Join</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1222,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Room Name:</translation>
+ <translation type="obsolete">Room Name:</translation>
</message>
<message>
<source>Rules:</source>
@@ -983,14 +1232,6 @@ Please pick another nickname:</source>
<source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Search:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Clear</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%1 players online</source>
<translation type="unfinished">
@@ -998,6 +1239,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1409,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1164,26 +1421,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Load</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1229,19 +1474,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1256,10 +1503,6 @@ Please pick another nickname:</source>
<translation>Info</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Restrict Joins</translation>
</message>
@@ -1293,7 +1536,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Update</translation>
+ <translation type="obsolete">Update</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1307,18 +1562,6 @@ Please pick another nickname:</source>
<translation>Fullscreen</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Frontend fullscreen</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Enable sound</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Enable music</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Show FPS</translation>
</message>
@@ -1335,18 +1578,6 @@ Please pick another nickname:</source>
<translation>Show ammo menu tooltips</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Enable frontend sounds</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Enable frontend music</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Frontend effects</translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1366,51 +1597,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>generated map...</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>Human</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>Level</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
- <translation>(System default)</translation>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
- <translation>Mission</translation>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>Human</translation>
</message>
<message>
- <source>In lobby</source>
- <translation type="unfinished"></translation>
+ <source>Level</source>
+ <translation>Level</translation>
</message>
<message>
- <source>In progress</source>
+ <source>(System default)</source>
+ <translation>(System default)</translation>
+ </message>
+ <message>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1450,10 +1685,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1489,18 +1720,6 @@ Please pick another nickname:</source>
<translation>Fort</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Key binds</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Teams</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Audio/Graphic options</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Net game</translation>
</message>
@@ -1508,37 +1727,17 @@ Please pick another nickname:</source>
<source>Playing teams</source>
<translation>Playing teams</translation>
</message>
- <message>
- <source>Game Modifiers</source>
- <translation>Game Modifiers</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Basic Settings</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Team Settings</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Misc</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <message>
+ <source>Game Modifiers</source>
+ <translation>Game Modifiers</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Basic Settings</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Team Settings</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,10 +1747,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1565,27 +1760,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Developers:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Art:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sounds:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Translations:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Special thanks:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Weapons</source>
@@ -1644,10 +1819,6 @@ Please pick another nickname:</source>
<translation>Crate Drops</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Game scheme</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Dud Mines</translation>
</message>
@@ -1684,10 +1855,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1728,10 +1895,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1762,10 +1925,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1793,6 +1952,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Fullscreen</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1815,6 +2018,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1831,10 +2038,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1881,47 +2084,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Cannot create directory %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Cannot create directory %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Unable to start the server: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Unable to start the server: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2040,16 +2208,42 @@ Do you still want to join the room?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nickname</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Please enter your nickname</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2107,47 +2301,86 @@ Do you still want to join the room?</translation>
<translation>Load</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Setup</translation>
+ <source>Associate file extensions</source>
+ <translation>Associate file extensions</translation>
</message>
<message>
- <source>Ready</source>
- <translation>Ready</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Random Team</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
- <translation>Associate file extensions</translation>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>More info</source>
+ <source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default options</source>
+ <source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Open videos directory</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Upload to YouTube</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cancel uploading</source>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2199,6 +2432,25 @@ Do you still want to join the room?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2226,105 +2478,43 @@ Do you still want to join the room?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirism</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artillery</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Fort Mode</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Divide Teams</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Solid Land</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Add Border</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Low Gravity</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Laser Sight</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Invulnerable</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Random Order</translation>
- </message>
- <message>
- <source>King</source>
- <translation>King</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Place Hedgehogs</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Clan Shares Ammo</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Disable Girders</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2459,12 +2649,6 @@ Do you still want to join the room?</translation>
<translation>capture</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>hedgehogs
-info</translation>
- </message>
- <message>
<source>quit</source>
<translation>quit</translation>
</message>
@@ -2500,33 +2684,33 @@ info</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Basic controls</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Weapon controls</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Weapons</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Camera and cursor controls</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Other</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Move your hogs and aim:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Traverse gaps and obstacles by jumping:</translation>
</message>
@@ -2590,6 +2774,10 @@ info</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_es.ts b/share/hedgewars/Data/Locale/hedgewars_es.ts
index 20c6805..e2e2a0a 100644
--- a/share/hedgewars/Data/Locale/hedgewars_es.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_es.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="es">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,12 +140,73 @@
<translation>Editar modos de juego</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Cuando esta opción esté activada escoger un modo de juego escogerá el set de armas correspondiente</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Opciones de juego</translation>
</message>
<message>
- <source>Game Options</source>
- <translation type="unfinished">Opciones de juego</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">No se pudo crear el directorio %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -102,7 +259,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +304,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">El nick %1 ya está registrado
-en Hedgewars.org. Por favor,
-introduce ahora tu clave de acceso
-o elige otro nick en las preferencias del juego:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">Nick</translation>
</message>
@@ -165,6 +316,63 @@ o elige otro nick en las preferencias del juego:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,18 +388,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temas</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtro</translation>
- </message>
- <message>
<source>All</source>
<translation>Todos</translation>
</message>
@@ -216,10 +412,6 @@ Please pick another nickname:</source>
<translation>Lunático</translation>
</message>
<message>
- <source>Type</source>
- <translation>Tipo</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Túneles estrechos</translation>
</message>
@@ -228,28 +420,96 @@ Please pick another nickname:</source>
<translation>Túneles normales</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Túneles anchos</translation>
+ <source>Seed</source>
+ <translation>Semilla</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Islas pequeñas</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Islas medianas</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Islas grandes</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>Semilla</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Aleatorio</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
- <translation>Cambiar</translation>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Cargar mapa</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished">Mapas dibujados a mano</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished">Todos los ficheros</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -295,7 +555,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 ha entrado</translation>
+ <translation type="obsolete">%1 *** %2 ha entrado</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +581,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Contraseña</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -337,6 +612,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +641,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +666,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +708,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Enviar datos</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">General</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +749,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +805,40 @@ Please pick another nickname:</source>
<translation>General</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avanzado</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Sombrero</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Nombre</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Equipo aleatorio</translation>
</message>
</context>
<context>
@@ -500,321 +890,96 @@ Please pick another nickname:</source>
<message numerus="yes">
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation>
- <numerusform><b>%1</b> acabó con <b>%2</b> de sus propios miembros.</numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> tenÃa demasiado miedo y pasó <b>%2</b> turno.</numerusform>
- <numerusform><b>%1</b> tenÃa demasiado miedo y pasó <b>%2</b> turnos.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Elige el mismo color que tus amigos para hacer una alianza con ellos. Cada uno de vosotros controlará sus propios erizos, pero la victoria o derrota será compartida por vuestra facción.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Puede que algunas armas hagan poco daño, pero pueden ser realmente devastadoras si son usadas en el momento correcto. Prueba a usar la Desert eagle para empujar erizos enemigos al agua, por ejemplo.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Si no tienes claro qué vas a hacer y prefieres no desperdiciar munición puedes pasar un turno. ¡Pero ten cuidado, si dejas pasar muchos turnos puede que empiece la muerte súbita!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Si prefieres que nadie más use tu nick en el servidor oficial puedes registrarlo en http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>¿Estás cansado del modo de juego de siempre? Prueba alguna de las misiones, encontrarás en ellas nuevos tipos de juego dependiendo de la que elijas.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>El juego intentará guardar la última partida como una demo de forma predeterminada. Más tarde puedes ir a "Juego local" y visitar la sección de "Demos" en la esquina inferior derecha para reproducirlas o gestionarlas.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. Si tienes algún problema estaremos encantados de ayudarte en nuestros foros o canal de IRC, pero ¡no esperes que estemos allà las 24 horas del dÃa!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. ¡Si te gusta podrÃas considerar el ayudarnos con una pequeña donación o contribuyendo con tu propio trabajo!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. ¡Compártelo con tu famÃlia y amigos tanto como quieras!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>De cuando en cuando celebramos torneos oficiales. Puedes mantenerte al dÃa sobre los próximos eventos en http://www.hedgewars.org.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars está disponible en varios idiomas. Si no encuentras traducción a tu idioma o piensas que la actual es de baja calidad o está desactualizada estaremos encantados de aceptar tu colaboración para mejorarla.</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars es un juego multiplataforma que puede ser ejecutado en diversos sistemas operativos, incluyendo Windows, Mac OS X y Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Recuerda: puedes crear tus propias partidas multijugador tanto en local como por red, no estás limitado a jugar contra la máquina.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Tu salud es lo primero. Recuerda descansar unos minutos al menos una vez por cada hora de juego.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Si tu tarjeta gráfica no soporta aceleración gráfica mediante OpenGL prueba a habilitar el modo de baja calidad gráfica en la pantalla de opciones, puede que mejore el rendimiento del juego.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Siempre estamos abiertos a sugerencias y opiniones constructivas. Si hay algo que no te guste o tienes grandes ideas que te gustarÃa ver en el juego, ¡háznoslo saber!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Si juegas a través de internet recuerda mantener tus buenos modales y siempre ten en cuenta que puede que estés jugando con o contra menores de edad.</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Los modos de juego especiales como "vampirismo" o "karma" te permiten desarrollar tácticas de juego completamente nuevas. ¡Pruébalos en tu próxima partida!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>¡Nunca instales Hedgewars en ordenadores que no te pertenezcan tales como los de tu escuela, universidad o trabajo sin perdir permiso primero a las personas responsables de los mismos!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars es realmente genial para jugar partidas rápidas durante pausas o descansos; sólo recuerda no añadir muchos erizos y no usar mapas excesivamente grandes para que la partida no se alargue demasiado. Reducir la duración de los turnos o la vida inicial también puede ayudar.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Ningún erizo fue lastimado durante la creación de este juego.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars es un juego gratuito de código abierto que hemos creado en nuestro tiempo libre. Si alguien te ha vendido el juego deberÃas pedirle que te devuelva tu dinero.</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Conecta tus mandos al ordenador antes de iniciar el juego para poder asignar correctamente los controles de a equipo.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Crea una cuenta con tu nick en %1 para evitar que otras personas puedan usarlo en el servidor oficial.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Si tu tarjeta gráfica no es capaz de usar aceleración gráfica mediante OpenGL prueba a instalar drivers más actualizados.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Hay tres tipos de salto en el juego. Presiona [salto alto] dos veces para realizar un salto muy alto, vertical y ligeramente hacia atrás.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>¿Te da miedo caerte por una cornisa? Mantén presionado [aumentar precisión] para voltearte a [izquierda] o [derecha] sin moverte del sitio.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Algunas armas pueden requerir estrategias especiales o mucho entrenamiento antes de ser usadas correctamente. No tires la a toalla con alguna de ellas sólo porque has fallado el tiro la primera vez.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>La mayorÃa de armas se desactivarán al tocar el agua. El abejorro y la tarta son algunas de las excepciones a la regla.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>La explosión del limbuger añejo es relativamente pequeña, pero produce una nube de gas venenoso que será arrastrada por el viento, siendo capaz de intoxicar a varios erizos a la vez.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>El piano es el ataque aéreo más destructivo del juego, aunque perderás el erizo que lo lance, asà que úsalo con cuidado.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Las bombas lapa son perfectas para crear reacciones en cadena y mandar a tus enemigos al agua... o la Luna.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>El mazo es mucho más efectivo si lo usas sobre vigas o puentes. Los erizos golpeados simplemente caerán por el agujero como Alicia por la madriguera.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Si estás atrapado tras un erizo enemigo puedes usar el mazo para abrirte paso sin resultar dañado por una explosión.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>El alcance de la tarta depende de lo escarpado del terreno que tenga que atravesar, aunque puedes pulsar [atacar] para detonarla antes de que el contador llegue a cero.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>El lanzallamas es un arma, pero puede usarse para excavar túneles en caso de necesidad.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>¿Quieres saber quiénes son los desarrolladores del juego? Pulsa el logo del juego en la pantalla principal para ver los créditos.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>¿Te gusta Hedgewars? ¡Hazte fan en %1 o sÃguenos en %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>¡Puedes dibujar tus propias tumbas, sombreros, banderas o incluso mapas y temas! Sólo ten en cuenta que el juego no es capaz de enviar archivos todavÃa, asà que tendrás que enviar tú mismo los archivos a tus amigos para poder jugar en red con ellos.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>¿Te gustarÃa poder usar un sombrero especial, sólo para ti? Haz una donación y dinos qué sombrero quieres, lo dibujaremos para ti.</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Mantén los drivers de tu tarjeta gráfica actualizados para evitar posibles problemas con este y otros juegos.</translation>
+ <numerusform><b>%1</b> acabó con <b>%2</b> de sus propios miembros.</numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puedes encontrar los archivos de configuración del juego en la carpeta "Mis Documentos\Hedgewars". Haz copias de seguridad de los mismos o cópialos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> tenÃa demasiado miedo y pasó <b>%2</b> turno.</numerusform>
+ <numerusform><b>%1</b> tenÃa demasiado miedo y pasó <b>%2</b> turnos.</numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Puedes asociar los tipos de archivo relacionados, partidas guardadas y demos, con Hedgewars para lanzarlos directamente desde tu gestor de archivos o navegador favoritos.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>¿Necesitas conservar cuerdas? Cuando estés usando una cuerda puedes desengancharla y volver a lanzarla de nuevo. ¡Mientras no toques el suelo seguirás usando la misma cuerda continuamente sin desperdiciar munición adicional!</translation>
+ <source>Save</source>
+ <translation type="unfinished">Guardar</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puedes encontrar los archivos de configuración del juego en la carpeta "Library/Application Support/Hedgewars" dentro de tu directorio personal. Puedes hacer copias de seguridad de los mismos o copiarlos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puedes encontrar los archivos de configuración del juego en la carpeta ".hedgewars" dentro de tu directorio personal. Puedes hacer copias de seguridad de los mismos o copiarlos a otro ordenador si lo deseas, pero no intentes editarlos a mano para evitar posibles pérdidas de datos.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>La versión de Hedgewars para Windows soporta Xfire. Recuerda agregar Hedgewars a tu lista de juegos para que tus amigos puedan saber cuándo estás jugando.</translation>
+ <source>Downloadable Content</source>
+ <translation>Contenido adicional</translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Puedes usar el cóctel molotov o el lanzallamas para evitar que erizos enemigos crucen túneles angostos o puentes.</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>El abejorro puede ser complicado de usar. Su maniobrabilidad depende de su velocidad, asà que intenta no lanzarlo a máxima potencia.</translation>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Contenido adicional</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -824,38 +989,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Empezar</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Opciones</translation>
+ <translation type="obsolete">Opciones</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished">Contenido adicional</translation>
+ <source>Start</source>
+ <translation type="unfinished">Empezar</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Red local</translation>
+ <source>Update</source>
+ <translation type="unfinished">Actualizar</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Servidor oficial</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -902,10 +1071,6 @@ Please pick another nickname:</source>
<translation>Eliminar set de armas</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">General</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Avanzado</translation>
</message>
@@ -945,6 +1110,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Equipos</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Set de armas</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -961,11 +1214,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Crear</translation>
+ <translation type="obsolete">Crear</translation>
</message>
<message>
<source>Join</source>
- <translation>Entrar</translation>
+ <translation type="obsolete">Entrar</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1226,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Nombre de la sala:</translation>
+ <translation type="obsolete">Nombre de la sala:</translation>
</message>
<message>
<source>Rules:</source>
@@ -985,11 +1238,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Búsqueda:</translation>
+ <translation type="obsolete">Búsqueda:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Limpiar</translation>
+ <translation type="obsolete">Limpiar</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1251,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1421,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1164,26 +1433,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Cargar</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1229,19 +1486,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1252,10 +1511,6 @@ Please pick another nickname:</source>
<translation>Expulsar</translation>
</message>
<message>
- <source>Start</source>
- <translation>Empezar</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Impedir que entren más jugadores</translation>
</message>
@@ -1293,7 +1548,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>Actualizar</translation>
+ <translation type="obsolete">Actualizar</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1303,10 +1570,6 @@ Please pick another nickname:</source>
<translation>Pantalla completa</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Habilitar sonidos del juego</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Mostrar FPS</translation>
</message>
@@ -1315,14 +1578,6 @@ Please pick another nickname:</source>
<translation>Mostrar el daño según ocurre</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Habilitar música del juego</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Interfaz a pantalla completa</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Agregar fecha y hora al nombre de los ficheros</translation>
</message>
@@ -1335,45 +1590,57 @@ Please pick another nickname:</source>
<translation>Mostrar globos de ayuda sobre el armamento</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Habilitar sonidos del interfaz</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Habilitar música del interfaz</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Habilitar efectos del interfaz</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>Terreno aleatorio...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Humano</translation>
</message>
@@ -1386,14 +1653,6 @@ Please pick another nickname:</source>
<translation>(Predeterminado del sistema)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>Laberinto aleatorio...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Misión</translation>
- </message>
- <message>
<source>Community</source>
<translation>Comunidad</translation>
</message>
@@ -1403,15 +1662,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>En espera</translation>
+ <translation type="obsolete">En espera</translation>
</message>
<message>
<source>In progress</source>
- <translation>En progreso</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>Mapa dibujado a mano...</translation>
+ <translation type="obsolete">En progreso</translation>
</message>
<message>
<source>Disabled</source>
@@ -1450,10 +1705,6 @@ Please pick another nickname:</source>
<translation>Arriba-Abajo</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Temblor</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Rojo/Cian en escala de grises</translation>
</message>
@@ -1485,22 +1736,10 @@ Please pick another nickname:</source>
<translation>Miembros del equipo</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Asociaciones de teclas</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Fuerte</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Equipos</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Opciones de Audio y Gráficos</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Juego en red</translation>
</message>
@@ -1512,33 +1751,13 @@ Please pick another nickname:</source>
<source>Game Modifiers</source>
<translation>Modificadores</translation>
</message>
- <message>
- <source>Basic Settings</source>
- <translation>Opciones básicas</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Opciones del equipo</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Otras opciones</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Modos de juego y sets de armas</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <message>
+ <source>Basic Settings</source>
+ <translation>Opciones básicas</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Opciones del equipo</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,30 +1767,10 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Developers:</source>
- <translation>Desarrolladores:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Gráficos:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Traducciones:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Agradecimientos:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Set de armas</translation>
</message>
@@ -1601,11 +1800,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Versión</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sonidos:</translation>
+ <translation type="obsolete">Versión</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1644,10 +1839,6 @@ Please pick another nickname:</source>
<translation>Aparición de cajas</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Modo de juego</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% minas defectuosas</translation>
</message>
@@ -1684,12 +1875,6 @@ Please pick another nickname:</source>
<translation>Consejo: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Esta es una versión experimental del juego y puede no ser compatible con otras versiones del mismo,
-asà como carecer de algunas funcionalidades o simplemente funcionar mal.
-¡Ãsalo bajo tu propia responsabilidad!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Calidad</translation>
</message>
@@ -1730,10 +1915,6 @@ asà como carecer de algunas funcionalidades o simplemente funcionar mal.
<translation>% duración de retirada</translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1764,10 +1945,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1795,6 +1972,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Pantalla completa</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1817,6 +2038,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1833,10 +2058,6 @@ Do you really want to quit?</source>
<translation>No se pudieron asociar los tipos de fichero.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1883,47 +2104,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">No se pudo crear el directorio %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">No se pudo crear el directorio %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">No se pudo iniciar el servidor: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">No se pudo iniciar el servidor: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2042,16 +2228,42 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nick</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Por favor introduce tu nick</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2109,26 +2321,10 @@ Do you still want to join the room?</source>
<translation>Cargar</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Configuración</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Listo</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Equipo aleatorio</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Asociar tipos de archivo</translation>
</message>
<message>
- <source>more</source>
- <translation>más</translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2152,6 +2348,61 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2185,7 +2436,7 @@ Do you still want to join the room?</source>
</message>
<message>
<source>Weapons</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Set de armas</translation>
</message>
<message>
<source>Random Map</source>
@@ -2201,6 +2452,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2228,106 +2498,44 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirismo</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>ArtillerÃa</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Fuertes</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Separar equipos</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Terreno indestructible</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Añadir borde</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Baja gravedad</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Mira láser</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Invulnerabilidad</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Orden aleatorio</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Rey</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Posicionar erizos</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Compartir munición</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Deshabilitar vigas</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Deshabilitar decoraciones</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>AI Survival Mode</source>
- <translation>Supervivencia contra la computadora</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>Ataques ilimitados</translation>
- </message>
- <message>
- <source>Reset Weapons</source>
- <translation>Reiniciar munición</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Munición individualizada</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Reset Health</source>
- <translation>Restaurar salud</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Deshabilitar viento</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Más viento</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tag team</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Añadir borde inferior</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2445,12 +2653,6 @@ Do you still want to join the room?</source>
<translation>capturar</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>información de
-los erizos</translation>
- </message>
- <message>
<source>quit</source>
<translation>salir</translation>
</message>
@@ -2502,33 +2704,33 @@ los erizos</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Controles básicos</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Armas</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Set de armas</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Cámara y cursor</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Otros</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Mueve tus erizos y apunta:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Sortea huecos y obstáculos saltando:</translation>
</message>
@@ -2592,6 +2794,10 @@ los erizos</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_fi.ts b/share/hedgewars/Data/Locale/hedgewars_fi.ts
index 0e33374..171ca6d 100644
--- a/share/hedgewars/Data/Locale/hedgewars_fi.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_fi.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="fi">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,11 +140,68 @@
<translation>Muokkaa kaavaa</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">Kartta</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Hakemiston %1 luonti epäonnistui</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -102,7 +255,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +300,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Nimimerkkisi %1 on
-rekisteröity Hedgewars.org-sivustolla
-Ole hyvä ja syötä salasanasi
-tai aseta eri nimimerkki asetuksissa:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">Nimimerkki</translation>
</message>
@@ -165,6 +312,63 @@ tai aseta eri nimimerkki asetuksissa:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,14 +384,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Kartta</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Suodatin</translation>
- </message>
- <message>
<source>All</source>
<translation>Kaikki</translation>
</message>
@@ -212,14 +408,6 @@ Please pick another nickname:</source>
<translation>Sekopäinen</translation>
</message>
<message>
- <source>Themes</source>
- <translation>Teemat</translation>
- </message>
- <message>
- <source>Type</source>
- <translation>Tyyppi</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Pieniä tunneleita</translation>
</message>
@@ -228,27 +416,95 @@ Please pick another nickname:</source>
<translation>Keskikokoisia tunneleita</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Laajoja tunneleita</translation>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Pieniä kelluvia saaria</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Keskikokoisia kelluvia saaria</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Suuria kelluvia saaria</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Satunnainen</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -295,7 +551,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 liittyi</translation>
+ <translation type="obsolete">%1 *** %2 liittyi</translation>
</message>
<message>
<source>%1 *** %2 has left</source>
@@ -321,8 +577,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Salasana</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -337,6 +608,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +637,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +662,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +704,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Aseta tiedot</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Yleiset</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +745,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +801,40 @@ Please pick another nickname:</source>
<translation>Yleiset</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Lisäasetukset</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Hattu</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Nimi</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Satunnainen joukkue</translation>
</message>
</context>
<context>
@@ -497,324 +883,99 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation type="unfinished">
- <numerusform><b>%1</b> tappoi <b>%2</b> omaa siiltä.</numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation type="unfinished">
- <numerusform><b>%1</b> pelkäsi ja jätti vuoronsa väliin <b>%2</b> kertaa.</numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Valitse sama väri kaverisi kanssa pelataksesi samassa joukkueessa. Kumpikin ohjaa omia siilejään, mutta voitatte ja häviätte yhdessä.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Jotkut aseet tekevät vain vähän vahinkoa, mutta voivat olla tuhoisampia oikeassa tilanteessa. Kokeile ampua useampi siili veteen Desert Eaglella.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Jos et tiedä mitä tehdä etkä halua tuhlata ammuksia, jätä vuoro väliin. Mutta älä anna ajan kulua liikaa koska Ãkkikuolema koittaa ennemmin tai myöhemmin!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Jos haluat estää muita käyttämästä nimimerkkiäsi virallisella palvelimella, rekisteröi tunnus osoitteessa http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Kyllästyttääkö normaali peli? Kokeila tehtäviä - Ne tarjoaa erilaisia pelitapoja riippuen valinnasta.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Oletuksena viimeisin peli nauhoitetaan demoksi. Valitse 'Demot' vasemmasta alakulmasta katsoaksesi ja hallitaksesi niitä.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos sinulla on ongelmia, kysy keskustelualueilta apua, mutta älä odota 24/7-tukea!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos pidät siitä, voit auttaa meitä pienellä lahjoituksella tai omaa työllä!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jaa sitä perheesi ja ystäviesi kesken miten haluat!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Toisinaan järjestetään virallisia turnauksia. Tulevista tapahtumista tiedotetaan osoitteessa http://www.hedgewars.org/ muutama päivä etukäteen.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars on saatavilla monilla kielillä. Jos oman kielinen käännös puuttuu tai on vanhentunut, ota yhteyttä!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars toimii useilla eri käyttöjärjestelmillä, kuten Microsoft Windowsissa, Mac OS X:ssä ja Linuxissa.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Muista että voit aina luoda oman pelisi paikallisesti ja verkkopelissä. Et ole rajoitettu yksinkertaiseen peliin.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Pelatessa sinun pitäisi pitää lyhyt tauko vähintään kerran tunnissa.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Jos näytönohjaimesi ei tarjoa laitteistokiihdytettä OpenGL:ää, kokeile heikennetyn laadun tilaa parantaaksesi suorituskykyä.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Me olemme avoimia ehdotuksille ja rakentavalle palautteelle. Jos et pidä jostain tai sinulla on loistava idea, kerro meille!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Erityisesti verkossa pelattaessa ole kohtelias ja muista että alaikäisiä saattaa myös olla pelaamassa.</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Erityispelimoodit kuten 'Vampyrismi' ja 'Karma' mahdollistavat kokonaan uusien taktiikoiden kehittämisen. Kokeile niitä muokatussa pelissä!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Sinun ei ikinä tulisi asentaa Hedgewarsia tietokoneille joita et omista (koulu, yliopisto, työpaikka jne.). Ole hvä ja pyydä vastuuhenkilöä tekemään se!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars voi olla täydellinen peli tauoille. Mutta varmista ettet lisää liian montaa siiltä ta käytä liian suurta karttaa. Ajan ja terveyden vähentäminen voi myös auttaa.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Yhtään siiliä ei vahingoitettu tämän pelin tekemisen aikana.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars on avointa lähdekoodia ja ilmainen ohjelma jota me luomme vapaa-aikanamme. Jos joku myi sinulle tämän pelin, koita saada rahasi takaisin!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Yhdistä yksi tai useampi peliohjain ennen pelin käynnistämistä liittääksesi niiden kontrollit omaan joukkueeseesi.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Luo käyttäjätili osoitteessa %1 estääksesi muita käyttämästä suosikkinimimerkkiäsi pelatessasi virallisella palvelimella.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Jos näytönohjaimesi ei tue laitteistokiihdytettyä OpenGL:ää, kokeile päivittää ajurit.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Hyppyjä on saatavilla kolmea erilaista. Napauta [korkea hyppy]-nappai kahdesti tehdäksesi todella korkean/taaksepäin hypyn.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Pelkäätkö että putoat kielekkeeltä? Pidä [tarkkuus]-näppäintä pohjassa kääntyäksesi [vasemmalle] ja [oikealle] liikkumatta.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Jotkut aseet vaativat erityisstrategiaa tai todella paljon harjoittelua, joten älä anna periksi vaikka et kerran osuisikaan.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation></translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Vanha Limburger-juusto aiheuttaa vain pienen räjähdyksen, mutta tuulen vaikuttama hajupilvi voi myrkyttää suuren määrän siiliä kerralla.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Pianoisku on vahingollisin ilmaisku. Menetät siilen joka sen esittää, joten sillä on myös suuri huono puoli.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Tarttuvat miinat ovat täydellinen työkalu luomaan pieniä ketjureaktioita jotka vie vihollissiilit kauheisiin tilanteisiin...tai veteen.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Vasara on tehokkaimmillaan silloilla ja palkeilla. Lyödyt siilit iskeytyvät maan läpi.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Jos olet jumissa vihollissiilin takana, käytä vasaraa vapauttaaksesi itsesi ilman että vahingoidut räjädyksen voimasta.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Kakun pisin mahdollinen kulkumatka riippuu maastosta. Käytä [hyökkäystä] räjäyttääksesi sen aikaisemmin.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Liekinheitin on ase mutta sitä voi käyttää myös tunneleiden kaivamiseen.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Haluatko tietää ketkä ovat pelin takana? Klikkaa Hedgewars-logoa päävalikossa nähdäksesi tekijäluettelon.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Piirrä vapaasti omia hautoja, hattuja, lippuja ja jopa karttoja ja teemoja! Mutta huomaa että sinun pitää jakaa ne jossain käyttääksesi niitä verkossa.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Haluatko todella pitää tiettyä hattua? Lahjoita meille niin saat yksinoikeudella vapaavalintaisen hatun!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Pidä näytönohjaimesi ajurit ajantasall välttääksesi ongelmat pelin pelaamisessa.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform><b>%1</b> tappoi <b>%2</b> omaa siiltä.</numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Löydät Hedgewars-asetustiedostot hakemistosta "Omat tiedostot\Hedgewars". Ota varmuuskopio tai ota ne mukaasi, mutta älä muokkaa niitä käsin.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform><b>%1</b> pelkäsi ja jätti vuoronsa väliin <b>%2</b> kertaa.</numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -824,38 +985,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Aloita</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Säädöt</translation>
+ <translation type="obsolete">Säädöt</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Lähiverkkopeli</translation>
+ <source>Update</source>
+ <translation type="unfinished">Päivitä</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Virallinen palvelin</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -902,10 +1067,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Yleiset</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Lisäasetukset</translation>
</message>
@@ -945,6 +1106,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Joukkueet</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Aseet</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -961,11 +1210,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Luo</translation>
+ <translation type="obsolete">Luo</translation>
</message>
<message>
<source>Join</source>
- <translation>Liity</translation>
+ <translation type="obsolete">Liity</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1222,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Huoneen nimi:</translation>
+ <translation type="obsolete">Huoneen nimi:</translation>
</message>
<message>
<source>Rules:</source>
@@ -985,11 +1234,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Haku:</translation>
+ <translation type="obsolete">Haku:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Tyhjennä</translation>
+ <translation type="obsolete">Tyhjennä</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1247,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1417,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1164,26 +1429,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Lataa</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1229,19 +1482,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1256,10 +1511,6 @@ Please pick another nickname:</source>
<translation>Tietoja</translation>
</message>
<message>
- <source>Start</source>
- <translation>Aloita</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Rajoita liittymisiä</translation>
</message>
@@ -1293,7 +1544,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Päivitä</translation>
+ <translation type="obsolete">Päivitä</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1307,18 +1570,6 @@ Please pick another nickname:</source>
<translation>Koko ruutu</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Koko ruutu käyttöliittymälle</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Ãänet päälle</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Musiikki päälle</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Näytä FPS</translation>
</message>
@@ -1335,45 +1586,57 @@ Please pick another nickname:</source>
<translation>Näytä asevalikon vihjeet</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Kytke käyttöliittymän äänet päälle</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Kytke käyttöliittymän musiikki päälle</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Käyttöliittymän tehosteet</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>generoitu kartta...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Ihminen</translation>
</message>
@@ -1386,14 +1649,6 @@ Please pick another nickname:</source>
<translation>(Järjestelmän oletus)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>Generoitu sokkelo...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Tehtävä</translation>
- </message>
- <message>
<source>Community</source>
<translation>Yhteisö</translation>
</message>
@@ -1403,15 +1658,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>Aulassa</translation>
+ <translation type="obsolete">Aulassa</translation>
</message>
<message>
<source>In progress</source>
- <translation>Kesken</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kesken</translation>
</message>
<message>
<source>Disabled</source>
@@ -1450,10 +1701,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1489,56 +1736,24 @@ Please pick another nickname:</source>
<translation>Linnake</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Näppäinasettelut</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Joukkueet</translation>
- </message>
- <message>
<source>Net game</source>
- <translation>Verkkopeli</translation>
- </message>
- <message>
- <source>Playing teams</source>
- <translation>Pelaavat joukkueet</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Ãäni/grafiikka-asetukset</translation>
- </message>
- <message>
- <source>Game Modifiers</source>
- <translation>Pelimuuttujat</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Perusasetukset</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Joukkueasetukset</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Muut</translation>
+ <translation>Verkkopeli</translation>
</message>
<message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
+ <source>Playing teams</source>
+ <translation>Pelaavat joukkueet</translation>
</message>
<message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <source>Game Modifiers</source>
+ <translation>Pelimuuttujat</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Perusasetukset</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Joukkueasetukset</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,10 +1763,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1565,27 +1776,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Versio</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Kehittäjät:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Taide:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Ãänet:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Käännökset:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Erikoiskiitokset:</translation>
+ <translation type="obsolete">Versio</translation>
</message>
<message>
<source>Weapons</source>
@@ -1644,10 +1835,6 @@ Please pick another nickname:</source>
<translation>Laatikkojen pudotukset</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Pelikaava</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% suutarimiinoja</translation>
</message>
@@ -1684,10 +1871,6 @@ Please pick another nickname:</source>
<translation>Vinkki: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Tämä kehitysversio on keskeneräinen ja ei välttämättä ole yhteensopiva muiden versioiden kanssa. Jotkut ominaisuudet voivat olla rikki tai kesken. Käytä omalla vastuulla!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Laatu</translation>
</message>
@@ -1728,10 +1911,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1762,10 +1941,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1793,6 +1968,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Koko ruutu</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1815,6 +2034,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1831,10 +2054,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1881,47 +2100,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Hakemiston %1 luonti epäonnistui</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Hakemiston %1 luonti epäonnistui</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Palvelinta ei pystytty käynnistämään: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Palvelinta ei pystytty käynnistämään: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2040,16 +2224,42 @@ Haluatko silti liittyä huoneeseen?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nimimerkki</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Ole hyvä ja syötä nimimerkkisi</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2107,47 +2317,86 @@ Haluatko silti liittyä huoneeseen?</translation>
<translation>Lataa</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Asetukset</translation>
+ <source>Associate file extensions</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ready</source>
- <translation>Valmis</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Satunnainen joukkue</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>More info</source>
+ <source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default options</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Open videos directory</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Upload to YouTube</source>
+ <source>Delete this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cancel uploading</source>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
+ </message>
+ <message>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2199,6 +2448,25 @@ Haluatko silti liittyä huoneeseen?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2226,105 +2494,43 @@ Haluatko silti liittyä huoneeseen?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampyrismi</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Tykistö</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Linnoitustila</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Jaa joukkueet</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Tuhoutumaton maa</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Lisää reunat</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Matala painovoima</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Lasertähtäin</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Vahingoittumaton</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Satunnainen Järjestys</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Kuningas</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Sijoita siilet</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Saman väriset jakavat ammukset</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Ei palkkeja</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Ei maaobjekteja</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Tekoäly selviytymistila</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Peruuta</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2459,12 +2665,6 @@ Haluatko silti liittyä huoneeseen?</translation>
<translation>kaappaa</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>siilien
-tiedot</translation>
- </message>
- <message>
<source>quit</source>
<translation>poistu</translation>
</message>
@@ -2500,33 +2700,33 @@ tiedot</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Peruskontrollit</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Asekontrollit</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Aseet</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kameran ja kursorin kontrollit</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Muu</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Liikuta siiliäsi ja tähtää:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Ylitä aukot ja esteet hyyppäämällä:</translation>
</message>
@@ -2590,6 +2790,10 @@ tiedot</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_fr.ts b/share/hedgewars/Data/Locale/hedgewars_fr.ts
index 21a0786..f1383ec 100644
--- a/share/hedgewars/Data/Locale/hedgewars_fr.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_fr.ts
@@ -2,10 +2,17 @@
<!DOCTYPE TS>
<TS version="2.0" language="fr">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation>Compilateur inconnu</translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
- <translation type="unfinished"></translation>
+ <translation>Retour</translation>
</message>
</context>
<context>
@@ -20,6 +27,107 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>Pseudo</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Pseudo</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Raison</translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation>Durée</translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>Ok</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation>Tu sait très bien pourquoi</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Attention</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation>Veuillez spécifier %1</translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>Pseudo</translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation>Permanent</translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation>Par défaut</translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation>Voir</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation>Envoyez</translation>
+ </message>
+ <message>
+ <source>Please give us feedback!</source>
+ <translation type="obsolete">Nous avons besoin de votre avis!</translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation>Toutes suggestions, idées ou rapport de bug sont les bienvenus</translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already known here (english): </source>
+ <translation type="obsolete">Si vous trouvez un bug, vous pouvez vérifier si il est déjà connu ici (anglais): </translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but we may want to contact you.</source>
+ <translation type="obsolete">Votre adresse email est optionelle, mais il est possible que nous essayons de vous contacter.</translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -41,68 +149,136 @@
</message>
<message>
<source>Edit schemes</source>
- <translation>Ãditer les paramètres</translation>
+ <translation>Ãditer les règles</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Une fois cette option activée, choisir les paramètres de jeu sélectionne automatiquement les armes correspondantes</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation>La règle choisis va choisir automatiquement les armes</translation>
</message>
<message>
- <source>Game Options</source>
- <translation type="unfinished"></translation>
+ <source>Map</source>
+ <translation>Carte</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation>Option de jeu</translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1 minute</numerusform>
+ <numerusform>%1 minutes</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1 heure</numerusform>
+ <numerusform>%1 heures</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1 heure</numerusform>
+ <numerusform>%1 heures</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation>
+ <numerusform>%1 jour</numerusform>
+ <numerusform>%1 jours</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1 jour</numerusform>
+ <numerusform>%1 jours</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation>Règle incomprise</translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation>Impossible de créer le dossier %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation>Impossible de trouver les fichiers:
+%1
+
+Veuillez verifier que votre jeu est installé correctement!</translation>
</message>
</context>
<context>
<name>HWAskQuitDialog</name>
<message>
<source>Do you really want to quit?</source>
- <translation type="unfinished"></translation>
+ <translation>Ãtes-vous sûr de vouloir quitter ?</translation>
</message>
</context>
<context>
<name>HWChatWidget</name>
<message>
<source>%1 has been removed from your ignore list</source>
- <translation type="unfinished"></translation>
+ <translation>%1 a été retiré de votre liste noire</translation>
</message>
<message>
<source>%1 has been added to your ignore list</source>
- <translation type="unfinished"></translation>
+ <translation>%1 a été ajouté à votre liste noire</translation>
</message>
<message>
<source>%1 has been removed from your friends list</source>
- <translation type="unfinished"></translation>
+ <translation>%1 a été retiré de votre liste d'amis</translation>
</message>
<message>
<source>%1 has been added to your friends list</source>
- <translation type="unfinished"></translation>
+ <translation>%1 a été ajouté à votre liste d'amis</translation>
</message>
<message>
<source>Stylesheet imported from %1</source>
- <translation type="unfinished"></translation>
+ <translation>Feuille de style (Stylesheet) importée de %1</translation>
</message>
<message>
<source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
- <translation type="unfinished"></translation>
+ <translation>Entrez %1 si vous voulez utiliser cette Feuille de style (Stylesheet) à l'avenir, entrez %2 pour rétablir l'ancienne apparence!</translation>
</message>
<message>
<source>Couldn't read %1</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de lire %1</translation>
</message>
<message>
<source>StyleSheet discarded</source>
- <translation type="unfinished"></translation>
+ <translation>Feuille de style (Stylesheet) effacée</translation>
</message>
<message>
<source>StyleSheet saved to %1</source>
- <translation type="unfinished"></translation>
+ <translation>Feuille de style (Stylesheet) enregistrée dans %1</translation>
</message>
<message>
<source>Failed to save StyleSheet to %1</source>
+ <translation>Impossible d'enregistrer la feuille de style (Stylesheet) dans %1</translation>
+ </message>
+ <message>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -110,7 +286,7 @@
<name>HWForm</name>
<message>
<source>Cannot save record to file %1</source>
- <translation>Impossible de sauvegarder la partie dans le fichier %1</translation>
+ <translation>Impossible de sauvegarder l'enregistrement dans le fichier %1</translation>
</message>
<message>
<source>DefaultTeam</source>
@@ -119,7 +295,7 @@
<message>
<source>Hedgewars Demo File</source>
<comment>File Types</comment>
- <translation>Fichier de démonstration d'Hedgewars</translation>
+ <translation>Fichier de demo d'Hedgewars</translation>
</message>
<message>
<source>Hedgewars Save File</source>
@@ -128,41 +304,94 @@
</message>
<message>
<source>Demo name</source>
- <translation type="unfinished"></translation>
+ <translation>Nom de la Demo</translation>
</message>
<message>
<source>Demo name:</source>
- <translation type="unfinished"></translation>
+ <translation>Nom de la Demo:</translation>
</message>
<message>
<source>Game aborted</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Votre pseudo %1 est
-enregistré sur Hedgewars.org
-Veuillez fournir votre mot de passe
-ou choisir un nouveau pseudo :</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
+ <translation>Abandon de la partie</translation>
</message>
<message>
<source>Nickname</source>
- <translation type="unfinished">Pseudo</translation>
+ <translation>Pseudo</translation>
</message>
<message>
<source>No nickname supplied.</source>
- <translation type="unfinished"></translation>
+ <translation>Aucun pseudo renseigné.</translation>
</message>
<message>
<source>Someone already uses your nickname %1 on the server.
Please pick another nickname:</source>
+ <translation>Quelqu'un utilise déjà le pseudo %1 sur le serveur
+Veuillez choisir un autre pseudo:</translation>
+ </message>
+ <message>
+ <source>%1's Team</source>
+ <translation>Equipe de %1</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation>Hedgewars - Pseudo enregistré</translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation>Ce pseudo est enregistré, vous n'avez spécifié aucun mot de passe.
+
+Si ce pseudo n'est pas le votre, veuillez enregistrer votre propre pseudo sur www.hedgewars.org
+
+Mot de passe:</translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation>Votre pseudo n'est pas enregistré.
+Pour éviter que d'autre joueurs l'utilisent,
+veuillez l'enregistrer sur www.hedgewars.org</translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation>
+
+Votre mot de passe non plus n'a pas été sauvegardé.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation>Hedgewars - Pseudo vide</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation>Hedgewars - Mauvais mot de passe</translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation>Le mot de passe que vous avez entré est incorrect</translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation>Réessayez</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation>Hedgewars - Erreur de connexion</translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation>Vous vous êtes reconnecté trop rapidement.
+Attendez quelques secondes et réessayez.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -174,24 +403,12 @@ Please pick another nickname:</source>
</message>
<message>
<source>Cannot open demofile %1</source>
- <translation>Erreur lors de l'ouverture du fichier de démonstration %1</translation>
+ <translation>Erreur lors de l'ouverture du fichier de demo %1</translation>
</message>
</context>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Carte</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Thèmes</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtre</translation>
- </message>
- <message>
<source>All</source>
<translation>Toutes</translation>
</message>
@@ -216,10 +433,6 @@ Please pick another nickname:</source>
<translation>Farfelu</translation>
</message>
<message>
- <source>Type</source>
- <translation>Type</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Petits tunnels</translation>
</message>
@@ -228,28 +441,100 @@ Please pick another nickname:</source>
<translation>Tunnels moyens</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Grand tunnels</translation>
+ <source>Seed</source>
+ <translation>Graine</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Petites Ãles flottantes</translation>
+ <source>Map type:</source>
+ <translation>Type de carte:</translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Ãles flottantes moyennes</translation>
+ <source>Image map</source>
+ <translation>Image de la carte</translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Grandes îles flottantes</translation>
+ <source>Mission map</source>
+ <translation>Carte avec mission</translation>
</message>
<message>
- <source>Seed</source>
- <translation>Graine</translation>
+ <source>Hand-drawn</source>
+ <translation>Dessinée</translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation>Générée aléatoirement</translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation>Labyrinthe généré aléatoirement</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>Aléatoire</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation>Apperçu de la carte</translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation>Charger un dessin</translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation>Editer un dessin</translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation>Petites îles</translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation>Moyennes îles</translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation>Grandes îles</translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation>Taille de la carte</translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation>Style du labyrinthe</translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation>Mission</translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation>Carte:</translation>
</message>
<message>
- <source>Set</source>
- <translation>Valider</translation>
+ <source>Theme: </source>
+ <translation type="obsolete">Theme: </translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation>Charger une carte dessinée</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation>Cartes dessinées</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Tout les fichiers</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation>Grands tunnels</translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -283,7 +568,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room destroyed</source>
- <translation>Salon fermé</translation>
+ <translation>Room fermée</translation>
</message>
<message>
<source>You got kicked</source>
@@ -291,11 +576,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined the room</source>
- <translation>%1 *** %2 a rejoint la salle</translation>
+ <translation>%1 *** %2 a rejoint la room</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 vient d'arriver</translation>
+ <translation type="obsolete">%1 *** %2 vient d'arriver</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -307,60 +592,117 @@ Please pick another nickname:</source>
</message>
<message>
<source>User quit</source>
- <translation type="unfinished"></translation>
+ <translation>S'est déconnecté</translation>
</message>
<message>
<source>Remote host has closed connection</source>
- <translation type="unfinished"></translation>
+ <translation>Le serveur à fermé la connection</translation>
</message>
<message>
<source>The server is too old. Disconnecting now.</source>
- <translation type="unfinished"></translation>
+ <translation>La version du serveur n'est pas à jour. Déconnexion.</translation>
</message>
</context>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Mot de passe</translation>
+ <source>Login</source>
+ <translation>Connexion</translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation>Pour vous connecter sur le serveur, veuillez entrer vos identifiants.
+Si vous n'avez pas de compte sur www.hedgewars.org,
+entrez juste votre pseudo.</translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation>Pseudo</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Mot de passe</translation>
</message>
</context>
<context>
<name>HWUploadVideoDialog</name>
<message>
<source>Upload video</source>
- <translation type="unfinished"></translation>
+ <translation>Importer une vidéo </translation>
</message>
<message>
<source>Upload</source>
- <translation type="unfinished"></translation>
+ <translation>Importer</translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation>Changer de chapeau (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation>Mettre le chapeau sélectionné</translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation>Chercher un chapeau:</translation>
</message>
</context>
<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
- <translation>SDL_ttf a retourné une erreur pendant l'affichage du texte, cela est sûrement causé par le bogue de freetype2. Il est recommandé de mettre à jour la librairie freetype.</translation>
+ <translation>SDL_ttf a renvoyé une erreur pendant l'affichage du texte, cela est sûrement causé par le bug de freetype2. Il est recommandé de mettre à jour la librairie freetype.</translation>
+ </message>
+</context>
+<context>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation>Catégorie</translation>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
- <translation type="unfinished"></translation>
+ <translation>Durée: %1m %2s</translation>
</message>
<message>
<source>Video: %1x%2, </source>
- <translation type="unfinished"></translation>
+ <translation>Vidéo: %1x%2</translation>
</message>
<message>
<source>%1 fps, </source>
- <translation type="unfinished"></translation>
+ <translation>%1 fps, </translation>
</message>
<message>
<source>Audio: </source>
- <translation type="unfinished"></translation>
+ <translation>Audio: </translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>inconnu</translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation>Aucune description disponible.</translation>
</message>
</context>
<context>
@@ -393,12 +735,55 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Enregistrer les données</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>Général</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation>Bans</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Pseudo</translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation>Durée</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Raison</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation>Rafraichir</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Ajouter</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Supprimer</translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
<message>
<source>Connecting...</source>
- <translation>En connexion...</translation>
+ <translation>Connexion...</translation>
+ </message>
+</context>
+<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -429,15 +814,15 @@ Please pick another nickname:</source>
</message>
<message>
<source>Drawn Maps</source>
- <translation type="unfinished"></translation>
+ <translation>Cartes dessinées</translation>
</message>
<message>
<source>All files</source>
- <translation type="unfinished"></translation>
+ <translation>Tout les fichiers</translation>
</message>
<message>
<source>Eraser</source>
- <translation type="unfinished"></translation>
+ <translation>Gomme</translation>
</message>
</context>
<context>
@@ -447,8 +832,40 @@ Please pick another nickname:</source>
<translation>Général</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avancé</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation>Choisissez une action afin d'y attribuer une touche pour cette équipe</translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation>Touche par defaut</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Reinitialiser toutes les touches</translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation>Préferences de commandes</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>Chapeau</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nom</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation>Le nom de ce herisson</translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation>Choisis un nom aléatoire pour ce herisson</translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation>Ãquipes aléatoires</translation>
</message>
</context>
<context>
@@ -459,7 +876,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Health graph</source>
- <translation>Courbes de santé-</translation>
+ <translation>Courbes de santé:</translation>
</message>
<message>
<source>Ranking</source>
@@ -485,8 +902,8 @@ Please pick another nickname:</source>
</message>
<message numerus="yes">
<source>(%1 kill)</source>
- <translation type="unfinished">
- <numerusform>(%1 tue)</numerusform>
+ <translation>
+ <numerusform>(%1 tué)</numerusform>
<numerusform></numerusform>
</translation>
</message>
@@ -511,446 +928,309 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished">Enregistrer</translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
<message>
<source>In game...</source>
- <translation type="unfinished"></translation>
+ <translation>En jeu...</translation>
</message>
</context>
<context>
<name>PageInfo</name>
<message>
<source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
+ <translation>Ouvrir le dossier de captures d'écran</translation>
</message>
</context>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Choisissez la même couleur qu'un ami pour jouer dans la même équipe. Chacun de vous continuera à contrôler son ou ses hérissons mais ils gagneront ou perdront ensembles.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Certaines armes peuvent occasionner seulement de faibles dommages mais être beaucoup plus dévastatrices dans la situation adéquate. Essayez le Révolver pour envoyer plusieurs hérissons à l'eau.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Si vous ne savez pas quoi faire et ne voulez pas gaspiller de munitions, passez un tour. Mais ne laissez pas trop filer le temps ou ce sera la Mort Subite !</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Si vous voulez empêcher les autres d'utiliser votre pseudo sur le serveur officiel, créez un compte sur http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Assez du mode par défaut ? Essayez une des missions - elles offrent différents types de jeu suivant votre choix.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Par défaut le jeu enregistre la dernière partie jouée comme une démonstration. Sélectionnez « Jeu en local » puis « Démonstrations » en bas à droite pour les visionner ou les gérer.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si vous avez des problèmes, demandez sur nos forums mais n'attendez pas de support 24h/24.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si vous l'aimez, aidez-nous avec un petit don ou contribuez par votre travail !</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Partagez-le avec votre famille et vos amis comme vous le voulez !</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>De temps en temps il y aura des tournois officiels. Les évènements à venir seront annoncés sur http://www.hedgewars.org/ quelques jours à l'avance.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars est disponible dans de nombreuses langues. Si la traduction dans votre langue est partielle ou obsolète, contactez-nous !</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars peux être exécuté sur de nombreux systèmes d'exploitation différents, incluant Microsoft Windows, Mac OS X et Linux. </translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Souvenez-vous que vous pouvez créer votre propres parties en local et en ligne. Vous n'est pas limités aux options de jeu par défaut.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Vous devriez faire une petite pause au moins une fois par heure.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Si votre carte graphique ne peut pas fournir d'accélération matérielle pour OpenGL, essayez le mode de faible qualité pour améliorer les performances.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Nous sommes ouverts aux suggestions et au critiques constructives. Si vous n'aimez pas quelque chose ou avez une grande idée, contactez-nous !</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Particulièrement quand vous jouez en ligne soyez polis et n'oubliez pas que certains joueurs peuvent être mineurs.</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Les modes de jeu spéciaux comme « Vampirisme » ou « Karma » vous permettent de développer de nouvelles tactiques. Essayez-les en parties personnalisées !</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Vous ne devriez jamais installer Hedgewars sur des ordinateurs ne vous appartenant pas (école, université, travail, etc...). Demandez au responsable !</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars peut être parfait pour des parties courtes pendant une pause. Assurez-vous juste de ne pas avoir mis trop de hérissons ou de ne pas utiliser une carte énorme. Réduire le temps ou la santé peuvent aider également.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Aucun hérisson n'a été blessé durant la conception de ce jeu.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars est un jeu libre et gratuit créé sur notre temps libre. Si quelqu'un vous l'a vendu, vous devriez vous faire rembourser !</translation>
+ <source>Downloadable Content</source>
+ <translation>Contenu téléchargeable</translation>
</message>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Branchez une ou plusieurs manettes avant de lancer le jeu pour pouvoir contrôler vos équipes avec.</translation>
+ <source>Play a game on a single computer</source>
+ <translation>Jouer une partie en solo</translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Créer un compte sur %1 vous permet d'empêcher les autres d'utiliser votre pseudo favori sur le serveur officiel.</translation>
+ <source>Play a game across a network</source>
+ <translation>Jouer en ligne</translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Si votre carte graphique ne peut pas fournir d'accélération matérielle pour OpenGL, essayez d'installer les drivers associés.</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation>A propos de ceux qui sont derrière le projet Hedgewars</translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Il y a différents types de saut disponibles. Pressez [high jump] deux fois pour faire un très haut saut un peu en arrière.</translation>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation>Donnez-nous votre avis, signalez un bug, déposez vos idées, ou dites nous juste à quel point vous aimez Hedgewars</translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Peur de tomber d'une falaise ? Maintenez [precise] pour tourner [left] ou [right] sans bouger.</translation>
+ <source>Access the user created content downloadable from our website</source>
+ <translation>Acces au contenu téléchargeable créé par les joueurs, disponible sur notre site</translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Certaines armes demandent de la stratégie ou juste beaucoup d'entrainement, alors ne laissez pas tomber une arme si vous avez raté une fois un ennemi.</translation>
+ <source>Exit game</source>
+ <translation>Quitter le jeu</translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>La plupart des armes ne fonctionnent pas une fois qu'elles ont touché l'eau. L'Abeille Missile ou le Gâteau sont des exceptions.</translation>
+ <source>Manage videos recorded from game</source>
+ <translation>Gérer les vidéos de parties enregistrées</translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Le vieux Limburger cause seulement une petite explosion. En revanche le vent affecte le petit nuage empoisonné qui peut contaminer de nombreux hérissons à la fois.</translation>
+ <source>Edit game preferences</source>
+ <translation>Editer vos préférences de jeu</translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished">L'attaque du Piano est la plus dévastatrice des attaques aériennes. Mais la contrepartie est grande puisque vous perdrez le hérisson qui la lance.</translation>
+ <source>Play a game across a local area network</source>
+ <translation>Jouer une partie en réseau local</translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Les Mines adhésives sont l'outil parfait pour créer de petites réactions en chaines envoyant les ennemis dans des situations délicates ... ou dans l'eau.</translation>
+ <source>Play a game on an official server</source>
+ <translation>Jouer une partie sur un serveur officiel</translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Le Marteau est plus efficace utilisé sur des ponts ou des poutrelles. Les hérissons touchés vont passer à travers le sol.</translation>
+ <source>Feedback</source>
+ <translation>Contact</translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Si vous êtes coincés derrière un hérisson ennemi, utilisez le Marteau pour vous libérer sans subir les dégâts d'une explosion.</translation>
+ <source>Play local network game</source>
+ <translation>Jouer en réseau local</translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>La distance maximale que le Gâteau peux parcourir dépend du terrain qu'il doit franchir. Utiliser [attack] pour le faire exploser avant.</translation>
+ <source>Play official network game</source>
+ <translation>Jouer sur le réseau officiel</translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Le Lance-flammes est une arme mais peut aussi être utilisé pour creuser un tunnel.</translation>
+ <source>Start</source>
+ <translation>Démarrer</translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Vous voulez savoir qui est derrière le jeu ? Cliquez sur le logo Hedgewars dans le menu principal pour voir les crédits.</translation>
+ <source>Edit game preferences</source>
+ <translation>Editer les préférences de jeu</translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Soyez libre de dessiner vos propres tombes, chapeaux, drapeaux ou même cartes et thèmes ! Mais pour les utiliser en ligne vous devrez les partager quelque part.</translation>
+ <source>Control</source>
+ <translation type="obsolete">Contrôles</translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Vous voulez vraiment un chapeau spécifique ? Faites un don et recevez un chapeau exclusif de votre choix.</translation>
+ <source>Edit game preferences</source>
+ <translation>Editer les préférences de jeu</translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Conservez les pilotes de votre carte graphique à jour pour éviter les problèmes en jouant.</translation>
+ <source>Start</source>
+ <translation>Démarrer</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Vous pouvez trouver vos fichiers de configuration Hedgewars sous « Mes Documents\Hedgewars ». Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main !</translation>
+ <source>Update</source>
+ <translation>Mise à jour</translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Vous pouvez associer les fichiers relatifs à Hedgewars (parties enregistrées ou démonstrations) au jeu pour les lancer depuis votre navigateur de fichiers ou internet.</translation>
+ <source>Room controls</source>
+ <translation>Contrôle de la room</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Vous aimez Hedgewars ? Devenez un fan sur %1 ou suivez-nous sur %2 !</translation>
+ <source>Click here for details</source>
+ <translation>Clique pour plus de détails</translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Envie d'économiser des Cordes Ninja ? Relâchez la Corde Ninja en l'air et tirez à nouveau. Du moment que vous ne touchez pas le sol, vous réutiliserez votre Corde Ninja sans gaspiller de munitions.</translation>
+ <source>Insert your address here</source>
+ <translation>Insert ton adresse ici</translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Vous pouvez trouver vos fichiers de configuration Hedgewars sous « Library/Application Support/Hedgewars » dans votre répertoire personnel. Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main !</translation>
+ <source>New team</source>
+ <translation>Nouvelle équipe</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Vous pouvez trouver vos fichiers de configuration Hedgewars sous « .hedgewars » dans votre répertoire personnel. Créez des sauvegardes ou prenez les fichiers avec vous, mais ne les modifiez pas à la main !</translation>
+ <source>Edit team</source>
+ <translation>Ãditer l'Ãquipe</translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation type="unfinished">La version Windows de Hedgewars supporte Xfire. Ajoutez Hedgewars à la liste des jeux pour que vos amis puissent vous voir jouer</translation>
+ <source>Delete team</source>
+ <translation>Supprimer une équipe</translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation type="unfinished"> Utilisez le Lance-Flammes ou le Cocktail Molotov pour empêcher temporairement les hérissons de circuler dans les tunnels ou sur les plateformes.</translation>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <translation>Vous ne pouvez pas modifier d'équipe depuis la sélection d'équipes. Retournez au menu principal pour ajouter, modifier ou supprimer des équipes.</translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New scheme</source>
+ <translation>Nouvelle règle</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Edit scheme</source>
+ <translation>Modifier règles</translation>
</message>
<message>
- <source>Local Game</source>
- <translation type="unfinished"></translation>
+ <source>Delete scheme</source>
+ <translation>Supprimer règles</translation>
</message>
<message>
- <source>Play a game on a single computer</source>
- <translation type="unfinished"></translation>
+ <source>New weapon set</source>
+ <translation>Nouvel ensemble d'armes</translation>
</message>
<message>
- <source>Network Game</source>
- <translation type="unfinished"></translation>
+ <source>Edit weapon set</source>
+ <translation>Modifier un ensemble d'armes</translation>
</message>
<message>
- <source>Play a game across a network</source>
- <translation type="unfinished"></translation>
+ <source>Delete weapon set</source>
+ <translation>Supprimer un ensemble d'armes</translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation>Avancé</translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
- <translation type="unfinished"></translation>
+ <source>Reset to default colors</source>
+ <translation>Remettre les couleurs de départ</translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <source>Start</source>
- <translation>Démarrer</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>Contrôles</translation>
+ <source>No proxy</source>
+ <translation>Pas de proxy</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
- <message>
- <source>LAN game</source>
- <translation>Jeu en réseau local (LAN)</translation>
- </message>
- <message>
- <source>Official server</source>
- <translation>Serveur officiel</translation>
- </message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation type="unfinished"></translation>
+ <source>Select an action to change what key controls it</source>
+ <translation>Choisissez une action afin d'y attribuer une touche</translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
- <translation>Nouvelle équipe</translation>
+ <source>Reset to default</source>
+ <translation>Par défaut</translation>
</message>
<message>
- <source>Edit team</source>
- <translation>Ãditer l'Ãquipe</translation>
+ <source>Reset all binds</source>
+ <translation>Remettre les touches par défaut</translation>
</message>
<message>
- <source>Delete team</source>
- <translation>Supprimer une équipe</translation>
+ <source>Game</source>
+ <translation>Jeu</translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
- <translation>Vous ne pouvez pas modifier d'équipe depuis la sélection d'équipes. Retournez au manu principal pour ajouter, modifier ou supprimer des équipes.</translation>
+ <source>Graphics</source>
+ <translation>Graphismes</translation>
</message>
<message>
- <source>New scheme</source>
- <translation>Nouveaux paramètres</translation>
+ <source>Audio</source>
+ <translation>Audio</translation>
</message>
<message>
- <source>Edit scheme</source>
- <translation>Modifier paramètres</translation>
+ <source>Controls</source>
+ <translation>Contrôles</translation>
</message>
<message>
- <source>Delete scheme</source>
- <translation>Supprimer paramètres</translation>
+ <source>Video Recording</source>
+ <translation>Enregistrement vidéo</translation>
</message>
<message>
- <source>New weapon set</source>
- <translation>Nouvel ensemble d'armes</translation>
+ <source>Network</source>
+ <translation>Réseau</translation>
</message>
<message>
- <source>Edit weapon set</source>
- <translation>Modifier un ensemble d'armes</translation>
+ <source>Teams</source>
+ <translation>Ãquipes</translation>
</message>
<message>
- <source>Delete weapon set</source>
- <translation>Supprimer un ensemble d'armes</translation>
+ <source>Schemes</source>
+ <translation>Règles</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Général</translation>
+ <source>Weapons</source>
+ <translation>Armes</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">Avancé</translation>
+ <source>Frontend</source>
+ <translation>Interface</translation>
</message>
<message>
- <source>Reset to default colors</source>
- <translation type="unfinished"></translation>
+ <source>Custom colors</source>
+ <translation>Couleurs personalisées</translation>
</message>
<message>
- <source>Proxy host</source>
- <translation type="unfinished"></translation>
+ <source>Game audio</source>
+ <translation>Son du jeu</translation>
</message>
<message>
- <source>Proxy port</source>
- <translation type="unfinished"></translation>
+ <source>Frontend audio</source>
+ <translation>Son de l'interface</translation>
</message>
<message>
- <source>Proxy login</source>
- <translation type="unfinished"></translation>
+ <source>Account</source>
+ <translation>Compte</translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
- <translation type="unfinished"></translation>
+ <source>Miscellaneous</source>
+ <translation>Autre</translation>
</message>
<message>
- <source>Socks5 proxy</source>
- <translation type="unfinished"></translation>
+ <source>Updates</source>
+ <translation>Mises à jour</translation>
</message>
<message>
- <source>HTTP proxy</source>
- <translation type="unfinished"></translation>
+ <source>Check for updates</source>
+ <translation>Vérifier les mises à jours</translation>
</message>
<message>
- <source>System proxy settings</source>
- <translation type="unfinished"></translation>
+ <source>Video recording options</source>
+ <translation>Option d'enregistrement vidéo</translation>
</message>
</context>
<context>
<name>PagePlayDemo</name>
<message>
<source>Rename dialog</source>
- <translation>Boîte de dialogue de renommage</translation>
+ <translation>Renommer</translation>
</message>
<message>
<source>Enter new file name:</source>
@@ -961,11 +1241,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Création</translation>
+ <translation type="obsolete">Création</translation>
</message>
<message>
<source>Join</source>
- <translation>Rejoindre</translation>
+ <translation type="obsolete">Rejoindre</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1253,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Nom du salon:</translation>
+ <translation type="obsolete">Nom de la room: </translation>
</message>
<message>
<source>Rules:</source>
@@ -985,19 +1265,43 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Recherche : </translation>
+ <translation type="obsolete">Recherche : </translation>
</message>
<message>
<source>Clear</source>
- <translation>Effacer</translation>
+ <translation type="obsolete">Effacer</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 joueur en ligne</numerusform>
+ <numerusform>%1 joueurs en ligne</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation>Chercher une room</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Créer une room</translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation>Rejoindre</translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation>Etat de la room</translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation>Enlever les filtres</translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation>Ouvre la page d'administration du serveur</translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1055,7 +1359,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Order of play is random instead of in room order.</source>
- <translation>Ordre de jeu aléatoire plutôt que par ordre dans la salle.</translation>
+ <translation>Ordre de jeu aléatoire plutôt que par ordre dans la room.</translation>
</message>
<message>
<source>Play with a King. If he dies, your side dies.</source>
@@ -1075,7 +1379,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Disable land objects when generating random maps.</source>
- <translation type="unfinished">Désactiver les objets de terrain lorsque des cartes aléatoires sont générées.</translation>
+ <translation>Désactiver les objets de terrain lorsque des cartes aléatoires sont générées.</translation>
</message>
<message>
<source>AI respawns on death.</source>
@@ -1111,7 +1415,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Teams in each clan take successive turns sharing their turn time.</source>
- <translation type="unfinished"></translation>
+ <translation>Les équipes de chaque clans jouent successivement, partageant le temps de leur tour.</translation>
</message>
<message>
<source>Add an indestructible border around the terrain</source>
@@ -1119,7 +1423,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Add an indestructible border along the bottom</source>
- <translation type="unfinished"></translation>
+ <translation>Ajouter une bordure indestructible en bas</translation>
</message>
</context>
<context>
@@ -1144,105 +1448,87 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
+ <translation>Jouer une partie rapide contre l'ordinateur avec des règles aléatoires</translation>
</message>
<message>
<source>Play a hotseat game against your friends, or AI teams</source>
- <translation type="unfinished"></translation>
+ <translation>Jouer une partie sur cet ordinateur contre vos amis ou l'IA</translation>
</message>
<message>
<source>Campaign Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Campagne</translation>
</message>
<message>
<source>Practice your skills in a range of training missions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
+ <translation>Améliorez vos competences avec un large choix de missions</translation>
</message>
<message>
<source>Watch recorded demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Load</source>
- <translation type="unfinished">Charger</translation>
+ <translation>Regarder les parties enregistrées</translation>
</message>
<message>
<source>Load a previously saved game</source>
- <translation type="unfinished"></translation>
+ <translation>Charger une partie</translation>
</message>
</context>
<context>
<name>PageTraining</name>
<message>
<source>No description available</source>
- <translation type="unfinished"></translation>
+ <translation>Aucune description disponible</translation>
</message>
<message>
<source>Select a mission!</source>
- <translation type="unfinished"></translation>
+ <translation>Choisis une mission!</translation>
</message>
<message>
<source>Pick the mission or training to play</source>
- <translation type="unfinished"></translation>
+ <translation>Choisis une mission ou entraine-toi à jouer</translation>
</message>
<message>
<source>Start fighting</source>
- <translation type="unfinished"></translation>
+ <translation>Commencer le combat</translation>
</message>
</context>
<context>
<name>PageVideos</name>
<message>
<source>Name</source>
- <translation type="unfinished">Nom</translation>
+ <translation>Nom</translation>
</message>
<message>
<source>Size</source>
- <translation type="unfinished"></translation>
+ <translation>Taille</translation>
</message>
<message numerus="yes">
<source>%1 bytes</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 octet</numerusform>
+ <numerusform>%1 octets</numerusform>
</translation>
</message>
<message>
<source>(in progress...)</source>
- <translation type="unfinished"></translation>
+ <translation>(en cours ...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation type="unfinished"></translation>
+ <source>encoding</source>
+ <translation>encodage</translation>
</message>
<message>
- <source>Size: </source>
- <translation type="unfinished"></translation>
+ <source>uploading</source>
+ <translation>importation</translation>
</message>
<message>
- <source>encoding</source>
- <translation type="unfinished"></translation>
+ <source>Date: %1
+</source>
+ <translation>Date: %1</translation>
</message>
<message>
- <source>uploading</source>
- <translation type="unfinished"></translation>
+ <source>Size: %1
+</source>
+ <translation>Taille: %1</translation>
</message>
</context>
<context>
@@ -1252,10 +1538,6 @@ Please pick another nickname:</source>
<translation>Exclure</translation>
</message>
<message>
- <source>Start</source>
- <translation>Démarrer</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Restreindre les accès</translation>
</message>
@@ -1293,16 +1575,24 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Mise à jour</translation>
+ <translation type="obsolete">Mise à jour</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation>Bloquer l'acces au joueurs non-enregistrés</translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation>Parties en attentes</translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation>Parties en cours</translation>
</message>
</context>
<context>
<name>QCheckBox</name>
<message>
- <source>Enable sound</source>
- <translation>Activer le son</translation>
- </message>
- <message>
<source>Fullscreen</source>
<translation>Plein écran</translation>
</message>
@@ -1315,14 +1605,6 @@ Please pick another nickname:</source>
<translation>Affichage de dommages alternatif</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Activer la musique</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Affichage en plein écran de l'interface</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Ajouter la date et l'heure au nom du fichier</translation>
</message>
@@ -1332,48 +1614,60 @@ Please pick another nickname:</source>
</message>
<message>
<source>Show ammo menu tooltips</source>
- <translation type="unfinished">Montrer les astuces du menu des armes.</translation>
+ <translation>Montrer les astuces du menu des armes.</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished">Activer les sons du menu principal</translation>
+ <source>Save password</source>
+ <translation>Enregistrer le mot de passe</translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation type="unfinished">Activer la musique du menu principal</translation>
+ <source>Save account name and password</source>
+ <translation>Enregistrer le nom de compte et mot de passe</translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation type="unfinished">Effets du menu principal</translation>
+ <source>Video is private</source>
+ <translation>Vidéo privée</translation>
</message>
<message>
- <source>Save password</source>
- <translation type="unfinished"></translation>
+ <source>Record audio</source>
+ <translation>Enregistrer le son</translation>
</message>
<message>
- <source>Save account name and password</source>
- <translation type="unfinished"></translation>
+ <source>Use game resolution</source>
+ <translation>Utiliser la résolution du jeu</translation>
</message>
<message>
- <source>Video is private</source>
- <translation type="unfinished"></translation>
+ <source>Visual effects</source>
+ <translation>Effets visuels</translation>
</message>
<message>
- <source>Record audio</source>
- <translation type="unfinished"></translation>
+ <source>Sound</source>
+ <translation>Son</translation>
</message>
<message>
- <source>Use game resolution</source>
- <translation type="unfinished"></translation>
+ <source>In-game sound effects</source>
+ <translation>Effets sonores en jeu</translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation>Musique</translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation>Musique en jeu</translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation>Effet sonores de l'interface</translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation>Musique de l'interface</translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>carte générée...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Humain</translation>
</message>
@@ -1383,99 +1677,83 @@ Please pick another nickname:</source>
</message>
<message>
<source>(System default)</source>
- <translation type="unfinished">Réglage du système</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation type="unfinished">Labyrinthe généré</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Mission</translation>
+ <translation>Automatique (systeme)</translation>
</message>
<message>
<source>Community</source>
- <translation type="unfinished">Communauté</translation>
+ <translation>Communauté</translation>
</message>
<message>
<source>Any</source>
- <translation type="unfinished">Aucun</translation>
+ <translation>Tout</translation>
</message>
<message>
<source>In lobby</source>
- <translation type="unfinished">En attente</translation>
+ <translation type="obsolete">En attente</translation>
</message>
<message>
<source>In progress</source>
- <translation type="unfinished">En cours</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation type="unfinished">Carte dessinée</translation>
+ <translation type="obsolete">En cours</translation>
</message>
<message>
<source>Disabled</source>
- <translation type="unfinished"></translation>
+ <translation>Aucun</translation>
</message>
<message>
<source>Red/Cyan</source>
- <translation type="unfinished">Rouge/Cyan</translation>
+ <translation>Rouge/Cyan</translation>
</message>
<message>
<source>Cyan/Red</source>
- <translation type="unfinished">Cyan/Rouge</translation>
+ <translation>Cyan/Rouge</translation>
</message>
<message>
<source>Red/Blue</source>
- <translation type="unfinished">Rouge/Bleu</translation>
+ <translation>Rouge/Bleu</translation>
</message>
<message>
<source>Blue/Red</source>
- <translation type="unfinished">Bleu/Rouge</translation>
+ <translation>Bleu/Rouge</translation>
</message>
<message>
<source>Red/Green</source>
- <translation type="unfinished">Rouge/Vert</translation>
+ <translation>Rouge/Vert</translation>
</message>
<message>
<source>Green/Red</source>
- <translation type="unfinished">Vert/Rouge</translation>
+ <translation>Vert/Rouge</translation>
</message>
<message>
<source>Side-by-side</source>
- <translation type="unfinished"></translation>
+ <translation>Côte-à -côte</translation>
</message>
<message>
<source>Top-Bottom</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
+ <translation>Dessus-dessous</translation>
</message>
<message>
<source>Red/Cyan grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Rouge/Cyan niveaux de gris</translation>
</message>
<message>
<source>Cyan/Red grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Cyan/Rouge niveaux de gris</translation>
</message>
<message>
<source>Red/Blue grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Rouge/Bleu niveaux de gris</translation>
</message>
<message>
<source>Blue/Red grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Bleu/Rouge niveaux de gris</translation>
</message>
<message>
<source>Red/Green grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Rouge/Vert niveaux de gris</translation>
</message>
<message>
<source>Green/Red grayscale</source>
- <translation type="unfinished"></translation>
+ <translation>Vert/Rouge niveaux de gris</translation>
</message>
</context>
<context>
@@ -1489,18 +1767,6 @@ Please pick another nickname:</source>
<translation>Fort</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Raccourcis clavier</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Ãquipes</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Options audio/vidéo</translation>
- </message>
- <message>
<source>Playing teams</source>
<translation>Ãquipes participantes</translation>
</message>
@@ -1521,36 +1787,12 @@ Please pick another nickname:</source>
<translation>Réglages de l'équipe</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Divers</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Paramètres et Armes</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
- <translation type="unfinished"></translation>
+ <translation>Vidéos</translation>
</message>
<message>
<source>Description</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
+ <translation>Description</translation>
</message>
</context>
<context>
@@ -1564,22 +1806,6 @@ Please pick another nickname:</source>
<translation>Limite de FPS</translation>
</message>
<message>
- <source>Developers:</source>
- <translation>Développeurs:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Graphismes:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Traductions:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Remerciements spéciaux:</translation>
- </message>
- <message>
<source>Server name:</source>
<translation>Nom du serveur:</translation>
</message>
@@ -1601,11 +1827,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sons:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1637,17 +1859,13 @@ Please pick another nickname:</source>
</message>
<message>
<source>Scheme Name:</source>
- <translation>Nom de la Configuration:</translation>
+ <translation>Nom de la règle:</translation>
</message>
<message>
<source>Crate Drops</source>
<translation>Lachers de caisse</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Paramètres de jeu</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% de Mines défectueuses</translation>
</message>
@@ -1657,7 +1875,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Type</source>
- <translation type="unfinished">Type</translation>
+ <translation>Type</translation>
</message>
<message>
<source>Grave</source>
@@ -1673,7 +1891,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Locale</source>
- <translation type="unfinished">Langue</translation>
+ <translation>Langue</translation>
</message>
<message>
<source>Explosives</source>
@@ -1681,11 +1899,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Tip: </source>
- <translation>Conseil : </translation>
- </message>
- <message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Cette version de développement est un travail en cours, il peut ne pas être compatible avec les autres versions du jeu. Certaines fonctionnalités peuvent être cassées ou incomplètes.</translation>
+ <translation>Conseil: </translation>
</message>
<message>
<source>Quality</source>
@@ -1709,88 +1923,126 @@ Please pick another nickname:</source>
</message>
<message>
<source>% Rope Length</source>
- <translation>% longueur de la Corde Ninja</translation>
+ <translation>% longueur du grappin</translation>
</message>
<message>
<source>Stereo rendering</source>
- <translation type="unfinished">Rendu stéréo</translation>
+ <translation>Rendu stéréo</translation>
</message>
<message>
<source>Style</source>
- <translation type="unfinished"></translation>
+ <translation>Style</translation>
</message>
<message>
<source>Scheme</source>
- <translation type="unfinished"></translation>
+ <translation>Règles</translation>
</message>
<message>
<source>% Get Away Time</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
+ <translation>% de temp de fuite</translation>
</message>
<message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
- <translation type="unfinished"></translation>
+ <translation>Il y a des vidéos actuellement en cours de traitement.
+Quitter maintenant arretera le processus
+Voulez-vous vraiment quitter?</translation>
</message>
<message>
<source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
- <translation type="unfinished"></translation>
+ <translation>Veuillez indiquer votre email et mot de passe de conexion à youtube</translation>
</message>
<message>
<source>Account name (or email): </source>
- <translation type="unfinished"></translation>
+ <translation>Email du compte: </translation>
</message>
<message>
<source>Password: </source>
- <translation type="unfinished"></translation>
+ <translation>Mot de passe: </translation>
</message>
<message>
<source>Video title: </source>
- <translation type="unfinished"></translation>
+ <translation>Titre de la video: </translation>
</message>
<message>
<source>Video description: </source>
- <translation type="unfinished"></translation>
+ <translation>Description de la vidéo: </translation>
</message>
<message>
<source>Tags (comma separated): </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
+ <translation>Tags (séparer avec une virgule): </translation>
</message>
<message>
<source>Description</source>
- <translation type="unfinished"></translation>
+ <translation>Description</translation>
</message>
<message>
<source>Nickname</source>
- <translation type="unfinished">Pseudo</translation>
+ <translation>Pseudo</translation>
</message>
<message>
<source>Format</source>
- <translation type="unfinished"></translation>
+ <translation>Format</translation>
</message>
<message>
<source>Audio codec</source>
- <translation type="unfinished"></translation>
+ <translation>Codecs audio</translation>
</message>
<message>
<source>Video codec</source>
- <translation type="unfinished"></translation>
+ <translation>Codecs vidéo</translation>
</message>
<message>
<source>Framerate</source>
- <translation type="unfinished"></translation>
+ <translation>Images/secondes</translation>
</message>
<message>
<source>Bitrate (Kbps)</source>
+ <translation>Bitrate(Kb/s)</translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation>Cette version est "en cours de développement" il est possible qu'elle ne soit pas compatible avec les autres versions du jeu, des parties peuvent ne pas fonctionner ou être incompletes!</translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>Plein écran</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation>Résolution en plein écran</translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation>Résolution fenêtrée</translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation>Votre email</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation>Sujet</translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation>Envoyer des informations système</translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation>Entrez le code de sécurité</translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation>Version de développement</translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation>Ce programme est distribué par %1</translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1802,11 +2054,11 @@ Do you really want to quit?</source>
</message>
<message>
<source>hedgehog %1</source>
- <translation type="unfinished"></translation>
+ <translation>Hérisson %1</translation>
</message>
<message>
<source>anonymous</source>
- <translation type="unfinished"></translation>
+ <translation>anonyme</translation>
</message>
</context>
<context>
@@ -1815,6 +2067,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation>-r%1 (%2)</translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1831,233 +2087,220 @@ Do you really want to quit?</source>
<translation>Les associations d'extensions de fichiers ont échoué.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
- <translation type="unfinished"></translation>
+ <translation>Erreur lors de l'authentification à google.com:
+</translation>
</message>
<message>
<source>Login or password is incorrect</source>
- <translation type="unfinished"></translation>
+ <translation>Identifiant ou mot de passe incorrecte</translation>
</message>
<message>
<source>Error while sending metadata to youtube.com:
</source>
- <translation type="unfinished"></translation>
+ <translation>Erreur lors de l'envoi des metadata à youtube.com:
+</translation>
</message>
<message>
<source>Teams - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Equipes - Etes-vous sûr?</translation>
</message>
<message>
<source>Do you really want to delete the team '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Voulez-vous vraiment supprimer l'équipe "%1"</translation>
</message>
<message>
<source>Cannot delete default scheme '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de retirer la règle par défaut "%1"</translation>
</message>
<message>
<source>Please select a record from the list</source>
- <translation type="unfinished"></translation>
+ <translation>Veuillez choisir un enregistrement dans la liste</translation>
</message>
<message>
<source>Unable to start server</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de démarrer le serveur</translation>
</message>
<message>
<source>Hedgewars - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Erreur</translation>
</message>
<message>
<source>Hedgewars - Success</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Succès</translation>
</message>
<message>
<source>All file associations have been set</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Les associations d'extensions de fichiers ont été effectuées</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Impossible de créer le dossier %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Impossible de créer le dossier %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Impossible de démarrer le serveur: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Impossible de démarrer le serveur: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Importation de vidéo - Erreur</translation>
</message>
<message>
<source>Netgame - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Partie en ligne - Erreur</translation>
</message>
<message>
<source>Please select a server from the list</source>
- <translation type="unfinished"></translation>
+ <translation>Veuillez choisir un serveur dans la liste</translation>
</message>
<message>
<source>Please enter room name</source>
- <translation type="unfinished">Veuillez saisir le nom du salon</translation>
+ <translation>Veuillez saisir le nom d'une room</translation>
</message>
<message>
<source>Record Play - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Jouer l'enregistrement - Erreur</translation>
</message>
<message>
<source>Please select record from the list</source>
- <translation type="unfinished">Veuillez sélectionner une partie dans cette liste</translation>
+ <translation>Veuillez choisir un enregistrement dans liste</translation>
</message>
<message>
<source>Cannot rename to </source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de renommer en </translation>
</message>
<message>
<source>Cannot delete file </source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de supprimer le fichier </translation>
</message>
<message>
<source>Room Name - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Nom de la room - Erreur</translation>
</message>
<message>
<source>Please select room from the list</source>
- <translation type="unfinished">Veuillez sélectionner un salon dans la liste</translation>
+ <translation>Veuillez choisir une room dans la liste</translation>
</message>
<message>
<source>Room Name - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Nom de la room - Etes-vous sûr?</translation>
</message>
<message>
<source>The game you are trying to join has started.
Do you still want to join the room?</source>
- <translation type="unfinished">Vous voulez rejoindre une partie qui a déjà commencée. Voulez-vous tout de même rejoindre la salle ?</translation>
+ <translation>Vous essayez de rejoindre une partie qui a déjà commencée.
+Voulez-vous tout de même rejoindre la room?</translation>
</message>
<message>
<source>Schemes - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Règles - Attention</translation>
</message>
<message>
<source>Schemes - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Règles - Etes-vous sûr?</translation>
</message>
<message>
<source>Do you really want to delete the game scheme '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Etes-vous sûr de vouloir supprimer cette règle : "%1" ?</translation>
</message>
<message>
<source>Videos - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Vidéos - Etes-vous sûr?</translation>
</message>
<message>
<source>Do you really want to delete the video '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Etes-vous sûr de vouloir supprimer cette vidéo : "%1" ?</translation>
</message>
<message numerus="yes">
<source>Do you really want to remove %1 file(s)?</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Etes-vous sûr de vouloir supprimer %1 fichier?</numerusform>
+ <numerusform>Etes-vous sûr de vouloir supprimer %1 fichiers?</numerusform>
</translation>
</message>
<message>
<source>Do you really want to cancel uploading %1?</source>
- <translation type="unfinished"></translation>
+ <translation>Voulez-vous arreter l'importation de %1?</translation>
</message>
<message>
<source>File error</source>
- <translation type="unfinished"></translation>
+ <translation>Erreur de fichier</translation>
</message>
<message>
<source>Cannot open '%1' for writing</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible d'écrire le fichier %1</translation>
</message>
<message>
<source>Cannot open '%1' for reading</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de lire le fichier %1</translation>
</message>
<message>
<source>Cannot use the ammo '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible d'utiliser cette arme : "%1"</translation>
</message>
<message>
<source>Weapons - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Armes - Attention</translation>
</message>
<message>
<source>Cannot overwrite default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de remplacer le set d'arme "%1"</translation>
</message>
<message>
<source>Cannot delete default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Impossible de supprimer le set d'arme par défaut "%1"</translation>
</message>
<message>
<source>Weapons - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Armes - Etes-vous sûr?</translation>
</message>
<message>
<source>Do you really want to delete the weapon set '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Etes-vous sûr de vouloir supprimer le set d'arme "%1"?</translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Pseudo</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation>Hedgewars - Pseudo non-enregistré</translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation>Apreçu des informations système</translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation>Echec de la génération du Captcha</translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation>Echec du téléchargement du Captcha</translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation>Veuillez remplir tout les champs. Email optionel.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation>Hedgewars - Attention</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation>Hedgewars - Information</translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation>Les joueurs ne sont pas tous prêts</translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Veuillez entrer votre pseudo</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation>Etes-vous sûr de vouloir lancer cette partie?
+Les joueurs ne sont pas tous prêts.</translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <source>Setup</source>
- <translation>Configuration</translation>
- </message>
- <message>
<source>Play demo</source>
<translation>Jouer la démo</translation>
</message>
@@ -2067,7 +2310,7 @@ Do you still want to join the room?</source>
</message>
<message>
<source>Go!</source>
- <translation>C'est parti !</translation>
+ <translation>C'est parti!</translation>
</message>
<message>
<source>Start</source>
@@ -2110,221 +2353,221 @@ Do you still want to join the room?</source>
<translation>Supprimer</translation>
</message>
<message>
- <source>Ready</source>
- <translation>Prêt</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Ãquipes aléatoires</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Associer les extensions de fichiers</translation>
</message>
<message>
- <source>more</source>
- <translation>plus</translation>
- </message>
- <message>
<source>More info</source>
- <translation type="unfinished"></translation>
+ <translation>Plus d'info</translation>
</message>
<message>
<source>Set default options</source>
- <translation type="unfinished"></translation>
+ <translation>Mettre les options par défaut</translation>
</message>
<message>
<source>Open videos directory</source>
- <translation type="unfinished"></translation>
+ <translation>Ouvrir le répertoire Vidéos</translation>
</message>
<message>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Jouer</translation>
</message>
<message>
<source>Upload to YouTube</source>
- <translation type="unfinished"></translation>
+ <translation>Importer vers Youtube</translation>
</message>
<message>
<source>Cancel uploading</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>RoomsListModel</name>
- <message>
- <source>In progress</source>
- <translation type="unfinished">En cours</translation>
+ <translation>Annuler l'importation</translation>
</message>
<message>
- <source>Room Name</source>
- <translation type="unfinished">Nom de la salle</translation>
+ <source>Restore default coding parameters</source>
+ <translation>Remettre les paramètres de codage par défaut</translation>
</message>
<message>
- <source>C</source>
- <translation type="unfinished">C</translation>
+ <source>Open the video directory in your system</source>
+ <translation>Ouvrir le répertoire vidéo dans votre système</translation>
</message>
<message>
- <source>T</source>
- <translation type="unfinished">Ã</translation>
+ <source>Play this video</source>
+ <translation>Lancer cette vidéo</translation>
</message>
<message>
- <source>Owner</source>
- <translation type="unfinished">Propriétaire</translation>
+ <source>Delete this video</source>
+ <translation>Supprimer cette vidéo</translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">Carte</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation>Importer cette vidéo sur votre compte Youtube</translation>
</message>
<message>
- <source>Rules</source>
- <translation type="unfinished">Règles</translation>
+ <source>Reset</source>
+ <translation>Réinitialiser</translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">Armes</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation>Mettre le port serveur par défaut pour Hedgewars</translation>
</message>
<message>
- <source>Random Map</source>
- <translation type="unfinished">Carte Aléatoire</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation>Invitez vos amis sur votre serveur en 1 clique!</translation>
</message>
<message>
- <source>Random Maze</source>
- <translation type="unfinished">Labyrinthe aléatoire</translation>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation>Cliquez pour copier votre URL serveur unique. Envoyez ce lien a vos amis et il pourront vous rejoindre.</translation>
</message>
<message>
- <source>Hand-drawn</source>
- <translation type="unfinished"></translation>
+ <source>Start private server</source>
+ <translation>Démarrer un serveur privé</translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
- <translation>Set d'armes</translation>
+ <source>Enter a name for your room.</source>
+ <translation>Entrez un nom pour votre room.</translation>
</message>
<message>
- <source>Probabilities</source>
- <translation>Probabilités</translation>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
</message>
<message>
- <source>Ammo in boxes</source>
- <translation>Munitions dans les caisses</translation>
+ <source>Create room</source>
+ <translation>Créer une room</translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
- <translation>Délais</translation>
+ <source>In progress</source>
+ <translation>En cours</translation>
</message>
<message>
- <source>new</source>
- <translation>Nouveau</translation>
+ <source>Room Name</source>
+ <translation>Nom de la room</translation>
</message>
<message>
- <source>copy of</source>
- <translation>Copie de</translation>
+ <source>C</source>
+ <translation>J</translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
- <translation>Vampirisme</translation>
+ <source>T</source>
+ <translation>Ã</translation>
</message>
<message>
- <source>Karma</source>
- <translation>Karma</translation>
+ <source>Owner</source>
+ <translation>Propriétaire</translation>
</message>
<message>
- <source>Artillery</source>
- <translation>Artillerie</translation>
+ <source>Map</source>
+ <translation>Carte</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>Mode Forteresse</translation>
+ <source>Rules</source>
+ <translation>Règles</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>Diviser les Ãquipes</translation>
+ <source>Weapons</source>
+ <translation>Armes</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>Terrain Solide</translation>
+ <source>Random Map</source>
+ <translation>Carte Aléatoire</translation>
</message>
<message>
- <source>Add Border</source>
- <translation>Ajouter des Bordures</translation>
+ <source>Random Maze</source>
+ <translation>Labyrinthe aléatoire</translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>Gravité Fable</translation>
+ <source>Hand-drawn</source>
+ <translation>Dessinée</translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
- <translation>Visée Laser</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation>Cette carte est la base pour toutes valeurs aléatoire générées par le jeu.</translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation>Invulnérable</translation>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
</message>
<message>
- <source>Random Order</source>
- <translation>Ordre aléatoire</translation>
+ <source>Set seed</source>
+ <translation>Générer une base (graine)</translation>
</message>
<message>
- <source>King</source>
- <translation>Roi</translation>
+ <source>Close</source>
+ <translation>Fermer</translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
- <translation>Placer les hérissons</translation>
+ <source>Weapon set</source>
+ <translation>Set d'armes</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation>Les Clans partagent les munitions</translation>
+ <source>Probabilities</source>
+ <translation>Probabilités</translation>
</message>
<message>
- <source>Disable Girders</source>
- <translation>Désactiver les poutres</translation>
+ <source>Ammo in boxes</source>
+ <translation>Munitions dans les caisses</translation>
</message>
<message>
- <source>Disable Land Objects</source>
- <translation>Désactiver les objets de terrain</translation>
+ <source>Delays</source>
+ <translation>Délais</translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished">Mode de survie de l'IA</translation>
+ <source>new</source>
+ <translation>Nouveau</translation>
</message>
<message>
- <source>Reset Health</source>
- <translation>Réinitialiser la Santé</translation>
+ <source>copy of</source>
+ <translation>Copie de</translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>Attaques illimitées</translation>
+ <source>Unable to start server at %1.</source>
+ <translation>Impossible de démarrer un serveur sur %1.</translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Réinitialiser les Armes</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation>Impossible de lancer le jeu sur %1</translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Munitions par hérisson</translation>
+ <source>At least two teams are required to play!</source>
+ <translation>Il doit y avoir deux équipes minimum pour jouer!</translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Désactiver le vent</translation>
+ <source>%1's team</source>
+ <translation>Equipe de %1</translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Davantage de vent</translation>
+ <source>Cancel</source>
+ <translation>Annuler</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation type="unfinished"></translation>
+ <source>Search for a theme:</source>
+ <translation>Chercher un thème</translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation type="unfinished"></translation>
+ <source>Use selected theme</source>
+ <translation>Utiliser le thème séléctionné</translation>
</message>
</context>
<context>
@@ -2446,12 +2689,6 @@ Do you still want to join the room?</source>
<translation>slot 9</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>infos
-hérissons</translation>
- </message>
- <message>
<source>chat</source>
<translation>chat</translation>
</message>
@@ -2490,49 +2727,49 @@ zoom</translation>
</message>
<message>
<source>slot 10</source>
- <translation type="unfinished">slot 10</translation>
+ <translation>slot 10</translation>
</message>
<message>
<source>mute audio</source>
- <translation type="unfinished"></translation>
+ <translation>couper le son</translation>
</message>
<message>
<source>record</source>
- <translation type="unfinished"></translation>
+ <translation>enregistrer</translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
+ <translation>Info hérisson</translation>
</message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Contrôles de base</translation>
+ <source>Movement</source>
+ <translation>Mouvements</translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Contrôles des armes</translation>
+ <source>Weapons</source>
+ <translation>Armes</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Contrôles de la caméra et du curseur</translation>
+ <source>Camera</source>
+ <translation>Caméra</translation>
</message>
<message>
- <source>Other</source>
- <translation>Autres</translation>
+ <source>Miscellaneous</source>
+ <translation>Autre</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Déplacez votre hérisson et visez:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Traversez des trous et des obstacles en sautant:</translation>
</message>
<message>
<source>Fire your selected weapon or trigger an utility item:</source>
- <translation>Tirez avec l'arme sélectionnée et activez un objet utilitaire:</translation>
+ <translation>Tirez avec l'arme sélectionnée ou activez un objet:</translation>
</message>
<message>
<source>Pick a weapon or a target location under the cursor:</source>
@@ -2544,7 +2781,7 @@ zoom</translation>
</message>
<message>
<source>Pick a weapon or utility item:</source>
- <translation>Sélectionnez une arme ou un objet utilitaire:</translation>
+ <translation>Sélectionnez une arme ou un objet:</translation>
</message>
<message>
<source>Set the timer on bombs and timed weapons:</source>
@@ -2568,7 +2805,7 @@ zoom</translation>
</message>
<message>
<source>Pause, continue or leave your game:</source>
- <translation>Stoppez, continuez ou quittez votre partie:</translation>
+ <translation>Pause, continuez ou quittez votre partie:</translation>
</message>
<message>
<source>Modify the game's volume while playing:</source>
@@ -2588,7 +2825,11 @@ zoom</translation>
</message>
<message>
<source>Record video:</source>
- <translation type="unfinished"></translation>
+ <translation>Enregistrer la vidéo</translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation>Déplacement du herisson</translation>
</message>
</context>
<context>
@@ -2607,7 +2848,7 @@ zoom</translation>
</message>
<message>
<source>Hat</source>
- <translation type="unfinished">Chapeau</translation>
+ <translation>Chapeau</translation>
</message>
<message>
<source>(Left)</source>
@@ -2647,11 +2888,11 @@ zoom</translation>
</message>
<message>
<source>Backspace</source>
- <translation>Backspace</translation>
+ <translation>Retour/Effacer</translation>
</message>
<message>
<source>Tab</source>
- <translation>Tabulation</translation>
+ <translation>Tab</translation>
</message>
<message>
<source>Return</source>
@@ -2910,4 +3151,115 @@ zoom</translation>
<translation>Effacer</translation>
</message>
</context>
+<context>
+ <name>server</name>
+ <message>
+ <source>Authentication failed</source>
+ <translation type="obsolete">Echec d'authentification</translation>
+ </message>
+ <message>
+ <source>60 seconds cooldown after kick</source>
+ <translation type="obsolete">Bannis pour 60 sec après un kick</translation>
+ </message>
+ <message>
+ <source>kicked</source>
+ <translation type="obsolete">Exclus (kick)</translation>
+ </message>
+ <message>
+ <source>Ping timeout</source>
+ <translation type="obsolete">Met trop de temps à répondre</translation>
+ </message>
+ <message>
+ <source>bye</source>
+ <translation type="obsolete">Aurevoir</translation>
+ </message>
+ <message>
+ <source>Empty config entry</source>
+ <translation type="obsolete">Configuration vide</translation>
+ </message>
+ <message>
+ <source>Not room master</source>
+ <translation type="obsolete">Vous n'êtes pas le propriétaire de la room</translation>
+ </message>
+ <message>
+ <source>Corrupted hedgehogs info</source>
+ <translation type="obsolete">Info hérisson corrompus</translation>
+ </message>
+ <message>
+ <source>too many teams</source>
+ <translation type="obsolete">trop d'équipes</translation>
+ </message>
+ <message>
+ <source>too many hedgehogs</source>
+ <translation type="obsolete">trop de hérissons</translation>
+ </message>
+ <message>
+ <source>There's already a team with same name in the list</source>
+ <translation type="obsolete">Il y a déja une équipe avec le même nom dans la liste</translation>
+ </message>
+ <message>
+ <source>round in progress</source>
+ <translation type="obsolete">La partie est en cour</translation>
+ </message>
+ <message>
+ <source>restricted</source>
+ <translation type="obsolete">Ajout interdis</translation>
+ </message>
+ <message>
+ <source>REMOVE_TEAM: no such team</source>
+ <translation type="obsolete">REMOVE_TEAM: aucune équipe de ce nom</translation>
+ </message>
+ <message>
+ <source>Not team owner!</source>
+ <translation type="obsolete">Vous n'êtes pas le propriétaire de cette équipe!</translation>
+ </message>
+ <message>
+ <source>Less than two clans!</source>
+ <translation type="obsolete">Il faut 2 clans minimum!</translation>
+ </message>
+ <message>
+ <source>Room with such name already exists</source>
+ <translation type="obsolete">Ce nom de room existe déjà </translation>
+ </message>
+ <message>
+ <source>Illegal room name</source>
+ <translation type="obsolete">Nom de room invalide</translation>
+ </message>
+ <message>
+ <source>No such room</source>
+ <translation type="obsolete">Cette room n'existe pas</translation>
+ </message>
+ <message>
+ <source>Joining restricted</source>
+ <translation type="obsolete">Accès interdis</translation>
+ </message>
+ <message>
+ <source>Registered users only</source>
+ <translation type="obsolete">Accès réservé aux utilisateurs enregistré</translation>
+ </message>
+ <message>
+ <source>You are banned in this room</source>
+ <translation type="obsolete">Vous avez été bannis de cette room</translation>
+ </message>
+ <message>
+ <source>Nickname already chosen</source>
+ <translation type="obsolete">Pseudo déjà choisis</translation>
+ </message>
+ <message>
+ <source>Illegal nickname</source>
+ <translation type="obsolete">Pseudo invalide</translation>
+ </message>
+ <message>
+ <source>Protocol already known</source>
+ <translation type="obsolete">Protocole déjà connu</translation>
+ </message>
+ <message>
+ <source>Bad number</source>
+ <translation type="obsolete">Mauvais numéro</translation>
+ </message>
+ <message>
+ <source>Nickname is already in use</source>
+ <translation type="obsolete">Ce pseudo est actuellement utilisé sur le serveur</translation>
+ </message>
+</context>
</TS>
diff --git a/share/hedgewars/Data/Locale/hedgewars_gl.ts b/share/hedgewars/Data/Locale/hedgewars_gl.ts
index 72b4b84..c892b8f 100644
--- a/share/hedgewars/Data/Locale/hedgewars_gl.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_gl.ts
@@ -1,1577 +1,3104 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.0" language="gl_ES">
-<context>
- <name>AmmoSchemeModel</name>
- <message>
- <source>new</source>
- <translation>novo</translation>
- </message>
-</context>
-<context>
- <name>FreqSpinBox</name>
- <message>
- <source>Never</source>
- <translation>Nunca</translation>
- </message>
- <message numerus="yes">
- <source>Every %1 turn</source>
- <translation>
- <numerusform>Cada rolda</numerusform>
- <numerusform>Cada %1 roldas</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>GameCFGWidget</name>
- <message>
- <source>Edit weapons</source>
- <translation>Editar os armamentos</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>Illegal ammo scheme</source>
- <translation>Non se permite ese armamento</translation>
- </message>
- <message>
- <source>Edit schemes</source>
- <translation>Editar os modos de xogo</translation>
- </message>
-</context>
-<context>
- <name>HWForm</name>
- <message>
- <source>new</source>
- <translation>novo</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>Aceptar</translation>
- </message>
- <message>
- <source>Unable to start the server</source>
- <translation>Non se puido iniciar o servidor</translation>
- </message>
- <message>
- <source>Cannot save record to file %1</source>
- <translation>Non se pode gardar a gravación no ficheiro %1</translation>
- </message>
- <message>
- <source>Please select record from the list above</source>
- <translation>Selecciona unha gravación da seguinte lista</translation>
- </message>
-</context>
-<context>
- <name>HWGame</name>
- <message>
- <source>Error reading training config file</source>
- <translation>Houbo un erro ao ler o ficheiro de configuración do adestramento</translation>
- </message>
- <message>
- <source>en.txt</source>
- <translation>gl.txt</translation>
- </message>
- <message>
- <source>Cannot open demofile %1</source>
- <translation>Non se pode abrir a demostración %1</translation>
- </message>
-</context>
-<context>
- <name>HWMapContainer</name>
- <message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temas visuais</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtro</translation>
- </message>
- <message>
- <source>All</source>
- <translation>Todos</translation>
- </message>
- <message>
- <source>Small</source>
- <translation>Pequeno</translation>
- </message>
- <message>
- <source>Medium</source>
- <translation>Mediano</translation>
- </message>
- <message>
- <source>Large</source>
- <translation>Grande</translation>
- </message>
- <message>
- <source>Cavern</source>
- <translation>Caverna</translation>
- </message>
- <message>
- <source>Wacky</source>
- <translation>Absurdo</translation>
- </message>
-</context>
-<context>
- <name>HWNetServersModel</name>
- <message>
- <source>Title</source>
- <translation>Nome</translation>
- </message>
- <message>
- <source>IP</source>
- <translation>IP</translation>
- </message>
- <message>
- <source>Port</source>
- <translation>Porto</translation>
- </message>
-</context>
-<context>
- <name>HWNewNet</name>
- <message>
- <source>The host was not found. Please check the host name and port settings.</source>
- <translation>Non se atopou o anfitrión. Comproba o nome e mailo porto do anfitrión.</translation>
- </message>
- <message>
- <source>Connection refused</source>
- <translation>Rexeitouse a conexión</translation>
- </message>
- <message>
- <source>Room destroyed</source>
- <translation>Destruiuse a sala</translation>
- </message>
- <message>
- <source>Quit reason: </source>
- <translation>Motivo da expulsión:</translation>
- </message>
- <message>
- <source>You got kicked</source>
- <translation>Botáronte</translation>
- </message>
- <message>
- <source>Password</source>
- <translation>Contrasinal</translation>
- </message>
- <message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</source>
- <translation>O teu alcume, «%1»
-está rexistrado en Hedgewars.org
-Introduce o contrasinal ou
-escolle outro alcume:</translation>
- </message>
- <message>
- <source>%1 *** %2 has joined the room</source>
- <translation>%1 *** %2 entrou na sala</translation>
- </message>
- <message>
- <source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 uniuse</translation>
- </message>
- <message>
- <source>%1 *** %2 has left (%3)</source>
- <translation>%1 *** %2 marchou (%3)</translation>
- </message>
- <message>
- <source>%1 *** %2 has left</source>
- <translation>%1 *** %2 marchou</translation>
- </message>
-</context>
-<context>
- <name>KB</name>
- <message>
- <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
- <translation>SDL_ttf devolveu un erro ao renderizar o texto, seguramente sexa por mor do erro de freetype2. Cómpre que actualices a túa biblioteca freetype.</translation>
- </message>
-</context>
-<context>
- <name>PageAdmin</name>
- <message>
- <source>Server message:</source>
- <translation>Mensaxe do servidor:</translation>
- </message>
- <message>
- <source>Set message</source>
- <translation>Establecer a mensaxe</translation>
- </message>
- <message>
- <source>Clear Accounts Cache</source>
- <translation>Borrar a caché das contas</translation>
- </message>
-</context>
-<context>
- <name>PageConnecting</name>
- <message>
- <source>Connecting...</source>
- <translation>Conectando...</translation>
- </message>
-</context>
-<context>
- <name>PageEditTeam</name>
- <message>
- <source>General</source>
- <translation>Xeral</translation>
- </message>
- <message>
- <source>Advanced</source>
- <translation>Avanzado</translation>
- </message>
-</context>
-<context>
- <name>PageGameStats</name>
- <message>
- <source><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></source>
- <translation><p>O mellor tirador foi <b>%1</b>, con <b>%2</b> puntos.</p></translation>
- </message>
- <message numerus="yes">
- <source><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></source>
- <translation>
- <numerusform><p>O mellor asasino é <b>%1</b>, con <b>%2</b> vÃtima nunha rolda.</p></numerusform>
- <numerusform><p>O mellor asasino é <b>%1</b>, con <b>%2</b> vÃtimas nunha rolda.</p></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><p>A total of <b>%1</b> hedgehog(s) were killed during this round.</p></source>
- <translation>
- <numerusform><p>Nesta rolda morrereu <b>un</b> ourizo.</p></numerusform>
- <numerusform><p>Nesta rolda morreron <b>%1</b> ourizos.</p></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Local Game (Play a game on a single computer)</source>
- <translation>Partida local (xoga unha partida nun só computador)</translation>
- </message>
- <message>
- <source>Network Game (Play a game across a network)</source>
- <translation>Partida na rede (xoga unha partida na rede)</translation>
- </message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <source>Start</source>
- <translation>Iniciar</translation>
- </message>
-</context>
-<context>
- <name>PageNet</name>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>Please select server from the list above</source>
- <translation>Selecciona un servidor da seguinte lista</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>Control</translation>
- </message>
-</context>
-<context>
- <name>PageNetType</name>
- <message>
- <source>LAN game</source>
- <translation>Partida na rede local</translation>
- </message>
- <message>
- <source>Official server</source>
- <translation>Servidor oficial</translation>
- </message>
-</context>
-<context>
- <name>PageOptions</name>
- <message>
- <source>New team</source>
- <translation>Novo equipo</translation>
- </message>
- <message>
- <source>Edit team</source>
- <translation>Editar o equipo</translation>
- </message>
- <message>
- <source>Weapons set</source>
- <translation>Armamento</translation>
- </message>
- <message>
- <source>Edit</source>
- <translation>Editar</translation>
- </message>
-</context>
-<context>
- <name>PagePlayDemo</name>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>Aceptar</translation>
- </message>
- <message>
- <source>Rename dialog</source>
- <translation>Diálogo de cambio de nome</translation>
- </message>
- <message>
- <source>Enter new file name:</source>
- <translation>Introduce un novo nome para o ficheiro:</translation>
- </message>
- <message>
- <source>Cannot rename to</source>
- <translation>Non se pode cambiar o nome a</translation>
- </message>
- <message>
- <source>Cannot delete file</source>
- <translation>Non se pode borrar o ficheiro</translation>
- </message>
- <message>
- <source>Please select record from the list</source>
- <translation>Selecciona unha gravación da lista</translation>
- </message>
-</context>
-<context>
- <name>PageRoomsList</name>
- <message>
- <source>Create</source>
- <translation>Crear</translation>
- </message>
- <message>
- <source>Join</source>
- <translation>Entrar</translation>
- </message>
- <message>
- <source>Refresh</source>
- <translation>Actualizar</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>Aceptar</translation>
- </message>
- <message>
- <source>Admin features</source>
- <translation>Administración</translation>
- </message>
- <message>
- <source>Room Name:</source>
- <translation>Nome da sala:</translation>
- </message>
- <message>
- <source>This game is in lobby.
-You may join and start playing once the game starts.</source>
- <translation>AÃnda non comezou a partida.
-Podes entrar e empezar a xogar cando comece.</translation>
- </message>
- <message>
- <source>This game is in progress.
-You may join and spectate now but you'll have to wait for the game to end to start playing.</source>
- <translation>A partida estase xogando.
-Poder entrar a ver, pero terás que agardar a que remate para xogar ti.</translation>
- </message>
- <message>
- <source>%1 is the host. He may adjust settings and start the game.</source>
- <translation>%1 é o anfitrión. Pode configurar e iniciar a partida.</translation>
- </message>
- <message>
- <source>Random Map</source>
- <translation>Mapa ao chou</translation>
- </message>
- <message>
- <source>Games may be played on precreated or randomized maps.</source>
- <translation>Pódese xogar en mapas elaborados ou mapas xerados ao chou.</translation>
- </message>
- <message>
- <source>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</source>
- <translation>O modo de xogo establece as opcións xerais tales coma "tempo por rolda", "morte súbita" ou "vampirismo".</translation>
- </message>
- <message>
- <source>The Weapon Scheme defines available weapons and their ammunition count.</source>
- <translation>O armamento establece as armas dispoñibles e a cantidade de munición para cada unha.</translation>
- </message>
- <message numerus="yes">
- <source>There are %1 clients connected to this room.</source>
- <translation>
- <numerusform>Hai un cliente conectado a esta sala.</numerusform>
- <numerusform>Hai %1 clientes conectados a esta sala.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>There are %1 teams participating in this room.</source>
- <translation>
- <numerusform>Hai un equipo participando nesta sala.</numerusform>
- <numerusform>Hai %1 equipos participando nesta sala.</numerusform>
- </translation>
- </message>
- <message>
- <source>Please enter room name</source>
- <translation>Introduce o nome da sala</translation>
- </message>
- <message>
- <source>Please select room from the list</source>
- <translation>Selecciona unha sala da lista</translation>
- </message>
-</context>
-<context>
- <name>PageScheme</name>
- <message>
- <source>Defend your fort and destroy the opponents, two team colours max!</source>
- <translation>Defende o teu forte e elimina os inimigos, máximo dous bandos!</translation>
- </message>
- <message>
- <source>Teams will start on opposite sides of the terrain, two team colours max!</source>
- <translation>Os bandos comezarán en lados opostos da superficie, máximo dous bandos!</translation>
- </message>
- <message>
- <source>Land can not be destroyed!</source>
- <translation>Non se pode destruÃr o terreo!</translation>
- </message>
- <message>
- <source>Add an indestructable border around the terrain</source>
- <translation>Engade un bordo indestructible arredor do terreo</translation>
- </message>
- <message>
- <source>Lower gravity</source>
- <translation>Baixa gravidade</translation>
- </message>
- <message>
- <source>Assisted aiming with laser sight</source>
- <translation>Mira láser</translation>
- </message>
- <message>
- <source>All hogs have a personal forcefield</source>
- <translation>Todos os ourizos teñen un escudo protector</translation>
- </message>
- <message>
- <source>Enable random mines</source>
- <translation>Activar as minas esparexidas</translation>
- </message>
- <message>
- <source>Gain 80% of the damage you do back in health</source>
- <translation>Gañar o 80% do daño inflixido en vida</translation>
- </message>
- <message>
- <source>Share your opponents pain, share their damage</source>
- <translation>Acompañar aos inimigos no sentimento e no dano</translation>
- </message>
- <message>
- <source>Your hogs are unable to move, put your artillery skills to the test</source>
- <translation>Os ourizos non se poden mover, pon a probas a túa faceta de artilleiro</translation>
- </message>
- <message>
- <source>Random</source>
- <translation>Ao chou</translation>
- </message>
- <message>
- <source>Seconds</source>
- <translation>segundos</translation>
- </message>
- <message>
- <source>New</source>
- <translation>Novo</translation>
- </message>
- <message>
- <source>Delete</source>
- <translation>Borrar</translation>
- </message>
-</context>
-<context>
- <name>PageSelectWeapon</name>
- <message>
- <source>Default</source>
- <translation>Por defecto</translation>
- </message>
- <message>
- <source>Delete</source>
- <translation>Borrar</translation>
- </message>
-</context>
-<context>
- <name>PageSinglePlayer</name>
- <message>
- <source>Simple Game (a quick game against the computer, settings are chosen for you)</source>
- <translation>Partida simple (unha partida rápida xa configurada contra a intelixencia artificial)</translation>
- </message>
- <message>
- <source>Multiplayer (play a hotseat game against your friends, or AI teams)</source>
- <translation>Partida colectiva (xoga no teu computador contra os teus amigos ou contra a intelixencia artificial)</translation>
- </message>
- <message>
- <source>Training Mode (Practice your skills in a range of training missions). IN DEVELOPMENT</source>
- <translation>Adestramento (practica as túas habilidades nunha serie de misións de adestramento). EN DESENVOLVEMENTO</translation>
- </message>
- <message>
- <source>Demos (Watch recorded demos)</source>
- <translation>Demostracións (reproduce demostracións gravadas)</translation>
- </message>
- <message>
- <source>Load (Load a previously saved game)</source>
- <translation>Cargar (carga unha partida gardada)</translation>
- </message>
-</context>
-<context>
- <name>QAction</name>
- <message>
- <source>Kick</source>
- <translation>Botar</translation>
- </message>
- <message>
- <source>Info</source>
- <translation>Información</translation>
- </message>
- <message>
- <source>Start</source>
- <translation>Iniciar</translation>
- </message>
- <message>
- <source>Restrict Joins</source>
- <translation>Restrinxir a entrada</translation>
- </message>
- <message>
- <source>Restrict Team Additions</source>
- <translation>Restrinxir o engadido de equipos</translation>
- </message>
- <message>
- <source>Ban</source>
- <translation>Expulsar</translation>
- </message>
-</context>
-<context>
- <name>QCheckBox</name>
- <message>
- <source>Check for updates at startup</source>
- <translation>Comprobar se hai actualizacións ao iniciar</translation>
- </message>
- <message>
- <source>Fullscreen</source>
- <translation>Partidas a pantalla completa</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Interface a pantalla completa</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Activar os sons</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Activar a música</translation>
- </message>
- <message>
- <source>Show FPS</source>
- <translation>Amosar as FPS</translation>
- </message>
- <message>
- <source>Alternative damage show</source>
- <translation>Gráficos de dano alternativos</translation>
- </message>
- <message>
- <source>Append date and time to record file name</source>
- <translation>Engadir a data e maila hora ao nome dos ficheiros de gravación</translation>
- </message>
- <message>
- <source>Frontend effects (requires restart)</source>
- <translation>Efectos na interface (hai que reiniciar)</translation>
- </message>
- <message>
- <source>Reduced quality</source>
- <translation>Baixa calidade</translation>
- </message>
-</context>
-<context>
- <name>QComboBox</name>
- <message>
- <source>generated map...</source>
- <translation>Mapa xerado...</translation>
- </message>
- <message>
- <source>Human</source>
- <translation>Xogador</translation>
- </message>
- <message>
- <source>Level</source>
- <translation>Nivel</translation>
- </message>
-</context>
-<context>
- <name>QGroupBox</name>
- <message>
- <source>Team Members</source>
- <translation>Membros do equipo</translation>
- </message>
- <message>
- <source>Team</source>
- <translation>Equipo</translation>
- </message>
- <message>
- <source>Fort</source>
- <translation>Forte</translation>
- </message>
- <message>
- <source>Key binds</source>
- <translation>Controis</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Equipos</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation>Armamento</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Configuración audiovisual</translation>
- </message>
- <message>
- <source>Net game</source>
- <translation>Partida na rede</translation>
- </message>
- <message>
- <source>Playing teams</source>
- <translation>Equipos xogando</translation>
- </message>
- <message>
- <source>Game Modifiers</source>
- <translation>Modificadores da partida</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Configuración básica</translation>
- </message>
-</context>
-<context>
- <name>QLabel</name>
- <message>
- <source>Mines Time</source>
- <translation>Temporizador das minas</translation>
- </message>
- <message>
- <source>Mines</source>
- <translation>Minas</translation>
- </message>
- <message>
- <source>Version</source>
- <translation>Versión</translation>
- </message>
- <message>
- <source>This program is distributed under the GNU General Public License</source>
- <translation>Esta aplicación distribúese baixo a GNU General Public License</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Desenvolvedores:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Gráficos:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sons:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Traducións:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Un especial agradecemento a:</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation>Armamento</translation>
- </message>
- <message>
- <source>Host:</source>
- <translation>Anfitrión:</translation>
- </message>
- <message>
- <source>Port:</source>
- <translation>Porto:</translation>
- </message>
- <message>
- <source>Net nick</source>
- <translation>Alcume</translation>
- </message>
- <message>
- <source>Resolution</source>
- <translation>Resolución</translation>
- </message>
- <message>
- <source>FPS limit</source>
- <translation>LÃmite de FPS</translation>
- </message>
- <message>
- <source>Server name:</source>
- <translation>Nome do servidor:</translation>
- </message>
- <message>
- <source>Server port:</source>
- <translation>Porto do servidor:</translation>
- </message>
- <message>
- <source>Initial sound volume</source>
- <translation>Volume inicial</translation>
- </message>
- <message>
- <source>Damage Modifier</source>
- <translation>Modificador de dano</translation>
- </message>
- <message>
- <source>Turn Time</source>
- <translation>Tempo por rolda</translation>
- </message>
- <message>
- <source>Initial Health</source>
- <translation>Saúde inicial</translation>
- </message>
- <message>
- <source>Sudden Death Timeout</source>
- <translation>Conta atrás ata a morte súbita</translation>
- </message>
- <message>
- <source>Scheme Name:</source>
- <translation>Nome do modo:</translation>
- </message>
- <message>
- <source>Crate Drops</source>
- <translation>CaÃda de caixas</translation>
- </message>
- <message>
- <source>Game scheme</source>
- <translation>Modo de xogo</translation>
- </message>
-</context>
-<context>
- <name>QLineEdit</name>
- <message>
- <source>unnamed</source>
- <translation>sen nome</translation>
- </message>
-</context>
-<context>
- <name>QMainWindow</name>
- <message>
- <source>Hedgewars %1</source>
- <translation>Hedgewars %1</translation>
- </message>
-</context>
-<context>
- <name>QMessageBox</name>
- <message>
- <source>Network</source>
- <translation>Rede</translation>
- </message>
- <message>
- <source>Connection to server is lost</source>
- <translation>Perdeuse a conexión co servidor</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-Please check your installation</source>
- <translation>Non se puido abrir o directorio dos datos:
- %1
-Verifica a instalación</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation>Armamento</translation>
- </message>
- <message>
- <source>Can not edit default weapon set</source>
- <translation>Non se pode editar o armamento por defecto</translation>
- </message>
- <message>
- <source>Can not delete default weapon set</source>
- <translation>Non se pode borrar o armamento por defecto</translation>
- </message>
- <message>
- <source>Really delete this weapon set?</source>
- <translation>Seguro que queres borrar este armamento?</translation>
- </message>
-</context>
-<context>
- <name>QObject</name>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>Cannot create directory %1</source>
- <translation>Non se puido crear o directorio %1</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>Aceptar</translation>
- </message>
- <message>
- <source>Nickname</source>
- <translation>Alcume</translation>
- </message>
- <message>
- <source>Please enter your nickname</source>
- <translation>Introduce o teu alcume</translation>
- </message>
-</context>
-<context>
- <name>QPushButton</name>
- <message>
- <source>default</source>
- <translation>por defecto</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>Aceptar</translation>
- </message>
- <message>
- <source>Cancel</source>
- <translation>Cancelar</translation>
- </message>
- <message>
- <source>Start server</source>
- <translation>Iniciar un servidor</translation>
- </message>
- <message>
- <source>Connect</source>
- <translation>Conectar</translation>
- </message>
- <message>
- <source>Update</source>
- <translation>Actualizar</translation>
- </message>
- <message>
- <source>Specify</source>
- <translation>Especificar</translation>
- </message>
- <message>
- <source>Start</source>
- <translation>Iniciar</translation>
- </message>
- <message>
- <source>Go!</source>
- <translation>Dálle!</translation>
- </message>
- <message>
- <source>Play demo</source>
- <translation>Reproducir a demostración</translation>
- </message>
- <message>
- <source>Rename</source>
- <translation>Cambiar o nome</translation>
- </message>
- <message>
- <source>Delete</source>
- <translation>Borrar</translation>
- </message>
- <message>
- <source>Load</source>
- <translation>Cargar</translation>
- </message>
- <message>
- <source>Setup</source>
- <translation>Configuración</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Preparado</translation>
- </message>
-</context>
-<context>
- <name>QTableWidget</name>
- <message>
- <source>Room Name</source>
- <translation>Nome da sala</translation>
- </message>
- <message>
- <source>C</source>
- <translation>C</translation>
- </message>
- <message>
- <source>T</source>
- <translation>T</translation>
- </message>
- <message>
- <source>Owner</source>
- <translation>Dono</translation>
- </message>
- <message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Rules</source>
- <translation>Regras</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation>Armamento</translation>
- </message>
-</context>
-<context>
- <name>SelWeaponWidget</name>
- <message>
- <source>Weapon set</source>
- <translation>Armamento</translation>
- </message>
- <message>
- <source>Probabilities</source>
- <translation>Probabilidades</translation>
- </message>
-</context>
-<context>
- <name>TCPBase</name>
- <message>
- <source>Error</source>
- <translation>Erro</translation>
- </message>
- <message>
- <source>Unable to start the server: %1.</source>
- <translation>Non se puido iniciar o servidor: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine: %1 (</source>
- <translation>Non se puido executar o motor: %1 (</translation>
- </message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirismo</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>ArtillerÃa</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Modo fortaleza</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Equipos divididos</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Terreo indestructible</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Con bordos</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Baixa gravidade</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Mira láser</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Invulnerable</translation>
- </message>
- <message>
- <source>Add Mines</source>
- <translation>Engadir minas</translation>
- </message>
-</context>
-<context>
- <name>binds</name>
- <message>
- <source>up</source>
- <translation>arriba</translation>
- </message>
- <message>
- <source>left</source>
- <translation>esquerda</translation>
- </message>
- <message>
- <source>right</source>
- <translation>dereita</translation>
- </message>
- <message>
- <source>down</source>
- <translation>abaixo</translation>
- </message>
- <message>
- <source>attack</source>
- <translation>atacar</translation>
- </message>
- <message>
- <source>precise aim</source>
- <translation>apuntar con precisión</translation>
- </message>
- <message>
- <source>put</source>
- <translation>poñer</translation>
- </message>
- <message>
- <source>switch</source>
- <translation>cambiar</translation>
- </message>
- <message>
- <source>find hedgehog</source>
- <translation>atopar ourizo</translation>
- </message>
- <message>
- <source>ammo menu</source>
- <translation>menú de armas</translation>
- </message>
- <message>
- <source>slot 1</source>
- <translation>1ª ranura</translation>
- </message>
- <message>
- <source>slot 2</source>
- <translation>2ª ranura</translation>
- </message>
- <message>
- <source>slot 3</source>
- <translation>3ª ranura</translation>
- </message>
- <message>
- <source>slot 4</source>
- <translation>4ª ranura</translation>
- </message>
- <message>
- <source>slot 5</source>
- <translation>5ª ranura</translation>
- </message>
- <message>
- <source>slot 6</source>
- <translation>6ª ranura</translation>
- </message>
- <message>
- <source>slot 7</source>
- <translation>7ª ranura</translation>
- </message>
- <message>
- <source>slot 8</source>
- <translation>8ª ranura</translation>
- </message>
- <message>
- <source>slot 9</source>
- <translation>9ª ranura</translation>
- </message>
- <message>
- <source>timer 1 sec</source>
- <translation>temporizador a 1 segundo</translation>
- </message>
- <message>
- <source>timer 2 sec</source>
- <translation>temporizador a 2 segundos</translation>
- </message>
- <message>
- <source>timer 3 sec</source>
- <translation>temporizador a 3 segundos</translation>
- </message>
- <message>
- <source>timer 4 sec</source>
- <translation>temporizador a 4 segundos</translation>
- </message>
- <message>
- <source>timer 5 sec</source>
- <translation>temporizador a 5 segundos</translation>
- </message>
- <message>
- <source>chat</source>
- <translation>conversa</translation>
- </message>
- <message>
- <source>chat history</source>
- <translation>historial de conversa</translation>
- </message>
- <message>
- <source>pause</source>
- <translation>pausa</translation>
- </message>
- <message>
- <source>confirmation</source>
- <translation>confirmación</translation>
- </message>
- <message>
- <source>volume down</source>
- <translation>baixar o volume</translation>
- </message>
- <message>
- <source>volume up</source>
- <translation>subir o volume</translation>
- </message>
- <message>
- <source>change mode</source>
- <translation>cambiar o modo</translation>
- </message>
- <message>
- <source>capture</source>
- <translation>capturar</translation>
- </message>
- <message>
- <source>hedgehogs
-info</source>
- <translation>información
-dos ourizos</translation>
- </message>
- <message>
- <source>quit</source>
- <translation>saÃr</translation>
- </message>
- <message>
- <source>zoom in</source>
- <translation>achegar</translation>
- </message>
- <message>
- <source>zoom out</source>
- <translation>afastar</translation>
- </message>
- <message>
- <source>reset zoom</source>
- <translation>distancia inicial</translation>
- </message>
- <message>
- <source>long jump</source>
- <translation>salto cara adiante</translation>
- </message>
- <message>
- <source>high jump</source>
- <translation>salto cara arriba</translation>
- </message>
-</context>
-<context>
- <name>binds (categories)</name>
- <message>
- <source>Basic controls</source>
- <translation>Controis básicos</translation>
- </message>
- <message>
- <source>Weapon controls</source>
- <translation>Controis das armas</translation>
- </message>
- <message>
- <source>Camera and cursor controls</source>
- <translation>Controis da cámara e mailo cursor</translation>
- </message>
- <message>
- <source>Other</source>
- <translation>Outros</translation>
- </message>
-</context>
-<context>
- <name>binds (descriptions)</name>
- <message>
- <source>Move your hogs and aim:</source>
- <translation>Move os teus ourizos e apunta:</translation>
- </message>
- <message>
- <source>Traverse gaps and obstacles by jumping:</source>
- <translation>Supera os obstáculos saltando:</translation>
- </message>
- <message>
- <source>Fire your selected weapon or trigger an utility item:</source>
- <translation>Dispara a arma seleccionada ou activa unha ferramenta:</translation>
- </message>
- <message>
- <source>Pick a weapon or a target location under the cursor:</source>
- <translation>Recolle un arma ou a situación dun obxectivo onde o cursor:</translation>
- </message>
- <message>
- <source>Switch your currently active hog (if possible):</source>
- <translation>Cambia de ourizo (se se pode):</translation>
- </message>
- <message>
- <source>Pick a weapon or utility item:</source>
- <translation>Recolle unha arma ou ferramenta:</translation>
- </message>
- <message>
- <source>Set the timer on bombs and timed weapons:</source>
- <translation>Establece o temporizador para as armas que o teñan:</translation>
- </message>
- <message>
- <source>Move the camera to the active hog:</source>
- <translation>Move a cámara ao ourizo activo:</translation>
- </message>
- <message>
- <source>Move the cursor or camera without using the mouse:</source>
- <translation>Move o cursor ou a cámara sen usar o rato:</translation>
- </message>
- <message>
- <source>Modify the camera's zoom level:</source>
- <translation>Cambia a distancia da cámara:</translation>
- </message>
- <message>
- <source>Talk to your team or all participants:</source>
- <translation>Fala co teu equipo ou con todos:</translation>
- </message>
- <message>
- <source>Pause, continue or leave your game:</source>
- <translation>Pausa, continúa ou sal da túa partida:</translation>
- </message>
- <message>
- <source>Modify the game's volume while playing:</source>
- <translation>Cambia o volume do xogo durante unha partida:</translation>
- </message>
- <message>
- <source>Toggle fullscreen mode:</source>
- <translation>Cambiar a pantalla completa:</translation>
- </message>
- <message>
- <source>Take a screenshot:</source>
- <translation>Facer unha captura de pantalla:</translation>
- </message>
- <message>
- <source>Toggle labels above hedgehogs:</source>
- <translation>Cambiar as etiquetas sobre os ourizos:</translation>
- </message>
-</context>
-<context>
- <name>binds (keys)</name>
- <message>
- <source>Axis</source>
- <translation>Eixo</translation>
- </message>
- <message>
- <source>(Up)</source>
- <translation>(Arriba)</translation>
- </message>
- <message>
- <source>(Down)</source>
- <translation>(Abaixo)</translation>
- </message>
- <message>
- <source>Hat</source>
- <translation>Sombreiro</translation>
- </message>
- <message>
- <source>(Left)</source>
- <translation>(Esquerda)</translation>
- </message>
- <message>
- <source>(Right)</source>
- <translation>(Dereita)</translation>
- </message>
- <message>
- <source>Button</source>
- <translation>Botón</translation>
- </message>
- <message>
- <source>Keyboard</source>
- <translation>Teclado</translation>
- </message>
- <message>
- <source>Mouse: Left button</source>
- <translation>Rato: botón esquerdo</translation>
- </message>
- <message>
- <source>Mouse: Middle button</source>
- <translation>Rato: botón central</translation>
- </message>
- <message>
- <source>Mouse: Right button</source>
- <translation>Rato: botón dereito</translation>
- </message>
- <message>
- <source>Mouse: Wheel up</source>
- <translation>Rato: roda cara arriba</translation>
- </message>
- <message>
- <source>Mouse: Wheel down</source>
- <translation>Rato: roda cara abaixo</translation>
- </message>
- <message>
- <source>Backspace</source>
- <translation>Retroceso</translation>
- </message>
- <message>
- <source>Tab</source>
- <translation>Tabulador</translation>
- </message>
- <message>
- <source>Clear</source>
- <translation>Borrado</translation>
- </message>
- <message>
- <source>Return</source>
- <translation>Retorno</translation>
- </message>
- <message>
- <source>Pause</source>
- <translation>Pausa</translation>
- </message>
- <message>
- <source>Escape</source>
- <translation>Escape</translation>
- </message>
- <message>
- <source>Space</source>
- <translation>Espazo</translation>
- </message>
- <message>
- <source>Delete</source>
- <translation>Borrar</translation>
- </message>
- <message>
- <source>Numpad 0</source>
- <translation>Teclado numérico: 0</translation>
- </message>
- <message>
- <source>Numpad 1</source>
- <translation>Teclado numérico: 1</translation>
- </message>
- <message>
- <source>Numpad 2</source>
- <translation>Teclado numérico: 2</translation>
- </message>
- <message>
- <source>Numpad 3</source>
- <translation>Teclado numérico: 3</translation>
- </message>
- <message>
- <source>Numpad 4</source>
- <translation>Teclado numérico: 4</translation>
- </message>
- <message>
- <source>Numpad 5</source>
- <translation>Teclado numérico: 5</translation>
- </message>
- <message>
- <source>Numpad 6</source>
- <translation>Teclado numérico: 6</translation>
- </message>
- <message>
- <source>Numpad 7</source>
- <translation>Teclado numérico: 7</translation>
- </message>
- <message>
- <source>Numpad 8</source>
- <translation>Teclado numérico: 8</translation>
- </message>
- <message>
- <source>Numpad 9</source>
- <translation>Teclado numérico: 9</translation>
- </message>
- <message>
- <source>Numpad .</source>
- <translation>Teclado numérico: .</translation>
- </message>
- <message>
- <source>Numpad /</source>
- <translation>Teclado numérico: /</translation>
- </message>
- <message>
- <source>Numpad *</source>
- <translation>Teclado numérico: *</translation>
- </message>
- <message>
- <source>Numpad -</source>
- <translation>Teclado numérico: -</translation>
- </message>
- <message>
- <source>Numpad +</source>
- <translation>Teclado numérico: +</translation>
- </message>
- <message>
- <source>Enter</source>
- <translation>Intro</translation>
- </message>
- <message>
- <source>Equals</source>
- <translation>Igual</translation>
- </message>
- <message>
- <source>Up</source>
- <translation>Arriba</translation>
- </message>
- <message>
- <source>Down</source>
- <translation>Abaixo</translation>
- </message>
- <message>
- <source>Right</source>
- <translation>Dereita</translation>
- </message>
- <message>
- <source>Left</source>
- <translation>Esquerda</translation>
- </message>
- <message>
- <source>Insert</source>
- <translation>Inserir</translation>
- </message>
- <message>
- <source>Home</source>
- <translation>Inicio</translation>
- </message>
- <message>
- <source>End</source>
- <translation>Fin</translation>
- </message>
- <message>
- <source>Page up</source>
- <translation>Re Páx</translation>
- </message>
- <message>
- <source>Page down</source>
- <translation>Av Páx</translation>
- </message>
- <message>
- <source>Num lock</source>
- <translation>Bloq Num</translation>
- </message>
- <message>
- <source>Caps lock</source>
- <translation>Bloq Maiús</translation>
- </message>
- <message>
- <source>Scroll lock</source>
- <translation>Bloq Despr</translation>
- </message>
- <message>
- <source>Right shift</source>
- <translation>Maiús dereito</translation>
- </message>
- <message>
- <source>Left shift</source>
- <translation>Maiús esquerdo</translation>
- </message>
- <message>
- <source>Right ctrl</source>
- <translation>Ctrl dereito</translation>
- </message>
- <message>
- <source>Left ctrl</source>
- <translation>Ctrl esquerdo</translation>
- </message>
- <message>
- <source>Right alt</source>
- <translation>Alt dereito</translation>
- </message>
- <message>
- <source>Left alt</source>
- <translation>Alt esquerdo</translation>
- </message>
- <message>
- <source>Right meta</source>
- <translation>Meta dereito</translation>
- </message>
- <message>
- <source>Left meta</source>
- <translation>Meta esquerdo</translation>
- </message>
- <message>
- <source>A button</source>
- <translation>Botón A</translation>
- </message>
- <message>
- <source>B button</source>
- <translation>Botón B</translation>
- </message>
- <message>
- <source>X button</source>
- <translation>Botón X</translation>
- </message>
- <message>
- <source>Y button</source>
- <translation>Botón Y</translation>
- </message>
- <message>
- <source>LB button</source>
- <translation>Botón LB</translation>
- </message>
- <message>
- <source>RB button</source>
- <translation>Botón RB</translation>
- </message>
- <message>
- <source>Back button</source>
- <translation>Botón de volver</translation>
- </message>
- <message>
- <source>Start button</source>
- <translation>Botón de inicio</translation>
- </message>
- <message>
- <source>Left stick</source>
- <translation>Stick esquerdo</translation>
- </message>
- <message>
- <source>Right stick</source>
- <translation>Stick dereito</translation>
- </message>
- <message>
- <source>Left stick (Right)</source>
- <translation>Stick esquerdo (Dereita)</translation>
- </message>
- <message>
- <source>Left stick (Left)</source>
- <translation>Stick esquerdo (Esquerda)</translation>
- </message>
- <message>
- <source>Left stick (Down)</source>
- <translation>Stick esquerdo (Abaixo)</translation>
- </message>
- <message>
- <source>Left stick (Up)</source>
- <translation>Stick esquerdo (Arriba)</translation>
- </message>
- <message>
- <source>Left trigger</source>
- <translation>Gatillo esquerdo</translation>
- </message>
- <message>
- <source>Right trigger</source>
- <translation>Gatillo dereito</translation>
- </message>
- <message>
- <source>Right stick (Down)</source>
- <translation>Stick dereito (Abaixo)</translation>
- </message>
- <message>
- <source>Right stick (Up)</source>
- <translation>Stick dereito (Arriba)</translation>
- </message>
- <message>
- <source>Right stick (Right)</source>
- <translation>Stick dereito (Dereita)</translation>
- </message>
- <message>
- <source>Right stick (Left)</source>
- <translation>Stick dereito (Esquerda)</translation>
- </message>
- <message>
- <source>DPad</source>
- <translation>Mando</translation>
- </message>
-</context>
-</TS>
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="gl_ES">
+<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AbstractPage</name>
+ <message>
+ <source>Go back</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AmmoSchemeModel</name>
+ <message>
+ <source>new</source>
+ <translation>novo</translation>
+ </message>
+ <message>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FreqSpinBox</name>
+ <message>
+ <source>Never</source>
+ <translation>Nunca</translation>
+ </message>
+ <message numerus="yes">
+ <source>Every %1 turn</source>
+ <translation>
+ <numerusform>Cada rolda</numerusform>
+ <numerusform>Cada %1 roldas</numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>GameCFGWidget</name>
+ <message>
+ <source>Edit weapons</source>
+ <translation>Editar os armamentos</translation>
+ </message>
+ <message>
+ <source>Edit schemes</source>
+ <translation>Editar os modos de xogo</translation>
+ </message>
+ <message>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Non se puido crear o directorio %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWAskQuitDialog</name>
+ <message>
+ <source>Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWChatWidget</name>
+ <message>
+ <source>%1 has been removed from your ignore list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has been added to your ignore list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has been removed from your friends list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has been added to your friends list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Stylesheet imported from %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Couldn't read %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>StyleSheet discarded</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>StyleSheet saved to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to save StyleSheet to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWForm</name>
+ <message>
+ <source>Cannot save record to file %1</source>
+ <translation>Non se pode gardar a gravación no ficheiro %1</translation>
+ </message>
+ <message>
+ <source>DefaultTeam</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation type="unfinished">Alcume</translation>
+ </message>
+ <message>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars Demo File</source>
+ <comment>File Types</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars Save File</source>
+ <comment>File Types</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Demo name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Demo name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWGame</name>
+ <message>
+ <source>en.txt</source>
+ <translation>gl.txt</translation>
+ </message>
+ <message>
+ <source>Cannot open demofile %1</source>
+ <translation>Non se pode abrir a demostración %1</translation>
+ </message>
+</context>
+<context>
+ <name>HWMapContainer</name>
+ <message>
+ <source>All</source>
+ <translation>Todos</translation>
+ </message>
+ <message>
+ <source>Small</source>
+ <translation>Pequeno</translation>
+ </message>
+ <message>
+ <source>Medium</source>
+ <translation>Mediano</translation>
+ </message>
+ <message>
+ <source>Large</source>
+ <translation>Grande</translation>
+ </message>
+ <message>
+ <source>Cavern</source>
+ <translation>Caverna</translation>
+ </message>
+ <message>
+ <source>Wacky</source>
+ <translation>Absurdo</translation>
+ </message>
+ <message>
+ <source>Small tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Ao chou</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWNetServersModel</name>
+ <message>
+ <source>Title</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Port</source>
+ <translation>Porto</translation>
+ </message>
+</context>
+<context>
+ <name>HWNewNet</name>
+ <message>
+ <source>The host was not found. Please check the host name and port settings.</source>
+ <translation>Non se atopou o anfitrión. Comproba o nome e mailo porto do anfitrión.</translation>
+ </message>
+ <message>
+ <source>Connection refused</source>
+ <translation>Rexeitouse a conexión</translation>
+ </message>
+ <message>
+ <source>Room destroyed</source>
+ <translation>Destruiuse a sala</translation>
+ </message>
+ <message>
+ <source>Quit reason: </source>
+ <translation>Motivo da expulsión:</translation>
+ </message>
+ <message>
+ <source>You got kicked</source>
+ <translation>Botáronte</translation>
+ </message>
+ <message>
+ <source>%1 *** %2 has joined the room</source>
+ <translation>%1 *** %2 entrou na sala</translation>
+ </message>
+ <message>
+ <source>%1 *** %2 has joined</source>
+ <translation type="obsolete">%1 *** %2 uniuse</translation>
+ </message>
+ <message>
+ <source>%1 *** %2 has left (%3)</source>
+ <translation>%1 *** %2 marchou (%3)</translation>
+ </message>
+ <message>
+ <source>%1 *** %2 has left</source>
+ <translation>%1 *** %2 marchou</translation>
+ </message>
+ <message>
+ <source>User quit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remote host has closed connection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The server is too old. Disconnecting now.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWPasswordDialog</name>
+ <message>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWUploadVideoDialog</name>
+ <message>
+ <source>Upload video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KB</name>
+ <message>
+ <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
+ <translation>SDL_ttf devolveu un erro ao renderizar o texto, seguramente sexa por mor do erro de freetype2. Cómpre que actualices a túa biblioteca freetype.</translation>
+ </message>
+</context>
+<context>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <source>Duration: %1m %2s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video: %1x%2, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 fps, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageAdmin</name>
+ <message>
+ <source>Clear Accounts Cache</source>
+ <translation>Borrar a caché das contas</translation>
+ </message>
+ <message>
+ <source>Fetch data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server message for latest version:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Server message for previous versions:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Latest version protocol number:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MOTD preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Xeral</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished">Actualizar</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageConnecting</name>
+ <message>
+ <source>Connecting...</source>
+ <translation>Conectando...</translation>
+ </message>
+</context>
+<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageDrawMap</name>
+ <message>
+ <source>Eraser</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="unfinished">Borrado</translation>
+ </message>
+ <message>
+ <source>Load</source>
+ <translation type="unfinished">Cargar</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageEditTeam</name>
+ <message>
+ <source>General</source>
+ <translation>Xeral</translation>
+ </message>
+ <message>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Sombreiro</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageGameStats</name>
+ <message>
+ <source>Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Health graph</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ranking</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageInGame</name>
+ <message>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageInfo</name>
+ <message>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageMain</name>
+ <message>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Downloadable Content</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Access the user created content downloadable from our website</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Exit game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Manage videos recorded from game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play local network game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play official network game</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
+ <message>
+ <source>Start</source>
+ <translation>Iniciar</translation>
+ </message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageNetGame</name>
+ <message>
+ <source>Control</source>
+ <translation type="obsolete">Control</translation>
+ </message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start</source>
+ <translation type="unfinished">Iniciar</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="unfinished">Actualizar</translation>
+ </message>
+ <message>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageNetServer</name>
+ <message>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageOptions</name>
+ <message>
+ <source>New team</source>
+ <translation>Novo equipo</translation>
+ </message>
+ <message>
+ <source>Edit team</source>
+ <translation>Editar o equipo</translation>
+ </message>
+ <message>
+ <source>Advanced</source>
+ <translation type="unfinished">Avanzado</translation>
+ </message>
+ <message>
+ <source>Delete team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Socks5 proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>HTTP proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished">Rede</translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Equipos</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Armamento</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PagePlayDemo</name>
+ <message>
+ <source>Rename dialog</source>
+ <translation>Diálogo de cambio de nome</translation>
+ </message>
+ <message>
+ <source>Enter new file name:</source>
+ <translation>Introduce un novo nome para o ficheiro:</translation>
+ </message>
+</context>
+<context>
+ <name>PageRoomsList</name>
+ <message>
+ <source>Create</source>
+ <translation type="obsolete">Crear</translation>
+ </message>
+ <message>
+ <source>Join</source>
+ <translation type="obsolete">Entrar</translation>
+ </message>
+ <message>
+ <source>Admin features</source>
+ <translation>Administración</translation>
+ </message>
+ <message>
+ <source>Room Name:</source>
+ <translation type="obsolete">Nome da sala:</translation>
+ </message>
+ <message>
+ <source>Rules:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation type="obsolete">Borrado</translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageScheme</name>
+ <message>
+ <source>Defend your fort and destroy the opponents, two team colours max!</source>
+ <translation>Defende o teu forte e elimina os inimigos, máximo dous bandos!</translation>
+ </message>
+ <message>
+ <source>Teams will start on opposite sides of the terrain, two team colours max!</source>
+ <translation>Os bandos comezarán en lados opostos da superficie, máximo dous bandos!</translation>
+ </message>
+ <message>
+ <source>Land can not be destroyed!</source>
+ <translation>Non se pode destruÃr o terreo!</translation>
+ </message>
+ <message>
+ <source>Lower gravity</source>
+ <translation>Baixa gravidade</translation>
+ </message>
+ <message>
+ <source>Assisted aiming with laser sight</source>
+ <translation>Mira láser</translation>
+ </message>
+ <message>
+ <source>All hogs have a personal forcefield</source>
+ <translation>Todos os ourizos teñen un escudo protector</translation>
+ </message>
+ <message>
+ <source>Gain 80% of the damage you do back in health</source>
+ <translation>Gañar o 80% do daño inflixido en vida</translation>
+ </message>
+ <message>
+ <source>Share your opponents pain, share their damage</source>
+ <translation>Acompañar aos inimigos no sentimento e no dano</translation>
+ </message>
+ <message>
+ <source>Your hogs are unable to move, put your artillery skills to the test</source>
+ <translation>Os ourizos non se poden mover, pon a probas a túa faceta de artilleiro</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>Ao chou</translation>
+ </message>
+ <message>
+ <source>Seconds</source>
+ <translation>segundos</translation>
+ </message>
+ <message>
+ <source>New</source>
+ <translation>Novo</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Borrar</translation>
+ </message>
+ <message>
+ <source>Add an indestructible border around the terrain</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All (living) hedgehogs are fully restored at the end of turn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Order of play is random instead of in room order.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play with a King. If he dies, your side dies.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Take turns placing your hedgehogs before the start of play.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ammo is shared between all teams that share a colour.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Disable girders when generating random maps.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Disable land objects when generating random maps.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AI respawns on death.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Attacking does not end your turn.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons are reset to starting values each turn.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Each hedgehog has its own ammo. It does not share with the team.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You will not have to worry about wind anymore.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Wind will affect almost everything.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams in each clan take successive turns sharing their turn time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add an indestructible border along the bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageSelectWeapon</name>
+ <message>
+ <source>Default</source>
+ <translation>Por defecto</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Borrar</translation>
+ </message>
+ <message>
+ <source>New</source>
+ <translation type="unfinished">Novo</translation>
+ </message>
+ <message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageSinglePlayer</name>
+ <message>
+ <source>Play a quick game against the computer with random settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play a hotseat game against your friends, or AI teams</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Campaign Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Practice your skills in a range of training missions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Watch recorded demos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load a previously saved game</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageTraining</name>
+ <message>
+ <source>Pick the mission or training to play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start fighting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No description available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Select a mission!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageVideos</name>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 bytes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>(in progress...)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>encoding</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QAction</name>
+ <message>
+ <source>Kick</source>
+ <translation>Botar</translation>
+ </message>
+ <message>
+ <source>Info</source>
+ <translation>Información</translation>
+ </message>
+ <message>
+ <source>Restrict Joins</source>
+ <translation>Restrinxir a entrada</translation>
+ </message>
+ <message>
+ <source>Restrict Team Additions</source>
+ <translation>Restrinxir o engadido de equipos</translation>
+ </message>
+ <message>
+ <source>Ban</source>
+ <translation>Expulsar</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="obsolete">Actualizar</translation>
+ </message>
+ <message>
+ <source>Follow</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ignore</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add friend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Unignore</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove friend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCheckBox</name>
+ <message>
+ <source>Check for updates at startup</source>
+ <translation>Comprobar se hai actualizacións ao iniciar</translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>Partidas a pantalla completa</translation>
+ </message>
+ <message>
+ <source>Show FPS</source>
+ <translation>Amosar as FPS</translation>
+ </message>
+ <message>
+ <source>Alternative damage show</source>
+ <translation>Gráficos de dano alternativos</translation>
+ </message>
+ <message>
+ <source>Append date and time to record file name</source>
+ <translation>Engadir a data e maila hora ao nome dos ficheiros de gravación</translation>
+ </message>
+ <message>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show ammo menu tooltips</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Record audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use game resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QComboBox</name>
+ <message>
+ <source>Human</source>
+ <translation>Xogador</translation>
+ </message>
+ <message>
+ <source>Level</source>
+ <translation>Nivel</translation>
+ </message>
+ <message>
+ <source>Community</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>(System default)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Cyan</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cyan/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Blue</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Blue/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Green</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Green/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Side-by-side</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Top-Bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Cyan grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cyan/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Blue grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Blue/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Red/Green grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Green/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Any</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QGroupBox</name>
+ <message>
+ <source>Team Members</source>
+ <translation>Membros do equipo</translation>
+ </message>
+ <message>
+ <source>Fort</source>
+ <translation>Forte</translation>
+ </message>
+ <message>
+ <source>Net game</source>
+ <translation>Partida na rede</translation>
+ </message>
+ <message>
+ <source>Playing teams</source>
+ <translation>Equipos xogando</translation>
+ </message>
+ <message>
+ <source>Game Modifiers</source>
+ <translation>Modificadores da partida</translation>
+ </message>
+ <message>
+ <source>Basic Settings</source>
+ <translation>Configuración básica</translation>
+ </message>
+ <message>
+ <source>Team Settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Videos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLabel</name>
+ <message>
+ <source>Mines Time</source>
+ <translation>Temporizador das minas</translation>
+ </message>
+ <message>
+ <source>Mines</source>
+ <translation>Minas</translation>
+ </message>
+ <message>
+ <source>Version</source>
+ <translation type="obsolete">Versión</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation>Armamento</translation>
+ </message>
+ <message>
+ <source>Host:</source>
+ <translation>Anfitrión:</translation>
+ </message>
+ <message>
+ <source>Port:</source>
+ <translation>Porto:</translation>
+ </message>
+ <message>
+ <source>Resolution</source>
+ <translation>Resolución</translation>
+ </message>
+ <message>
+ <source>FPS limit</source>
+ <translation>LÃmite de FPS</translation>
+ </message>
+ <message>
+ <source>Server name:</source>
+ <translation>Nome do servidor:</translation>
+ </message>
+ <message>
+ <source>Server port:</source>
+ <translation>Porto do servidor:</translation>
+ </message>
+ <message>
+ <source>Initial sound volume</source>
+ <translation>Volume inicial</translation>
+ </message>
+ <message>
+ <source>Damage Modifier</source>
+ <translation>Modificador de dano</translation>
+ </message>
+ <message>
+ <source>Turn Time</source>
+ <translation>Tempo por rolda</translation>
+ </message>
+ <message>
+ <source>Initial Health</source>
+ <translation>Saúde inicial</translation>
+ </message>
+ <message>
+ <source>Sudden Death Timeout</source>
+ <translation>Conta atrás ata a morte súbita</translation>
+ </message>
+ <message>
+ <source>Scheme Name:</source>
+ <translation>Nome do modo:</translation>
+ </message>
+ <message>
+ <source>Crate Drops</source>
+ <translation>CaÃda de caixas</translation>
+ </message>
+ <message>
+ <source>There are videos that are currently being processed.
+Exiting now will abort them.
+Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account name (or email): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video title: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video description: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Tags (comma separated): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Grave</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Flag</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Voice</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Tip: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Locale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation type="unfinished">Alcume</translation>
+ </message>
+ <message>
+ <source>Quality</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Stereo rendering</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sudden Death Water Rise</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sudden Death Health Decrease</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Rope Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Health Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Health in Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Dud Mines</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Explosives</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Get Away Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Style</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Partidas a pantalla completa</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLineEdit</name>
+ <message>
+ <source>unnamed</source>
+ <translation>sen nome</translation>
+ </message>
+ <message>
+ <source>hedgehog %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>anonymous</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QMainWindow</name>
+ <message>
+ <source>Hedgewars %1</source>
+ <translation>Hedgewars %1</translation>
+ </message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QMessageBox</name>
+ <message>
+ <source>Connection to server is lost</source>
+ <translation>Perdeuse a conexión co servidor</translation>
+ </message>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <source>Teams - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the team '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot delete default scheme '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select a record from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Unable to start server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Success</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All file associations have been set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File association failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="obsolete">Non se puido crear o directorio %1</translation>
+ </message>
+ <message>
+ <source>Unable to start the server: %1.</source>
+ <translation type="obsolete">Non se puido iniciar o servidor: %1.</translation>
+ </message>
+ <message>
+ <source>Error while authenticating at google.com:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Login or password is incorrect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video upload - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while sending metadata to youtube.com:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Netgame - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select a server from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please enter room name</source>
+ <translation type="unfinished">Introduce o nome da sala</translation>
+ </message>
+ <message>
+ <source>Record Play - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select record from the list</source>
+ <translation type="unfinished">Selecciona unha gravación da lista</translation>
+ </message>
+ <message>
+ <source>Cannot rename to </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot delete file </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room Name - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please select room from the list</source>
+ <translation type="unfinished">Selecciona unha sala da lista</translation>
+ </message>
+ <message>
+ <source>Room Name - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Schemes - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Schemes - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the game scheme '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Videos - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the video '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to remove %1 file(s)?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Do you really want to cancel uploading %1?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>File error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot open '%1' for writing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot open '%1' for reading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot use the ammo '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot overwrite default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot delete default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Do you really want to delete the weapon set '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QPushButton</name>
+ <message>
+ <source>default</source>
+ <translation>por defecto</translation>
+ </message>
+ <message>
+ <source>OK</source>
+ <translation>Aceptar</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>Start server</source>
+ <translation>Iniciar un servidor</translation>
+ </message>
+ <message>
+ <source>Connect</source>
+ <translation>Conectar</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation>Actualizar</translation>
+ </message>
+ <message>
+ <source>Specify</source>
+ <translation>Especificar</translation>
+ </message>
+ <message>
+ <source>Start</source>
+ <translation>Iniciar</translation>
+ </message>
+ <message>
+ <source>Go!</source>
+ <translation>Dálle!</translation>
+ </message>
+ <message>
+ <source>Play demo</source>
+ <translation>Reproducir a demostración</translation>
+ </message>
+ <message>
+ <source>Rename</source>
+ <translation>Cambiar o nome</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Borrar</translation>
+ </message>
+ <message>
+ <source>Load</source>
+ <translation>Cargar</translation>
+ </message>
+ <message>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Associate file extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload to YouTube</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomsListModel</name>
+ <message>
+ <source>In progress</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room Name</source>
+ <translation type="unfinished">Nome da sala</translation>
+ </message>
+ <message>
+ <source>C</source>
+ <translation type="unfinished">C</translation>
+ </message>
+ <message>
+ <source>T</source>
+ <translation type="unfinished">T</translation>
+ </message>
+ <message>
+ <source>Owner</source>
+ <translation type="unfinished">Dono</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Rules</source>
+ <translation type="unfinished">Regras</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Armamento</translation>
+ </message>
+ <message>
+ <source>Random Map</source>
+ <translation type="unfinished">Mapa ao chou</translation>
+ </message>
+ <message>
+ <source>Random Maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
+ <message>
+ <source>Weapon set</source>
+ <translation>Armamento</translation>
+ </message>
+ <message>
+ <source>Probabilities</source>
+ <translation>Probabilidades</translation>
+ </message>
+ <message>
+ <source>Ammo in boxes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delays</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>new</source>
+ <translation type="unfinished">novo</translation>
+ </message>
+ <message>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TCPBase</name>
+ <message>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
+ <message>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
+ <message>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ThemePrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds</name>
+ <message>
+ <source>up</source>
+ <translation>arriba</translation>
+ </message>
+ <message>
+ <source>left</source>
+ <translation>esquerda</translation>
+ </message>
+ <message>
+ <source>right</source>
+ <translation>dereita</translation>
+ </message>
+ <message>
+ <source>down</source>
+ <translation>abaixo</translation>
+ </message>
+ <message>
+ <source>attack</source>
+ <translation>atacar</translation>
+ </message>
+ <message>
+ <source>precise aim</source>
+ <translation>apuntar con precisión</translation>
+ </message>
+ <message>
+ <source>put</source>
+ <translation>poñer</translation>
+ </message>
+ <message>
+ <source>switch</source>
+ <translation>cambiar</translation>
+ </message>
+ <message>
+ <source>find hedgehog</source>
+ <translation>atopar ourizo</translation>
+ </message>
+ <message>
+ <source>ammo menu</source>
+ <translation>menú de armas</translation>
+ </message>
+ <message>
+ <source>slot 1</source>
+ <translation>1ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 2</source>
+ <translation>2ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 3</source>
+ <translation>3ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 4</source>
+ <translation>4ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 5</source>
+ <translation>5ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 6</source>
+ <translation>6ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 7</source>
+ <translation>7ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 8</source>
+ <translation>8ª ranura</translation>
+ </message>
+ <message>
+ <source>slot 9</source>
+ <translation>9ª ranura</translation>
+ </message>
+ <message>
+ <source>timer 1 sec</source>
+ <translation>temporizador a 1 segundo</translation>
+ </message>
+ <message>
+ <source>timer 2 sec</source>
+ <translation>temporizador a 2 segundos</translation>
+ </message>
+ <message>
+ <source>timer 3 sec</source>
+ <translation>temporizador a 3 segundos</translation>
+ </message>
+ <message>
+ <source>timer 4 sec</source>
+ <translation>temporizador a 4 segundos</translation>
+ </message>
+ <message>
+ <source>timer 5 sec</source>
+ <translation>temporizador a 5 segundos</translation>
+ </message>
+ <message>
+ <source>chat</source>
+ <translation>conversa</translation>
+ </message>
+ <message>
+ <source>chat history</source>
+ <translation>historial de conversa</translation>
+ </message>
+ <message>
+ <source>pause</source>
+ <translation>pausa</translation>
+ </message>
+ <message>
+ <source>confirmation</source>
+ <translation>confirmación</translation>
+ </message>
+ <message>
+ <source>volume down</source>
+ <translation>baixar o volume</translation>
+ </message>
+ <message>
+ <source>volume up</source>
+ <translation>subir o volume</translation>
+ </message>
+ <message>
+ <source>change mode</source>
+ <translation>cambiar o modo</translation>
+ </message>
+ <message>
+ <source>capture</source>
+ <translation>capturar</translation>
+ </message>
+ <message>
+ <source>quit</source>
+ <translation>saÃr</translation>
+ </message>
+ <message>
+ <source>zoom in</source>
+ <translation>achegar</translation>
+ </message>
+ <message>
+ <source>zoom out</source>
+ <translation>afastar</translation>
+ </message>
+ <message>
+ <source>reset zoom</source>
+ <translation>distancia inicial</translation>
+ </message>
+ <message>
+ <source>long jump</source>
+ <translation>salto cara adiante</translation>
+ </message>
+ <message>
+ <source>high jump</source>
+ <translation>salto cara arriba</translation>
+ </message>
+ <message>
+ <source>slot 10</source>
+ <translation type="unfinished">10ª ranura</translation>
+ </message>
+ <message>
+ <source>mute audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>record</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (categories)</name>
+ <message>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Armamento</translation>
+ </message>
+ <message>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (descriptions)</name>
+ <message>
+ <source>Traverse gaps and obstacles by jumping:</source>
+ <translation>Supera os obstáculos saltando:</translation>
+ </message>
+ <message>
+ <source>Fire your selected weapon or trigger an utility item:</source>
+ <translation>Dispara a arma seleccionada ou activa unha ferramenta:</translation>
+ </message>
+ <message>
+ <source>Pick a weapon or a target location under the cursor:</source>
+ <translation>Recolle un arma ou a situación dun obxectivo onde o cursor:</translation>
+ </message>
+ <message>
+ <source>Switch your currently active hog (if possible):</source>
+ <translation>Cambia de ourizo (se se pode):</translation>
+ </message>
+ <message>
+ <source>Pick a weapon or utility item:</source>
+ <translation>Recolle unha arma ou ferramenta:</translation>
+ </message>
+ <message>
+ <source>Set the timer on bombs and timed weapons:</source>
+ <translation>Establece o temporizador para as armas que o teñan:</translation>
+ </message>
+ <message>
+ <source>Move the camera to the active hog:</source>
+ <translation>Move a cámara ao ourizo activo:</translation>
+ </message>
+ <message>
+ <source>Move the cursor or camera without using the mouse:</source>
+ <translation>Move o cursor ou a cámara sen usar o rato:</translation>
+ </message>
+ <message>
+ <source>Modify the camera's zoom level:</source>
+ <translation>Cambia a distancia da cámara:</translation>
+ </message>
+ <message>
+ <source>Talk to your team or all participants:</source>
+ <translation>Fala co teu equipo ou con todos:</translation>
+ </message>
+ <message>
+ <source>Pause, continue or leave your game:</source>
+ <translation>Pausa, continúa ou sal da túa partida:</translation>
+ </message>
+ <message>
+ <source>Modify the game's volume while playing:</source>
+ <translation>Cambia o volume do xogo durante unha partida:</translation>
+ </message>
+ <message>
+ <source>Toggle fullscreen mode:</source>
+ <translation>Cambiar a pantalla completa:</translation>
+ </message>
+ <message>
+ <source>Take a screenshot:</source>
+ <translation>Facer unha captura de pantalla:</translation>
+ </message>
+ <message>
+ <source>Toggle labels above hedgehogs:</source>
+ <translation>Cambiar as etiquetas sobre os ourizos:</translation>
+ </message>
+ <message>
+ <source>Record video:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (keys)</name>
+ <message>
+ <source>Axis</source>
+ <translation>Eixo</translation>
+ </message>
+ <message>
+ <source>(Up)</source>
+ <translation>(Arriba)</translation>
+ </message>
+ <message>
+ <source>(Down)</source>
+ <translation>(Abaixo)</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>Sombreiro</translation>
+ </message>
+ <message>
+ <source>(Left)</source>
+ <translation>(Esquerda)</translation>
+ </message>
+ <message>
+ <source>(Right)</source>
+ <translation>(Dereita)</translation>
+ </message>
+ <message>
+ <source>Button</source>
+ <translation>Botón</translation>
+ </message>
+ <message>
+ <source>Keyboard</source>
+ <translation>Teclado</translation>
+ </message>
+ <message>
+ <source>Mouse: Left button</source>
+ <translation>Rato: botón esquerdo</translation>
+ </message>
+ <message>
+ <source>Mouse: Middle button</source>
+ <translation>Rato: botón central</translation>
+ </message>
+ <message>
+ <source>Mouse: Right button</source>
+ <translation>Rato: botón dereito</translation>
+ </message>
+ <message>
+ <source>Mouse: Wheel up</source>
+ <translation>Rato: roda cara arriba</translation>
+ </message>
+ <message>
+ <source>Mouse: Wheel down</source>
+ <translation>Rato: roda cara abaixo</translation>
+ </message>
+ <message>
+ <source>Backspace</source>
+ <translation>Retroceso</translation>
+ </message>
+ <message>
+ <source>Tab</source>
+ <translation>Tabulador</translation>
+ </message>
+ <message>
+ <source>Clear</source>
+ <translation>Borrado</translation>
+ </message>
+ <message>
+ <source>Return</source>
+ <translation>Retorno</translation>
+ </message>
+ <message>
+ <source>Pause</source>
+ <translation>Pausa</translation>
+ </message>
+ <message>
+ <source>Escape</source>
+ <translation>Escape</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation>Espazo</translation>
+ </message>
+ <message>
+ <source>Delete</source>
+ <translation>Borrar</translation>
+ </message>
+ <message>
+ <source>Numpad 0</source>
+ <translation>Teclado numérico: 0</translation>
+ </message>
+ <message>
+ <source>Numpad 1</source>
+ <translation>Teclado numérico: 1</translation>
+ </message>
+ <message>
+ <source>Numpad 2</source>
+ <translation>Teclado numérico: 2</translation>
+ </message>
+ <message>
+ <source>Numpad 3</source>
+ <translation>Teclado numérico: 3</translation>
+ </message>
+ <message>
+ <source>Numpad 4</source>
+ <translation>Teclado numérico: 4</translation>
+ </message>
+ <message>
+ <source>Numpad 5</source>
+ <translation>Teclado numérico: 5</translation>
+ </message>
+ <message>
+ <source>Numpad 6</source>
+ <translation>Teclado numérico: 6</translation>
+ </message>
+ <message>
+ <source>Numpad 7</source>
+ <translation>Teclado numérico: 7</translation>
+ </message>
+ <message>
+ <source>Numpad 8</source>
+ <translation>Teclado numérico: 8</translation>
+ </message>
+ <message>
+ <source>Numpad 9</source>
+ <translation>Teclado numérico: 9</translation>
+ </message>
+ <message>
+ <source>Numpad .</source>
+ <translation>Teclado numérico: .</translation>
+ </message>
+ <message>
+ <source>Numpad /</source>
+ <translation>Teclado numérico: /</translation>
+ </message>
+ <message>
+ <source>Numpad *</source>
+ <translation>Teclado numérico: *</translation>
+ </message>
+ <message>
+ <source>Numpad -</source>
+ <translation>Teclado numérico: -</translation>
+ </message>
+ <message>
+ <source>Numpad +</source>
+ <translation>Teclado numérico: +</translation>
+ </message>
+ <message>
+ <source>Enter</source>
+ <translation>Intro</translation>
+ </message>
+ <message>
+ <source>Equals</source>
+ <translation>Igual</translation>
+ </message>
+ <message>
+ <source>Up</source>
+ <translation>Arriba</translation>
+ </message>
+ <message>
+ <source>Down</source>
+ <translation>Abaixo</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>Dereita</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>Esquerda</translation>
+ </message>
+ <message>
+ <source>Insert</source>
+ <translation>Inserir</translation>
+ </message>
+ <message>
+ <source>Home</source>
+ <translation>Inicio</translation>
+ </message>
+ <message>
+ <source>End</source>
+ <translation>Fin</translation>
+ </message>
+ <message>
+ <source>Page up</source>
+ <translation>Re Páx</translation>
+ </message>
+ <message>
+ <source>Page down</source>
+ <translation>Av Páx</translation>
+ </message>
+ <message>
+ <source>Num lock</source>
+ <translation>Bloq Num</translation>
+ </message>
+ <message>
+ <source>Caps lock</source>
+ <translation>Bloq Maiús</translation>
+ </message>
+ <message>
+ <source>Scroll lock</source>
+ <translation>Bloq Despr</translation>
+ </message>
+ <message>
+ <source>Right shift</source>
+ <translation>Maiús dereito</translation>
+ </message>
+ <message>
+ <source>Left shift</source>
+ <translation>Maiús esquerdo</translation>
+ </message>
+ <message>
+ <source>Right ctrl</source>
+ <translation>Ctrl dereito</translation>
+ </message>
+ <message>
+ <source>Left ctrl</source>
+ <translation>Ctrl esquerdo</translation>
+ </message>
+ <message>
+ <source>Right alt</source>
+ <translation>Alt dereito</translation>
+ </message>
+ <message>
+ <source>Left alt</source>
+ <translation>Alt esquerdo</translation>
+ </message>
+ <message>
+ <source>Right meta</source>
+ <translation>Meta dereito</translation>
+ </message>
+ <message>
+ <source>Left meta</source>
+ <translation>Meta esquerdo</translation>
+ </message>
+ <message>
+ <source>A button</source>
+ <translation>Botón A</translation>
+ </message>
+ <message>
+ <source>B button</source>
+ <translation>Botón B</translation>
+ </message>
+ <message>
+ <source>X button</source>
+ <translation>Botón X</translation>
+ </message>
+ <message>
+ <source>Y button</source>
+ <translation>Botón Y</translation>
+ </message>
+ <message>
+ <source>LB button</source>
+ <translation>Botón LB</translation>
+ </message>
+ <message>
+ <source>RB button</source>
+ <translation>Botón RB</translation>
+ </message>
+ <message>
+ <source>Back button</source>
+ <translation>Botón de volver</translation>
+ </message>
+ <message>
+ <source>Start button</source>
+ <translation>Botón de inicio</translation>
+ </message>
+ <message>
+ <source>Left stick</source>
+ <translation>Stick esquerdo</translation>
+ </message>
+ <message>
+ <source>Right stick</source>
+ <translation>Stick dereito</translation>
+ </message>
+ <message>
+ <source>Left stick (Right)</source>
+ <translation>Stick esquerdo (Dereita)</translation>
+ </message>
+ <message>
+ <source>Left stick (Left)</source>
+ <translation>Stick esquerdo (Esquerda)</translation>
+ </message>
+ <message>
+ <source>Left stick (Down)</source>
+ <translation>Stick esquerdo (Abaixo)</translation>
+ </message>
+ <message>
+ <source>Left stick (Up)</source>
+ <translation>Stick esquerdo (Arriba)</translation>
+ </message>
+ <message>
+ <source>Left trigger</source>
+ <translation>Gatillo esquerdo</translation>
+ </message>
+ <message>
+ <source>Right trigger</source>
+ <translation>Gatillo dereito</translation>
+ </message>
+ <message>
+ <source>Right stick (Down)</source>
+ <translation>Stick dereito (Abaixo)</translation>
+ </message>
+ <message>
+ <source>Right stick (Up)</source>
+ <translation>Stick dereito (Arriba)</translation>
+ </message>
+ <message>
+ <source>Right stick (Right)</source>
+ <translation>Stick dereito (Dereita)</translation>
+ </message>
+ <message>
+ <source>Right stick (Left)</source>
+ <translation>Stick dereito (Esquerda)</translation>
+ </message>
+ <message>
+ <source>DPad</source>
+ <translation>Mando</translation>
+ </message>
+</context>
+</TS>
diff --git a/share/hedgewars/Data/Locale/hedgewars_hu.ts b/share/hedgewars/Data/Locale/hedgewars_hu.ts
index b72028d..10f6255 100644
--- a/share/hedgewars/Data/Locale/hedgewars_hu.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_hu.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="hu">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -43,11 +139,63 @@
<translation>Sémák szerkesztése</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Pálya</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Nem sikerült létrehozni %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -101,7 +249,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -138,27 +294,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
+ <translation type="unfinished">Becenév</translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">Becenév</translation>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -176,18 +378,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Pálya</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Témák</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>SzűrÅ</translation>
- </message>
- <message>
<source>All</source>
<translation>Minden</translation>
</message>
@@ -212,10 +402,6 @@ Please pick another nickname:</source>
<translation>Årült</translation>
</message>
<message>
- <source>Type</source>
- <translation>TÃpus</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Szűk alagutak</translation>
</message>
@@ -224,27 +410,95 @@ Please pick another nickname:</source>
<translation>Ãtlagos alagutak</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Tágas alagutak</translation>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Apró lebegŠszigetek</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Közepes lebegŠszigetek</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Nagy lebegÅ szigetek</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Véletlen</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -291,7 +545,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 csatlakozott</translation>
+ <translation type="obsolete">%1 *** %2 csatlakozott</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -317,8 +571,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">JElszó</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -333,6 +602,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -340,7 +631,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -358,6 +656,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -389,6 +698,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Adat beállÃtása</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Ãltalános</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -398,6 +739,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -443,8 +795,40 @@ Please pick another nickname:</source>
<translation>Ãltalános</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Haladó</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Kalap</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Név</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Véletlen csapat</translation>
</message>
</context>
<context>
@@ -501,6 +885,14 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -519,420 +911,275 @@ Please pick another nickname:</source>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>Start</translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">IrányÃtás</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Update</source>
+ <translation type="unfinished">FrissÃtés</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New team</source>
+ <translation>Ãj csapat</translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Edit team</source>
+ <translation>Csapat szerkesztése</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Delete team</source>
+ <translation>Csapat törlése</translation>
</message>
<message>
- <source>Local Game</source>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation type="unfinished">Haladó</translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <source>Start</source>
- <translation>Start</translation>
+ <source>Proxy port</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <source>Control</source>
- <translation>IrányÃtás</translation>
+ <source>Proxy login</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>DLC</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>LAN játék</translation>
+ <source>Socks5 proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
- <translation>Hivatalos szerver</translation>
+ <source>HTTP proxy</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
- <translation>Ãj csapat</translation>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Edit team</source>
- <translation>Csapat szerkesztése</translation>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delete team</source>
- <translation>Csapat törlése</translation>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
- <translation type="unfinished"></translation>
+ <source>Teams</source>
+ <translation type="unfinished">Csapatok</translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Ãltalános</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Fegyverek</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">Haladó</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -951,11 +1198,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Létrehozás</translation>
+ <translation type="obsolete">Létrehozás</translation>
</message>
<message>
<source>Join</source>
- <translation>Csatlakozás</translation>
+ <translation type="obsolete">Csatlakozás</translation>
</message>
<message>
<source>Admin features</source>
@@ -963,7 +1210,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Szoba neve:</translation>
+ <translation type="obsolete">Szoba neve:</translation>
</message>
<message>
<source>Rules:</source>
@@ -974,12 +1221,8 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Clear</source>
- <translation type="unfinished">Törlés</translation>
+ <translation type="obsolete">Törlés</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -987,6 +1230,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1133,18 +1400,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1153,26 +1412,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Betöltés</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1217,19 +1464,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1244,10 +1493,6 @@ Please pick another nickname:</source>
<translation>Info</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Csatlakozások korlátozása</translation>
</message>
@@ -1281,7 +1526,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">FrissÃtés</translation>
+ <translation type="obsolete">FrissÃtés</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1295,18 +1552,6 @@ Please pick another nickname:</source>
<translation>Teljes képernyÅ</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Frontend teljesképernyÅ</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Hangok engedélyezése</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Zene engedélyezése</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>FPS megjelenÃtése</translation>
</message>
@@ -1323,18 +1568,6 @@ Please pick another nickname:</source>
<translation>LÅszer menü tippjeinek mutatása</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Frontend hangok engedélyezése</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Frontend zenéjének engedélyezése</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Frontend effektusok</translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1354,51 +1587,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>a létrehozott pálya...</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>Ember</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>Szint</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
- <translation>(rendszer default)</translation>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
- <translation>Küldetés</translation>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>a létrehozott labirintus...</translation>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>Ember</translation>
</message>
<message>
- <source>In lobby</source>
- <translation type="unfinished"></translation>
+ <source>Level</source>
+ <translation>Szint</translation>
</message>
<message>
- <source>In progress</source>
+ <source>(System default)</source>
+ <translation>(rendszer default)</translation>
+ </message>
+ <message>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1438,10 +1675,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1477,56 +1710,24 @@ Please pick another nickname:</source>
<translation>ErÅd</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Billentyűzet testreszabása</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Csapatok</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Hang- és képi beállÃtások</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Netes játék</translation>
</message>
<message>
- <source>Playing teams</source>
- <translation>RésztvevŠcsapatok</translation>
- </message>
- <message>
- <source>Game Modifiers</source>
- <translation>Játék módosÃtók</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Alap beállÃtások</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Csapat beállÃtások</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Egyéb</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
+ <source>Playing teams</source>
+ <translation>RésztvevŠcsapatok</translation>
</message>
<message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <source>Game Modifiers</source>
+ <translation>Játék módosÃtók</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Alap beállÃtások</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Csapat beállÃtások</translation>
</message>
<message>
<source>Videos</source>
@@ -1536,10 +1737,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1553,27 +1750,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Verzió</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>FejlesztÅk:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafika:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Hangok:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>FordÃtások:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Külön köszönet:</translation>
+ <translation type="obsolete">Verzió</translation>
</message>
<message>
<source>Weapons</source>
@@ -1632,10 +1809,6 @@ Please pick another nickname:</source>
<translation>Csomagok érkezése</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Játék sémája</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% hamis aknák</translation>
</message>
@@ -1672,10 +1845,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1716,10 +1885,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1750,10 +1915,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,6 +1942,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Teljes képernyÅ</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1803,6 +2008,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1819,10 +2028,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1869,47 +2074,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Nem sikerült létrehozni %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nem sikerült létrehozni %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Nem sikerült a szerverhez csatlakozni: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nem sikerült a szerverhez csatlakozni: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2026,16 +2196,42 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Becenév</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Add meg a beceneved</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2093,47 +2289,86 @@ Do you still want to join the room?</source>
<translation>Betöltés</translation>
</message>
<message>
- <source>Setup</source>
- <translation>BeállÃtás</translation>
+ <source>Associate file extensions</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ready</source>
- <translation>Kész</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Véletlen csapat</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
+ <source>Open videos directory</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>More info</source>
+ <source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default options</source>
+ <source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Open videos directory</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Upload to YouTube</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cancel uploading</source>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
+ </message>
+ <message>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2185,6 +2420,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2212,105 +2466,43 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>VámpÃrizmus</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Tüzérség</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>ErÅdÃtmény</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Csapatok felosztása</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Szilárd talaj</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Határok felállÃtása</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Alacsony gravitáció</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Lézeres mutató</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Sérthetetlenség</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Véletlen sorrend</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Király</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Sünik elhelyezése</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Közös lÅszerek</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Hidak tiltása</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Disable Land Objects</source>
- <translation>Tereptárgyak tiltása</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Mégse</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2445,12 +2637,6 @@ Do you still want to join the room?</source>
<translation>elfogás</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>süni
-info</translation>
- </message>
- <message>
<source>quit</source>
<translation>kilépés</translation>
</message>
@@ -2486,33 +2672,33 @@ info</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Alap irányÃtás</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Fegyverek kezelése</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Fegyverek</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kamera és kurzor irányÃtása</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Egyéb</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Süni mozgatása és célzás:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Gödrök és akadályok leküzdése ugrással:</translation>
</message>
@@ -2576,6 +2762,10 @@ info</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_it.ts b/share/hedgewars/Data/Locale/hedgewars_it.ts
index e371bbf..26c6b46 100644
--- a/share/hedgewars/Data/Locale/hedgewars_it.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_it.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="it">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation>Compilatore sconosciuto</translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,107 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>Soprannome</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Soprannome</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Motivo</translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation>Durata</translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>Ok</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avviso</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation>Per favore, specifica %1</translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>soprannome</translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation>permanente</translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation>Usa Default</translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation>Leggi</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation>Invia Commento</translation>
+ </message>
+ <message>
+ <source>Please give us feedback!</source>
+ <translation type="obsolete">Per favore, inviaci un commento!</translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation>Siamo sempre felici di ricevere suggerimenti, idee o segnalazioni di bachi.</translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already known here (english): </source>
+ <translation type="obsolete">Se torvi u nbaco, puoi vedere se è già conosciuto qui (in inglese): </translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but we may want to contact you.</source>
+ <translation type="obsolete">Il tuo indirizzo di posta elettronica è opzionale, ma potremmo volerti contattare.</translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,12 +152,76 @@
<translation>Modifica schemi</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Quando questa opzione è attiva, la scelta di uno schema di gioco selezionerà automaticamente le armi appropriate</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Opzioni di Gioco</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Opzioni di Gioco</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation>Lo schema di gioco sceglierà automaticamente un'arma</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation>Mappa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation>Opzioni di gioco</translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1 minuto</numerusform>
+ <numerusform>%1 minuti</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1 ora</numerusform>
+ <numerusform>%1 ore</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1 ora</numerusform>
+ <numerusform>%1 ore</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation>
+ <numerusform>%1 giorno</numerusform>
+ <numerusform>%1 giorni</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1 giorno</numerusform>
+ <numerusform>%1 giorni</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation>Impossibile creare la directory %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation>Impossibile creare la directory dati:
+%1
+
+Per favore controlla l'installazione!</translation>
</message>
</context>
<context>
@@ -102,8 +274,16 @@
<translation>Impossibile salvare la StyleSheet in %1! Errore interno!</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 non è un comando valido!</translation>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -139,30 +319,83 @@
<translation>Gioco concluso per volere del giocatore</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>Il nickname %1 è
-registrato su Hedgewars.org
-Per favore inserisci la tua password
-o scegli un altro nickname:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>Nessuna password valida inserita.</translation>
- </message>
- <message>
<source>Nickname</source>
- <translation>Nickname</translation>
+ <translation>Nome</translation>
</message>
<message>
<source>No nickname supplied.</source>
- <translation>Nessun nickname valido inserito.</translation>
+ <translation>Nessun nome valido inserito.</translation>
</message>
<message>
<source>Someone already uses your nickname %1 on the server.
Please pick another nickname:</source>
+ <translation>Qualcun altro sta già usando il tuo nome %1 sul server.
+Per favore scegli un altro nome:</translation>
+ </message>
+ <message>
+ <source>%1's Team</source>
+ <translation>Squadra di %1</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation>Hedgewars - Nome registrato</translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation>Questo nome è registrato, e non hai specificato una password.
+
+Se questo nome non è tuo, per favore registra un tuo nome a www.hedgewars.org
+
+Password:</translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation>Il tuo nome non è registrato.
+Per evitare che qualcun altro lo usi,
+per favore registralo su www.hedgewars.org</translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation>
+
+Anche la tua password non è stata salvata.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation>Hedgewars - Nome vuoto</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation>Hedgewars - Password sbagliata</translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation>Hai inserito una password sbagliata.</translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation>Prova ancora</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation>Hedgewars - Errore di connessione</translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation>Ti sei ricollegato troppo velocemente.
+Per favore aspetta qualche secondo e prova di nuovo.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -180,18 +413,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mappa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temi</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtro</translation>
- </message>
- <message>
<source>All</source>
<translation>Tutte</translation>
</message>
@@ -216,10 +437,6 @@ Please pick another nickname:</source>
<translation>Stramba</translation>
</message>
<message>
- <source>Type</source>
- <translation>Tipo</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Gallerie piccole</translation>
</message>
@@ -228,28 +445,100 @@ Please pick another nickname:</source>
<translation>Gallerie medie</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Gallerie grandi</translation>
+ <source>Seed</source>
+ <translation>Seed</translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation>Tipo mappa:</translation>
+ </message>
+ <message>
+ <source>Image map</source>
+ <translation>Immagine mappa</translation>
+ </message>
+ <message>
+ <source>Mission map</source>
+ <translation>Mappa missione</translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation>Disegnata a mano</translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation>Generata casualmente</translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation>Labirinto casuale</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>Casuale</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation>Anteprima mappa:</translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Load map drawing</source>
+ <translation>Carica disegno mappa</translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation>Modifica disegno mappa</translation>
+ </message>
+ <message>
+ <source>Small islands</source>
<translation>Isole piccole</translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Medium islands</source>
<translation>Isole medie</translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Large islands</source>
<translation>Isole grandi</translation>
</message>
<message>
- <source>Seed</source>
- <translation>Seed</translation>
+ <source>Map size:</source>
+ <translation>Dimensione mappa:</translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation>Stile labirinto:</translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation>Missione:</translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation>Mappa:</translation>
+ </message>
+ <message>
+ <source>Theme: </source>
+ <translation type="obsolete">Tema: </translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation>Carica mappa disegnata</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation>Mappe disegnate</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Tutti i file</translation>
</message>
<message>
- <source>Set</source>
- <translation>Imposta</translation>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -295,7 +584,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 è entrato</translation>
+ <translation type="obsolete">%1 *** %2 è entrato</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +610,26 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation>Password</translation>
+ <source>Login</source>
+ <translation>Login</translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation>Per collegarsi al server, per favore accedi.
+
+Se non possiedi un account su www.hedgewars.org,
+inserisci solo il tuo soprannome.</translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation>Soprannome:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>Password:</translation>
</message>
</context>
<context>
@@ -337,6 +644,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation>Cambia cappello (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation>Usa cappello selezionato</translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation>Cerca un cappello:</translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +673,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation>Categoria</translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +698,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation>Audio:</translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation>sconosciuto</translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation>Nessuna descrizione disponibile.</translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +740,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Imposta dati</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>Generale</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation>Espulsi</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Nome</translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation>Scadenza</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Motivo</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation>Aggiorna</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Aggiungi</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Rimuovi</translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +781,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +837,40 @@ Please pick another nickname:</source>
<translation>Generale</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avanzato</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation>Seleziona un'azione per scegliere il tasto personalizzato per questa squadra</translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation>Usa il mio predefinito</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Ripristina tutte le associazioni</translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation>Controlli personalizzati</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>Cappello</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation>Il nome di questo riccio</translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation>Genera casualmetne il nome di questo riccio</translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation>Squadra Casuale</translation>
</message>
</context>
<context>
@@ -511,12 +933,20 @@ Please pick another nickname:</source>
<numerusform><b>%1</b> aveva paura e ha passato il turno <b>%2</b> volte.</numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished">Salva</translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
<message>
<source>In game...</source>
- <translation>In Game....</translation>
+ <translation>In gioco...</translation>
</message>
</context>
<context>
@@ -529,267 +959,14 @@ Please pick another nickname:</source>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Scegli lo stesso colore di un amico per giocare in squadra. Ciascuno controllerà i propri ricci ma la vittoria o la sconfitta saranno comuni.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Alcune armi potrebbero fare pochi danni ma possono essere devastanti se usate al momento giusto. Prova ad esempio ad utilizzare la Desert Eagle per spingere più ricci in acqua.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Se non sai cosa fare e non vuoi sprecare munizioni, salta il turno. Ma non farlo troppe volte perché c'è il Sudden Death!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Se vuoi evitare che altri possano impersonarti, utilizzando il tuo nickname, sul server ufficiale, registrati su http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Sei stanco delle partite preimpostate? Prova una missione - le missioni offrono interessanti modalità differenti di partite in base alle tue scelte.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Il gioco salverà sempre l'ultima partita giocata come demo. Seleziona 'Gioco locale' e clicca il bottone 'Demos' nell'angolo in basso a destra per gestirle.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars è un programma Open Source e gratuito che noi creiamo nel nostro tempo libero. Se hai problemi, chiedi nei nostri forum ma, per favore, non aspettarti un supporto 24/7!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Se ti piace, aiutaci con una piccola donazione o contribuisci con il tuo lavoro!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Condividilo con tutta la famiglia e e con gli amici come più ti piace!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Di tanto in tanto ci saranno tornei ufficiali. Gli eventi saranno annunciati su http://www.hedgewars.org/ con qualche giorno di anticipo.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars è disponibile in molte lingue. Se la traduzione nella tua lingua sembra mancante o non aggiornata, sentiti libero di contattaci!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars può essere usato su molti sistemi operativi differenti come Microsoft Windows - XP, Vista, 7 -, Mac OS X e Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Ricordati che sei sempre in grado di configurare partire personalizzate in locale e online. Non devi sentirti limitato alle opzioni predefinite!</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Durante il gioco dovresti fare una breve pausa almeno ogni ora. In caso di partite più lunghe, sospendi l'attività per almeno 30 minuti al termine del gioco!</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Se la tua scheda grafica non è in grado di fornire OpenGL con accelerazione hardware, prova ad abilitare la modalità a bassa qualità per migliorare le prestazioni.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Siamo aperti a suggerimenti e consigli costruttivi. Se non ti piace qualcosa o hai una buona idea, comunicacelo!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>In particolare quando giochi online sii educato e ricorda che potrebbero esserci dei minorenni che stanno giocando con te o contro di te!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Le modalità di gioco speciali, come 'Vampirismo' o 'Karma' ti permettono di sviluppare nuove tattiche. Provale in una partita personalizzata!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Non dovresti mai installare Hedgewars su computer che non possiedi (scuola, università , lavoro, ecc.). Per favore, chiedi ai responsabili!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars può essere perfetto per brevi partite durante le pause. Assicurati solamente di non aver aggiunto troppi ricci o di usare una mappa troppo grande. Ridurre tempo e vita può aiutare allo stesso modo.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Nessun riccio è stato maltrattato durante lo sviluppo di questo gioco.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars è un programma Open Source e gratuito che creiamo nel nostro tempo libero. Se qualcuno ti ha venduto il gioco, dovresti chiedere un rimborso!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Collega uno o più gamepad prima di iniziare il gioco per poterli assegnare alle tue squadra.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Crea un account su %1 per evitare che altri possano usare il tuo nickname preferito mentre giochi sul server ufficiale.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Se la tua scheda grafica non è in grado di fornire OpenGL con accelerazione hardware, prova ad aggiornarne i driver.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Ci sono tre salti disponibili. Premi [salto in alto] due volte per eseguire un salto in alto all'indietro.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Paura di cadere da un dirupo? Premi [mirino di precisione] per girare a [sinistra] o a [destra] senza muoverti.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Alcune armi richiedono strategie particolari o semplicemente molto allenamento, quindi non arrenderti nell'utilizzo di un'arma specifica se manchi il nemico una volta.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>Molte armi non funzionano quando toccano l'acqua. L'Ape a Ricerca così come la Torta sono delle eccezioni.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Il vecchio Limburger causa solo una piccola esplosione. Tuttavia il vento influisce sulla nuvola puzzolente e può avvelenare più ricci contemporaneamente.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>L'Ultima Sonata è l'attacco aereo più dannoso. Perderai il tuo riccio, eseguendolo, quindi ci sono anche delle grosse controindicazioni.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Le Mine Adesive sono lo strumento perfetto per creare piccole reazioni a catena e spingere i ricci nemici in situazioni difficili... o in acqua.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Il Martello è più efficate se usato su ponti o travi. Colpire i ricci li farà sprofondare attraverso il terreno.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Se sei bloccato dietro un riccio nemico, usa il Martello per liberarti senza essere danneggiato da un'esplosione.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>La distanza massima di cammino della Torta dipende dal terreno che deve attraversare. Usa [attacca] per farla esplodere prima.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Il Lanciafiamme è un'arma che può essere usata anche per scavare gallerie.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Vuoi sapere chi c'è dietro il gioco? Clicca sul logo Hedgewars nel menu principale per vederne gli autori e sviluppatori.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Ti piace Hedgewars? Diventa fan su %1 o seguici su %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Sentiti libero di disegnare tombe, cappelli, bandiere o anche mappe e temi personalizzati - lo puoi fare con TheGIMP! Ma nota che dovrai condividerli in qualche modo per usarli online.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Vuoi proprio un cappello specifico? Facci una piccola donazione e riceverai un cappello esclusivo a tua scelta!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Mantieni aggiornati i driver della tua scheda video, per evitare problemi durante il gioco.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puoi trovare i file di configurazione del gioco in "Documenti\Hedgewars". Crea delle copie di sicurezza o prendi i file con te, ma non modificarli manualmente!</translation>
- </message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Puoi associare i file relativi a Hedgewars (partite salvate e registrazioni demo) al gioco, in modo da lanciarli direttamente dal tuo gestore file o browser Internet.</translation>
- </message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Vuoi utilizzare più a lungo la corda? Rilascia la corda a mezz'aria e spara di nuovo. Finché non tocchi il terreno potrai riusare la corda senza sprecare munizioni!</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puoi trovare i file di configurazione del gioco in "Library/Application Support/Hedgewars" nella tua cartella utente. Crea una copia di sicurezza o porta i file con te, ma non modificarli mai manualmente.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Puoi trovare i file di configurazione del gioco in ".hedgewars" nella tua cartella home. Crea una copia di sicurezza o porta i file con te, ma non modificarli mai manualmente.</translation>
- </message>
- <message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>La versione Windows di Hedgewars supporta Xfire. Assicurati di aggiungere Hedgewars alla sua lista giochi, così i tuoi amici potranno vederti giocare.</translation>
- </message>
- <message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Usa la Bomba Molotov o il Lanciafiamme per impedire temporaneamente ai ricci di attraversari terreni pianeggianti, tunnel o collinette.</translation>
- </message>
- <message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>L'Ape a Ricerca può essere difficile da usare. Il suo raggio di curvatura dipende dalla sua velocità , quindi cerca di non usarla a piena potenza.</translation>
- </message>
- <message>
<source>Downloadable Content</source>
<translation>Contenuti Scaricabili</translation>
</message>
<message>
- <source>Local Game</source>
- <translation>Gioco in locale</translation>
- </message>
- <message>
<source>Play a game on a single computer</source>
<translation>Gioca una partita offline</translation>
</message>
<message>
- <source>Network Game</source>
- <translation>Gioco in rete</translation>
- </message>
- <message>
<source>Play a game across a network</source>
<translation>Gioca una partita attraverso una rete</translation>
</message>
@@ -802,20 +979,40 @@ Please pick another nickname:</source>
<translation>Lascia un feedback segnalando problemi, suggerendo nuove funzionalità o solamente indicando il tuo livello di gradimento del gioco.</translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
- <translation>Accedi al download di contenuti creati dalla comunità dal nostro sito web</translation>
+ <source>Access the user created content downloadable from our website</source>
+ <translation>Accedi al download di contenuti creati dalla comunità dal nostro sito web</translation>
+ </message>
+ <message>
+ <source>Exit game</source>
+ <translation>Esci dal gioco</translation>
+ </message>
+ <message>
+ <source>Manage videos recorded from game</source>
+ <translation>Organizza i video registrati tramite il gioco</translation>
+ </message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation>Modifica preferenze</translation>
+ </message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation>Gioca una partita su una rete locale</translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation>Gioca una partita su un server ufficiale</translation>
</message>
<message>
- <source>Exit game</source>
- <translation>Esci dal gioco</translation>
+ <source>Feedback</source>
+ <translation>Opinioni</translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
- <translation>Organizza i video registrati tramite il gioco</translation>
+ <source>Play local network game</source>
+ <translation>Gioca una partita in rete locale</translation>
</message>
<message>
- <source>Edit game preferences</source>
- <translation>Modifica preferenze</translation>
+ <source>Play official network game</source>
+ <translation>Gioca una partita sul server ufficiale</translation>
</message>
</context>
<context>
@@ -824,39 +1021,43 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Gioca</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation>Modifica preferenze</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Controllo</translation>
+ <translation type="obsolete">Controllo</translation>
</message>
<message>
- <source>DLC</source>
- <translation>DLC</translation>
+ <source>Edit game preferences</source>
+ <translation>Modifica preferenze</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Contenuti Scaricabili</translation>
+ <source>Start</source>
+ <translation>Gioca</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Gioco in LAN</translation>
+ <source>Update</source>
+ <translation>Aggiorna</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Server ufficiale</translation>
+ <source>Room controls</source>
+ <translation>Controlli stanza</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
- <translation>Incontra centinaia di giocatori online!</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation>Unisciti ad un server o creane uno nuovo per il gioco online in una rete LAN.</translation>
+ <source>Insert your address here</source>
+ <translation>Inserisci il tuo indirizzo</translation>
</message>
</context>
<context>
@@ -902,10 +1103,6 @@ Please pick another nickname:</source>
<translation>Elimina set delle armi</translation>
</message>
<message>
- <source>General</source>
- <translation>Generale</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avanzate</translation>
</message>
@@ -915,35 +1112,123 @@ Please pick another nickname:</source>
</message>
<message>
<source>Proxy host</source>
- <translation type="unfinished"></translation>
+ <translation>Server proxy</translation>
</message>
<message>
<source>Proxy port</source>
- <translation type="unfinished"></translation>
+ <translation>Porta proxy</translation>
</message>
<message>
<source>Proxy login</source>
- <translation type="unfinished"></translation>
+ <translation>Login Proxy</translation>
</message>
<message>
<source>Proxy password</source>
- <translation type="unfinished"></translation>
+ <translation>Password proxy</translation>
</message>
<message>
<source>No proxy</source>
- <translation type="unfinished"></translation>
+ <translation>Nessun proxy</translation>
</message>
<message>
<source>Socks5 proxy</source>
- <translation type="unfinished"></translation>
+ <translation>Proxy Socks5</translation>
</message>
<message>
<source>HTTP proxy</source>
- <translation type="unfinished"></translation>
+ <translation>Proxy HTTP</translation>
</message>
<message>
<source>System proxy settings</source>
- <translation type="unfinished"></translation>
+ <translation>Impostazioni proxy di sistema</translation>
+ </message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation>Seleziona un'azione per cambiare il tasto che la controlla</translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation>Ripristina i valori predefiniti</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Ripristina tutte le associazioni</translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation>Gioco</translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation>Grafica</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Audio</translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation>Controlli</translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation>Registrazione video</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rete</translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation>Squadre</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation>Schemi</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation>Armi</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation>Presentazione</translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation>Colori personalizzati</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation>Audio gioco</translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation>Audio presentazione</translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation>Account</translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation>Impostazioni proxy</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation>Varie</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation>Aggiornamenti</translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation>Controlla aggiornamenti</translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation>Opzioni di registrazione video</translation>
</message>
</context>
<context>
@@ -961,11 +1246,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Crea</translation>
+ <translation type="obsolete">Crea</translation>
</message>
<message>
<source>Join</source>
- <translation>Entra</translation>
+ <translation type="obsolete">Entra</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1258,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Nome stanza:</translation>
+ <translation type="obsolete">Nome stanza:</translation>
</message>
<message>
<source>Rules:</source>
@@ -985,11 +1270,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Cerca:</translation>
+ <translation type="obsolete">Cerca:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Cancella</translation>
+ <translation type="obsolete">Cancella</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1283,30 @@ Please pick another nickname:</source>
<numerusform>%1 giocatori online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation>Cerca una stanza:</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Crea stanza</translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation>Entra nella stanza</translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation>Stato della stanza</translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation>Rimuovi filtri</translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation>Apri pagina di amministrazione del server</translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1453,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation>Partita Semplice</translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation>Gioca una partita rapida contro il computer con impostazioni casuali</translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation>Multiplayer</translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation>Gioca una partira controlo un amico oppure contro il computer</translation>
</message>
@@ -1164,26 +1465,14 @@ Please pick another nickname:</source>
<translation>Modalità Campagna</translation>
</message>
<message>
- <source>Training Mode</source>
- <translation>Modalità allenamento</translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation>Metti alla prova le tue capacità in una vasta gamma di missioni di addestramento</translation>
</message>
<message>
- <source>Demos</source>
- <translation>Demo</translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation>Visualizza demo registrate</translation>
</message>
<message>
- <source>Load</source>
- <translation>Carica</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation>Carica un gioco salvato in precedenza</translation>
</message>
@@ -1220,8 +1509,8 @@ Please pick another nickname:</source>
<message numerus="yes">
<source>%1 bytes</source>
<translation>
- <numerusform>%1 bytes</numerusform>
- <numerusform>%1 bytes</numerusform>
+ <numerusform>%1 byte</numerusform>
+ <numerusform>%1 byte</numerusform>
</translation>
</message>
<message>
@@ -1229,14 +1518,6 @@ Please pick another nickname:</source>
<translation>(in corso...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation>Data: </translation>
- </message>
- <message>
- <source>Size: </source>
- <translation>Dimensione: </translation>
- </message>
- <message>
<source>encoding</source>
<translation>encoding</translation>
</message>
@@ -1244,6 +1525,18 @@ Please pick another nickname:</source>
<source>uploading</source>
<translation>caricamento</translation>
</message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation>Dimensione: %1
+</translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1252,10 +1545,6 @@ Please pick another nickname:</source>
<translation>Caccia via</translation>
</message>
<message>
- <source>Start</source>
- <translation>Gioca</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Limita le entrate</translation>
</message>
@@ -1293,7 +1582,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>Aggiorna</translation>
+ <translation type="obsolete">Aggiorna</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation>Impedisci la partecipazione di giocatori non registrati</translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation>Mostra le partite nell'elenco</translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation>Mostra partite in corso</translation>
</message>
</context>
<context>
@@ -1303,10 +1604,6 @@ Please pick another nickname:</source>
<translation>Schermo intero</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Abilita il suono</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Mostra FPS</translation>
</message>
@@ -1319,14 +1616,6 @@ Please pick another nickname:</source>
<translation>Controlla aggiornamenti all'avvio</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Abilita musica</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Frontend schermo intero</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Concatena data e ora di registrazione al nome file</translation>
</message>
@@ -1335,18 +1624,6 @@ Please pick another nickname:</source>
<translation>Mostra suggerimenti nel menu armi</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Abilita suoni nel frontend</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Abilita la musica nel frontend</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Effetti speciali nel frontend</translation>
- </message>
- <message>
<source>Save password</source>
<translation>Salva password</translation>
</message>
@@ -1366,14 +1643,38 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation>Usa la risoluzione del gioco</translation>
</message>
+ <message>
+ <source>Visual effects</source>
+ <translation>Effetti speciali</translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation>Suono</translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation>Effetti sonori nel gioco</translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation>Musica</translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation>Musica nel gioco</translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation>Effetti sonori in presentazione</translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation>Musica in presentazione</translation>
+ </message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>Mappa generata...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Umano</translation>
</message>
@@ -1386,14 +1687,6 @@ Please pick another nickname:</source>
<translation>(Predefinito)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>Labirinto generato...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Missione</translation>
- </message>
- <message>
<source>Community</source>
<translation>Comunità </translation>
</message>
@@ -1403,15 +1696,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>In lobby</translation>
+ <translation type="obsolete">In lobby</translation>
</message>
<message>
<source>In progress</source>
- <translation>In corso</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>Mappa disegnata...</translation>
+ <translation type="obsolete">In corso</translation>
</message>
<message>
<source>Disabled</source>
@@ -1450,10 +1739,6 @@ Please pick another nickname:</source>
<translation>Dall'alto in basso</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Movimento continuo</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Scala di grigi rosso/azzurro</translation>
</message>
@@ -1485,22 +1770,10 @@ Please pick another nickname:</source>
<translation>Membri della squadra</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Associazione tasti</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Fortino</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Squadre</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Opzioni Audio/Grafica</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Gioco in rete</translation>
</message>
@@ -1521,26 +1794,6 @@ Please pick another nickname:</source>
<translation>Impostazioni delle Squadre</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Varie</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Schemi di Gioco e Armi</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation>Colori personalizzati</translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation>Varie</translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation>Opzioni di registrazione video</translation>
- </message>
- <message>
<source>Videos</source>
<translation>Video</translation>
</message>
@@ -1548,10 +1801,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation>Descrizione</translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1564,22 +1813,6 @@ Please pick another nickname:</source>
<translation>Mine</translation>
</message>
<message>
- <source>Developers:</source>
- <translation>Sviluppatori:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafica:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Traduttori:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Ringraziamenti speciali:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Armi</translation>
</message>
@@ -1609,11 +1842,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Versione</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Suoni:</translation>
+ <translation type="obsolete">Versione</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1644,10 +1873,6 @@ Please pick another nickname:</source>
<translation>Caduta Casse</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Schema di gioco</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Mine Difettose</translation>
</message>
@@ -1684,10 +1909,6 @@ Please pick another nickname:</source>
<translation>Suggerimento: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Questa versione di sviluppo è in corso d'opera e può non essere compatibile con le altre versioni del gioco. Alcune funzionalità potrebbero essere incomplete o non funzionanti. Usatela a vostro rischio!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Qualità </translation>
</message>
@@ -1729,7 +1950,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>Questo programma è distribuito con licenza GNU General Public License v2</translation>
+ <translation type="obsolete">Questo programma è distribuito con licenza GNU General Public License v2</translation>
</message>
<message>
<source>There are videos that are currently being processed.
@@ -1756,44 +1977,84 @@ Vuoi veramente uscire?</translation>
<translation>Titolo del video: </translation>
</message>
<message>
- <source>Video description: </source>
- <translation>Descrizione del video:</translation>
+ <source>Video description: </source>
+ <translation>Descrizione del video:</translation>
+ </message>
+ <message>
+ <source>Tags (comma separated): </source>
+ <translation>Tag (separate da una virgola): </translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation>Descrizione</translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation>Nickname</translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation>Formato</translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation>Codec audio</translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation>Codec video</translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation>Framerate</translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation>Bitrate (Kbps)</translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation>Questo rilascio è in fase di sviluppo e potrebbe non essere compatibile con altre versioni del gioco, e alcune funzionalità potrebbero essere malfunzionanti o incomplete!</translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>Schermo intero</translation>
</message>
<message>
- <source>Tags (comma separated): </source>
- <translation>Tag (separate da una virgola): </translation>
+ <source>Fullscreen Resolution</source>
+ <translation>Risoluzione schermo interno</translation>
</message>
<message>
- <source>Summary </source>
- <translation>Riassunto </translation>
+ <source>Windowed Resolution</source>
+ <translation>Risoluzione finestra</translation>
</message>
<message>
- <source>Description</source>
- <translation>Descrizione</translation>
+ <source>Your Email</source>
+ <translation>Indirizzo di posta elettronica</translation>
</message>
<message>
- <source>Nickname</source>
- <translation>Nickname</translation>
+ <source>Summary</source>
+ <translation>Sommario</translation>
</message>
<message>
- <source>Format</source>
- <translation>Formato</translation>
+ <source>Send system information</source>
+ <translation>Invia informazioni di sistema</translation>
</message>
<message>
- <source>Audio codec</source>
- <translation>Codec audio</translation>
+ <source>Type the security code:</source>
+ <translation>Inserisci il codice di sicurezza:</translation>
</message>
<message>
- <source>Video codec</source>
- <translation>Codec video</translation>
+ <source>Revision</source>
+ <translation>Revisione</translation>
</message>
<message>
- <source>Framerate</source>
- <translation>Framerate</translation>
+ <source>This program is distributed under the %1</source>
+ <translation>Questo programma è distribuito secondo i termini di %1</translation>
</message>
<message>
- <source>Bitrate (Kbps)</source>
- <translation>Bitrate (Kbps)</translation>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1817,6 +2078,10 @@ Vuoi veramente uscire?</translation>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation>-r%1 (%2)</translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1833,10 +2098,6 @@ Vuoi veramente uscire?</translation>
<translation>Associazione delle estensioni a Hedgewars fallita.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation>E' necessario compilare tutti i campi</translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation>Errore durante l'autenticazione su google.com:</translation>
@@ -1852,206 +2113,228 @@ Vuoi veramente uscire?</translation>
</message>
<message>
<source>Teams - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Squadre - Sei sicuro?</translation>
</message>
<message>
<source>Do you really want to delete the team '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Vuoi davvero cancellare la squadra '%1'?</translation>
</message>
<message>
<source>Cannot delete default scheme '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso cancellare lo schema di default '%1'!</translation>
</message>
<message>
<source>Please select a record from the list</source>
- <translation type="unfinished"></translation>
+ <translation>Per favore scegli una voce dalla lista</translation>
</message>
<message>
<source>Unable to start server</source>
- <translation type="unfinished"></translation>
+ <translation>Impossibile avviare il server</translation>
</message>
<message>
<source>Hedgewars - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Errore</translation>
</message>
<message>
<source>Hedgewars - Success</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Completato</translation>
</message>
<message>
<source>All file associations have been set</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
+ <translation>Tutte le associazioni di file sono state impostate</translation>
</message>
<message>
<source>Main - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Main - Errore</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Impossibile creare la directory %1</translation>
+ <translation type="obsolete">Impossibile creare la directory %1</translation>
</message>
<message>
<source>Failed to open data directory:
%1
Please check your installation!</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Impossibile creare la directory dati:
+%1
+
+Per favore controlla l'installazione!</translation>
</message>
<message>
<source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">TCP - Errore</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Impossibile avviare il server: %1.</translation>
+ <translation type="obsolete">Impossibile avviare il server: %1.</translation>
</message>
<message>
<source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Impossibile avviare il motore a </translation>
</message>
<message>
<source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Codice di errore: %1</translation>
</message>
<message>
<source>Video upload - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Caricamento video - Errore</translation>
</message>
<message>
<source>Netgame - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Gioco in rete - Errore</translation>
</message>
<message>
<source>Please select a server from the list</source>
- <translation type="unfinished"></translation>
+ <translation>Per favore scegli un server dalla lista</translation>
</message>
<message>
<source>Please enter room name</source>
- <translation type="unfinished">Inserisci il nome della stanza</translation>
+ <translation>Inserisci il nome della stanza</translation>
</message>
<message>
<source>Record Play - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Registrazione gioco - Errore</translation>
</message>
<message>
<source>Please select record from the list</source>
- <translation type="unfinished">Seleziona un record dalla lista</translation>
+ <translation>Seleziona un record dalla lista</translation>
</message>
<message>
<source>Cannot rename to </source>
- <translation type="unfinished"></translation>
+ <translation>Impossibile rinominare a </translation>
</message>
<message>
<source>Cannot delete file </source>
- <translation type="unfinished"></translation>
+ <translation>Impossibile cancellare il file </translation>
</message>
<message>
<source>Room Name - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Nome stanza - Errore</translation>
</message>
<message>
<source>Please select room from the list</source>
- <translation type="unfinished">Seleziona la stanza dalla lista</translation>
+ <translation>Seleziona la stanza dalla lista</translation>
</message>
<message>
<source>Room Name - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Nome stanza - Sei sicuro?</translation>
</message>
<message>
<source>The game you are trying to join has started.
Do you still want to join the room?</source>
- <translation type="unfinished">La partita a cui stai cercando di unirti è già iniziata.
+ <translation>La partita a cui stai cercando di unirti è già iniziata.
Voui comunque entrare nella stanza?</translation>
</message>
<message>
<source>Schemes - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Schemi - Attenzione</translation>
</message>
<message>
<source>Schemes - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Schemi - Sei sicuro?</translation>
</message>
<message>
<source>Do you really want to delete the game scheme '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Vuoi davvero cancellare lo schema di gioco '%1'?</translation>
</message>
<message>
<source>Videos - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Video - Sei sicuro?</translation>
</message>
<message>
<source>Do you really want to delete the video '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Vuoi davvero cancellare il video '%1'?</translation>
</message>
<message numerus="yes">
<source>Do you really want to remove %1 file(s)?</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Vuoi davvero cancellare il file?</numerusform>
+ <numerusform>Vuoi davvero cancellare %1 file?</numerusform>
</translation>
</message>
<message>
<source>Do you really want to cancel uploading %1?</source>
- <translation type="unfinished"></translation>
+ <translation>Vuoi davvero terminare di caricare %1?</translation>
</message>
<message>
<source>File error</source>
- <translation type="unfinished">Errore con il file</translation>
+ <translation>Errore con il file</translation>
</message>
<message>
<source>Cannot open '%1' for writing</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso aprire '%1' in scrittura</translation>
</message>
<message>
<source>Cannot open '%1' for reading</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso aprire '%1' in lettura</translation>
</message>
<message>
<source>Cannot use the ammo '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso usare le munizioni '%1'!</translation>
</message>
<message>
<source>Weapons - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Armi - Attenzione</translation>
</message>
<message>
<source>Cannot overwrite default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso sovrascrivere l'insieme base di armi '%1'!</translation>
</message>
<message>
<source>Cannot delete default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Non posso cancellare l'insieme base di armi '%1'!</translation>
</message>
<message>
<source>Weapons - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Armi - Sei sicuro?</translation>
</message>
<message>
<source>Do you really want to delete the weapon set '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Vuoi davvero cancellare l'insieme di armi '%1'?</translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nickname</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation>Hedgewars - Nome non registrato</translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation>Anteprima informazioni di sistema</translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation>Impossibile generare captcha</translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Per favore inserisci il tuo nickname</translation>
+ <source>Failed to download captcha</source>
+ <translation>Impossibile scaricare captcha</translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation>Per favore riempi tutti i campi. L'indirizzo di posta elettronica è opzionale.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation>Hedgewars - Attenzione</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation>Hedgewars - Avviso</translation>
+ </message>
+ <message>
+ <source>Hedgewars</source>
+ <translation type="obsolete">Hedgewars</translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation>Non tutti i giocatori sono pronti</translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation>Sei sicuro che vuoi iniziare il gioco?
+Non tutti i giocatori sono pronti.</translation>
</message>
</context>
<context>
@@ -2109,26 +2392,10 @@ Voui comunque entrare nella stanza?</translation>
<translation>Carica</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Impostazioni</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Pronto</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Squadra Casuale</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Associa estensioni a Hedgewars</translation>
</message>
<message>
- <source>more</source>
- <translation>altro</translation>
- </message>
- <message>
<source>More info</source>
<translation>Più informazioni</translation>
</message>
@@ -2152,6 +2419,61 @@ Voui comunque entrare nella stanza?</translation>
<source>Cancel uploading</source>
<translation>Sospendi caricamento</translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation>Ripristina i parametri di base della codifica</translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation>Apri la directory video sul tuo sistema</translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation>Riproduci questo video</translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation>Cancella questo video</translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation>Cariva questo video nel tuo account Youtube</translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation>Ripristina</translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation>Seleziona la porta di configurazione del server di Hedgewars</translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation>Invita i tuoi amici sul tuo serve con 1 solo clic!</translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation>Clicca per copiare il tuo URL univoco del serve negli appunti. Invia questo collegamento ai tuoi amici e potranno unirsi a te.</translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation>Avvia un server privato</translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation>Inserisci un nome per la tua stanza.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Crea stanza</translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2201,6 +2523,25 @@ Voui comunque entrare nella stanza?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation>Il seme della mappa è la base per tutti i valori casuali generati dal gioco.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation>Imposta seme</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>Chiudi</translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2228,106 +2569,45 @@ Voui comunque entrare nella stanza?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirismo</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artiglieria</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Modalità Fortino</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Dividi le Squadre</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Terreno Solido</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Aggiunta Bordo</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Gravità Zero</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Laser Sight</source>
- <translation>Vista Laser</translation>
+ <source>Unable to start server at %1.</source>
+ <translation>Impossibile avviare il server a %1.</translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation>Invulnerabilità </translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Ordine Casuale</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Re</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Posiziona Ricci</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Munizioni Condivise</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Disabilita Travi</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Disabilita Oggetti Terreno</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Modalità Sopravvivenza AI</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>Resetta la vita allo stato di partenza</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>Attacchi Illimitati</translation>
- </message>
- <message>
- <source>Reset Weapons</source>
- <translation>Resetta le armi allo stato di partenza</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation>Impossibile eseguire il motore a %1
+Codice di errore: %2</translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Munzioni non condivise con gli altri ricci</translation>
+ <source>At least two teams are required to play!</source>
+ <translation>Servono almeno due squadre per giocare!</translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Disabilita Vento</translation>
+ <source>%1's team</source>
+ <translation>Squadra di %1</translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Più Vento</translation>
+ <source>Cancel</source>
+ <translation>Annulla</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tag Team</translation>
+ <source>Search for a theme:</source>
+ <translation>Cerca un tema:</translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Aggiungi Bordo Inferiore</translation>
+ <source>Use selected theme</source>
+ <translation>Usa tema selezionato</translation>
</message>
</context>
<context>
@@ -2445,12 +2725,6 @@ Voui comunque entrare nella stanza?</translation>
<translation>cattura</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>informazioni
-ricci</translation>
- </message>
- <message>
<source>quit</source>
<translation>esci</translation>
</message>
@@ -2502,33 +2776,33 @@ ricci</translation>
<source>record</source>
<translation>registra</translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation>informazioni riccio</translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Controlli di base</translation>
+ <source>Movement</source>
+ <translation>Movimento</translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Controlli per le armi</translation>
+ <source>Weapons</source>
+ <translation>Armi</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Controlli camera e cursore</translation>
+ <source>Camera</source>
+ <translation>Telecamera</translation>
</message>
<message>
- <source>Other</source>
- <translation>Altro</translation>
+ <source>Miscellaneous</source>
+ <translation>Varie</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Muovi i tuoi ricci e punta:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Scavalca buchi e ostacoli saltando:</translation>
</message>
@@ -2592,6 +2866,10 @@ ricci</translation>
<source>Record video:</source>
<translation>Registra video:</translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation>Movimento riccio</translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
@@ -2912,4 +3190,115 @@ ricci</translation>
<translation>DPad</translation>
</message>
</context>
+<context>
+ <name>server</name>
+ <message>
+ <source>Not room master</source>
+ <translation type="obsolete">Non proprietario della stanza</translation>
+ </message>
+ <message>
+ <source>Corrupted hedgehogs info</source>
+ <translation type="obsolete">Informazioni ricci corrotte</translation>
+ </message>
+ <message>
+ <source>too many teams</source>
+ <translation type="obsolete">troppe squadre</translation>
+ </message>
+ <message>
+ <source>too many hedgehogs</source>
+ <translation type="obsolete">troppi ricci</translation>
+ </message>
+ <message>
+ <source>There's already a team with same name in the list</source>
+ <translation type="obsolete">C'è già una quadra collo stesso nome in lista</translation>
+ </message>
+ <message>
+ <source>round in progress</source>
+ <translation type="obsolete">turno in corso</translation>
+ </message>
+ <message>
+ <source>restricted</source>
+ <translation type="obsolete">proibito</translation>
+ </message>
+ <message>
+ <source>REMOVE_TEAM: no such team</source>
+ <translation type="obsolete">CANCELLA_SQUADRA: squadra non presente</translation>
+ </message>
+ <message>
+ <source>Not team owner!</source>
+ <translation type="obsolete">Non proprietario della squadra!</translation>
+ </message>
+ <message>
+ <source>Less than two clans!</source>
+ <translation type="obsolete">Meno di due clan!</translation>
+ </message>
+ <message>
+ <source>Room with such name already exists</source>
+ <translation type="obsolete">Esiste già una stanza con questo nome</translation>
+ </message>
+ <message>
+ <source>Nickname already chosen</source>
+ <translation type="obsolete">Nome già scelto</translation>
+ </message>
+ <message>
+ <source>Illegal nickname</source>
+ <translation type="obsolete">Nome non valido</translation>
+ </message>
+ <message>
+ <source>Protocol already known</source>
+ <translation type="obsolete">Protocollo già conosciuto</translation>
+ </message>
+ <message>
+ <source>Bad number</source>
+ <translation type="obsolete">Numero non valido</translation>
+ </message>
+ <message>
+ <source>Nickname is already in use</source>
+ <translation type="obsolete">Nome già in uso</translation>
+ </message>
+ <message>
+ <source>Authentication failed</source>
+ <translation type="obsolete">Autenticazione fallita</translation>
+ </message>
+ <message>
+ <source>60 seconds cooldown after kick</source>
+ <translation type="obsolete">60 secondi di raffreddamento prima dell'espulsione</translation>
+ </message>
+ <message>
+ <source>kicked</source>
+ <translation type="obsolete">espulso</translation>
+ </message>
+ <message>
+ <source>Ping timeout</source>
+ <translation type="obsolete">Scadenza ping</translation>
+ </message>
+ <message>
+ <source>bye</source>
+ <translation type="obsolete">ciao</translation>
+ </message>
+ <message>
+ <source>Illegal room name</source>
+ <translation type="obsolete">Nome stanza non valido</translation>
+ </message>
+ <message>
+ <source>No such room</source>
+ <translation type="obsolete">Stanza non esistente</translation>
+ </message>
+ <message>
+ <source>Joining restricted</source>
+ <translation type="obsolete">Ingresso riservato</translation>
+ </message>
+ <message>
+ <source>Registered users only</source>
+ <translation type="obsolete">Solo utenti registrati</translation>
+ </message>
+ <message>
+ <source>You are banned in this room</source>
+ <translation type="obsolete">Sei stato espulso dalla stanza</translation>
+ </message>
+ <message>
+ <source>Empty config entry</source>
+ <translation type="obsolete">Configurazione vuota</translation>
+ </message>
+</context>
</TS>
diff --git a/share/hedgewars/Data/Locale/hedgewars_ja.ts b/share/hedgewars/Data/Locale/hedgewars_ja.ts
index de4eac5..68774ae 100644
--- a/share/hedgewars/Data/Locale/hedgewars_ja.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_ja.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="ja">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">ãã¹ãåï¼ï¼©ï¼°</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>ããã¯ãã¼ã </translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IPï¼ããã¯ãã¼ã </translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>ãªãã±ã¼</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>è¦å ±ã¡ãã»ã¼ã¸</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>ããã¯ãã¼ã </translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -43,11 +139,63 @@
<translation>ããã¿ãç·¨é</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>ãã®ãªãã·ã§ã³ãæå¹ã«ãã¦ãããã¿ãé¸ã¶ã¨æ¦å¨ãèªåé¸æ</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation>å°å³</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1å</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1æ</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1æ</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform>%1æ¥</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1æ¥</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">ãã©ã«ãã¼%1ä½ææå¦</translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -101,7 +249,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -138,31 +294,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">ããªãã®ã%1ãã¨ããããã¯åã¯
-Hedgewars.orgã«ç»é²ããã¾ããã
-ä¸ã«ãã¹ã¯ã¼ããå
¥åãã¦ãã¾ãã¯
-ã²ã¼ã æ§æã«å¥ã®åãé¸æãã¦ãã ããï¼
-</translation>
+ <source>Nickname</source>
+ <translation>ããã¯ãã¼ã </translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>%1's Team</source>
+ <translation>%1ã®ãã¼ã </translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -180,18 +378,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>å°å³</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>ãã¼ã</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>濾é</translation>
- </message>
- <message>
<source>All</source>
<translation>å
¨é¨</translation>
</message>
@@ -216,10 +402,6 @@ Please pick another nickname:</source>
<translation>ãã¡ããã¡ã</translation>
</message>
<message>
- <source>Type</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>å°ãã³ãã«</translation>
</message>
@@ -228,27 +410,95 @@ Please pick another nickname:</source>
<translation>ä¸ãã³ãã«</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>大ãã³ãã«</translation>
+ <source>Seed</source>
+ <translation>ä¹±æ°ã·ã¼ã</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>åæµ®ã島</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>ä¸æµ®ã島</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>大浮ã島</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>ä¹±æ°ã·ã¼ã</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -295,7 +545,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 ããã¯åå </translation>
+ <translation type="obsolete">%1 *** %2 ããã¯åå </translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +571,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">ãã¹ã¯ã¼ã</translation>
+ <source>Login</source>
+ <translation>ãã°ã¤ã³</translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -333,6 +598,28 @@ Please pick another nickname:</source>
</message>
<message>
<source>Upload</source>
+ <translation>ã¢ãããã¼ã</translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -344,7 +631,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +656,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +698,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>ä¸è¬</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IPï¼ããã¯ãã¼ã </translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +739,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -413,11 +761,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Load</source>
- <translation type="unfinished">ãã¼ã</translation>
+ <translation>ãã¼ã</translation>
</message>
<message>
<source>Save</source>
- <translation type="unfinished"></translation>
+ <translation>ã»ã¼ã</translation>
</message>
<message>
<source>Load drawn map</source>
@@ -447,8 +795,40 @@ Please pick another nickname:</source>
<translation>ä¸è¬</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>é«ç´</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -493,450 +873,313 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Save</source>
+ <translation type="unfinished">ã»ã¼ã</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>ã¹ã¿ã¼ã</translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">ã³ã³ããã¼ã«</translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>ã¹ã¿ã¼ã</translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Update</source>
+ <translation>æ´æ°</translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New team</source>
+ <translation>ãã¼ã ä½æ</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Edit team</source>
+ <translation>ãã¼ã ç·¨é</translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation>é«ç´</translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <source>Start</source>
- <translation>ã¹ã¿ã¼ã</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>ã³ã³ããã¼ã«</translation>
- </message>
<message>
- <source>DLC</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
- <message>
- <source>New team</source>
- <translation>ãã¼ã ä½æ</translation>
- </message>
- <message>
- <source>Edit team</source>
- <translation>ãã¼ã ç·¨é</translation>
- </message>
<message>
- <source>Delete team</source>
- <translation type="unfinished"></translation>
+ <source>Game</source>
+ <translation>ã²ã¼ã </translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
- <translation type="unfinished"></translation>
+ <source>Teams</source>
+ <translation type="unfinished">ãã¼ã </translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">ä¸è¬</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">é«ç´</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -955,11 +1198,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>ä½æ</translation>
+ <translation type="obsolete">ä½æ</translation>
</message>
<message>
<source>Join</source>
- <translation>æ¥ç¶</translation>
+ <translation type="obsolete">æ¥ç¶</translation>
</message>
<message>
<source>Admin features</source>
@@ -967,7 +1210,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation type="unfinished">ã«ã¼ã åï¼</translation>
+ <translation type="obsolete">ã«ã¼ã åï¼</translation>
</message>
<message>
<source>Rules:</source>
@@ -977,19 +1220,35 @@ Please pick another nickname:</source>
<source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>Search:</source>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1137,18 +1396,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1157,26 +1408,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">ãã¼ã</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1221,19 +1460,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1248,10 +1489,6 @@ Please pick another nickname:</source>
<translation>æ
å ±</translation>
</message>
<message>
- <source>Start</source>
- <translation>ã¹ã¿ã¼ã</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Restrict Joins</translation>
</message>
@@ -1285,30 +1522,30 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">æ´æ°</translation>
+ <translation type="obsolete">æ´æ°</translation>
</message>
-</context>
-<context>
- <name>QCheckBox</name>
<message>
- <source>Check for updates at startup</source>
+ <source>Restrict Unregistered Players Join</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Fullscreen</source>
- <translation>ãã«ã¹ã¯ãªã¼ã³</translation>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>ãã«ã¹ã¯ãªã¼ã³ãã¡ãã¥ã¼</translation>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QCheckBox</name>
<message>
- <source>Enable sound</source>
- <translation>ãµã¦ã³ã</translation>
+ <source>Check for updates at startup</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable music</source>
- <translation>é³æ¥½</translation>
+ <source>Fullscreen</source>
+ <translation>ãã«ã¹ã¯ãªã¼ã³</translation>
</message>
<message>
<source>Show FPS</source>
@@ -1327,18 +1564,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1358,51 +1583,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>çæå°å³...</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>人é</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>ã¬ãã«</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>人é</translation>
+ </message>
+ <message>
+ <source>Level</source>
+ <translation>ã¬ãã«</translation>
</message>
<message>
- <source>In lobby</source>
+ <source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In progress</source>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1434,15 +1663,11 @@ Please pick another nickname:</source>
<translation>ç·ï¼èµ¤</translation>
</message>
<message>
- <source>Side-by-side</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Top-Bottom</source>
+ <source>Side-by-side</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
+ <source>Top-Bottom</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1481,18 +1706,6 @@ Please pick another nickname:</source>
<translation>å°å ´</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>ãã¼ binds</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>ãã¼ã </translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>ãªãã£ãª/ç»é¢ è¨å®</translation>
- </message>
- <message>
<source>Net game</source>
<translation>ãããã²ã¼ã </translation>
</message>
@@ -1513,26 +1726,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
@@ -1540,10 +1733,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1557,27 +1746,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>ãã¼ã·ã§ã³</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>éçºè
:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>ã¢ã¼ã:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>é³æ¥½ã»é³:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>é訳è
:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>ç¹å¥æè¬:</translation>
+ <translation type="obsolete">ãã¼ã·ã§ã³</translation>
</message>
<message>
<source>Weapons</source>
@@ -1636,10 +1805,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game scheme</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation type="unfinished"></translation>
</message>
@@ -1676,10 +1841,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1720,10 +1881,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1754,16 +1911,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Nickname</source>
- <translation type="unfinished"></translation>
+ <translation>ããã¯ãã¼ã </translation>
</message>
<message>
<source>Format</source>
@@ -1785,6 +1938,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">ãã«ã¹ã¯ãªã¼ã³</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1807,6 +2004,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1823,10 +2024,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1873,47 +2070,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">ãã©ã«ãã¼%1ä½ææå¦</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ãã©ã«ãã¼%1ä½ææå¦</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">ãµã¼ãã¼%1ã®èµ·åã¯åºæ¥ãªãã£ã</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ãµã¼ãã¼%1ã®èµ·åã¯åºæ¥ãªãã£ã</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2030,15 +2192,41 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2097,26 +2285,10 @@ Do you still want to join the room?</source>
<translation>ãã¼ã</translation>
</message>
<message>
- <source>Setup</source>
- <translation>è¨å®</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2140,181 +2312,193 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>RoomsListModel</name>
<message>
- <source>In progress</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Room Name</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
+ <source>Delete this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
+ <source>Upload this video to your Youtube account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">å°å³</translation>
- </message>
- <message>
- <source>Rules</source>
+ <source>Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">æ¦å¨</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
+ <source>Invite your friends to your server in just 1 click!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
+ <source>Enter a name for your room.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
</message>
<message>
- <source>Ammo in boxes</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
+ <source>In progress</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
- <translation type="unfinished">ä½æ</translation>
+ <source>Room Name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
- <translation type="unfinished">模å</translation>
+ <source>C</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
+ <source>T</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Karma</source>
+ <source>Owner</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Artillery</source>
- <translation type="unfinished"></translation>
+ <source>Map</source>
+ <translation type="unfinished">å°å³</translation>
</message>
<message>
- <source>Fort Mode</source>
+ <source>Rules</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation type="unfinished"></translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Solid Land</source>
+ <source>Random Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Border</source>
+ <source>Random Maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Low Gravity</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
+ <source>The map seed is the basis for all random values generated by the game.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
</message>
<message>
- <source>Random Order</source>
+ <source>Set seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
+ <source>Close</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
+ <source>Weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
+ <source>Probabilities</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Girders</source>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
+ <source>new</source>
+ <translation type="unfinished">ä½æ</translation>
</message>
<message>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
+ <source>copy of</source>
+ <translation type="unfinished">模å</translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation>ãã£ã³ã»ã«</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2449,12 +2633,6 @@ Do you still want to join the room?</source>
<translation>é²ç»</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>éé¼
-æ
å ±</translation>
- </message>
- <message>
<source>quit</source>
<translation>éåº</translation>
</message>
@@ -2490,33 +2668,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation type="unfinished">åºæ¬ã³ã³ããã¼ã«</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation type="unfinished">æ¦å¨ã³ã³ããã¼ã«</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation type="unfinished">ã«ã¡ã©ã¨ã«ã¼ã½ã«ã®ã³ã³ããã¼ã«</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation type="unfinished">ãã®ä»</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>âãºããããããã¨ãããï¼</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>ç©´ã¨é害ãè·³ãã§è¶
ããï¼</translation>
</message>
@@ -2580,6 +2758,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_ko.ts b/share/hedgewars/Data/Locale/hedgewars_ko.ts
index 3d63535..009cff7 100644
--- a/share/hedgewars/Data/Locale/hedgewars_ko.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_ko.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="ko">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -43,11 +139,63 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -101,7 +249,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -138,27 +294,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>%1's Team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -176,75 +378,127 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
+ <source>All</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Themes</source>
+ <source>Small</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Filter</source>
+ <source>Medium</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All</source>
+ <source>Large</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small</source>
+ <source>Cavern</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium</source>
+ <source>Wacky</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large</source>
+ <source>Small tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cavern</source>
+ <source>Medium tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wacky</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small tunnels</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium tunnels</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Randomly generated</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Random maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -290,10 +544,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has joined</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>%1 *** %2 has left (%3)</source>
<translation type="unfinished"></translation>
</message>
@@ -317,7 +567,22 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -333,606 +598,580 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>KB</name>
+ <name>HatButton</name>
<message>
- <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
+ <source>Change hat (%1)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>HatPrompt</name>
<message>
- <source>Duration: %1m %2s
-</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video: %1x%2, </source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 fps, </source>
+ <source>Use selected hat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Audio: </source>
+ <source>Search for a hat:</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageAdmin</name>
+ <name>KB</name>
<message>
- <source>Clear Accounts Cache</source>
+ <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>KeyBinder</name>
<message>
- <source>Fetch data</source>
+ <source>Category</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
- <source>Server message for latest version:</source>
+ <source>Duration: %1m %2s
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Server message for previous versions:</source>
+ <source>Video: %1x%2, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Latest version protocol number:</source>
+ <source>%1 fps, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>MOTD preview:</source>
+ <source>Audio: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set data</source>
+ <source>unknown</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageConnecting</name>
+ <name>MapModel</name>
<message>
- <source>Connecting...</source>
+ <source>No description available.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageDrawMap</name>
+ <name>PageAdmin</name>
<message>
- <source>Undo</source>
+ <source>Clear Accounts Cache</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Fetch data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
+ <source>Server message for latest version:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save</source>
+ <source>Server message for previous versions:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load drawn map</source>
+ <source>Latest version protocol number:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save drawn map</source>
+ <source>MOTD preview:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Drawn Maps</source>
+ <source>Set data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All files</source>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Eraser</source>
+ <source>Bans</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageEditTeam</name>
<message>
- <source>General</source>
+ <source>IP/Nick</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Advanced</source>
+ <source>Expiration</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageGameStats</name>
<message>
- <source>Details</source>
+ <source>Reason</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Health graph</source>
+ <source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ranking</source>
+ <source>Add</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
+ <source>Remove</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>(%1 kill)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
</context>
<context>
- <name>PageInGame</name>
+ <name>PageConnecting</name>
<message>
- <source>In game...</source>
+ <source>Connecting...</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageInfo</name>
+ <name>PageDataDownload</name>
<message>
- <source>Open the snapshot folder</source>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>PageMain</name>
+ <name>PageDrawMap</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
+ <source>Undo</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
+ <source>Clear</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
+ <source>Load</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
+ <source>Load drawn map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
+ <source>Save drawn map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
+ <source>Drawn Maps</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
+ <source>All files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
+ <source>Eraser</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageEditTeam</name>
<message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
+ <source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
+ <source>Select an action to choose a custom key bind for this team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
+ <source>Use my default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
+ <source>Custom Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
+ <source>Hat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
+ <source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
+ <source>This hedgehog's name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
+ <source>Randomize this hedgehog's name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>Random Team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageGameStats</name>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
+ <source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <source>Health graph</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
+ <source>Ranking</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
+ <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>Downloadable Content</source>
+ <source>New team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Edit team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Advanced</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <source>Start</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <source>Control</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>DLC</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit team</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete team</source>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
+ <source>Teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Advanced</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Frontend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -950,42 +1189,46 @@ Please pick another nickname:</source>
<context>
<name>PageRoomsList</name>
<message>
- <source>Create</source>
+ <source>Admin features</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join</source>
+ <source>Rules:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Admin features</source>
+ <source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>Room Name:</source>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules:</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons:</source>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
+ <source>Room state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Clear filters</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1133,18 +1376,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1153,26 +1388,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1217,19 +1440,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1244,10 +1469,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Start</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation type="unfinished"></translation>
</message>
@@ -1280,30 +1501,26 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QCheckBox</name>
- <message>
- <source>Check for updates at startup</source>
+ <source>Restrict Unregistered Players Join</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Fullscreen</source>
+ <source>Show games in lobby</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend fullscreen</source>
+ <source>Show games in-progress</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QCheckBox</name>
<message>
- <source>Enable sound</source>
+ <source>Check for updates at startup</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable music</source>
+ <source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1323,18 +1540,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1354,51 +1559,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
+ <source>In-game sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Community</source>
+ <source>Human</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Any</source>
+ <source>Level</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In lobby</source>
+ <source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In progress</source>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1438,10 +1647,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1477,18 +1682,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Key binds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Teams</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Net game</source>
<translation type="unfinished"></translation>
</message>
@@ -1509,26 +1702,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
@@ -1536,10 +1709,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1552,30 +1721,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Version</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Art:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Weapons</source>
<translation type="unfinished"></translation>
</message>
@@ -1632,10 +1777,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game scheme</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation type="unfinished"></translation>
</message>
@@ -1672,10 +1813,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1716,10 +1853,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1750,10 +1883,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,134 +1910,135 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QLineEdit</name>
<message>
- <source>unnamed</source>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hedgehog %1</source>
+ <source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>anonymous</source>
+ <source>Fullscreen Resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMainWindow</name>
<message>
- <source>Hedgewars %1</source>
+ <source>Windowed Resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMessageBox</name>
<message>
- <source>Connection to server is lost</source>
+ <source>Your Email</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
+ <source>Summary</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>File association failed.</source>
+ <source>Send system information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
+ <source>Type the security code:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error while authenticating at google.com:
-</source>
+ <source>Revision</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Login or password is incorrect</source>
+ <source>This program is distributed under the %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error while sending metadata to youtube.com:
-</source>
+ <source>This setting will be effective at next restart.</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QLineEdit</name>
<message>
- <source>Teams - Are you sure?</source>
+ <source>unnamed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Do you really want to delete the team '%1'?</source>
+ <source>hedgehog %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot delete default scheme '%1'!</source>
+ <source>anonymous</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMainWindow</name>
<message>
- <source>Please select a record from the list</source>
+ <source>Hedgewars %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start server</source>
+ <source>-r%1 (%2)</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMessageBox</name>
<message>
- <source>Hedgewars - Error</source>
+ <source>Connection to server is lost</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars - Success</source>
+ <source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All file associations have been set</source>
+ <source>File association failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while authenticating at google.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
+ <source>Login or password is incorrect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error during authentication at google.com</source>
+ <source>Error while sending metadata to youtube.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
+ <source>Teams - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Main - Error</source>
+ <source>Do you really want to delete the team '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot create directory %1</source>
+ <source>Cannot delete default scheme '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
+ <source>Please select a record from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>TCP - Error</source>
+ <source>Unable to start server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server: %1.</source>
+ <source>Hedgewars - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to run engine at </source>
+ <source>Hedgewars - Success</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error code: %1</source>
+ <source>All file associations have been set</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2026,15 +2156,41 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2093,26 +2249,10 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Setup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ready</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2136,181 +2276,193 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>RoomsListModel</name>
- <message>
- <source>In progress</source>
- <translation type="unfinished"></translation>
- </message>
<message>
- <source>Room Name</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
+ <source>Delete this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
+ <source>Upload this video to your Youtube account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
+ <source>Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
+ <source>Set the default server port for Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
+ <source>Invite your friends to your server in just 1 click!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
+ <source>Enter a name for your room.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ammo in boxes</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
+ <source>In progress</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
+ <source>Room Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
+ <source>C</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
+ <source>T</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Karma</source>
+ <source>Owner</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Artillery</source>
+ <source>Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Fort Mode</source>
+ <source>Rules</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Divide Teams</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Solid Land</source>
+ <source>Random Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Border</source>
+ <source>Random Maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Low Gravity</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
+ <source>The map seed is the basis for all random values generated by the game.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Order</source>
+ <source>Set seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
+ <source>Close</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
+ <source>Weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
+ <source>Probabilities</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Girders</source>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>AI Survival Mode</source>
+ <source>new</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Health</source>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2445,11 +2597,6 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>quit</source>
<translation type="unfinished"></translation>
</message>
@@ -2485,33 +2632,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
+ <source>Movement</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Camera and cursor controls</source>
+ <source>Camera</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished"></translation>
</message>
@@ -2575,6 +2722,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_lt.ts b/share/hedgewars/Data/Locale/hedgewars_lt.ts
index 4411760..51e62d2 100644
--- a/share/hedgewars/Data/Locale/hedgewars_lt.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_lt.ts
@@ -2,9 +2,17 @@
<!DOCTYPE TS>
<TS version="2.0" language="lt_LT">
<context>
+ <name>About</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="93"/>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/AbstractPage.cpp" line="51"/>
+ <location filename="../../../../QTfrontend/ui/page/AbstractPage.cpp" line="55"/>
<source>Go back</source>
<translation type="unfinished"></translation>
</message>
@@ -23,6 +31,116 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="35"/>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>IP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="39"/>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="40"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="41"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="42"/>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="48"/>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="49"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="77"/>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="151"/>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="91"/>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="90"/>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="92"/>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="93"/>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="124"/>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="150"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="178"/>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<location filename="../../../../QTfrontend/ui/widget/FreqSpinBox.cpp" line="36"/>
@@ -42,23 +160,99 @@
<context>
<name>GameCFGWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="54"/>
- <source>Game Options</source>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="67"/>
+ <source>Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="79"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="68"/>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="132"/>
<source>Edit schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="94"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="147"/>
<source>Edit weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="102"/>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="155"/>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="25"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="26"/>
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="27"/>
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="28"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="29"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="30"/>
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="31"/>
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="34"/>
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/HWApplication.cpp" line="92"/>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="102"/>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="253"/>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -73,142 +267,209 @@
<context>
<name>HWChatWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="627"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="502"/>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="523"/>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="525"/>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="652"/>
<source>%1 has been removed from your ignore list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="637"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="662"/>
<source>%1 has been added to your ignore list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="667"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="692"/>
<source>%1 has been removed from your friends list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="676"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="701"/>
<source>%1 has been added to your friends list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="742"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="767"/>
<source>Stylesheet imported from %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="743"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="768"/>
<source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="751"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="776"/>
<source>Couldn't read %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="759"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="784"/>
<source>StyleSheet discarded</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="784"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="808"/>
<source>StyleSheet saved to %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="787"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="811"/>
<source>Failed to save StyleSheet to %1</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="807"/>
- <source>%1 is not a valid command!</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>HWForm</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="463"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="465"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="478"/>
<source>DefaultTeam</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="569"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="636"/>
<source>Game aborted</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="981"/>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
+ <source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="985"/>
- <source>No password supplied.</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1011"/>
- <source>Nickname</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1015"/>
- <source>No nickname supplied.</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="482"/>
+ <source>%1's Team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1011"/>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1075"/>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1430"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1717"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1076"/>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1104"/>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1109"/>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1173"/>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1696"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2015"/>
<source>Cannot save record to file %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1660"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1945"/>
<source>Hedgewars Demo File</source>
<comment>File Types</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1661"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1946"/>
<source>Hedgewars Save File</source>
<comment>File Types</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1709"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
<source>Demo name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1709"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
<source>Demo name:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2075"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
<message>
- <location filename="../../../../QTfrontend/game.cpp" line="350"/>
- <location filename="../../../../QTfrontend/net/recorder.cpp" line="118"/>
+ <location filename="../../../../QTfrontend/game.cpp" line="386"/>
+ <location filename="../../../../QTfrontend/net/recorder.cpp" line="112"/>
<source>en.txt</source>
<translation>lt.txt</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/game.cpp" line="361"/>
+ <location filename="../../../../QTfrontend/game.cpp" line="427"/>
<source>Cannot open demofile %1</source>
<translation type="unfinished"></translation>
</message>
@@ -216,93 +477,159 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="82"/>
- <source>Map</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="94"/>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="97"/>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="98"/>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="99"/>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="100"/>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="101"/>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="111"/>
+ <source>Random</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="135"/>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="188"/>
+ <source>Load map drawing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="85"/>
- <source>Filter</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="194"/>
+ <source>Edit map drawing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="89"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="207"/>
<source>All</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="90"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="208"/>
<source>Small</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="91"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="209"/>
<source>Medium</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="92"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="210"/>
<source>Large</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="93"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="211"/>
<source>Cavern</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="94"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="212"/>
<source>Wacky</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="99"/>
- <source>Type</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="222"/>
+ <source>Large tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="103"/>
- <source>Small tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="223"/>
+ <source>Small islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="104"/>
- <source>Medium tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="224"/>
+ <source>Medium islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="105"/>
- <source>Large tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="225"/>
+ <source>Large islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="106"/>
- <source>Small floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="710"/>
+ <source>Map size:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="107"/>
- <source>Medium floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="717"/>
+ <source>Maze style:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="108"/>
- <source>Large floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="730"/>
+ <source>Mission:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="118"/>
- <source>Themes</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="740"/>
+ <source>Map:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="162"/>
- <source>Seed</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="804"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="935"/>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>All files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="555"/>
- <source>Set</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="220"/>
+ <source>Small tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="221"/>
+ <source>Medium tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="126"/>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -327,65 +654,58 @@ Please pick another nickname:</source>
<context>
<name>HWNewNet</name>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="75"/>
<source>User quit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="212"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="218"/>
<source>Remote host has closed connection</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="215"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="221"/>
<source>The host was not found. Please check the host name and port settings.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="218"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="224"/>
<source>Connection refused</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="276"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="283"/>
<source>The server is too old. Disconnecting now.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="648"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="707"/>
<source>Room destroyed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="447"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="484"/>
<source>You got kicked</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="597"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="724"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="651"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="782"/>
<source>%1 *** %2 has joined the room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="471"/>
- <source>%1 *** %2 has joined</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="518"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="739"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="797"/>
<source>%1 *** %2 has left</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="520"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="741"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="799"/>
<source>%1 *** %2 has left (%3)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1285"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
<source>Quit reason: </source>
<translation type="unfinished"></translation>
</message>
@@ -394,7 +714,25 @@ Please pick another nickname:</source>
<name>HWPasswordDialog</name>
<message>
<location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="30"/>
- <source>Password</source>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="35"/>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="39"/>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="47"/>
+ <source>Password:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -412,6 +750,32 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatbutton.cpp" line="40"/>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="83"/>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="119"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="123"/>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<location filename="../../../../QTfrontend/KB.h" line="28"/>
@@ -420,66 +784,127 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="282"/>
+ <location filename="../../../../QTfrontend/ui/widget/keybinder.cpp" line="100"/>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="281"/>
<source>Duration: %1m %2s
</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="294"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="293"/>
<source>Video: %1x%2, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="298"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="297"/>
<source>%1 fps, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="302"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="301"/>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="305"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/MapModel.cpp" line="193"/>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="34"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="40"/>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="41"/>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="48"/>
<source>Fetch data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="52"/>
<source>Server message for latest version:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="46"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="60"/>
<source>Server message for previous versions:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="54"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="68"/>
<source>Latest version protocol number:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="62"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="76"/>
<source>MOTD preview:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="85"/>
<source>Clear Accounts Cache</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="74"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="88"/>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="97"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="98"/>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="99"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="108"/>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="109"/>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="110"/>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -490,6 +915,19 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="66"/>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="126"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="32"/>
@@ -543,12 +981,52 @@ Please pick another nickname:</source>
<name>PageEditTeam</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="47"/>
<source>General</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="46"/>
- <source>Advanced</source>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="48"/>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="66"/>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="67"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="78"/>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="84"/>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="88"/>
+ <source>Random Team</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -570,12 +1048,22 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="173"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="113"/>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="118"/>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="193"/>
<source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="181"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="201"/>
<source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -584,7 +1072,7 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="188"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="208"/>
<source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -593,7 +1081,7 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="272"/>
<source>(%1 kill)</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -602,7 +1090,7 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="263"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="283"/>
<source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -611,7 +1099,7 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="271"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="291"/>
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -620,7 +1108,7 @@ Please pick another nickname:</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="279"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="299"/>
<source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -649,510 +1137,337 @@ Please pick another nickname:</source>
<name>PageMain</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="45"/>
- <source>Local Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="46"/>
<source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="50"/>
- <source>Network Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="51"/>
<source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="58"/>
- <source>Read about who is behind the Hedgewars Project</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="63"/>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="64"/>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="67"/>
- <source>Downloadable Content</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="65"/>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="69"/>
- <source>Access the user created content downloadable from our website</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="89"/>
- <source>Exit game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="93"/>
- <source>Manage videos recorded from game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="97"/>
- <source>Edit game preferences</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="128"/>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="129"/>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="130"/>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="131"/>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="132"/>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="133"/>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="134"/>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="135"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="136"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="137"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="138"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="139"/>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="140"/>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="141"/>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="142"/>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="143"/>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="144"/>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="145"/>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="146"/>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="147"/>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="70"/>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="148"/>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="149"/>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="150"/>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="151"/>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="152"/>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="77"/>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="153"/>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="80"/>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="154"/>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="82"/>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="155"/>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="85"/>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="156"/>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="87"/>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="157"/>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="107"/>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="158"/>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="111"/>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="159"/>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="115"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="160"/>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="50"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="161"/>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="62"/>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="162"/>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="62"/>
+ <source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="163"/>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="80"/>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="164"/>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="116"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="165"/>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="141"/>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="166"/>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="87"/>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="167"/>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="138"/>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="168"/>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="169"/>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="170"/>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="171"/>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="96"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="239"/>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="175"/>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="99"/>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="176"/>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="102"/>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="178"/>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="104"/>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="180"/>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="108"/>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="182"/>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="112"/>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="55"/>
- <source>Start</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="115"/>
+ <source>Advanced</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="65"/>
- <source>DLC</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="128"/>
+ <source>Teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="66"/>
- <source>Downloadable Content</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="138"/>
+ <source>New team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="87"/>
- <source>Control</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="146"/>
+ <source>Edit team</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="35"/>
- <source>LAN game</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="154"/>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="36"/>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="162"/>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="37"/>
- <source>Official server</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="169"/>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="38"/>
- <source>Join hundreds of players online!</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="178"/>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="50"/>
- <source>General</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="185"/>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="51"/>
- <source>Advanced</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="192"/>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="77"/>
- <source>New team</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="200"/>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="85"/>
- <source>Edit team</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="209"/>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="93"/>
- <source>Delete team</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="216"/>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="101"/>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="223"/>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="127"/>
- <source>New scheme</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="371"/>
+ <source>Frontend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="134"/>
- <source>Edit scheme</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="388"/>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="141"/>
- <source>Delete scheme</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="418"/>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="155"/>
- <source>New weapon set</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="431"/>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="162"/>
- <source>Edit weapon set</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="469"/>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="169"/>
- <source>Delete weapon set</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="492"/>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="405"/>
- <source>Reset to default colors</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="518"/>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="454"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="524"/>
<source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="455"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="525"/>
<source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="456"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="526"/>
<source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="457"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="527"/>
<source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="468"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="540"/>
<source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="469"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="541"/>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="470"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="542"/>
<source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="471"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="543"/>
<source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="578"/>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="624"/>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="637"/>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="651"/>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -1170,47 +1485,52 @@ Please pick another nickname:</source>
<context>
<name>PageRoomsList</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="44"/>
- <source>Room Name:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="64"/>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="71"/>
- <source>Rules:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="91"/>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="79"/>
- <source>Weapons:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="95"/>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="87"/>
- <source>Search:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="153"/>
+ <source>Room state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="102"/>
- <source>Create</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="177"/>
+ <source>Rules:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="103"/>
- <source>Join</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="191"/>
+ <source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="104"/>
- <source>Clear</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="202"/>
+ <source>Clear filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="129"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="220"/>
<source>Admin features</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="222"/>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="492"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="609"/>
<source>%1 players online</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -1222,152 +1542,152 @@ Please pick another nickname:</source>
<context>
<name>PageScheme</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="72"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="71"/>
<source>Defend your fort and destroy the opponents, two team colours max!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="77"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="75"/>
<source>Teams will start on opposite sides of the terrain, two team colours max!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="82"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="79"/>
<source>Land can not be destroyed!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="87"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="83"/>
<source>Add an indestructible border around the terrain</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="92"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="87"/>
<source>Lower gravity</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="97"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="91"/>
<source>Assisted aiming with laser sight</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="102"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="95"/>
<source>All hogs have a personal forcefield</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="107"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="99"/>
<source>All (living) hedgehogs are fully restored at the end of turn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="112"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="103"/>
<source>Gain 80% of the damage you do back in health</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="117"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="107"/>
<source>Share your opponents pain, share their damage</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="122"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="111"/>
<source>Your hogs are unable to move, put your artillery skills to the test</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="127"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="115"/>
<source>Order of play is random instead of in room order.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="132"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="119"/>
<source>Play with a King. If he dies, your side dies.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="137"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="123"/>
<source>Take turns placing your hedgehogs before the start of play.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="142"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="127"/>
<source>Ammo is shared between all teams that share a colour.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="147"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="131"/>
<source>Disable girders when generating random maps.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="152"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="135"/>
<source>Disable land objects when generating random maps.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="157"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="139"/>
<source>AI respawns on death.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="162"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="143"/>
<source>Attacking does not end your turn.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="167"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="147"/>
<source>Weapons are reset to starting values each turn.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="172"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="151"/>
<source>Each hedgehog has its own ammo. It does not share with the team.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="177"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="155"/>
<source>You will not have to worry about wind anymore.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="182"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="159"/>
<source>Wind will affect almost everything.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="187"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="163"/>
<source>Teams in each clan take successive turns sharing their turn time.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="192"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="167"/>
<source>Add an indestructible border along the bottom</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="350"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="325"/>
<source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="351"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="326"/>
<source>Seconds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="427"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="402"/>
<source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="428"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="403"/>
<source>New</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="429"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="404"/>
<source>Delete</source>
<translation type="unfinished"></translation>
</message>
@@ -1399,57 +1719,31 @@ Please pick another nickname:</source>
<name>PageSinglePlayer</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="39"/>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="40"/>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="43"/>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="42"/>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="49"/>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="50"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="47"/>
<source>Campaign Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="54"/>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="51"/>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="66"/>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="67"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="62"/>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="70"/>
- <source>Load</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="65"/>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1467,12 +1761,12 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="211"/>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="206"/>
<source>No description available</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="219"/>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="214"/>
<source>Select a mission!</source>
<translation type="unfinished"></translation>
</message>
@@ -1480,17 +1774,17 @@ Please pick another nickname:</source>
<context>
<name>PageVideos</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="233"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="121"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="234"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="122"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="492"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="263"/>
<source>%1 bytes</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -1499,27 +1793,29 @@ Please pick another nickname:</source>
</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="736"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="507"/>
<source>(in progress...)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="740"/>
- <source>Date: </source>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="511"/>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="741"/>
- <source>Size: </source>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="512"/>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="955"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="731"/>
<source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="957"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="733"/>
<source>uploading</source>
<translation type="unfinished"></translation>
</message>
@@ -1527,133 +1823,145 @@ Please pick another nickname:</source>
<context>
<name>QAction</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="248"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="253"/>
<source>Info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="257"/>
<source>Kick</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="256"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="261"/>
<source>Ban</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="260"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="265"/>
<source>Follow</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="264"/>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="865"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="269"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="885"/>
<source>Ignore</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="268"/>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="877"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="273"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="897"/>
<source>Add friend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="860"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="880"/>
<source>Unignore</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="872"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="892"/>
<source>Remove friend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="82"/>
- <source>Update</source>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="169"/>
+ <source>Restrict Joins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="112"/>
- <source>Restrict Joins</source>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="171"/>
+ <source>Restrict Team Additions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="114"/>
- <source>Restrict Team Additions</source>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="173"/>
+ <source>Restrict Unregistered Players Join</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="90"/>
- <source>Start</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="162"/>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="165"/>
+ <source>Show games in-progress</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QCheckBox</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="431"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="366"/>
<source>Show ammo menu tooltips</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="365"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="360"/>
<source>Alternative damage show</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="436"/>
- <source>Append date and time to record file name</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="383"/>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="241"/>
- <source>Check for updates at startup</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="456"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="473"/>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="457"/>
+ <source>In-game sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="261"/>
- <source>Frontend fullscreen</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="463"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="478"/>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="265"/>
- <source>Frontend effects</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="464"/>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="269"/>
- <source>Enable frontend sounds</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="474"/>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="273"/>
- <source>Enable frontend music</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="479"/>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="291"/>
- <source>Fullscreen</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="610"/>
+ <source>Append date and time to record file name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="349"/>
- <source>Enable sound</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="630"/>
+ <source>Check for updates at startup</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="353"/>
- <source>Enable music</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="377"/>
+ <source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="424"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="349"/>
<source>Show FPS</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="43"/>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="231"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="509"/>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1668,12 +1976,12 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="151"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="691"/>
<source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="192"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="740"/>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
@@ -1681,206 +1989,130 @@ Please pick another nickname:</source>
<context>
<name>QComboBox</name>
<message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="116"/>
- <source>Mission</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="50"/>
- <source>generated map...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="52"/>
- <source>generated maze...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="54"/>
- <source>hand drawn map...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="115"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="122"/>
<source>Human</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="119"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="126"/>
<source>Level</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="323"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="284"/>
<source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="199"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="590"/>
<source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="312"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="313"/>
<source>Disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="313"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="314"/>
<source>Red/Cyan</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="314"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="315"/>
<source>Cyan/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="315"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="316"/>
<source>Red/Blue</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="316"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="317"/>
<source>Blue/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="317"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="318"/>
<source>Red/Green</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="318"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="319"/>
<source>Green/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="319"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="326"/>
<source>Side-by-side</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="320"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="327"/>
<source>Top-Bottom</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="321"/>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="322"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="320"/>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="323"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="321"/>
<source>Cyan/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="324"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="322"/>
<source>Red/Blue grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="323"/>
<source>Blue/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="326"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="324"/>
<source>Red/Green grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="327"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="325"/>
<source>Green/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="111"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="112"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="176"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="211"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="286"/>
<source>Any</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="113"/>
- <source>In lobby</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="114"/>
- <source>In progress</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QGroupBox</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="60"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="61"/>
<source>Team Members</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="89"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="96"/>
<source>Team Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="143"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="150"/>
<source>Fort</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="162"/>
- <source>Key binds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="40"/>
<source>Net game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="69"/>
- <source>Teams</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="116"/>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="184"/>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="253"/>
- <source>Audio/Graphic options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="381"/>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="412"/>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="448"/>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="48"/>
<source>Game Modifiers</source>
<translation type="unfinished"></translation>
@@ -1891,22 +2123,17 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="253"/>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="259"/>
<source>Playing teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="120"/>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="230"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="118"/>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="265"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="154"/>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1914,129 +2141,102 @@ Please pick another nickname:</source>
<context>
<name>QLabel</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="53"/>
- <source>Version</source>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="71"/>
+ <source>Revision</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="55"/>
- <source>This program is distributed under the GNU General Public License v2</source>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="73"/>
+ <source>This program is distributed under the %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="70"/>
- <source>Developers:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="90"/>
- <source>Art:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="108"/>
- <source>Sounds:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="118"/>
- <source>Translations:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="142"/>
- <source>Special thanks:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="108"/>
<source>Style</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="74"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="127"/>
<source>Scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="148"/>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="86"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="139"/>
<source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="33"/>
<source>Host:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="36"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="37"/>
<source>Port:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="93"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="100"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="96"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="103"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="99"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="106"/>
<source>Grave</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="102"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="109"/>
<source>Flag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="105"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="112"/>
<source>Voice</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="116"/>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="139"/>
<source>Tip: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="120"/>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="137"/>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="51"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="56"/>
<source>Server name:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="58"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="63"/>
<source>Server port:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="120"/>
- <source>Game scheme</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="584"/>
+ <source>Locale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="189"/>
- <source>Locale</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="498"/>
+ <source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="221"/>
- <source>Nickname</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="599"/>
+ <source>This setting will be effective at next restart.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="283"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="172"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="716"/>
<source>Resolution</source>
<translation type="unfinished"></translation>
</message>
@@ -2046,97 +2246,112 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="308"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="250"/>
+ <source>Fullscreen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="255"/>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="265"/>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="309"/>
<source>Stereo rendering</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="340"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="439"/>
<source>Initial sound volume</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="418"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="340"/>
<source>FPS limit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="200"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="175"/>
<source>Damage Modifier</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="214"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="189"/>
<source>Turn Time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="228"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="203"/>
<source>Initial Health</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="242"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="217"/>
<source>Sudden Death Timeout</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="256"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="231"/>
<source>Sudden Death Water Rise</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="270"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="245"/>
<source>Sudden Death Health Decrease</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="284"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="259"/>
<source>% Rope Length</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="298"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="273"/>
<source>Crate Drops</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="311"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="286"/>
<source>% Health Crates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="300"/>
<source>Health in Crates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="339"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="314"/>
<source>Mines Time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="355"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="330"/>
<source>Mines</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="369"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="344"/>
<source>% Dud Mines</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="383"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="358"/>
<source>Explosives</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="397"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="372"/>
<source>% Get Away Time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="411"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="386"/>
<source>Scheme Name:</source>
<translation type="unfinished"></translation>
</message>
@@ -2178,37 +2393,52 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagefeedback.cpp" line="45"/>
- <source>Summary </source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="103"/>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="111"/>
+ <source>Summary</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagefeedback.cpp" line="52"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="121"/>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="136"/>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="125"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="164"/>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="660"/>
<source>Format</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="142"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="680"/>
<source>Audio codec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="163"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="705"/>
<source>Video codec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="197"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="746"/>
<source>Framerate</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="208"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="760"/>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
@@ -2216,18 +2446,18 @@ Do you really want to quit?</source>
<context>
<name>QLineEdit</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="882"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="952"/>
<source>unnamed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/team.cpp" line="42"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="335"/>
+ <location filename="../../../../QTfrontend/team.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="296"/>
<source>hedgehog %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="226"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="503"/>
<source>anonymous</source>
<translation type="unfinished"></translation>
</message>
@@ -2235,95 +2465,115 @@ Do you really want to quit?</source>
<context>
<name>QMainWindow</name>
<message>
+ <location filename="../../../../QTfrontend/ui_hwform.cpp" line="57"/>
+ <source>Hedgewars %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../../../QTfrontend/ui_hwform.cpp" line="59"/>
- <source>Hedgewars %1</source>
+ <source>-r%1 (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QMessageBox</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="904"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="388"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="346"/>
<source>Teams - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="905"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="389"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="347"/>
<source>Do you really want to delete the team '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="921"/>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="525"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="981"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="500"/>
<source>Cannot delete default scheme '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="947"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1007"/>
<source>Please select a record from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1241"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1102"/>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1498"/>
<source>Unable to start server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1285"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
<source>Connection to server is lost</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1392"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2082"/>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2083"/>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="352"/>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="24"/>
<source>Hedgewars - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1692"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1783"/>
- <source>Hedgewars - Success</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="362"/>
+ <source>System Information Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1693"/>
- <source>All file associations have been set</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="377"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="388"/>
+ <source>Failed to generate captcha</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1784"/>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="405"/>
+ <source>Failed to download captcha</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1796"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1809"/>
- <source>Error during authentication at google.com</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="469"/>
+ <source>Please fill out all fields. Email is optional.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1812"/>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1985"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="439"/>
+ <source>Hedgewars - Success</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1698"/>
- <source>File association failed.</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1986"/>
+ <source>All file associations have been set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1734"/>
- <source>Please fill out all fields</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1991"/>
+ <source>File association failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="276"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="367"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="277"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="368"/>
<source>Cannot use the ammo '%1'!</source>
<translation type="unfinished"></translation>
</message>
@@ -2351,59 +2601,18 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/main.cpp" line="96"/>
- <location filename="../../../../QTfrontend/main.cpp" line="212"/>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/main.cpp" line="97"/>
- <source>Cannot create directory %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/main.cpp" line="213"/>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="50"/>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="122"/>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="51"/>
- <source>Unable to start the server: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="123"/>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="124"/>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="113"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="162"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="118"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="244"/>
<source>Netgame - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="114"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="119"/>
<source>Please select a server from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="163"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="431"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="245"/>
<source>Please enter room name</source>
<translation type="unfinished"></translation>
</message>
@@ -2432,56 +2641,55 @@ Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="430"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="445"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="560"/>
<source>Room Name - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="446"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="561"/>
<source>Please select room from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="479"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="596"/>
<source>Room Name - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="480"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="597"/>
<source>The game you are trying to join has started.
Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="524"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="499"/>
<source>Schemes - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="533"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="508"/>
<source>Schemes - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="534"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="509"/>
<source>Do you really want to delete the game scheme '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="844"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="868"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="1093"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="615"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="644"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="869"/>
<source>Videos - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="845"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="616"/>
<source>Do you really want to delete the video '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="869"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="645"/>
<source>Do you really want to remove %1 file(s)?</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -2490,13 +2698,14 @@ Do you still want to join the room?</source>
</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="1094"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="870"/>
<source>Do you really want to cancel uploading %1?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="101"/>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="121"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="896"/>
<source>File error</source>
<translation type="unfinished"></translation>
</message>
@@ -2507,91 +2716,72 @@ Do you still want to join the room?</source>
</message>
<message>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="122"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="897"/>
<source>Cannot open '%1' for reading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="199"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="254"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="229"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="266"/>
<source>Weapons - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="200"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="230"/>
<source>Cannot overwrite default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="255"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="267"/>
<source>Cannot delete default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="263"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="275"/>
<source>Weapons - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="264"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="276"/>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1203"/>
- <source>Nickname</source>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="32"/>
+ <source>Hedgewars - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1204"/>
- <source>Please enter your nickname</source>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="40"/>
+ <source>Hedgewars - Information</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="48"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="67"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="49"/>
<source>default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="52"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="53"/>
<source>OK</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="57"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="729"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="58"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="170"/>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/page/pagecampaign.cpp" line="44"/>
<location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="92"/>
<source>Go!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="84"/>
- <source>Random Team</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="40"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="51"/>
- <source>Setup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="73"/>
<source>Start server</source>
<translation type="unfinished"></translation>
@@ -2612,17 +2802,37 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="75"/>
- <source>Ready</source>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="73"/>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="74"/>
+ <source>Set the default server port for Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="77"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="78"/>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="79"/>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="99"/>
<source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="440"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="100"/>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="616"/>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
@@ -2639,8 +2849,8 @@ Do you still want to join the room?</source>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="53"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="300"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="729"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="190"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
<source>Delete</source>
<translation type="unfinished"></translation>
</message>
@@ -2655,33 +2865,77 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="219"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="773"/>
<source>Set default options</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="774"/>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="140"/>
<source>Open videos directory</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="297"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="141"/>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="186"/>
<source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="303"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="730"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="188"/>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="192"/>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="194"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="877"/>
<source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="730"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="196"/>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="42"/>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="61"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="62"/>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>RoomsListModel</name>
<message>
<location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="37"/>
@@ -2724,181 +2978,124 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="131"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="132"/>
<source>Random Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="132"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="133"/>
<source>Random Maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="133"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="134"/>
<source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="119"/>
- <source>Weapon set</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="120"/>
- <source>Probabilities</source>
- <translation type="unfinished"></translation>
- </message>
+ <name>SeedPrompt</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="121"/>
- <source>Ammo in boxes</source>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="42"/>
+ <source>The map seed is the basis for all random values generated by the game.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="122"/>
- <source>Delays</source>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="61"/>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="277"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="282"/>
- <source>new</source>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="62"/>
+ <source>Set seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="313"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="318"/>
- <source>copy of</source>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="76"/>
+ <source>Close</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="71"/>
- <source>Fort Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="76"/>
- <source>Divide Teams</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="81"/>
- <source>Solid Land</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="86"/>
- <source>Add Border</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="91"/>
- <source>Low Gravity</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="96"/>
- <source>Laser Sight</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="101"/>
- <source>Invulnerable</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="106"/>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="111"/>
- <source>Vampirism</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="116"/>
- <source>Karma</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="121"/>
- <source>Artillery</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="126"/>
- <source>Random Order</source>
- <translation type="unfinished"></translation>
- </message>
+ <name>SelWeaponWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="131"/>
- <source>King</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="119"/>
+ <source>Weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="136"/>
- <source>Place Hedgehogs</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="120"/>
+ <source>Probabilities</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="141"/>
- <source>Clan Shares Ammo</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="121"/>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="146"/>
- <source>Disable Girders</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="122"/>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="151"/>
- <source>Disable Land Objects</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="289"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="294"/>
+ <source>new</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="156"/>
- <source>AI Survival Mode</source>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="330"/>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="161"/>
- <source>Unlimited Attacks</source>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="91"/>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="166"/>
- <source>Reset Weapons</source>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="168"/>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="171"/>
- <source>Per Hedgehog Ammo</source>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="264"/>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="176"/>
- <source>Disable Wind</source>
+ <location filename="../../../../QTfrontend/ui/widget/teamselhelper.cpp" line="58"/>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="181"/>
- <source>More Wind</source>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="84"/>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="186"/>
- <source>Tag Team</source>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="120"/>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="191"/>
- <source>Add Bottom Border</source>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="124"/>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2944,97 +3141,97 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
<source>attack</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
<source>put</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
<source>switch</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
<source>ammo menu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="34"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
<source>slot 1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="35"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
<source>slot 2</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="36"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="34"/>
<source>slot 3</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="37"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="35"/>
<source>slot 4</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="36"/>
<source>slot 5</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="39"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="37"/>
<source>slot 6</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="40"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="38"/>
<source>slot 7</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="41"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="39"/>
<source>slot 8</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="40"/>
<source>slot 9</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="43"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="41"/>
<source>slot 10</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
<source>timer 1 sec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="45"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="43"/>
<source>timer 2 sec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="46"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
<source>timer 3 sec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="45"/>
<source>timer 4 sec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="46"/>
<source>timer 5 sec</source>
<translation type="unfinished"></translation>
</message>
@@ -3110,12 +3307,11 @@ Do you still want to join the room?</source>
</message>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="68"/>
- <source>hedgehogs
-info</source>
+ <source>hedgehog info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="69"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
<source>record</source>
<translation type="unfinished"></translation>
</message>
@@ -3124,59 +3320,59 @@ info</source>
<name>binds (categories)</name>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="23"/>
- <source>Basic controls</source>
+ <source>Movement</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
- <source>Weapon controls</source>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="49"/>
- <source>Camera and cursor controls</source>
+ <source>Camera</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="58"/>
- <source>Other</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/binds.cpp" line="28"/>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
<source>Fire your selected weapon or trigger an utility item:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
<source>Pick a weapon or a target location under the cursor:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
<source>Switch your currently active hog (if possible):</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
<source>Pick a weapon or utility item:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
<source>Set the timer on bombs and timed weapons:</source>
<translation type="unfinished"></translation>
</message>
@@ -3226,7 +3422,7 @@ info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="69"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
@@ -3234,44 +3430,44 @@ info</source>
<context>
<name>binds (keys)</name>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="129"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="133"/>
<source>Axis</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="133"/>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="148"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="137"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="152"/>
<source>(Up)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="137"/>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="152"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="141"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="156"/>
<source>(Down)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="144"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="148"/>
<source>Hat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="156"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="160"/>
<source>(Left)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="160"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="164"/>
<source>(Right)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="168"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="172"/>
<source>Button</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/DataManager.cpp" line="193"/>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="158"/>
<source>Keyboard</source>
<translation type="unfinished"></translation>
</message>
diff --git a/share/hedgewars/Data/Locale/hedgewars_ms.ts b/share/hedgewars/Data/Locale/hedgewars_ms.ts
new file mode 100644
index 0000000..baae676
--- /dev/null
+++ b/share/hedgewars/Data/Locale/hedgewars_ms.ts
@@ -0,0 +1,3800 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ms_MY">
+<context>
+ <name>About</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="93"/>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AbstractPage</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/AbstractPage.cpp" line="55"/>
+ <source>Go back</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AmmoSchemeModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/ammoSchemeModel.cpp" line="673"/>
+ <source>new</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/ammoSchemeModel.cpp" line="679"/>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>BanDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="35"/>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>IP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="39"/>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="40"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="41"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="42"/>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="48"/>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="49"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="77"/>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="151"/>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="91"/>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="90"/>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="92"/>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="93"/>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="124"/>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="150"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="178"/>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FreqSpinBox</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/FreqSpinBox.cpp" line="36"/>
+ <source>Never</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/widget/FreqSpinBox.cpp" line="38"/>
+ <source>Every %1 turn</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>GameCFGWidget</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="67"/>
+ <source>Map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="68"/>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="132"/>
+ <source>Edit schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="147"/>
+ <source>Edit weapons</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="155"/>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="25"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="26"/>
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="27"/>
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="28"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="29"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="30"/>
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="31"/>
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="34"/>
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/HWApplication.cpp" line="92"/>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="102"/>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="253"/>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWAskQuitDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="33"/>
+ <source>Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWChatWidget</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="502"/>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="523"/>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="525"/>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="652"/>
+ <source>%1 has been removed from your ignore list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="662"/>
+ <source>%1 has been added to your ignore list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="692"/>
+ <source>%1 has been removed from your friends list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="701"/>
+ <source>%1 has been added to your friends list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="767"/>
+ <source>Stylesheet imported from %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="768"/>
+ <source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="776"/>
+ <source>Couldn't read %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="784"/>
+ <source>StyleSheet discarded</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="808"/>
+ <source>StyleSheet saved to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="811"/>
+ <source>Failed to save StyleSheet to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWForm</name>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="478"/>
+ <source>DefaultTeam</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="482"/>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="636"/>
+ <source>Game aborted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1075"/>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1076"/>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1104"/>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1109"/>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
+ <source>Nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
+ <source>No nickname supplied.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1173"/>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1696"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2015"/>
+ <source>Cannot save record to file %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1945"/>
+ <source>Hedgewars Demo File</source>
+ <comment>File Types</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1946"/>
+ <source>Hedgewars Save File</source>
+ <comment>File Types</comment>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
+ <source>Demo name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
+ <source>Demo name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2075"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWGame</name>
+ <message>
+ <location filename="../../../../QTfrontend/game.cpp" line="386"/>
+ <location filename="../../../../QTfrontend/net/recorder.cpp" line="112"/>
+ <source>en.txt</source>
+ <translation>ms.txt</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/game.cpp" line="427"/>
+ <source>Cannot open demofile %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWMapContainer</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="94"/>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="97"/>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="98"/>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="99"/>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="100"/>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="101"/>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="111"/>
+ <source>Random</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="135"/>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="188"/>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="194"/>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="207"/>
+ <source>All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="208"/>
+ <source>Small</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="209"/>
+ <source>Medium</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="210"/>
+ <source>Large</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="211"/>
+ <source>Cavern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="212"/>
+ <source>Wacky</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="222"/>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="223"/>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="224"/>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="225"/>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="710"/>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="717"/>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="730"/>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="740"/>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="804"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="935"/>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="220"/>
+ <source>Small tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="221"/>
+ <source>Medium tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="126"/>
+ <source>Seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWNetServersModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/netserverslist.cpp" line="46"/>
+ <source>Title</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/netserverslist.cpp" line="48"/>
+ <source>IP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/netserverslist.cpp" line="50"/>
+ <source>Port</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWNewNet</name>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
+ <source>Quit reason: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="75"/>
+ <source>User quit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="218"/>
+ <source>Remote host has closed connection</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="221"/>
+ <source>The host was not found. Please check the host name and port settings.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="224"/>
+ <source>Connection refused</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="283"/>
+ <source>The server is too old. Disconnecting now.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="484"/>
+ <source>You got kicked</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="797"/>
+ <source>%1 *** %2 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="799"/>
+ <source>%1 *** %2 has left (%3)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="651"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="782"/>
+ <source>%1 *** %2 has joined the room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="707"/>
+ <source>Room destroyed</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWPasswordDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="30"/>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="35"/>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="39"/>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="47"/>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWUploadVideoDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="53"/>
+ <source>Upload video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="149"/>
+ <source>Upload</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatbutton.cpp" line="40"/>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="83"/>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="119"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="123"/>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KB</name>
+ <message>
+ <location filename="../../../../QTfrontend/KB.h" line="28"/>
+ <source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>KeyBinder</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/keybinder.cpp" line="100"/>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="281"/>
+ <source>Duration: %1m %2s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="293"/>
+ <source>Video: %1x%2, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="297"/>
+ <source>%1 fps, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="301"/>
+ <source>Audio: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="305"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/MapModel.cpp" line="193"/>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageAdmin</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="40"/>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="41"/>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="48"/>
+ <source>Fetch data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="52"/>
+ <source>Server message for latest version:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="60"/>
+ <source>Server message for previous versions:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="68"/>
+ <source>Latest version protocol number:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="76"/>
+ <source>MOTD preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="85"/>
+ <source>Clear Accounts Cache</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="88"/>
+ <source>Set data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="97"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="98"/>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="99"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="108"/>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="109"/>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="110"/>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageConnecting</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageconnecting.cpp" line="29"/>
+ <source>Connecting...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageDataDownload</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="66"/>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="126"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageDrawMap</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="32"/>
+ <source>Eraser</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="34"/>
+ <source>Undo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="35"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="36"/>
+ <source>Load</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="37"/>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="61"/>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="61"/>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="69"/>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="61"/>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="69"/>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="69"/>
+ <source>Save drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageEditTeam</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="47"/>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="48"/>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="66"/>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="67"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="78"/>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="84"/>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="88"/>
+ <source>Random Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageGameStats</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="56"/>
+ <source>Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="70"/>
+ <source>Health graph</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="87"/>
+ <source>Ranking</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="113"/>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="118"/>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="193"/>
+ <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="201"/>
+ <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="208"/>
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="272"/>
+ <source>(%1 kill)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="283"/>
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="291"/>
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="299"/>
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>PageInGame</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageingame.cpp" line="29"/>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageInfo</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageinfo.cpp" line="44"/>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageMain</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="45"/>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="50"/>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="64"/>
+ <source>Play local network game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="65"/>
+ <source>Play a game across a local area network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="69"/>
+ <source>Play official network game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="70"/>
+ <source>Play a game on an official server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="77"/>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="80"/>
+ <source>Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="82"/>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="85"/>
+ <source>Downloadable Content</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="87"/>
+ <source>Access the user created content downloadable from our website</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="107"/>
+ <source>Exit game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="111"/>
+ <source>Manage videos recorded from game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="115"/>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="50"/>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="62"/>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageNetGame</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="62"/>
+ <source>Update</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="80"/>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="116"/>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="141"/>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageNetServer</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="87"/>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="138"/>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageOptions</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="96"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="239"/>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="99"/>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="102"/>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="104"/>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="108"/>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="112"/>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="115"/>
+ <source>Advanced</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="128"/>
+ <source>Teams</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="138"/>
+ <source>New team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="146"/>
+ <source>Edit team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="154"/>
+ <source>Delete team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="162"/>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="169"/>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="178"/>
+ <source>New scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="185"/>
+ <source>Edit scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="192"/>
+ <source>Delete scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="200"/>
+ <source>Weapons</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="209"/>
+ <source>New weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="216"/>
+ <source>Edit weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="223"/>
+ <source>Delete weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="371"/>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="388"/>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="418"/>
+ <source>Reset to default colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="431"/>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="469"/>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="492"/>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="518"/>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="524"/>
+ <source>Proxy host</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="525"/>
+ <source>Proxy port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="526"/>
+ <source>Proxy login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="527"/>
+ <source>Proxy password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="540"/>
+ <source>No proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="541"/>
+ <source>System proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="542"/>
+ <source>Socks5 proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="543"/>
+ <source>HTTP proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="578"/>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="624"/>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="637"/>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="651"/>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PagePlayDemo</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="137"/>
+ <source>Rename dialog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="137"/>
+ <source>Enter new file name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageRoomsList</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="64"/>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="91"/>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="95"/>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="153"/>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="177"/>
+ <source>Rules:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="191"/>
+ <source>Weapons:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="202"/>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="220"/>
+ <source>Admin features</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="222"/>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="609"/>
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+</context>
+<context>
+ <name>PageScheme</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="71"/>
+ <source>Defend your fort and destroy the opponents, two team colours max!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="75"/>
+ <source>Teams will start on opposite sides of the terrain, two team colours max!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="79"/>
+ <source>Land can not be destroyed!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="83"/>
+ <source>Add an indestructible border around the terrain</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="87"/>
+ <source>Lower gravity</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="91"/>
+ <source>Assisted aiming with laser sight</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="95"/>
+ <source>All hogs have a personal forcefield</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="99"/>
+ <source>All (living) hedgehogs are fully restored at the end of turn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="103"/>
+ <source>Gain 80% of the damage you do back in health</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="107"/>
+ <source>Share your opponents pain, share their damage</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="111"/>
+ <source>Your hogs are unable to move, put your artillery skills to the test</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="115"/>
+ <source>Order of play is random instead of in room order.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="119"/>
+ <source>Play with a King. If he dies, your side dies.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="123"/>
+ <source>Take turns placing your hedgehogs before the start of play.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="127"/>
+ <source>Ammo is shared between all teams that share a colour.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="131"/>
+ <source>Disable girders when generating random maps.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="135"/>
+ <source>Disable land objects when generating random maps.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="139"/>
+ <source>AI respawns on death.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="143"/>
+ <source>Attacking does not end your turn.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="147"/>
+ <source>Weapons are reset to starting values each turn.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="151"/>
+ <source>Each hedgehog has its own ammo. It does not share with the team.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="155"/>
+ <source>You will not have to worry about wind anymore.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="159"/>
+ <source>Wind will affect almost everything.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="163"/>
+ <source>Teams in each clan take successive turns sharing their turn time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="167"/>
+ <source>Add an indestructible border along the bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="325"/>
+ <source>Random</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="326"/>
+ <source>Seconds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="402"/>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="403"/>
+ <source>New</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="404"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageSelectWeapon</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageselectweapon.cpp" line="46"/>
+ <source>New</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageselectweapon.cpp" line="47"/>
+ <source>Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageselectweapon.cpp" line="50"/>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageselectweapon.cpp" line="51"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageSinglePlayer</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="39"/>
+ <source>Play a quick game against the computer with random settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="42"/>
+ <source>Play a hotseat game against your friends, or AI teams</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="47"/>
+ <source>Campaign Mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="51"/>
+ <source>Practice your skills in a range of training missions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="62"/>
+ <source>Watch recorded demos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="65"/>
+ <source>Load a previously saved game</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageTraining</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="78"/>
+ <source>Pick the mission or training to play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="93"/>
+ <source>Start fighting</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="206"/>
+ <source>No description available</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="214"/>
+ <source>Select a mission!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageVideos</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="121"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="122"/>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="263"/>
+ <source>%1 bytes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="507"/>
+ <source>(in progress...)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="511"/>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="512"/>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="731"/>
+ <source>encoding</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="733"/>
+ <source>uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QAction</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="169"/>
+ <source>Restrict Joins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="171"/>
+ <source>Restrict Team Additions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="173"/>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="253"/>
+ <source>Info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="257"/>
+ <source>Kick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="261"/>
+ <source>Ban</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="265"/>
+ <source>Follow</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="269"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="885"/>
+ <source>Ignore</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="273"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="897"/>
+ <source>Add friend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="880"/>
+ <source>Unignore</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="892"/>
+ <source>Remove friend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="162"/>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="165"/>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QCheckBox</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="509"/>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="95"/>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="131"/>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="630"/>
+ <source>Check for updates at startup</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="377"/>
+ <source>Fullscreen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="360"/>
+ <source>Alternative damage show</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="349"/>
+ <source>Show FPS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="366"/>
+ <source>Show ammo menu tooltips</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="383"/>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="456"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="473"/>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="457"/>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="463"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="478"/>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="464"/>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="474"/>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="479"/>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="610"/>
+ <source>Append date and time to record file name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="691"/>
+ <source>Record audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="740"/>
+ <source>Use game resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QComboBox</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="122"/>
+ <source>Human</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="126"/>
+ <source>Level</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="284"/>
+ <source>Community</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="590"/>
+ <source>(System default)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="313"/>
+ <source>Disabled</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="314"/>
+ <source>Red/Cyan</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="315"/>
+ <source>Cyan/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="316"/>
+ <source>Red/Blue</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="317"/>
+ <source>Blue/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="318"/>
+ <source>Red/Green</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="319"/>
+ <source>Green/Red</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="326"/>
+ <source>Side-by-side</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="327"/>
+ <source>Top-Bottom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="320"/>
+ <source>Red/Cyan grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="321"/>
+ <source>Cyan/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="322"/>
+ <source>Red/Blue grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="323"/>
+ <source>Blue/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="324"/>
+ <source>Red/Green grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="325"/>
+ <source>Green/Red grayscale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="211"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="286"/>
+ <source>Any</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QGroupBox</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="61"/>
+ <source>Team Members</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="96"/>
+ <source>Team Settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="150"/>
+ <source>Fort</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="40"/>
+ <source>Net game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="48"/>
+ <source>Game Modifiers</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="49"/>
+ <source>Basic Settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="118"/>
+ <source>Videos</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="154"/>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="259"/>
+ <source>Playing teams</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLabel</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="38"/>
+ <source>There are videos that are currently being processed.
+Exiting now will abort them.
+Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="33"/>
+ <source>Host:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="37"/>
+ <source>Port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="74"/>
+ <source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="80"/>
+ <source>Account name (or email): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="87"/>
+ <source>Password: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="105"/>
+ <source>Video title: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="114"/>
+ <source>Video description: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="121"/>
+ <source>Tags (comma separated): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="100"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="103"/>
+ <source>Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="106"/>
+ <source>Grave</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="109"/>
+ <source>Flag</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="112"/>
+ <source>Voice</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="103"/>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="111"/>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="121"/>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="136"/>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="164"/>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="139"/>
+ <source>Tip: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="137"/>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="56"/>
+ <source>Server name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="63"/>
+ <source>Server port:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="139"/>
+ <source>Weapons</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="584"/>
+ <source>Locale</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="498"/>
+ <source>Nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="599"/>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="716"/>
+ <source>Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="295"/>
+ <source>Quality</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="250"/>
+ <source>Fullscreen</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="255"/>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="265"/>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="309"/>
+ <source>Stereo rendering</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="439"/>
+ <source>Initial sound volume</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="340"/>
+ <source>FPS limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="175"/>
+ <source>Damage Modifier</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="189"/>
+ <source>Turn Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="203"/>
+ <source>Initial Health</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="217"/>
+ <source>Sudden Death Timeout</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="231"/>
+ <source>Sudden Death Water Rise</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="245"/>
+ <source>Sudden Death Health Decrease</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="259"/>
+ <source>% Rope Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="273"/>
+ <source>Crate Drops</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="286"/>
+ <source>% Health Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="300"/>
+ <source>Health in Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="314"/>
+ <source>Mines Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="330"/>
+ <source>Mines</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="344"/>
+ <source>% Dud Mines</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="358"/>
+ <source>Explosives</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="372"/>
+ <source>% Get Away Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="386"/>
+ <source>Scheme Name:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="660"/>
+ <source>Format</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="680"/>
+ <source>Audio codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="705"/>
+ <source>Video codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="746"/>
+ <source>Framerate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="760"/>
+ <source>Bitrate (Kbps)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="71"/>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="73"/>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="108"/>
+ <source>Style</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="127"/>
+ <source>Scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLineEdit</name>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="952"/>
+ <source>unnamed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/team.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="296"/>
+ <source>hedgehog %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="503"/>
+ <source>anonymous</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QMainWindow</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui_hwform.cpp" line="57"/>
+ <source>Hedgewars %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui_hwform.cpp" line="59"/>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QMessageBox</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="346"/>
+ <source>Teams - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="347"/>
+ <source>Do you really want to delete the team '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="981"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="500"/>
+ <source>Cannot delete default scheme '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1007"/>
+ <source>Please select a record from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1102"/>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1498"/>
+ <source>Unable to start server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
+ <source>Connection to server is lost</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2082"/>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2083"/>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="352"/>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="24"/>
+ <source>Hedgewars - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="362"/>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="377"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="388"/>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="405"/>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="469"/>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1985"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="439"/>
+ <source>Hedgewars - Success</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1986"/>
+ <source>All file associations have been set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1991"/>
+ <source>File association failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="232"/>
+ <source>Error while authenticating at google.com:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="234"/>
+ <source>Login or password is incorrect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="240"/>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="302"/>
+ <source>Video upload - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/upload_video.cpp" line="297"/>
+ <source>Error while sending metadata to youtube.com:
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="118"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="244"/>
+ <source>Netgame - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="119"/>
+ <source>Please select a server from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="245"/>
+ <source>Please enter room name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="125"/>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="152"/>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="169"/>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="184"/>
+ <source>Record Play - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="126"/>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="170"/>
+ <source>Please select record from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="153"/>
+ <source>Cannot rename to </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="185"/>
+ <source>Cannot delete file </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="560"/>
+ <source>Room Name - Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="561"/>
+ <source>Please select room from the list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="596"/>
+ <source>Room Name - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="597"/>
+ <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="499"/>
+ <source>Schemes - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="508"/>
+ <source>Schemes - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="509"/>
+ <source>Do you really want to delete the game scheme '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="615"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="644"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="869"/>
+ <source>Videos - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="616"/>
+ <source>Do you really want to delete the video '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="645"/>
+ <source>Do you really want to remove %1 file(s)?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="870"/>
+ <source>Do you really want to cancel uploading %1?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="101"/>
+ <location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="121"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="896"/>
+ <source>File error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="102"/>
+ <source>Cannot open '%1' for writing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="122"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="897"/>
+ <source>Cannot open '%1' for reading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="367"/>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="368"/>
+ <source>Cannot use the ammo '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="229"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="266"/>
+ <source>Weapons - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="230"/>
+ <source>Cannot overwrite default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="267"/>
+ <source>Cannot delete default weapon set '%1'!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="275"/>
+ <source>Weapons - Are you sure?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="276"/>
+ <source>Do you really want to delete the weapon set '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="32"/>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="40"/>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QPushButton</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="50"/>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="49"/>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="53"/>
+ <source>OK</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="58"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagecampaign.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="92"/>
+ <source>Go!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="49"/>
+ <source>Connect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="58"/>
+ <source>Update</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="63"/>
+ <source>Specify</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="73"/>
+ <source>Start server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="73"/>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="74"/>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="78"/>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="79"/>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="99"/>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="100"/>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="616"/>
+ <source>Associate file extensions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="45"/>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="87"/>
+ <source>Play demo</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="49"/>
+ <source>Rename</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="53"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="190"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="93"/>
+ <source>Load</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="773"/>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="774"/>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="140"/>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="141"/>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="186"/>
+ <source>Play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="188"/>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="192"/>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="194"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="877"/>
+ <source>Upload to YouTube</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="196"/>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
+ <source>Cancel uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="42"/>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="61"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="62"/>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomsListModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="37"/>
+ <source>In progress</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="38"/>
+ <source>Room Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="39"/>
+ <source>C</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="40"/>
+ <source>T</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="41"/>
+ <source>Owner</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="42"/>
+ <source>Map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="43"/>
+ <source>Rules</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="44"/>
+ <source>Weapons</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="132"/>
+ <source>Random Map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="133"/>
+ <source>Random Maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="134"/>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SeedPrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="42"/>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="61"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="62"/>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="76"/>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="119"/>
+ <source>Weapon set</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="120"/>
+ <source>Probabilities</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="121"/>
+ <source>Ammo in boxes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="122"/>
+ <source>Delays</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="289"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="294"/>
+ <source>new</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="330"/>
+ <source>copy of</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TCPBase</name>
+ <message>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="91"/>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="168"/>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="264"/>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/teamselhelper.cpp" line="58"/>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ThemePrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="84"/>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="120"/>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="124"/>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds</name>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="50"/>
+ <source>up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="24"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="51"/>
+ <source>left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="25"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="52"/>
+ <source>right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="26"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="53"/>
+ <source>down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="27"/>
+ <source>precise aim</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="28"/>
+ <source>long jump</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="29"/>
+ <source>high jump</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
+ <source>attack</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
+ <source>put</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <source>switch</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <source>ammo menu</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
+ <source>slot 1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
+ <source>slot 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="34"/>
+ <source>slot 3</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="35"/>
+ <source>slot 4</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="36"/>
+ <source>slot 5</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="37"/>
+ <source>slot 6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="38"/>
+ <source>slot 7</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="39"/>
+ <source>slot 8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="40"/>
+ <source>slot 9</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="41"/>
+ <source>slot 10</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
+ <source>timer 1 sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="43"/>
+ <source>timer 2 sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
+ <source>timer 3 sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="45"/>
+ <source>timer 4 sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="46"/>
+ <source>timer 5 sec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="49"/>
+ <source>find hedgehog</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="55"/>
+ <source>zoom in</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="56"/>
+ <source>zoom out</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="57"/>
+ <source>reset zoom</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="58"/>
+ <source>chat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="59"/>
+ <source>chat history</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="60"/>
+ <source>pause</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="61"/>
+ <source>quit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="62"/>
+ <source>confirmation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="63"/>
+ <source>volume down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="64"/>
+ <source>volume up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="65"/>
+ <source>mute audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="66"/>
+ <source>change mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="67"/>
+ <source>capture</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="68"/>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
+ <source>record</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (categories)</name>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <source>Weapons</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="49"/>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="58"/>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (descriptions)</name>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="28"/>
+ <source>Traverse gaps and obstacles by jumping:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
+ <source>Fire your selected weapon or trigger an utility item:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
+ <source>Pick a weapon or a target location under the cursor:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <source>Switch your currently active hog (if possible):</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <source>Pick a weapon or utility item:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
+ <source>Set the timer on bombs and timed weapons:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="49"/>
+ <source>Move the camera to the active hog:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="50"/>
+ <source>Move the cursor or camera without using the mouse:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="55"/>
+ <source>Modify the camera's zoom level:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="58"/>
+ <source>Talk to your team or all participants:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="60"/>
+ <source>Pause, continue or leave your game:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="63"/>
+ <source>Modify the game's volume while playing:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="66"/>
+ <source>Toggle fullscreen mode:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="67"/>
+ <source>Take a screenshot:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="68"/>
+ <source>Toggle labels above hedgehogs:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
+ <source>Record video:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>binds (keys)</name>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="21"/>
+ <source>Mouse: Left button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="22"/>
+ <source>Mouse: Middle button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="23"/>
+ <source>Mouse: Right button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="24"/>
+ <source>Mouse: Wheel up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="25"/>
+ <source>Mouse: Wheel down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="26"/>
+ <source>Backspace</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="27"/>
+ <source>Tab</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="28"/>
+ <source>Clear</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="29"/>
+ <source>Return</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="30"/>
+ <source>Pause</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="31"/>
+ <source>Escape</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="32"/>
+ <source>Space</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="96"/>
+ <source>Delete</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="97"/>
+ <source>Numpad 0</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="98"/>
+ <source>Numpad 1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="99"/>
+ <source>Numpad 2</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="100"/>
+ <source>Numpad 3</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="101"/>
+ <source>Numpad 4</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="102"/>
+ <source>Numpad 5</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="103"/>
+ <source>Numpad 6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="104"/>
+ <source>Numpad 7</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="105"/>
+ <source>Numpad 8</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="106"/>
+ <source>Numpad 9</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="107"/>
+ <source>Numpad .</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="108"/>
+ <source>Numpad /</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="109"/>
+ <source>Numpad *</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="110"/>
+ <source>Numpad -</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="111"/>
+ <source>Numpad +</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="112"/>
+ <source>Enter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="113"/>
+ <source>Equals</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="114"/>
+ <source>Up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="115"/>
+ <source>Down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="116"/>
+ <source>Right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="117"/>
+ <source>Left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="118"/>
+ <source>Insert</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="119"/>
+ <source>Home</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="120"/>
+ <source>End</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="121"/>
+ <source>Page up</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="122"/>
+ <source>Page down</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="138"/>
+ <source>Num lock</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="139"/>
+ <source>Caps lock</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="140"/>
+ <source>Scroll lock</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="141"/>
+ <source>Right shift</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="142"/>
+ <source>Left shift</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="143"/>
+ <source>Right ctrl</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="144"/>
+ <source>Left ctrl</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="145"/>
+ <source>Right alt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="146"/>
+ <source>Left alt</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="147"/>
+ <source>Right meta</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="148"/>
+ <source>Left meta</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="155"/>
+ <source>A button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="156"/>
+ <source>B button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="157"/>
+ <source>X button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="158"/>
+ <source>Y button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="159"/>
+ <source>LB button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="160"/>
+ <source>RB button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="161"/>
+ <source>Back button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="162"/>
+ <source>Start button</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="163"/>
+ <source>Left stick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="164"/>
+ <source>Right stick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="171"/>
+ <source>Left stick (Right)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="172"/>
+ <source>Left stick (Left)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="173"/>
+ <source>Left stick (Down)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="174"/>
+ <source>Left stick (Up)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="175"/>
+ <source>Left trigger</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="176"/>
+ <source>Right trigger</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="177"/>
+ <source>Right stick (Down)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="178"/>
+ <source>Right stick (Up)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="179"/>
+ <source>Right stick (Right)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="180"/>
+ <source>Right stick (Left)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/sdlkeys.h" line="182"/>
+ <source>DPad</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="158"/>
+ <source>Keyboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="133"/>
+ <source>Axis</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="137"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="152"/>
+ <source>(Up)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="141"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="156"/>
+ <source>(Down)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="148"/>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="160"/>
+ <source>(Left)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="164"/>
+ <source>(Right)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="172"/>
+ <source>Button</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
diff --git a/share/hedgewars/Data/Locale/hedgewars_nl.ts b/share/hedgewars/Data/Locale/hedgewars_nl.ts
index 9c52333..827012b 100644
--- a/share/hedgewars/Data/Locale/hedgewars_nl.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_nl.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="nl">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,11 +140,68 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -102,7 +255,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,27 +300,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>%1's Team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -177,75 +384,127 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
+ <source>All</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Themes</source>
+ <source>Small</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Filter</source>
+ <source>Medium</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All</source>
+ <source>Large</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small</source>
+ <source>Cavern</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium</source>
+ <source>Wacky</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large</source>
+ <source>Small tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cavern</source>
+ <source>Medium tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wacky</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small tunnels</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium tunnels</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Randomly generated</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Random maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -291,10 +550,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has joined</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>%1 *** %2 has left (%3)</source>
<translation type="unfinished"></translation>
</message>
@@ -318,7 +573,22 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -334,6 +604,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -341,7 +633,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -359,6 +658,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -390,6 +700,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -399,6 +741,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -444,7 +797,39 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Advanced</source>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -508,6 +893,14 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -526,420 +919,271 @@ Please pick another nickname:</source>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Update</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>New team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Edit team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Advanced</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
<message>
- <source>Start</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <source>Control</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>DLC</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit team</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete team</source>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
+ <source>Teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Advanced</source>
+ <source>Frontend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -957,43 +1201,47 @@ Please pick another nickname:</source>
<context>
<name>PageRoomsList</name>
<message>
- <source>Create</source>
+ <source>Admin features</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join</source>
+ <source>Rules:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Admin features</source>
+ <source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>Room Name:</source>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules:</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons:</source>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
+ <source>Room state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Clear filters</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- </translation>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1141,18 +1389,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1161,26 +1401,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1226,19 +1454,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1253,10 +1483,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Start</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation type="unfinished"></translation>
</message>
@@ -1289,30 +1515,26 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Update</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>QCheckBox</name>
- <message>
- <source>Check for updates at startup</source>
+ <source>Restrict Unregistered Players Join</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Fullscreen</source>
+ <source>Show games in lobby</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend fullscreen</source>
+ <source>Show games in-progress</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QCheckBox</name>
<message>
- <source>Enable sound</source>
+ <source>Check for updates at startup</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable music</source>
+ <source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1332,18 +1554,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1363,51 +1573,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
+ <source>In-game sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Community</source>
+ <source>Human</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Any</source>
+ <source>Level</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In lobby</source>
+ <source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In progress</source>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1447,10 +1661,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1486,18 +1696,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Key binds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Teams</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Net game</source>
<translation type="unfinished"></translation>
</message>
@@ -1518,26 +1716,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
@@ -1545,10 +1723,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1561,30 +1735,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Version</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Art:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Weapons</source>
<translation type="unfinished"></translation>
</message>
@@ -1641,10 +1791,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game scheme</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation type="unfinished"></translation>
</message>
@@ -1681,10 +1827,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1725,10 +1867,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1759,10 +1897,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1790,134 +1924,135 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QLineEdit</name>
<message>
- <source>unnamed</source>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hedgehog %1</source>
+ <source>Fullscreen</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>anonymous</source>
+ <source>Fullscreen Resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMainWindow</name>
<message>
- <source>Hedgewars %1</source>
+ <source>Windowed Resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMessageBox</name>
<message>
- <source>Connection to server is lost</source>
+ <source>Your Email</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
+ <source>Summary</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>File association failed.</source>
+ <source>Send system information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
+ <source>Type the security code:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error while authenticating at google.com:
-</source>
+ <source>Revision</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Login or password is incorrect</source>
+ <source>This program is distributed under the %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error while sending metadata to youtube.com:
-</source>
+ <source>This setting will be effective at next restart.</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QLineEdit</name>
<message>
- <source>Teams - Are you sure?</source>
+ <source>unnamed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Do you really want to delete the team '%1'?</source>
+ <source>hedgehog %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot delete default scheme '%1'!</source>
+ <source>anonymous</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMainWindow</name>
<message>
- <source>Please select a record from the list</source>
+ <source>Hedgewars %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start server</source>
+ <source>-r%1 (%2)</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMessageBox</name>
<message>
- <source>Hedgewars - Error</source>
+ <source>Connection to server is lost</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars - Success</source>
+ <source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All file associations have been set</source>
+ <source>File association failed.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error while authenticating at google.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
+ <source>Login or password is incorrect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error during authentication at google.com</source>
+ <source>Error while sending metadata to youtube.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
+ <source>Teams - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Main - Error</source>
+ <source>Do you really want to delete the team '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot create directory %1</source>
+ <source>Cannot delete default scheme '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
+ <source>Please select a record from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>TCP - Error</source>
+ <source>Unable to start server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server: %1.</source>
+ <source>Hedgewars - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to run engine at </source>
+ <source>Hedgewars - Success</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Error code: %1</source>
+ <source>All file associations have been set</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2036,15 +2171,41 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2103,26 +2264,10 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Setup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Ready</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2146,181 +2291,193 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>RoomsListModel</name>
- <message>
- <source>In progress</source>
- <translation type="unfinished"></translation>
- </message>
<message>
- <source>Room Name</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
+ <source>Delete this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
+ <source>Upload this video to your Youtube account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
+ <source>Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
+ <source>Set the default server port for Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
+ <source>Invite your friends to your server in just 1 click!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
+ <source>Enter a name for your room.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ammo in boxes</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
+ <source>In progress</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
+ <source>Room Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
+ <source>C</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
+ <source>T</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Karma</source>
+ <source>Owner</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Artillery</source>
+ <source>Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Fort Mode</source>
+ <source>Rules</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Divide Teams</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Solid Land</source>
+ <source>Random Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Border</source>
+ <source>Random Maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Low Gravity</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
+ <source>The map seed is the basis for all random values generated by the game.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Order</source>
+ <source>Set seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
+ <source>Close</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
+ <source>Weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
+ <source>Probabilities</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Girders</source>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>AI Survival Mode</source>
+ <source>new</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Health</source>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
+ <source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2455,11 +2612,6 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>quit</source>
<translation type="unfinished"></translation>
</message>
@@ -2495,33 +2647,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
+ <source>Movement</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
+ <source>Weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Camera and cursor controls</source>
+ <source>Camera</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished"></translation>
</message>
@@ -2585,6 +2737,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_pl.ts b/share/hedgewars/Data/Locale/hedgewars_pl.ts
index af42910..c71d2ff 100644
--- a/share/hedgewars/Data/Locale/hedgewars_pl.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_pl.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="pl">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation>Nieznany kompilator</translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>Nick</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Nick</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Powód</translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation>Czas trwania</translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>Ok</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation>Wiesz za co</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ostrzeżenie</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished">ProszÄ, opisz %1</translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>ksywka</translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation>dożywotni</translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation>Użyj domyÅlnych</translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation>Pokaż</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation>WyÅÅij opiniÄ</translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation>JesteÅmy wdziÄczni za sugestie, pomysÅy i znalezione bÅÄdy.</translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation>WyÅlij swojÄ
opiniÄ!</translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation>JeÅli znalazÅeÅ bÅÄ
d, możesz sprawdziÄ czy zostaÅ już zgÅoszony w tym miejscu: </translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation>E-mail jest opcjonalny chyba, że chcesz byÅmy siÄ z tobÄ
skontaktowali.</translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,12 +141,88 @@
<translation>Edytuj uzbrojenie</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Kiedy ta opcja jest wÅÄ
czona, wybór ustawieŠgry zmienia uzbrojenie na odpowiednie</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Opcje</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Opcje</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished">Schemat gry automatycznie wybierze uzbrojenie</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation>Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation>Ustawienia gry</translation>
+ </message>
+</context>
+<context>
+ <name>GameUIConfig</name>
+ <message>
+ <source>Guest</source>
+ <translation>GoÅÄ</translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1 minuta</numerusform>
+ <numerusform>%1 minuty</numerusform>
+ <numerusform>%1 minut</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1 godzina</numerusform>
+ <numerusform>%1 godziny</numerusform>
+ <numerusform>%1 godzin</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1 godziny</numerusform>
+ <numerusform>%1 godziny</numerusform>
+ <numerusform>%1 godzin</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation>
+ <numerusform>%1 dzieÅ</numerusform>
+ <numerusform>%1 dni</numerusform>
+ <numerusform>%1 dni</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1 dni</numerusform>
+ <numerusform>%1 dni</numerusform>
+ <numerusform>%1 dni</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation>Shemat '%1' nie jest wspierany</translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation>Nie można utworzyÄ katalogu %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation>Nie można otworzyÄ katalogu z danymi:
+%1
+
+Sprawdź poprawnoÅÄ instalacji!</translation>
</message>
</context>
<context>
@@ -103,8 +275,16 @@
<translation>Nie można byÅo zapisaÄ arkusza stylów jako %1</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 nie jest poprawnym poleceniem!</translation>
+ <source>%1 has joined</source>
+ <translation>%1 doÅÄ
czyÅ</translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation>%1 wyszedÅ</translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation>%1 wyszedÅ (%2)</translation>
</message>
</context>
<context>
@@ -140,20 +320,6 @@
<translation>Gra przerwana</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>Twój nick %1 jest zarejestrowany
-na Hedgewars.org
-ProszÄ podaÄ hasÅo bÄ
dź zmieniÄ nick
-w ustawieniach gry:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>Nie podano hasÅa.</translation>
- </message>
- <message>
<source>Nickname</source>
<translation>Nick</translation>
</message>
@@ -167,6 +333,76 @@ Please pick another nickname:</source>
<translation>KtoŠużywa tego nicku %1 na serwerze.
Wybierz inny nick:</translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation>ZespóŠ%1</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation>Hedgewars - Zarejestrowany nick</translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation>Ten nick jest zarejestrowany i musisz podaÄ hasÅo.
+
+Jeżeli ten nick nie jest twój, zarejestrój wÅasny na www.hedgewars.org
+
+HasÅo:</translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation>Twój nick nie jest zarejestrowany.
+By zapobiec używania go przez kogoŠinnego
+zarejestruj go na www.hedgewars.org</translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation>
+
+Twoje hasÅo nie zostaÅo zapisane.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation>Hedgewars - Brak nicku</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation>Hedgewars - ZÅe hasÅo</translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation>WpisaÅeÅ zÅe hasÅo.</translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation>Spróbuj ponownie</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation>Hedgewars - BÅÄ
d poÅÄ
czenia</translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation>Za szybko poÅÄ
czyÅes siÄ ponownie.
+Poczekaj kilka sekund i spróbuj ponownie.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation>Ta strona wymaga poÅÄ
czenia z internetem.</translation>
+ </message>
+ <message>
+ <source>Guest</source>
+ <translation>GoÅÄ</translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -182,18 +418,6 @@ Wybierz inny nick:</translation>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Motywy</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtr</translation>
- </message>
- <message>
<source>All</source>
<translation>Wszystkie</translation>
</message>
@@ -218,10 +442,6 @@ Wybierz inny nick:</translation>
<translation>Odjechane</translation>
</message>
<message>
- <source>Type</source>
- <translation>Typ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>MaÅe tunele</translation>
</message>
@@ -230,28 +450,96 @@ Wybierz inny nick:</translation>
<translation>Årednie tunele</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Duże tunele</translation>
+ <source>Seed</source>
+ <translation>Ziarno</translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation>Typ mapy:</translation>
+ </message>
+ <message>
+ <source>Image map</source>
+ <translation type="unfinished">Mapa z obrazka</translation>
+ </message>
+ <message>
+ <source>Mission map</source>
+ <translation>Misja</translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation>Rysowana rÄcznie</translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation>Losowa mapa</translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Random maze</source>
+ <translation>Losowe labirynty</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>Losowo</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation>PodglÄ
d:</translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation>Wczytaj rysowana mapÄ</translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation>Edytuj mapÄ</translation>
+ </message>
+ <message>
+ <source>Small islands</source>
<translation>MaÅe wyspy</translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Medium islands</source>
<translation>Årednie wyspy</translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Large islands</source>
<translation>Duże wyspy</translation>
</message>
<message>
- <source>Seed</source>
- <translation>Ziarno</translation>
+ <source>Map size:</source>
+ <translation>Rozmiar mapy:</translation>
</message>
<message>
- <source>Set</source>
- <translation>Ustaw</translation>
+ <source>Maze style:</source>
+ <translation>Styl labiryntu:</translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation>Misja:</translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation>Mapa:</translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation>ZaÅaduj mapÄ</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation>Narysowane mapy</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Wszystkie pliki</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation>Duże tunele</translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation>Motyw: %1</translation>
</message>
</context>
<context>
@@ -297,7 +585,7 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 doÅÄ
czyÅ</translation>
+ <translation type="obsolete">%1 *** %2 doÅÄ
czyÅ</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -323,8 +611,26 @@ Wybierz inny nick:</translation>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation>HasÅo</translation>
+ <source>Login</source>
+ <translation>Login</translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation>Zaloguj siÄ by poÅÄ
czyÄ siÄ z serwerem.
+
+JeÅli nie masz konta na www.hedgewars.org,
+po prostu wpisz swój nick.</translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation>Nick:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>HasÅo:</translation>
</message>
</context>
<context>
@@ -339,6 +645,28 @@ Wybierz inny nick:</translation>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation>ZmieÅ czapkÄ (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation>Użyj wybranej czapki</translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation>Szukaj czapki:</translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -346,7 +674,14 @@ Wybierz inny nick:</translation>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation>Kategoria</translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -364,6 +699,17 @@ Wybierz inny nick:</translation>
<source>Audio: </source>
<translation>Audio: </translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation>nieznany</translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation>Brak opisu.</translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -395,6 +741,38 @@ Wybierz inny nick:</translation>
<source>Set data</source>
<translation>Zapisz</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>Ogólne</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation>Bany</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Nick</translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation>WygaÅnie</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Powód</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation>OdÅwież</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Dodaj</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>UsuÅ</translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -404,6 +782,17 @@ Wybierz inny nick:</translation>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation>Åadowanie, proszÄ czekaÄ.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation>Ta strona wymaga poÅÄ
czenia z internetem.</translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -438,19 +827,51 @@ Wybierz inny nick:</translation>
<translation>Wszystkie pliki</translation>
</message>
<message>
- <source>Eraser</source>
- <translation>Gumka</translation>
+ <source>Eraser</source>
+ <translation>Gumka</translation>
+ </message>
+</context>
+<context>
+ <name>PageEditTeam</name>
+ <message>
+ <source>General</source>
+ <translation>Ogólne</translation>
+ </message>
+ <message>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation>Wybierz czynnoÅÄ by przypisaÄ klawisz dla tego zespoÅu</translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation>Użyj domyÅlnych</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Zresetuj przypisania</translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation>WÅasne ustawienia</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>Czapka</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nazwa</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation>ImiÄ jeża</translation>
</message>
-</context>
-<context>
- <name>PageEditTeam</name>
<message>
- <source>General</source>
- <translation>Ogólne</translation>
+ <source>Randomize this hedgehog's name</source>
+ <translation>Losuj imiÄ</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Zaawansowane</translation>
+ <source>Random Team</source>
+ <translation>Losowa Drużyna</translation>
</message>
</context>
<context>
@@ -519,6 +940,14 @@ Wybierz inny nick:</translation>
<numerusform><b>%1</b> trzÄ
sÅ portkami i opuÅciÅ turÄ <b>%2</b> razy.</numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation>Zagraj ponownie</translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation>Zapisz</translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -537,267 +966,14 @@ Wybierz inny nick:</translation>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>By graÄ ze swoim przyjacielem w tej samej drużynie po prostu wybierzcie taki sam kolor obydwu zespoÅów. Każdy z was bÄdzie sterowaÄ swoimi wÅasnymi jeżami ale wygracie bÄ
dź przegracie jako jedna drużyna.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Niektóre z broni zadajÄ
maÅo punktów obrażeÅ jednak użyte w odpowiednim momencie mogÄ
pokazaÄ pazur. Na przykÅad spróbuj użyÄ pistoletu by strÄ
ciÄ swoich przeciwników do wody.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>JeÅli nie jesteÅ pewien co zrobiÄ w danej turze i nie chcesz traciÄ amunicji możesz pominÄ
Ä turÄ. Nie rób tak jednak zbyt czÄsto gdyż nagÅa ÅmierÄ jest nieuchronna!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>JeÅli chciaÅbyÅ zapobiec używania wÅasnego nicka przez kogoÅ innego, zarejestruj go na http://www.hedgewars.org .</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Znudzony domyÅlnymi ustawieniami gry? Spróbuj zagraÄ w którÄ
Å z misji. - oferujÄ
one zmienione zasady gry w zależnoÅci od tej którÄ
wybraÅeÅ.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Gra zawsze bÄdzie zapisywaÅa ostatniÄ
rozgrywkÄ jako Demo. Wybierz "GrÄ LokalnÄ
" i kliknij w przycisk "Dema" który znajduje siÄ w prawym dolnym rogu ekranu by je odtworzyÄ i zarzÄ
dzaÄ nimi.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest darmowÄ
grÄ
o otwartym kodzie, którÄ
tworzymy w naszym wolnym czasie. JeÅli masz jakiÅ problem, zapytaj na forum ale nie spodziewaj siÄ wsparcia 24 godziny na dobÄ!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest darmowÄ
grÄ
o otwartym kodzie, którÄ
tworzymy w naszym wolnym czasie. JeÅli jÄ
lubisz, wspomóż nas maÅÄ
wpÅatÄ
lub stwórz wÅasnÄ
czapkÄ bÄ
dź mapÄ!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest darmowÄ
grÄ
o otwartym kodzie, którÄ
tworzymy w naszym wolnym czasie. JeÅli tylko chcesz, rozdaj jÄ
swojej rodzinie i kolegom!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Od czasu do czasu bÄdÄ
organizowane mistrzostwa. BÄdÄ
one ogÅaszane z wyprzedzeniem na http://www.hedgewars.org/ .</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest dostÄpne w wielu jÄzykach. JeÅli brakuje tÅumaczenia w twoim jÄzyku bÄ
dź jest ono niekompletne, nie bój siÄ z nami skontaktowaÄ!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars może byÄ uruchomione na różnych systemach operacyjnych takich jak Microsoft Windows, MacOS X, FreeBSD oraz Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Zawsze możesz zmieniaÄ ustawienia gry w opcjach gry lokalnej lub sieciowej. Nie musisz ciÄ
gle używaÄ tzw. "Szybkiej gry".</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Zawsze pamiÄtaj o robieniu krótkich przerw co godzinÄ kiedy grasz na komputerze.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>JeÅli twoja karta graficzna nie ma sprzÄtowego przyspieszania OpenGL, spróbuj wÅÄ
czyÄ tryb obniżonej jakoÅci by zwiÄkszyÄ pÅynnoÅÄ gry.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>JesteÅmy otwarci na sugestie oraz konstruktywnÄ
krytykÄ. JeÅli coÅ Ci siÄ nie podoba bÄ
dź masz jakiÅ pomysÅ, daj nam znaÄ!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>BÄ
dź kulturalny grajÄ
c przez internet. PamiÄtaj o tym, że w Hedgewars mogÄ
graÄ także mÅodsze osoby!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Specjalne tryby gry takie jak "Karma" bÄ
dź "Wampiryzm" pozwalajÄ
na stworzenie nowej taktyki!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Nie powinieneÅ instalowaÄ Hedgewars na komputerach których nie posiadasz (w szkole, na studiach, w pracy itp.). Zapytaj osoby odpowiedzialnej za te komputery!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest idealny do gry w czasie przerw.Upewnij siÄ, że nie daÅeÅ zbyt dużej iloÅci jeży, bÄ
dź zbyt dużej mapy. Pomóc może także zmniejszenie dÅugoÅci tury lub obniżenie iloÅci życia.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Żaden jeż nie zostaŠranny w czasie tworzenia tej gry.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars jest darmowÄ
grÄ
o otwartym kodzie źródÅowym którÄ
tworzymy w naszym wolnym czasie. JeÅli ktokolwiek sprzedaÅ Tobie tÄ grÄ powinieneÅ upomnieÄ siÄ o swoje pieniÄ
dze!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>JeÅli podÅÄ
czysz jeden lub wiÄcej gamepadów przed wÅÄ
czeniem gry bÄdziesz miaÅ możliwoÅÄ przypisania klawiszy by sterowaÄ swoimi jeżami.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Stwórz konto na %1 by zapobiec używania twojego ulubionego nicku przez innych na oficjalnym serwerze.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>JeÅli twoja karta nie wspiera sprzÄtowego przyspieszania OpenGL spróbuj uaktualniÄ swoje sterowniki.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>SÄ
trzy różne rodzaje skoku możliwe do wykonania. NaciÅnij [wysoki skok] dwa razy by zrobiÄ bardzo wysoki skok w tyÅ.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Boisz siÄ upadku z krawÄdzi terenu? Przytrzymaj klawisz [precyzyjnego celowania] by obróciÄ siÄ w [lewo] lub [prawo] bez ruszenia siÄ z miejsca.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Niektóre z broni wymagajÄ
specjalnej strategii lub dużo treningu by je popranie używaÄ. Nie poddawaj siÄ gdy nie wychodzi ci za pierwszym razem.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>WiÄkszoÅÄ uzbrojenia nie dziaÅa pod wodÄ
. PszczoÅa i Ciasto sÄ
wyjÄ
tkami od tej reguÅy.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>CuchnÄ
cy ser nie powoduje wielkiego wybuchu. Jednakże pod wpÅywem wiatru chmura ÅmierdzÄ
cego gazu może bardzo daleko zawÄdrowaÄ i otruÄ wiele jeży naraz.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Zrzut pianina jest najbardziej morderczym atakiem powietrznym. PamiÄtaj, że tracisz jeża którym wykonujesz ten atak wiÄc dobrze zaplanuj swój ruch.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Miny samoprzylepne sÄ
idealnym narzÄdziem by tworzyÄ maÅe reakcje ÅaÅcuchowe bÄ
dź do zmuszenia przeciwnika by popadŠw tarapaty lub wpadŠdo wody.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>MÅotek jest najbardziej skuteczny na mostach bÄ
dź kÅadkach. Uderzone jeże przelecÄ
przez nie na sam dóÅ.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>JeÅli utknÄ
ÅeÅ za jeżem przeciwnika, użyj mÅotka by wbiÄ go w ziemiÄ. Unikniesz wtedy eksplozji która z pewnoÅciÄ
zabraÅaby Tobie punkty życia.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Dystans który Ciasto może przebyÄ zależy od terenu który ma do przebycia. Użyj [ataku] by zdetonowaÄ je wczeÅniej.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Miotacz ognia jest ÅmiercionoÅnÄ
broniÄ
ale może byÄ użyty również jako narzÄdzie do kopania tuneli.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Chcesz wiedzieÄ kto tworzy tÄ grÄ? Kliknij logo w gÅównym menu by zobaczyÄ autorów.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Lubisz Hedgewars? ZostaÅ fanem na %1 lub doÅÄ
cz do grupy na %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Możesz rysowaÄ wÅasne nagrobki, czapki, flagi lub nawet mapy albo tematy! Miej na uwadze to by udostÄpniÄ je każdemu który bÄdzie graÅ z TobÄ
przez sieÄ.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Chcesz nosiÄ wymarzonÄ
czapkÄ? Wspomóż nas pieniÄżnie a my zrobimy specjalnÄ
czapkÄ tylko dla Ciebie!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>PamiÄtaj o aktualizowaniu sterowników by zapobiec problemom z grami.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Swoje zespoÅy i konfiguracjÄ gry znajdziesz w folderze "Moje Dokumenty\Hedgewars". Twórz regularnie kopie zapasowe, ale nie edytuj tych plików wÅasnorÄcznie.</translation>
- </message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Możesz powiÄ
zaÄ typy plików zwiÄ
zane z Hedgewars (zapisy gier i dema) by móc je uruchamiaÄ bezpoÅrednio z ulubionego menedżera plików bÄ
dź przeglÄ
darki internetowej.</translation>
- </message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Chcesz zaoszczÄdziÄ liny? OdÅÄ
cz jÄ
bÄdÄ
c w powietrzu, a potem wypuÅÄ jÄ
ponownie. Dopóki nie dotkniesz ziemi, bÄdziesz używaÅ pojedynczego naboju!</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Swoje zespoÅy i konfiguracjÄ gry znajdziesz w folderze "Library/Application Support/Hedgewars" w twoim katalogu domowym. Twórz regularnie kopie zapasowe, ale nie edytuj tych plików wÅasnorÄcznie.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Swoje zespoÅy i konfiguracjÄ gry znajdziesz w folderze ".hedgewars" w twoim katalogu domowym. Twórz regularnie kopie zapasowe, ale nie edytuj tych plików wÅasnorÄcznie.</translation>
- </message>
- <message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Wersja Hedgewars dla systemu Windows wspiera XFire. Upewnij siÄ, że dodaÅeÅ Hedgewars do listy gier by Twoi znajomi mogli zobaczyÄ Ciebie w czasie gry.</translation>
- </message>
- <message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Użyj koktajlu MoÅotowa lub Miotacza ognia by powstrzymaÄ przeciwnika przed przedostaniem siÄ przez tunele lub platformy.</translation>
- </message>
- <message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>PszczoÅa potrafi byÄ ciÄżka w użyciu. Jej promieÅ skrÄtu zależy od prÄdkoÅci lotu, wiÄc nie staraj siÄ nie używaÄ peÅnej mocy podczas strzaÅu.</translation>
- </message>
- <message>
<source>Downloadable Content</source>
<translation>Dodatki</translation>
</message>
<message>
- <source>Local Game</source>
- <translation>Gra lokalna</translation>
- </message>
- <message>
<source>Play a game on a single computer</source>
<translation>Graj na swoim komputerze</translation>
</message>
<message>
- <source>Network Game</source>
- <translation>Gra sieciowa</translation>
- </message>
- <message>
<source>Play a game across a network</source>
<translation>Graj poprzez sieÄ</translation>
</message>
@@ -825,6 +1001,26 @@ Wybierz inny nick:</translation>
<source>Edit game preferences</source>
<translation>ZmieÅ ustawienia gry</translation>
</message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation>Zagraj poprzez sieÄ lokalnÄ
</translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation>Zagraj na oficjalnym serwerze</translation>
+ </message>
+ <message>
+ <source>Feedback</source>
+ <translation>Twoja opinia</translation>
+ </message>
+ <message>
+ <source>Play local network game</source>
+ <translation>Zagraj poprzez LAN</translation>
+ </message>
+ <message>
+ <source>Play official network game</source>
+ <translation>Zagraj na oficjalnym serwerze</translation>
+ </message>
</context>
<context>
<name>PageMultiplayer</name>
@@ -832,39 +1028,43 @@ Wybierz inny nick:</translation>
<source>Start</source>
<translation>Start</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation>ZmieÅ ustawienia gry</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Kontrola</translation>
+ <translation type="obsolete">Kontrola</translation>
</message>
<message>
- <source>DLC</source>
- <translation>DLC</translation>
+ <source>Edit game preferences</source>
+ <translation>ZmieÅ ustawienia gry</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Dodatki</translation>
+ <source>Start</source>
+ <translation>Start</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>SieÄ lokalna</translation>
+ <source>Update</source>
+ <translation>Aktualizuj</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Oficjalny serwer</translation>
+ <source>Room controls</source>
+ <translation>Ustawienia pokoju</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
- <translation>DoÅÄ
cz do setek graczy w sieci!</translation>
+ <source>Click here for details</source>
+ <translation>Pokaż szczegóÅy</translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation>DoÅÄ
cz lub stwórz nowÄ
grÄ w sieci lokalnej.</translation>
+ <source>Insert your address here</source>
+ <translation>Wprowadź adres</translation>
</message>
</context>
<context>
@@ -910,10 +1110,6 @@ Wybierz inny nick:</translation>
<translation>UsuÅ zestaw uzbrojenia</translation>
</message>
<message>
- <source>General</source>
- <translation>Ogólne</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Zaawansowane</translation>
</message>
@@ -953,6 +1149,94 @@ Wybierz inny nick:</translation>
<source>System proxy settings</source>
<translation>Systemowe ustawienia proxy</translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished">Wybierz czynnoÅÄ by przypisaÄ do niej klawisz</translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation>PrzywrÃ³Ä domyÅlne</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Zresetuj klawisze</translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation>Gra</translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation>Grafika</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>DźwiÄk</translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation>Sterowanie</translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation>Nagrywanie wideo</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>SieÄ</translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation>Drużyny</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation>Schematy</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation>Uzbrojenie</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation>Interfejs</translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation>WÅasne kolory</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation>DźwiÄki w grze</translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation>DźwiÄki interfejsu</translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation>Konto</translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation>Ustawienia proxy</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation>Różne</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation>Aktualizacja</translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation>Sprawdź aktualizacje</translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation>Ustawienia nagrywania</translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -969,11 +1253,11 @@ Wybierz inny nick:</translation>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Stwórz</translation>
+ <translation type="obsolete">Stwórz</translation>
</message>
<message>
<source>Join</source>
- <translation>DoÅÄ
cz</translation>
+ <translation type="obsolete">DoÅÄ
cz</translation>
</message>
<message>
<source>Admin features</source>
@@ -981,7 +1265,7 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>Room Name:</source>
- <translation>Nazwa pokoju:</translation>
+ <translation type="obsolete">Nazwa pokoju:</translation>
</message>
<message>
<source>Rules:</source>
@@ -993,11 +1277,11 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>Search:</source>
- <translation>Szukaj:</translation>
+ <translation type="obsolete">Szukaj:</translation>
</message>
<message>
<source>Clear</source>
- <translation>WyczyÅÄ</translation>
+ <translation type="obsolete">WyczyÅÄ</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1007,6 +1291,30 @@ Wybierz inny nick:</translation>
<numerusform>%1 graczy online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation>Szukaj pokoju:</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Stwórz pokój</translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation>DoÅÄ
cz do gry</translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation>Stan gry</translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation>UsuÅ filtry</translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation>Otwórz ustawienia admina</translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1128,7 +1436,7 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>Add an indestructible border along the bottom</source>
- <translation>>Dodaje niezniszczalnÄ
ramkÄ u doÅu mapy</translation>
+ <translation>Dodaje niezniszczalnÄ
ramkÄ u doÅu mapy</translation>
</message>
</context>
<context>
@@ -1153,18 +1461,10 @@ Wybierz inny nick:</translation>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation>Szybka gra</translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation>Zagraj szybkÄ
grÄ z losowymi ustawieniami przeciwko komputerowi</translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation>Gra wieloosobowa</translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation>Graj na zmianÄ ze swoimi przyjacióÅmi lub przeciwko komputerowi</translation>
</message>
@@ -1173,26 +1473,14 @@ Wybierz inny nick:</translation>
<translation>Kampania</translation>
</message>
<message>
- <source>Training Mode</source>
- <translation>Trening</translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation>Sprawdź swoje umiejÄtnoÅci przwechodzÄ
c kilka misji</translation>
</message>
<message>
- <source>Demos</source>
- <translation>Dema</translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation>Obejrzyj nagrane dema</translation>
</message>
<message>
- <source>Load</source>
- <translation>Wczytaj</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation>Wczytaj zapisanÄ
grÄ</translation>
</message>
@@ -1239,14 +1527,6 @@ Wybierz inny nick:</translation>
<translation>(w trakcie...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation>Data: </translation>
- </message>
- <message>
- <source>Size: </source>
- <translation>Rozmiar: </translation>
- </message>
- <message>
<source>encoding</source>
<translation>enkodowanie</translation>
</message>
@@ -1254,6 +1534,16 @@ Wybierz inny nick:</translation>
<source>uploading</source>
<translation>wysyÅanie</translation>
</message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1</translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation>Rozmiar: %1</translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1262,10 +1552,6 @@ Wybierz inny nick:</translation>
<translation>WyrzuÄ</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>ZabroÅ doÅÄ
czania</translation>
</message>
@@ -1294,16 +1580,28 @@ Wybierz inny nick:</translation>
<translation>Dodaj przyjaciela</translation>
</message>
<message>
- <source>Unignore</source>
- <translation>PrzestaÅ ignorowaÄ</translation>
+ <source>Unignore</source>
+ <translation>PrzestaÅ ignorowaÄ</translation>
+ </message>
+ <message>
+ <source>Remove friend</source>
+ <translation>UsuÅ przyjaciela</translation>
+ </message>
+ <message>
+ <source>Update</source>
+ <translation type="obsolete">ZmieÅ</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation>Blokuj niezarejestrowanych graczy</translation>
</message>
<message>
- <source>Remove friend</source>
- <translation>UsuÅ przyjaciela</translation>
+ <source>Show games in lobby</source>
+ <translation>Pokaż nierozpoczÄte gry</translation>
</message>
<message>
- <source>Update</source>
- <translation>ZmieÅ</translation>
+ <source>Show games in-progress</source>
+ <translation>Pokaż trwajÄ
ce gry</translation>
</message>
</context>
<context>
@@ -1317,10 +1615,6 @@ Wybierz inny nick:</translation>
<translation>PeÅny ekran</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>WÅÄ
cz dźwiÄk</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Pokazuj FPS</translation>
</message>
@@ -1329,14 +1623,6 @@ Wybierz inny nick:</translation>
<translation>Inny sposób wyÅwietlania obrażeÅ</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>WÅÄ
cz muzykÄ</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>PeÅnoekranowe menu</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Dodaj czas i datÄ do nazwy pliku</translation>
</message>
@@ -1345,18 +1631,6 @@ Wybierz inny nick:</translation>
<translation>Pokaż opisy broni</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>WÅÄ
cz dźwiÄki w menu</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>WÅÄ
cz muzykÄ w menu</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Efekty w menu</translation>
- </message>
- <message>
<source>Save password</source>
<translation>Zapisz hasÅo</translation>
</message>
@@ -1376,14 +1650,38 @@ Wybierz inny nick:</translation>
<source>Use game resolution</source>
<translation>Użyj rozdzielczoÅci z gry</translation>
</message>
+ <message>
+ <source>Visual effects</source>
+ <translation>Efekty wizualne</translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation>DźwiÄk</translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation>Efekty dźwiÄkowe w grze</translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation>Muzyka</translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation>Muzyka w grze</translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation>Efekty dźwiÄkowe w menu</translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation>Muzyka w menu</translation>
+ </message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>wygenerowana mapa...</translation>
- </message>
- <message>
<source>Human</source>
<translation>CzÅowiek</translation>
</message>
@@ -1396,14 +1694,6 @@ Wybierz inny nick:</translation>
<translation>(DomyÅlny)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>wygenerowany labirynt...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Misja</translation>
- </message>
- <message>
<source>Community</source>
<translation>SpoÅecznoÅÄ</translation>
</message>
@@ -1413,15 +1703,11 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>In lobby</source>
- <translation>W lobby</translation>
+ <translation type="obsolete">W lobby</translation>
</message>
<message>
<source>In progress</source>
- <translation>W toku</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>Mapa rysowana rÄcznie...</translation>
+ <translation type="obsolete">W toku</translation>
</message>
<message>
<source>Disabled</source>
@@ -1460,10 +1746,6 @@ Wybierz inny nick:</translation>
<translation>Góra-dóÅ</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>TrzÄsÄ
cy siÄ obraz</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Czer/BÅÄk w odc. szar</translation>
</message>
@@ -1495,22 +1777,10 @@ Wybierz inny nick:</translation>
<translation>CzÅonkowie drużyny</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Ustawienia klawiszy</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Fort</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Drużyny</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Ustawienia dźwiÄku/grafiki</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Gra sieciowa</translation>
</message>
@@ -1531,26 +1801,6 @@ Wybierz inny nick:</translation>
<translation>Ustawienia drużyn</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Różne</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Schematy i uzbrojenie</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation>WÅasne kolory</translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation>Różne</translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation>Ustawienia nagrywania</translation>
- </message>
- <message>
<source>Videos</source>
<translation>Filmy</translation>
</message>
@@ -1558,30 +1808,10 @@ Wybierz inny nick:</translation>
<source>Description</source>
<translation>Opis</translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation>Ustawienia proxy</translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Developers:</source>
- <translation>Twórcy:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafika:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>TÅumaczenia:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Szczególne podziÄkowania:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Uzbrojenie</translation>
</message>
@@ -1611,11 +1841,7 @@ Wybierz inny nick:</translation>
</message>
<message>
<source>Version</source>
- <translation>Wersja</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>DźwiÄki:</translation>
+ <translation type="obsolete">Wersja</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1646,10 +1872,6 @@ Wybierz inny nick:</translation>
<translation>Zrzuty skrzyÅ</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Ustawienia gry</translation>
- </message>
- <message>
<source>Mines Time</source>
<translation>Czas detonacji min</translation>
</message>
@@ -1694,11 +1916,6 @@ Wybierz inny nick:</translation>
<translation>Rada:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Ta wersja testowa jest w fazie produkcji i może nie byÄ kompatybilna z innymi wersjami gry.
-Niektóre funkcje mogÄ
nie dziaÅaÄ lub byÄ niekompletne. Używaj na wÅasne ryzyko!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>JakoÅÄ</translation>
</message>
@@ -1740,7 +1957,7 @@ Niektóre funkcje mogÄ
nie dziaÅaÄ lub byÄ niekompletne. Używaj na wÅasne
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>Ten program jest rozprowadzany na zasadach GNU GPL v2</translation>
+ <translation type="obsolete">Ten program jest rozprowadzany na zasadach GNU GPL v2</translation>
</message>
<message>
<source>There are videos that are currently being processed.
@@ -1775,10 +1992,6 @@ Czy na pewno chcesz wyjÅÄ?</translation>
<translation>Tagi (oddzielone przecinkami): </translation>
</message>
<message>
- <source>Summary </source>
- <translation>Podsumowanie </translation>
- </message>
- <message>
<source>Description</source>
<translation>Opis</translation>
</message>
@@ -1806,6 +2019,50 @@ Czy na pewno chcesz wyjÅÄ?</translation>
<source>Bitrate (Kbps)</source>
<translation>Bitrate (Kbps)</translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation>Ta wersja deweloperska nie jest koÅcowÄ
wersjÄ
gry i może byÄ niekompatybilna z innymi wersjami i niektóre funkcje mogÄ
byÄ niekompletne lub nie dziaÅaÄ w ogóle!</translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>PeÅny ekran</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation>RozdzielczoÅÄ</translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation>Rozmiar okna</translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation>Twój e-mail</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation>Krótki opis</translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation>WyÅÅij informacje o systemie</translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation>Wpisz litery z obrazka:</translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation>Wersja</translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation>Ten program jest rozpowszechniany na licencji %1</translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation>Ustawienia zadziaÅajÄ
po restarcie gry.</translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1828,6 +2085,10 @@ Czy na pewno chcesz wyjÅÄ?</translation>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation>-r%1 (%2)</translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1844,10 +2105,6 @@ Czy na pewno chcesz wyjÅÄ?</translation>
<translation>PowiÄ
zanie plików nie powiodÅo siÄ.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation>WypeÅnij wszystkie pola</translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation>BÅÄ
d logowania na google.com:</translation>
@@ -1894,50 +2151,38 @@ Czy na pewno chcesz wyjÅÄ?</translation>
<translation>Wszystkie powiÄ
zania plików zostaÅy ustawione</translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation>PomyÅlnie utworzono wpis na hedgewars.googlecode.com </translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation>BÅÄ
d podczas logowania do google.com</translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation>BÅad podczas wysyÅania informacji. Spróbuj ponownie później lub odwiedź hedgewars.googlecode.com)</translation>
- </message>
- <message>
<source>Main - Error</source>
- <translation>BÅÄ
d</translation>
+ <translation type="obsolete">BÅÄ
d</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation>Nie można utworzyÄ katalogu %1</translation>
+ <translation type="obsolete">Nie można utworzyÄ katalogu %1</translation>
</message>
<message>
<source>Failed to open data directory:
%1
Please check your installation!</source>
- <translation>Nie można otworzyÄ katalogu z danymi:
+ <translation type="obsolete">Nie można otworzyÄ katalogu z danymi:
%1
Sprawdź poprawnoÅÄ instalacji!</translation>
</message>
<message>
<source>TCP - Error</source>
- <translation>TCP - BÅÄ
d</translation>
+ <translation type="obsolete">TCP - BÅÄ
d</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation>Nie można uruchomiÄ serwera: %1.</translation>
+ <translation type="obsolete">Nie można uruchomiÄ serwera: %1.</translation>
</message>
<message>
<source>Unable to run engine at </source>
- <translation>Nie można uruchomiÄ silnika na </translation>
+ <translation type="obsolete">Nie można uruchomiÄ silnika na </translation>
</message>
<message>
<source>Error code: %1</source>
- <translation>Kod bÅÄdu: %1</translation>
+ <translation type="obsolete">Kod bÅÄdu: %1</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2057,16 +2302,43 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation>Na pewno chcesz usunÄ
c zestaw broni '%1'?</translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nick</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation>Hedgewars - Niezarejestrowany nick</translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation>PodglÄ
d informacji o systemie</translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation>Nie udaÅo siÄ wygenerowaÄ captchy</translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation>Nie udaÅo siÄ pobraÄ captchy</translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation>WypeÅnij wszystkie pola. E-mail nie jest wymagany.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation>Hedgewars - Ostrzeżenie</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation>Hedgewars - Informacja</translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation>Nie wszyscy gracze sÄ
gotowi</translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Podaj swój nick</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation>JesteÅ pewien, że chcesz rozpoczÄ
c grÄ?
+Nie wszyscy gracze sÄ
gotowi.</translation>
</message>
</context>
<context>
@@ -2124,32 +2396,16 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
<translation>Wczytaj</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Ustawienia</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Gotowe</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Losowa Drużyna</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>PowiÄ
ż typy plików z Hedgewars</translation>
</message>
<message>
- <source>more</source>
- <translation>WiÄcej</translation>
- </message>
- <message>
<source>More info</source>
<translation>WiÄcej informacji</translation>
</message>
<message>
<source>Set default options</source>
- <translation>Zapisz jako domyÅÅne ustawienia</translation>
+ <translation>PrzywrÃ³Ä domyÅlne ustawienia</translation>
</message>
<message>
<source>Open videos directory</source>
@@ -2167,6 +2423,61 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
<source>Cancel uploading</source>
<translation>Anuluj wysyÅanie</translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation>PrzywrÃ³Ä domyÅlne ustawienia</translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation>Otwórz katalog z filmami</translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation>Odtwórz wideo</translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation>UsuÅ wideo</translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation>WyÅlij to wideo na konto Youtube</translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation>Zresetuj</translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation>Ustaw domyÅlny port serwera Hedgewars</translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation>ZaproÅ swoich znajomych jednym klikniÄciem!</translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation>Kliknij by skopiowaÄ unikalny link twojego serwera do schowka. WyÅlij link swoim znajomym aby mogli doÅÄ
czyÄ do gry.</translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation>Uruchom prywatny serwer</translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation>Wprowadź nazwÄ pokoju.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Stwórz pokój</translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2216,6 +2527,25 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation>Ziarno jest podstawÄ
wszystkich losowych wartoÅci tworzynych przez grÄ.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation>Ustaw ziarno</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>Zamknij</translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2243,106 +2573,45 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Wampiryzm</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artyleria</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Tryb fortów</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Rozdziel drużyny</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Niezniszczalny teren</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Dodaj ramkÄ</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Niska grawitacja</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Celownik laserowy</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>NieÅmiertelnoÅÄ</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Losowa kolejnoÅÄ</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Król</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Place Hedgehogs</source>
- <translation>RozmieÅÄ jeże</translation>
+ <source>Unable to start server at %1.</source>
+ <translation>Nie można uruchomiÄ serwera na %1.</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation>Wspólna amunicja</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>WyÅÄ
cz mosty</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>WyÅÄ
cz dodatki terenu</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Tryb przetrwania</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>NiekoÅczÄ
cy siÄ atak</translation>
- </message>
- <message>
- <source>Reset Weapons</source>
- <translation>Resetuj Uzbrojenie</translation>
- </message>
- <message>
- <source>Per Hedgehog Ammo</source>
- <translation>Oddzielna amunicja</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation>Nie można uruchomiÄ silnika na %1
+Kod bÅÄdu: %2</translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Reset Health</source>
- <translation>Odnów życie</translation>
+ <source>At least two teams are required to play!</source>
+ <translation>Do rozpoczÄcia gry potrzeba dwóch druzyn!</translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>WyÅÄ
cz wiatr</translation>
+ <source>%1's team</source>
+ <translation>Drużyna %1</translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>WiÄcej wiatru</translation>
+ <source>Cancel</source>
+ <translation>Anuluj</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>ZespóÅ</translation>
+ <source>Search for a theme:</source>
+ <translation>Szukaj motywu:</translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Dodaj ramkÄ na dole</translation>
+ <source>Use selected theme</source>
+ <translation>Użyj wybranego motywu</translation>
</message>
</context>
<context>
@@ -2460,11 +2729,6 @@ Czy chcesz doÅÄ
czyÄ do pokoju?</translation>
<translation>zrzut ekranu</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>opisy jeży</translation>
- </message>
- <message>
<source>quit</source>
<translation>wyjÅcie</translation>
</message>
@@ -2516,33 +2780,33 @@ info</source>
<source>record</source>
<translation>nagrywaj</translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation>informacje o jeżu</translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Podstawowe sterowanie</translation>
+ <source>Movement</source>
+ <translation>Ruch</translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>BroÅ</translation>
+ <source>Weapons</source>
+ <translation>Uzbrojenie</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kamera i kursor</translation>
+ <source>Camera</source>
+ <translation>Kamera</translation>
</message>
<message>
- <source>Other</source>
- <translation>Inne</translation>
+ <source>Miscellaneous</source>
+ <translation>Różne</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Poruszanie siÄ jeżem i strzelanie:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>OmiÅ dziury i przeszkody, skaczÄ
c:</translation>
</message>
@@ -2606,6 +2870,10 @@ info</source>
<source>Record video:</source>
<translation>Nagraj wideo:</translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation>Poruszanie siÄ jeżem</translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts b/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts
index 84d9b4a..afc6a25 100644
--- a/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_pt_BR.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="pt_BR">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">Endereço IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,11 +140,68 @@
<translation>Editar esquemas</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Quando esta opção está habilitada a seleção de um esquema de jogo implicará em auto seleção do esquema de armas</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Não foi possÃvel criar o diretório %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -102,7 +255,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +300,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Seu apelido %1 é
-registrado no Hedgewars.org
-Por favor, forneça sua senha
-ou escolha outro apelido:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">Apelido</translation>
</message>
@@ -165,6 +312,63 @@ ou escolha outro apelido:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,18 +384,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temas</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtro</translation>
- </message>
- <message>
<source>All</source>
<translation>Todos</translation>
</message>
@@ -216,10 +408,6 @@ Please pick another nickname:</source>
<translation>Excêntrico</translation>
</message>
<message>
- <source>Type</source>
- <translation>Tipo</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Túneis estreitos</translation>
</message>
@@ -228,29 +416,97 @@ Please pick another nickname:</source>
<translation>Túneis médios</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Túneis grandes</translation>
+ <source>Seed</source>
+ <translatorcomment>checar</translatorcomment>
+ <translation type="unfinished">Semeie</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Ilhas pequenas</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Ilhas médias</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Ilhas grandes</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translatorcomment>checar</translatorcomment>
- <translation type="unfinished">Semeie</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Aleatório</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
- <translation type="unfinished">Esquema</translation>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Carregar mapa</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -296,7 +552,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 entrou</translation>
+ <translation type="obsolete">%1 *** %2 entrou</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -322,8 +578,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Senha</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -338,6 +609,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -345,7 +638,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -363,6 +663,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -394,6 +705,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Atribuir Dados</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Geral</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -403,6 +746,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -448,8 +802,40 @@ Please pick another nickname:</source>
<translation>Geral</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avançado</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Chapéu</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Nome</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Equipe Aleatória</translation>
</message>
</context>
<context>
@@ -496,327 +882,101 @@ Please pick another nickname:</source>
<translation>
<numerusform><b>%1</b> pensou que era bom atirar na sua própria equipe totalizando <b>%2</b> ponto.</numerusform>
<numerusform><b>%1</b> pensou que era bom atirar na sua própria equipe totalizando <b>%2</b> pontos.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation>
- <numerusform><b>%1</b> matou <b>%2</b> dos próprios ouriços.</p>.</numerusform>
- <numerusform><b>%1</b> matou <b>%2</b> dos próprios ouriços.</p>.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> estava assustado e passou o turno <b>%2</b> vez.</p>.</numerusform>
- <numerusform><b>%1</b> estava assustado e passou o turno <b>%2</b> vezes.</p>.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Use a mesma cor que um amigo para jogar como uma equipe única. Cada um controlará seus próprios ouriços, mas vencerão em equipe (ou perderão).</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Algumas armas que fazem pouco dano podem ser mais que devastadoras na situação certa. Tente usar a Desert Eagle para derrubar vários ouriços na água.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Se você não tem certeza se quer desperdiçar munição ou Ãtens, passe a vez. Mas não deixe muitos turnos passarem ou chegará a Morte Súbita!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Se você quiser evitar que outros usem seu apelido no servidor oficial, registre-o em http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Cansado do jogo padrão? Tente uma das missões - elas oferecem diferentes modos de jogo dependendo da sua escolha.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>O jogo irá, por padrão, sempre gravar o último jogo como demo. Selecione "Jogo Local" e use o botão "Demos" no canto inferior direito para assitir ou gerenciá-los.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars possui código aberto e é grátis, nós o desenvolvemos em nosso tempo livre. Se você encontrou problemas peça ajuda em nossos fóruns, mas não espere ser atendido 24 horas por dia!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars possui código aberto e é grátis, nós o desenvolvemos em nosso tempo livre. Se você deseja ajudar, pode doar ou contribuir com seu trabalho!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars possui código aberto e é grátis, nós o desenvolvemos em nosso tempo livre. Compartilhe com sua famÃlia e amigos!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>De tempos em tempos ocorrem torneios. Esses eventos podem ser acompanhados através do endereço http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars está disponÃvel em diversas linguages! Se você acha que a tradução não te satisfaz ou não é compatÃvel, contacte-nos!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars pode ser jogado em muitos sistemas operacionais, incluindo Windows, Mac OS X e Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Lembre-se que você pode selecionar suas próprias regras em jogos locais ou em rede. Você não está limitado ao "Jogo Simples".</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Não jogue por diversas horas sem descansar! De uma pausa a cada hora.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Se sua placa de vÃdeo não é capaz de suportar aceleração OpenGL, tente ativar a opção de "Qualidade Reduzida" para melhorar a performance.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Somos abertos para sugestões e crÃticas construtivas. Se você não gosta de alguma coisa ou teve uma grande idéia, nos avise!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Seja sempre educado, especialmente quando jogar on line, pois pode haver menores jogando com ou contra você!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Modos especiais de jogo, como Vampirismo ou Karma permitem desenvolver novas táticas. Tente-os em um jogo personalisado!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Não instale este jogo em computadores que não seja permitido (escola, trabalho, universidade). Solicite isso ao responsável!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars pode ser um jogo perfeito nos intervalos! Apenas certifique-se de não adicionar muitos ouriços ou usar um mapa muito grande! Reduzir o tempo de turno e a vida também pode ajudar.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Nenhum ouriço foi ferido para fazer este jogo.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars é um jogo de Código Aberto e grátis que criamos em nosso tempo livre. Se alguém te vendeu este jogo, você deveria pedir reembolso!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Conecte um ou mais joysticks antes de começar o jogo para poder usá-los para controlar a sua equipe.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Crie uma conta em %1 para evitar que outros usem seu apelido quando jogar no servidor oficial.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Se sua placa gráfica não tem aceleração gráfica OpenGl, tente atualizar os drivers relacionados.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Há 3 diferentes pulos. Aperte [pulo alto] 2 vezes para fazer um pulo alto para trás.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translatorcomment>O que é o colchetes?</translatorcomment>
- <translation>Medo de cair de um desfiladeiro? Mantenha pressionado [mira precisa] para virar à [esquerda] or [direita] sem se mover.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Algumas armas necessitam estratégias especiais ou muito treino, então não desista de uma arma ou utilidade se você errou em seu uso.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>Muitas armas não funcionarão após tocar na água. A Abelha e o bolo são excessões a regra.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>O Velho Limburger causa uma pequena explosão. Porém, o vento carregará uma nuvem fedorenta que poderá envenenar muitos ouriços.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>O Ataque com Piano é o mais violento ataque aéreo. Você perderá seu ouriço ao executá-lo, logo, há uma grande contra-partida.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Minas Adesivas são a arma perfeita para criar pequenas reações em cadeias, colocando ouriços inimigos em situações complicadas.... ou na água</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>O Martelo é mais efetivo quando usado em pontes ou vigas. Ouriços atingidos atravessarão o chão.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Se você está preso atrás de um ouriço inimigo, use o Martelo para se libertar sem sofrer danos.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>A distância máxima que o Bolo anda depende do terreno por onde ele passa. Use [ataque] para detoná-lo antes.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>O Lança-Chamas é uma arma porém pode ser usado para cavar túneis também.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Quer saber quem está por trás desse jogo? Clique no logo do Hedgewars no menu principal para ver os créditos.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Gostou de Hedgewars? Se torne um fã no %1 ou nos siga pelo %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Desenhe suas próprias tumbas, chapéus, bandeiras ou até mapas e temas! Mas observe que você terá que compartilhá-los para jogar online.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Realmente quer usar um chapéu especÃfico? Doe para o Hedgewars e receba um chapéu exclusivo!</translation>
+ </translation>
</message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Mantenha a sua placa de vÃdeo atualizada para evitar problemas ao jogar este jogo.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation>
+ <numerusform><b>%1</b> matou <b>%2</b> dos próprios ouriços.</p>.</numerusform>
+ <numerusform><b>%1</b> matou <b>%2</b> dos próprios ouriços.</p>.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Você pode encontrar os arquivos de configuração em "Meus Documentos\Hedgewars". Crie cópias ou leve os arquivos com você, mas não edite eles manualmente.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> estava assustado e passou o turno <b>%2</b> vez.</p>.</numerusform>
+ <numerusform><b>%1</b> estava assustado e passou o turno <b>%2</b> vezes.</p>.</numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Você pode associar os arquivos relacionados ao Hedgewars (jogos salvos e gravações demo), podendo abrÃ-los diretamente do gerenciador de arquivos ou do navegador</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Quer economizar corda? Solte-a quando estiver no meio do ar e então atire de novo. Se você não tocar o solo, você reutilizará a corda e não desperdiçará-la do seu arsenal!</translation>
+ <source>Save</source>
+ <translation type="unfinished">Salvar</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Você pode encontrar os arquivos de configuração do Hedgewars em "Library/Application Support/Hedgewars" no seu diretório base. Crie backups ou leve os arquivos com você, mas não os edite manualmente.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished">Você pode encontrar os arquivos de configuração do Hedgewars em ".hedgewars/" no seu diretório base. Crie backups ou leve os arquivos com você, mas não os edite manualmente.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -826,38 +986,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Começar</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Controle</translation>
+ <translation type="obsolete">Controle</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Start</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Jogo na rede local</translation>
+ <source>Update</source>
+ <translation type="unfinished">Atualizar</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Servidor Oficial</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -904,10 +1068,6 @@ Please pick another nickname:</source>
<translation>Apagar esquema de armas</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Geral</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Avançado</translation>
</message>
@@ -947,6 +1107,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Equipes</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Armas</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -963,11 +1211,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Criar</translation>
+ <translation type="obsolete">Criar</translation>
</message>
<message>
<source>Join</source>
- <translation>Entrar</translation>
+ <translation type="obsolete">Entrar</translation>
</message>
<message>
<source>Admin features</source>
@@ -975,7 +1223,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Nome da Sala:</translation>
+ <translation type="obsolete">Nome da Sala:</translation>
</message>
<message>
<source>Rules:</source>
@@ -987,11 +1235,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Procurar:</translation>
+ <translation type="obsolete">Procurar:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Limpar</translation>
+ <translation type="obsolete">Limpar</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1000,6 +1248,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1146,18 +1418,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1166,26 +1430,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Carregar</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1231,19 +1483,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1254,10 +1508,6 @@ Please pick another nickname:</source>
<translation>Chutar</translation>
</message>
<message>
- <source>Start</source>
- <translation>Iniciar</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Restringir Participação</translation>
</message>
@@ -1295,7 +1545,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Atualizar</translation>
+ <translation type="obsolete">Atualizar</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1305,10 +1567,6 @@ Please pick another nickname:</source>
<translation>Tela cheia</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Habilitar sons</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Mostrar FPS (Performance)</translation>
</message>
@@ -1317,14 +1575,6 @@ Please pick another nickname:</source>
<translation>Mostrar dano de maneira alternativa</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Habilitar música</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Interface em tela cheia</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Adicionar data e hora no nome do arquivo</translation>
</message>
@@ -1337,45 +1587,57 @@ Please pick another nickname:</source>
<translation>Mostrar instruções no menu de armas</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Habilitar sons da interface</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Habilitar música da interface</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Efeitos da interface</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>mapa gerado...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Humano</translation>
</message>
@@ -1388,14 +1650,6 @@ Please pick another nickname:</source>
<translation>(Padrão do sistema)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>labirinto gerado...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Missão</translation>
- </message>
- <message>
<source>Community</source>
<translation>Comunidade</translation>
</message>
@@ -1405,15 +1659,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>Em espera</translation>
+ <translation type="obsolete">Em espera</translation>
</message>
<message>
<source>In progress</source>
- <translation>Em progresso</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation type="unfinished">mapa desenhado a mão...</translation>
+ <translation type="obsolete">Em progresso</translation>
</message>
<message>
<source>Disabled</source>
@@ -1452,10 +1702,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1487,22 +1733,10 @@ Please pick another nickname:</source>
<translation>Membros da equipe</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Associação de teclas</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Forte</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Equipes</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Opções de áudio e gráficos</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Jogo em rede</translation>
</message>
@@ -1511,36 +1745,16 @@ Please pick another nickname:</source>
<translation>Equipes em jogo</translation>
</message>
<message>
- <source>Game Modifiers</source>
- <translation>Modificadores de Jogo</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Opções Básicas</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Opções de Equipe</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Misc</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Esquemas e Armas</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <source>Game Modifiers</source>
+ <translation>Modificadores de Jogo</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Opções Básicas</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Opções de Equipe</translation>
</message>
<message>
<source>Videos</source>
@@ -1550,30 +1764,10 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Developers:</source>
- <translation>Desenvolvedores:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Arte:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Traduções:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Agradecimentos especiais:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Armas</translation>
</message>
@@ -1603,11 +1797,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Versão</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sons:</translation>
+ <translation type="obsolete">Versão</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1646,10 +1836,6 @@ Please pick another nickname:</source>
<translation>Caixas caem</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Esquema de jogo</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Minas falhas</translation>
</message>
@@ -1686,10 +1872,6 @@ Please pick another nickname:</source>
<translation>Dica:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Esta versão do Hedgewars é um trabalho em progresso e pode não ser compatÃvel com outras versões do jogo. Algumas coisas podem não funcionar ou podem estar incompletas. Use a sua conta e risco!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Qualidade</translation>
</message>
@@ -1730,10 +1912,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1764,10 +1942,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1795,6 +1969,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Tela cheia</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1817,6 +2035,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1833,10 +2055,6 @@ Do you really want to quit?</source>
<translation>Associação de arquivos falhou.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1883,47 +2101,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Não foi possÃvel criar o diretório %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Não foi possÃvel criar o diretório %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Não foi possÃvel iniciar o servidor: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Não foi possÃvel iniciar o servidor: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2042,16 +2225,42 @@ Você ainda quer entrar na sala?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Apelido</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Entre com seu apelido</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2109,47 +2318,86 @@ Você ainda quer entrar na sala?</translation>
<translation>Carregar</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Configuração</translation>
+ <source>Associate file extensions</source>
+ <translation>Associar extensão de arquivos.</translation>
</message>
<message>
- <source>Ready</source>
- <translation>Pronto</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Equipe Aleatória</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
- <translation>Associar extensão de arquivos.</translation>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>More info</source>
+ <source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set default options</source>
+ <source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Open videos directory</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Upload to YouTube</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cancel uploading</source>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2201,6 +2449,25 @@ Você ainda quer entrar na sala?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2229,105 +2496,43 @@ Você ainda quer entrar na sala?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirismo</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artilharia</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Modo de Forte</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Dividir Equipes</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Terreno Sólido</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Adicionar Bordas</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Baixa Gravidade</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Mira Laser</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Invulnerabilidade</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Ordem Aleatória</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Rei</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Posicionar Ouriços</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Clan Compartilha Armas</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Desabilitar Vigas</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Desabilitar objetos do terreno</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>AI Modo de Sobrevivência</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>Ataques Ilimitados</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Reset Weapons</source>
- <translation>Reiniciar Armas</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Munição por Ouriço</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Reset Health</source>
- <translation>Restaurar Vida</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation type="unfinished">Desativar Vento</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished">Mais Vento</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancelar</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2446,12 +2651,6 @@ Você ainda quer entrar na sala?</translation>
<translation>capturar</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>informação dos
-ouriços</translation>
- </message>
- <message>
<source>quit</source>
<translation>sair</translation>
</message>
@@ -2503,33 +2702,33 @@ ouriços</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Controles Básicos</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Controles das armas</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Armas</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Controle de câmera e cursor</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Outros</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Mova seu ouriço e mire:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Atravesse buracos e obstáculos pulando:</translation>
</message>
@@ -2593,6 +2792,10 @@ ouriços</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts b/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
index 5a39430..2f9eb52 100644
--- a/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_pt_PT.ts
@@ -2,10 +2,17 @@
<!DOCTYPE TS>
<TS version="2.0" language="pt_PT">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation>Compilador Desconhecido</translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
- <translation>Retrodecer</translation>
+ <translation>Retroceder</translation>
</message>
</context>
<context>
@@ -16,7 +23,96 @@
</message>
<message>
<source>copy of</source>
- <translation>copia de</translation>
+ <translation>cópia de</translation>
+ </message>
+</context>
+<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>Utilizador</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Utilizador</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Motivo</translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation>Duração</translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>Ok</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation>tu sabes porquê</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Aviso</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation>Por favor, especifica %1</translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>utilizador</translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation>permanente</translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation>Utilizar configuração por omissão</translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation>Ver</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation>Enviar Feedback</translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -44,12 +140,76 @@
<translation>Editar esquemas</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Com esta opção activada o esquema de jogo irá automaticamente seleccionar uma arma</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Opções de Jogo</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Opções de Jogo</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation>O esquema de jogo irá auto-selecionar uma arma</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation>Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation>Opções de jogo</translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1 minuto</numerusform>
+ <numerusform>%1 minutos</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1 hora</numerusform>
+ <numerusform>%1 horas</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1 hora</numerusform>
+ <numerusform>%1 horas</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation>
+ <numerusform>%1 dia</numerusform>
+ <numerusform>%1 dias</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1 dia</numerusform>
+ <numerusform>%1 dias</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Não foi possÃvel criar o diretório %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished">Erro ao abrir o diretório:
+%1
+
+Por favor verifica a tua instalação!</translation>
</message>
</context>
<context>
@@ -87,7 +247,7 @@
</message>
<message>
<source>Couldn't read %1</source>
- <translation>Não foi possivel carregar %1</translation>
+ <translation>Não foi possÃvel carregar %1</translation>
</message>
<message>
<source>StyleSheet discarded</source>
@@ -102,8 +262,16 @@
<translation>Não foi possÃvel gravar o StyleSheet em %1</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 não é um comando valido!</translation>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -139,20 +307,6 @@
<translation>Jogo abortado</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>O nome de utilizador %1 está
-registado em Hedgewars.org
-Por favor digita a tua palavra passe ou escolhe
-outro nome de utilizador no menu de configuração:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>Não foi fornecida uma palavra passe.</translation>
- </message>
- <message>
<source>Nickname</source>
<translation>Nome de utilizador</translation>
</message>
@@ -163,9 +317,75 @@ outro nome de utilizador no menu de configuração:</translation>
<message>
<source>Someone already uses your nickname %1 on the server.
Please pick another nickname:</source>
- <translation>Alguem já está a utilizar o teu nome de utilizador %1 no servidor.
+ <translation>Alguém já está a utilizar o teu nome de utilizador %1 no servidor.
Por favor escolhe outro nome de utilizador:</translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation>Equipa de %1</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation>Hedgewars - Utilizador registado</translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation>Este utilizador está registado, e não foi especificada uma palavra-passe.
+
+Se este utilizador não te pertence, acede a www.hedgewars.org e regista o teu próprio utilizador.
+
+Palavra-passe:</translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation>O teu nome de utilizador não está registado.
+De forma a prevenir que alguém o utilize,
+por favor regista-o em www.hedgewars.org</translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation>
+
+A tua palavra-passe também não foi gravada.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation>Hedgewars - Utilizador vazio</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation>Hedgewars - Palavra-passe incorreta</translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation>Introduziste a palavra-passe errada.</translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation>Tenta Novamente</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation>Hedgewars - Erro na ligação</translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation>Tentás-te voltar ao servidor num espaço de tempo demasiado curto.
+Por favor, aguarda alguns segundos e tenta novamente.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -181,18 +401,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temas</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtro</translation>
- </message>
- <message>
<source>All</source>
<translation>Todos</translation>
</message>
@@ -217,40 +425,108 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Invulgar</translation>
</message>
<message>
- <source>Type</source>
- <translation>Tipo</translation>
- </message>
- <message>
<source>Small tunnels</source>
- <translation>Túneis pequenos</translation>
+ <translation>Túneis estreitos</translation>
</message>
<message>
<source>Medium tunnels</source>
- <translation>Túneis medios</translation>
+ <translation>Túneis médios</translation>
+ </message>
+ <message>
+ <source>Seed</source>
+ <translation>Semente</translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation>Mapa:</translation>
+ </message>
+ <message>
+ <source>Image map</source>
+ <translation>Imagem</translation>
+ </message>
+ <message>
+ <source>Mission map</source>
+ <translation>Missão</translation>
+ </message>
+ <message>
+ <source>Hand-drawn</source>
+ <translation>Desenhado à mão</translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation>Aleatoriamente gerado</translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation>Labirinto aleatório</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>Aleatório</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation>Pré-visualização do mapa:</translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation>Carregar mapa desenhado</translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation>Editar mapa desenhado</translation>
</message>
<message>
<source>Large tunnels</source>
- <translation>Túneis grandes</translation>
+ <translation>Túneis largos</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Ilhas flutuantes pequenas</translation>
+ <source>Small islands</source>
+ <translation>Ilhas pequenas</translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Ilhas flutuantes médias</translation>
+ <source>Medium islands</source>
+ <translation>Ilhas médias</translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Ilhas flutuantes grandes</translation>
+ <source>Large islands</source>
+ <translation>Ilhas grandes</translation>
</message>
<message>
- <source>Seed</source>
- <translation>Semente</translation>
+ <source>Map size:</source>
+ <translation>Tamanho do mapa:</translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation>Estilo de labirinto:</translation>
</message>
<message>
- <source>Set</source>
- <translation>Definir</translation>
+ <source>Mission:</source>
+ <translation>Missão:</translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation>Mapa:</translation>
+ </message>
+ <message>
+ <source>Theme: </source>
+ <translation type="obsolete">Tema: </translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation>Carregar mapa desenhado</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation>Mapas Desenhados</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>Todos os ficheiros</translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -276,7 +552,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Connection refused</source>
- <translation>Conexão rejeitada</translation>
+ <translation>Ligação rejeitada</translation>
</message>
<message>
<source>Room destroyed</source>
@@ -284,11 +560,11 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Quit reason: </source>
- <translation>Motivo de saÃda: </translation>
+ <translation>Motivo: </translation>
</message>
<message>
<source>You got kicked</source>
- <translation>Foi expulso</translation>
+ <translation>Foste expulso</translation>
</message>
<message>
<source>%1 *** %2 has joined the room</source>
@@ -296,7 +572,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 juntou-se</translation>
+ <translation type="obsolete">%1 *** %2 entrou</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -322,8 +598,23 @@ Por favor escolhe outro nome de utilizador:</translation>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation>Palavra-passe</translation>
+ <source>Login</source>
+ <translation>Login</translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -338,21 +629,52 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation>Trocar chapéu (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation>Utiliza o chapéu selecionado</translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation>Procurar:</translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
- <translation>SDL_ttf retornou um erro ao renderizar o texto, muito provavelmente está relacionado com o bug no freetype2. à recomendado actualizar a sua lib freetype.</translation>
+ <translation>SDL_ttf retornou um erro ao renderizar o texto, muito provavelmente está relacionado com o bug no freetype2. à recomendado atualizar a sua lib freetype.</translation>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
<message>
- <source>Duration: %1m %2s</source>
- <translation>Duração: %1m %2s</translation>
+ <source>Category</source>
+ <translation>Categoria</translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <source>Duration: %1m %2s
+</source>
+ <translation>Duração: %1m %2s
+</translation>
</message>
<message>
<source>Video: %1x%2, </source>
- <translation>VÃdeo: %1x%2, </translation>
+ <translation>VÃdeo: %1x%2, </translation>
</message>
<message>
<source>%1 fps, </source>
@@ -360,7 +682,18 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Audio: </source>
- <translation>Audio: </translation>
+ <translation>Ãudio: </translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation>desconhecido</translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation>Nenhuma descrição disponÃvel.</translation>
</message>
</context>
<context>
@@ -393,6 +726,38 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>Set data</source>
<translation>Gravar modificações</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation>Expulsões</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/Utilizador</translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation>Expiração</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>Motivo</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation>Atualizar</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>Adicionar</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>Remover</translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +767,17 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +823,40 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Geral</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avançado</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation>Seleciona uma ação para personalizar uma tecla com esta equipa</translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation>Configuração por omissão</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Repor todos os valores</translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation>Controlos Personalizados</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>Chapéu</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Nome</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation>Nome deste ouriço</translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation>Escolhe um nome para este ouriço aleatoriamente</translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation>Gerar Equipa Aleatória</translation>
</message>
</context>
<context>
@@ -472,8 +880,8 @@ Por favor escolhe outro nome de utilizador:</translation>
<message numerus="yes">
<source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
<translation>
- <numerusform>O extreminador da ronda foi <b>%1</b> com <b>%2</b> morto num unico turno.</numerusform>
- <numerusform>O extreminador da ronda foi <b>%1</b> com <b>%2</b> mortes num unico turno.</numerusform>
+ <numerusform>O exterminador da ronda foi <b>%1</b> com <b>%2</b> morto num unico turno.</numerusform>
+ <numerusform>O exterminador da ronda foi <b>%1</b> com <b>%2</b> mortes num unico turno.</numerusform>
</translation>
</message>
<message numerus="yes">
@@ -483,319 +891,74 @@ Por favor escolhe outro nome de utilizador:</translation>
<numerusform>Um total de <b>%1</b> ouriços perderam a vida durante esta ronda.</numerusform>
</translation>
</message>
- <message numerus="yes">
- <source>(%1 kill)</source>
- <translation>
- <numerusform>(%1 morto)</numerusform>
- <numerusform>(%1 mortos)</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
- <translation>
- <numerusform><b>%1</b> axou que seria divertido atacar a sua própria equipa causando <b>%2</b> ponto de dano.</numerusform>
- <numerusform><b>%1</b> axou que seria divertido atacar a sua própria equipa causando um total de <b>%2</b> pontos de dano.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation>
- <numerusform><b>%1</b> matou <b>%2</b> ouriço da sua própria equipa.</numerusform>
- <numerusform><b>%1</b> matou <b>%2</b> ouriços da sua própria equipa.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> estava tão amedrontado que passou <b>%2</b> turno.</numerusform>
- <numerusform><b>%1</b> estava tão amedrontado que passou <b>%2</b> turnos.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation>Em jogo...</translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation>Abrir a pasta com as capturas de ecrã</translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Simplesmente selecciona a mesma cor de outro jogador para jogarem em equipa. Continuas a ter total controlo dos teus ouriços, mas ganham ou perdem juntos.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Algumas armas podem não fazer muito dano, mas em ocasiões especificas podem-se demonstrar bastante mais letais. Experimenta usar a Desert Eagle para empurrar varios ouriços para a água.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Se não tens a certeza do que fazer a seguir não desperdiçes munições, passa o turno. Mas não desperdices muito tempo, a Morte Súbita aproxima-se.</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Se não queres que outros usem o teu nome de utilizador preferido no servidor oficial, regista-o em http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Estás cansado do modo de jogo habitual? Experimenta uma das missões - existem várias por onde escolher, e todas com objectivos um pouco diferentes.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Por defeito, o ultimo jogo em que participaste é sempre gravado como 'demo'. Selecciona 'Jogo Local' e aà a opção 'Demos' no canto inferior direito para os gerir ou reproduzir.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>O Hedgewars é Open Source e Freeware, desenvolvido nos tempos livres. Se tiveres algum problema pergunta nos fóruns, mas por favor não esperes suporte 24/7!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>O Hedgewars é Open Source e Freeware, desenvolvido nos tempos livres. Se gostares do jogo podes contribuir com uma pequena doação ou o teu próprio trabalho!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>O Hedgewars é Open Source e Freeware, desenvolvido nos tempos livres. Partilha-o com a famÃlia e amigos como quiseres!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>De tempos a tempos realizam-se torneios oficiais. Todos estes eventos são anunciados em http://www.hedgewars.org/ com alguns dias de antecedência.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>O Hedgewars está disponÃvel em vários idiomas. Se a tradução do teu idioma está desactualizada ou em falta, não hesites em contactar-nos!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>O Hedgewars está disponÃvel para vários sistemas operativos incluindo Microsoft Windows, Mac OS X e Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Lembra-te que tens sempre a opção de poder jogar na tua rede local ou online. Não estás restrito ao modo de Jogo Local.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Lembra-te de fazer pequenos intervalos durante sessões de jogo prolongadas.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Se a tua placa gráfica não é capaz de fornecer aceleração por hardware para OpenGL experimenta activar o modo de baixa qualidade para melhorar a performance.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Estamos abertos a sugestões e crÃticas construtivas. Se há algo que não gostas em particular ou tiveste uma boa ideia, deixa-nos saber!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Especialmente durante partidas online é importante ser educado. Lembra-te que podem haver menores a jogar com ou contra ti!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Modos de jogo especiais como 'Vampirismo' ou 'Karma' permitem-te desenvolver tácticas completamente novas! Experimenta-os num jogo personalizado!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Não deves instalar o Hedgewars em computadores que não te pertençam (escola, universidade, trabalho, etc.). Por favor contacta o responsável caso o pretendas fazer.</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>O Hedgewars é perfeito para pequenos jogos durante intervalos. Tem apenas a certeza que não adicionas muitos ouriços ou usas um mapa muito grande. Reduzir o tempo e pontos de vida pode ajudar também.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Nenhum ouriço foi mal tratado durante a produção deste jogo.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>O Hedgewars é Open Source e Freeware desenvolvido durante o tempo livre. Se alguem te vendeu o jogo, tente obter o reembolso!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Conecta um ou mais comandos antes de lançar o jogo para que seja possÃvel configura-los com as tuas equipas.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Cria uma conta em http://www.hedgewars.org/ para prevenir que outros usem o teu nome de utilizador favorito no servidor oficial.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Se a tua placa gráfica se está a demonstrar incapaz de fornecer aceleração gráfica em OpenGL, experimenta actualizar os drivers da mesma.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Existem três diferentes tipos de salto. Pressiona [salto alto] duas vezes para fazer um salto muito alto para trás.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Com medo de cair de um penhasco? Deixa o [botão de precisão] pressionado e vira-te para a [direita] ou [esquerda] sem sair do sitio.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Algumas armas requerem estratégias especiais ou imensa prática, por isso não desistas imediatamente dessa ferramenta em particular se falhares o alvo.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>A maiora das armas deixa de funcionar se tocarem na água. A Abelha Teleguiada e o Bolo são excepções a esta regra.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>O Limburger Venho causa apenas uma pequena explosão. No entanto a pequena nuvem malcheirosa, afectada pelo vento, pode envenenar vários ouriços de uma vez.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>O Piano é o ataque aéreo que mais potencial dano causa. No entanto uma enorme desvantagem, é necessario sacrificar um ouriço para o utilizar.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>As Minas Pegajosas são a arma ideal para com pequenas explosões em cadeia empurrar ouriços para situações terrÃveis... ou para a água.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>O melhor local para usar o Martelo é em pontes ou vigas. Os ouriços atingidos nestes locais vão simplesmente furar pelo chão.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Se ficares preso atrás de um ouriço inimigo utiliza o Martelo para te libertares sem ser necessário levar dano de uma explosão.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>A distancia máxima que o Bolo é capaz de alcançar depende do terreno que tenha de ultrapassar. Podes também utilizar [ataque] para o detonar a qualquer altura.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Embora o Lança-chamas seja uma arma, pode também ser usado para escavar túneis.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Gostavas de saber quem está por traz deste jogo? Clica no logótipo do Hedgewars no menu inicial para aceder aos créditos.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Gostas do Hedgewars? Torna-te fã no %1 ou segue-nos pelo %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Está à vontade para desenhar as tuas próprias sepulturas, chapéus, bandeiras ou mesmo mapas e temas! Tem em nota que vai ser necessário partilha-los algures para que os consigas usar online.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Gostavas poder usar um chapéu em particular que ainda não existe? Faz uma pequena doação para este projecto e recebe um chapéu exclusivo à tua escolha!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Mantém os drivers da placa gráfica actualizados de forma a evitar problemas com o jogo.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Podes encontrar os ficheiros de configuração do Hedgewars em "Documentos\Hedgewars". Cria cópias de segurança ou leva os ficheiros contigo, apenas não os edites.</translation>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation>
+ <numerusform>(%1 morto)</numerusform>
+ <numerusform>(%1 mortos)</numerusform>
+ </translation>
</message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>à possivel associar os ficheiros relacionados com o Hedgewars (partidas e demonstrações) directamente com o jogo para que seja possivel lançalos directamente do teu explorador de ficheiros ou internet favorito.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation>
+ <numerusform><b>%1</b> axou que seria divertido atacar a sua própria equipa causando <b>%2</b> ponto de dano.</numerusform>
+ <numerusform><b>%1</b> axou que seria divertido atacar a sua própria equipa causando um total de <b>%2</b> pontos de dano.</numerusform>
+ </translation>
</message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Gostavas de poupar algumas cordas? Solta a corda enquanto no ar e dispara-a novamente. Desde que não toques no solo podes reutilizar a usar a mesma corda quantas vezes quiseres!</translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation>
+ <numerusform><b>%1</b> matou <b>%2</b> ouriço da sua própria equipa.</numerusform>
+ <numerusform><b>%1</b> matou <b>%2</b> ouriços da sua própria equipa.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Podes encontrar os ficheiros de configuração do Hedgewars em "Library/Application Support/Hedgewars" dentro da tua "Pasta Pessoal". Cria cópias de segurança ou leva os ficheiros contigo, mas não os edites manualmente.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> estava tão amedrontado que passou <b>%2</b> turno.</numerusform>
+ <numerusform><b>%1</b> estava tão amedrontado que passou <b>%2</b> turnos.</numerusform>
+ </translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Podes encontrar os ficheiros de configuração do Hedgewars em ".hedgewars" dentro da tua "Pasta Pessoal". Cria cópias de segurança ou leva os ficheiros contigo, mas não os edites manualmente.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>A versão do Hedgewars para Windows suporta Xfire. Não te esqueças de adicionar o Hedgewars à tua lista de jogos para que os teus amigos te possam ver a jogar.</translation>
+ <source>Save</source>
+ <translation type="unfinished">Gravar</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Utiliza um Molotov ou o Lança-chamas para temporariamente impedir outros ouriços de passar por áreas no terreno como túneis ou plataformas.</translation>
+ <source>In game...</source>
+ <translation>Em jogo...</translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>A Abelha Teleguiada pode-se demonstrar complicada de utilizar. O grau a que consegue virar depende da sua velocidade, por isso experimenta lança-la com diferentes nÃveis de força.</translation>
+ <source>Open the snapshot folder</source>
+ <translation>Abrir a pasta de capturas de ecrã</translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
<source>Downloadable Content</source>
<translation>Conteúdo TransferÃvel (DLC)</translation>
</message>
<message>
- <source>Local Game</source>
- <translation>Jogo Local</translation>
- </message>
- <message>
<source>Play a game on a single computer</source>
<translation>Joga num único computador</translation>
</message>
<message>
- <source>Network Game</source>
- <translation>Jogo em Rede</translation>
- </message>
- <message>
<source>Play a game across a network</source>
<translation>Joga Hedgewars através da rede</translation>
</message>
<message>
<source>Read about who is behind the Hedgewars Project</source>
- <translation>Lê sobre quem está por trás do Projecto Hedgewars</translation>
+ <translation>Descobre quem está por trás do Projecto Hedgewars</translation>
</message>
<message>
<source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
@@ -815,7 +978,27 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Edit game preferences</source>
- <translation>Editar as preferencias de jogo</translation>
+ <translation>Editar as preferências de jogo</translation>
+ </message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation>Joga na rede local</translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation>Joga num servidor oficial</translation>
+ </message>
+ <message>
+ <source>Feedback</source>
+ <translation>Feedback</translation>
+ </message>
+ <message>
+ <source>Play local network game</source>
+ <translation>Jogar na rede local</translation>
+ </message>
+ <message>
+ <source>Play official network game</source>
+ <translation>Jogar no servidor oficial</translation>
</message>
</context>
<context>
@@ -824,39 +1007,39 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>Start</source>
<translation>Iniciar</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation>Editar preferências de jogo</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
- <source>Control</source>
- <translation>Controlo</translation>
- </message>
- <message>
- <source>DLC</source>
- <translation>DLC</translation>
+ <source>Edit game preferences</source>
+ <translation>Editar preferências de jogo</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Conteúdo TransferÃvel</translation>
+ <source>Start</source>
+ <translation>Iniciar</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>Jogo em LAN</translation>
+ <source>Update</source>
+ <translation>Atualizar</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Servidor oficial</translation>
+ <source>Room controls</source>
+ <translation>Restrições</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
- <translation>Junta-te a centenas de jogadores online!</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation>Cria ou junta-te a jogo numa Rede Local</translation>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -902,16 +1085,12 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Apagar esquema de armas</translation>
</message>
<message>
- <source>General</source>
- <translation>Geral</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>Avançado</translation>
</message>
<message>
<source>Reset to default colors</source>
- <translation>Repor cores por omisão</translation>
+ <translation>Repor cores por omissão</translation>
</message>
<message>
<source>Proxy host</source>
@@ -945,6 +1124,94 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>System proxy settings</source>
<translation>Configuração proxy do sistema</translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation>Seleciona uma ação para alterar a tecla que a controla</translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation>Repor valor por omissão</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>Repor todos os valores</translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation>Jogo</translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation>Gráficos</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>Ãudio</translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation>Controlos</translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation>VÃdeo Gravação</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>Rede</translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation>Equipas</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation>Esquemas</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation>Armamento</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation>Frontend</translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation>Cores personalizadas</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation>Ãudio de jogo</translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation>Ãudio do frontend</translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation>Conta</translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation>Definições do Proxy</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation>Outras opções</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation>Atualizações</translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation>Procurar atualizações</translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation>Opções de criação de vÃdeo</translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -960,36 +1227,16 @@ Por favor escolhe outro nome de utilizador:</translation>
<context>
<name>PageRoomsList</name>
<message>
- <source>Create</source>
- <translation>Criar</translation>
- </message>
- <message>
- <source>Join</source>
- <translation>Entrar</translation>
- </message>
- <message>
<source>Admin features</source>
<translation>Recursos de administrador</translation>
</message>
<message>
- <source>Room Name:</source>
- <translation>Nome da Sala:</translation>
- </message>
- <message>
<source>Rules:</source>
- <translation>Regras</translation>
+ <translation>Regras:</translation>
</message>
<message>
<source>Weapons:</source>
- <translation>Armas:</translation>
- </message>
- <message>
- <source>Search:</source>
- <translation>Pesquisa:</translation>
- </message>
- <message>
- <source>Clear</source>
- <translation>Limpar</translation>
+ <translation>Armamento:</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1245,30 @@ Por favor escolhe outro nome de utilizador:</translation>
<numerusform>%1 jogadores online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation>Procurar sala:</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Criar sala</translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation>Entrar no jogo</translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation>Estado da sala</translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation>Limpar filtros</translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation>Abrir menu de administração do servidor</translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1035,7 +1306,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Your hogs are unable to move, put your artillery skills to the test</source>
- <translation>Os teus ouriços serão impossibilidados de se mover, testa as tuas capacidades no modo artilharia</translation>
+ <translation>Os teus ouriços serão impossibilitados de se mover, testa as tuas capacidades no modo artilharia</translation>
</message>
<message>
<source>Random</source>
@@ -1067,15 +1338,15 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Ammo is shared between all teams that share a colour.</source>
- <translation>As armas são partilhadas entre todas as equipas da mesma cor.</translation>
+ <translation>O armamento é partilhado entre todas as equipas da mesma cor.</translation>
</message>
<message>
<source>Disable girders when generating random maps.</source>
- <translation>Desactivar vigas em mapas gerados aleatoriamente.</translation>
+ <translation>Desativar vigas em mapas gerados aleatoriamente.</translation>
</message>
<message>
<source>Disable land objects when generating random maps.</source>
- <translation>Não adicionar objectos no terreno ao gerar mapas aleatórios.</translation>
+ <translation>Não adicionar objetos no terreno ao gerar mapas aleatórios.</translation>
</message>
<message>
<source>AI respawns on death.</source>
@@ -1103,7 +1374,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Wind will affect almost everything.</source>
- <translation>O vento afecta praticamente tudo.</translation>
+ <translation>O vento afeta praticamente tudo.</translation>
</message>
<message>
<source>Copy</source>
@@ -1144,18 +1415,10 @@ Por favor escolhe outro nome de utilizador:</translation>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation>Jogo Simples</translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation>Joga um jogo rápido contra o computador com configurações aleatórias</translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation>Multi-jogador</translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation>Joga alternadamente contra os teus amigos, ou o computador</translation>
</message>
@@ -1164,26 +1427,14 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Modo Campanha</translation>
</message>
<message>
- <source>Training Mode</source>
- <translation>Modo Treino</translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation>Pratica as tuas habilidades numa variedade de missões de treino</translation>
</message>
<message>
- <source>Demos</source>
- <translation>Demos</translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation>Assistir aos demos guardados</translation>
</message>
<message>
- <source>Load</source>
- <translation>Carregar</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation>Carrega um jogo gravado anteriormente</translation>
</message>
@@ -1196,7 +1447,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Select a mission!</source>
- <translation>Selecciona uma missão!</translation>
+ <translation>Seleciona uma missão!</translation>
</message>
<message>
<source>Pick the mission or training to play</source>
@@ -1229,14 +1480,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>(em progresso...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation>Data: </translation>
- </message>
- <message>
- <source>Size: </source>
- <translation>Tamanho: </translation>
- </message>
- <message>
<source>encoding</source>
<translation>a converter</translation>
</message>
@@ -1244,6 +1487,18 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>uploading</source>
<translation>a enviar</translation>
</message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>Data: %1
+</translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation>Tamanho: %1
+</translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1256,16 +1511,12 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Informação</translation>
</message>
<message>
- <source>Start</source>
- <translation>Iniciar</translation>
- </message>
- <message>
<source>Restrict Joins</source>
- <translation>Restringir entradas</translation>
+ <translation>Impedir a entrada de novos utilizadores</translation>
</message>
<message>
<source>Restrict Team Additions</source>
- <translation>Restringir adição de equipas</translation>
+ <translation>Trancar a adição de equipas</translation>
</message>
<message>
<source>Ban</source>
@@ -1292,33 +1543,29 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Remover amigo</translation>
</message>
<message>
- <source>Update</source>
- <translation>Actualizar</translation>
+ <source>Restrict Unregistered Players Join</source>
+ <translation>Impedir a entrada de utilizadores não registados</translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation>Mostrar jogos a aguardar jogadores</translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation>Mostrar jogos em progresso</translation>
</message>
</context>
<context>
<name>QCheckBox</name>
<message>
<source>Check for updates at startup</source>
- <translation>Verificar por actualizações no arranque</translation>
+ <translation>Verificar por atualizações no arranque</translation>
</message>
<message>
<source>Fullscreen</source>
<translation>Ecrã completo</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Menu em ecrã completo</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Activar som</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Activar música</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Mostrar FPS</translation>
</message>
@@ -1332,19 +1579,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Show ammo menu tooltips</source>
- <translation>Mostrar a ajuda no menu das armas</translation>
- </message>
- <message>
- <source>Enable frontend sounds</source>
- <translation>Activar os sons no frontend</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>Activar a musica no frontend</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>Efeitos no frontend</translation>
+ <translation>Mostrar a ajuda no menu de armamento</translation>
</message>
<message>
<source>Save password</source>
@@ -1360,20 +1595,44 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Record audio</source>
- <translation>Gravar audio</translation>
+ <translation>Gravar áudio</translation>
</message>
<message>
<source>Use game resolution</source>
<translation>Utilizar a resolução do jogo</translation>
</message>
+ <message>
+ <source>Visual effects</source>
+ <translation>Efeitos visuais</translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation>Som</translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation>Efeitos sonoros durante o jogo</translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation>Musica</translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation>Musica durante o jogo</translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation>Efeitos sonoros no frontend</translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation>Musica no frontend</translation>
+ </message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>mapa gerado...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Humano</translation>
</message>
@@ -1386,14 +1645,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>(Definições por omissão)</translation>
</message>
<message>
- <source>Mission</source>
- <translation>Missão</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation>labirinto gerado...</translation>
- </message>
- <message>
<source>Community</source>
<translation>Comunidade</translation>
</message>
@@ -1402,20 +1653,8 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Qualquer</translation>
</message>
<message>
- <source>In lobby</source>
- <translation>No lobby</translation>
- </message>
- <message>
- <source>In progress</source>
- <translation>Em progresso</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>mapa desenhado à mão...</translation>
- </message>
- <message>
<source>Disabled</source>
- <translation>Desactivado</translation>
+ <translation>Desativado</translation>
</message>
<message>
<source>Red/Cyan</source>
@@ -1450,10 +1689,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Cima-baixo</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>"Wiggle"</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Vermelho/Ciano (tons de cinza)</translation>
</message>
@@ -1489,18 +1724,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Forte</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Associação de teclas</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Equipas</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Opções de Ãudio/Gráficos</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Jogo em rede</translation>
</message>
@@ -1508,37 +1731,17 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>Playing teams</source>
<translation>Equipas a jogar</translation>
</message>
- <message>
- <source>Game Modifiers</source>
- <translation>Modificadores de jogo</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Definições básicas</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Configurações de Equipa</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Diversos</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Esquemas e Armamento</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation>Cores personalizadas</translation>
+ <message>
+ <source>Game Modifiers</source>
+ <translation>Modificadores de jogo</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation>Outras opções</translation>
+ <source>Basic Settings</source>
+ <translation>Definições básicas</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation>Opções de criação de vÃdeo</translation>
+ <source>Team Settings</source>
+ <translation>Configurações de Equipa</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,10 +1751,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<source>Description</source>
<translation>Descrição</translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation>Definições do Proxy</translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1564,32 +1763,8 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Minas</translation>
</message>
<message>
- <source>Version</source>
- <translation>Versão</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Programadores:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Arte:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Som:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Tradutores:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Agradecimentos especiais:</translation>
- </message>
- <message>
<source>Weapons</source>
- <translation>Armas</translation>
+ <translation>Armamento</translation>
</message>
<message>
<source>Host:</source>
@@ -1644,10 +1819,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Queda de Caixas</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Esquema de jogo</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% Minas Falsas</translation>
</message>
@@ -1684,10 +1855,6 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>Dica: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Qualidade</translation>
</message>
@@ -1701,7 +1868,7 @@ Por favor escolhe outro nome de utilizador:</translation>
</message>
<message>
<source>Sudden Death Water Rise</source>
- <translation>Súbida da Ãgua durante Morte Súbita</translation>
+ <translation>Subida da Ãgua durante Morte Súbita</translation>
</message>
<message>
<source>Sudden Death Health Decrease</source>
@@ -1728,14 +1895,10 @@ Por favor escolhe outro nome de utilizador:</translation>
<translation>% Tempo Para Retirar</translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation>Esta aplicação é distribuÃda sob a GNU General Public License v2</translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
- <translation>Existem vÃdeos a serem currentemente processados.
+ <translation>Existem vÃdeos a serem correntemente processados.
Sair irá cancela-los.
Deseja mesmo sair?</translation>
</message>
@@ -1757,15 +1920,11 @@ Deseja mesmo sair?</translation>
</message>
<message>
<source>Video description: </source>
- <translation>Descrição do vÃdeo</translation>
+ <translation>Descrição do vÃdeo: </translation>
</message>
<message>
<source>Tags (comma separated): </source>
- <translation>Tags\Etiquetas (separados por virgula)</translation>
- </message>
- <message>
- <source>Summary </source>
- <translation>Sumário </translation>
+ <translation>Tags\Etiquetas (separados por virgula): </translation>
</message>
<message>
<source>Description</source>
@@ -1781,7 +1940,7 @@ Deseja mesmo sair?</translation>
</message>
<message>
<source>Audio codec</source>
- <translation>Codec de Audio</translation>
+ <translation>Codec de Ãudio</translation>
</message>
<message>
<source>Video codec</source>
@@ -1795,6 +1954,50 @@ Deseja mesmo sair?</translation>
<source>Bitrate (Kbps)</source>
<translation>Bitrate (Kbps)</translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation>Esta versão de desenvolvimento demonstra um "trabalho em progresso" o qual pode não ser compatÃvel com outras versões do jogo, enquanto algumas funcionalidades podem estar inutilizáveis ou incompletas!</translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>Ecrã completo</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation>Resolução Ecrã Completo</translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation>Resolução da Janela</translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation>E-mail</translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation>Sumário</translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation>Enviar informações de sistema</translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation>Digita o código de segurança:</translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation>Revisão</translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation>Este programa é distribuÃdo sob a %1</translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1817,12 +2020,16 @@ Deseja mesmo sair?</translation>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation>-r%1 (%2)</translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
<message>
<source>Connection to server is lost</source>
- <translation>Conexão com o servidor perdida</translation>
+ <translation>Ligação com o servidor perdida</translation>
</message>
<message>
<source>Error</source>
@@ -1830,11 +2037,7 @@ Deseja mesmo sair?</translation>
</message>
<message>
<source>File association failed.</source>
- <translation>Não foi possivel associar os ficheiros.</translation>
- </message>
- <message>
- <source>Please fill out all fields</source>
- <translation>Por favor preencha todos os campos</translation>
+ <translation>Não foi possÃvel associar os ficheiros.</translation>
</message>
<message>
<source>Error while authenticating at google.com:
@@ -1862,7 +2065,7 @@ Deseja mesmo sair?</translation>
</message>
<message>
<source>Cannot delete default scheme '%1'!</source>
- <translation>Não é possivel apagar o esquema por omisão '%1'!</translation>
+ <translation>Não é possÃvel apagar o esquema por omissão '%1'!</translation>
</message>
<message>
<source>Please select a record from the list</source>
@@ -1885,50 +2088,38 @@ Deseja mesmo sair?</translation>
<translation>Todos os ficheiros foram corretamente associados</translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation>Problema publicado com sucesso em hedgewars.googlecode.com</translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation>Ocorreu um erro durante a autenticação em google.com</translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation>Erro ao reportar o problema, por favor tenta novamente mais tarde (ou visita hedgewars.googlecode.com diretamente)</translation>
- </message>
- <message>
<source>Main - Error</source>
- <translation>Main - Erro</translation>
+ <translation type="obsolete">Main - Erro</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation>Não foi possÃvel criar o directório %1</translation>
+ <translation type="obsolete">Não foi possÃvel criar o diretório %1</translation>
</message>
<message>
<source>Failed to open data directory:
%1
Please check your installation!</source>
- <translation>Erro ao abrir o diretório:
+ <translation type="obsolete">Erro ao abrir o diretório:
%1
Por favor verifica a tua instalação!</translation>
</message>
<message>
<source>TCP - Error</source>
- <translation>TCP - Erro</translation>
+ <translation type="obsolete">TCP - Erro</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation>Não foi possÃvel iniciar o servidor: %1.</translation>
+ <translation type="obsolete">Não foi possÃvel iniciar o servidor: %1.</translation>
</message>
<message>
<source>Unable to run engine at </source>
- <translation>Não foi possivel lançar o motor de jogo em </translation>
+ <translation type="obsolete">Não foi possÃvel lançar o motor de jogo em </translation>
</message>
<message>
<source>Error code: %1</source>
- <translation>Código de erro: %1</translation>
+ <translation type="obsolete">Código de erro: %1</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -1952,15 +2143,15 @@ Por favor verifica a tua instalação!</translation>
</message>
<message>
<source>Please select record from the list</source>
- <translation>Por favor selecciona uma gravação da lista</translation>
+ <translation>Por favor seleciona uma gravação da lista</translation>
</message>
<message>
<source>Cannot rename to </source>
- <translation>Não é possivel renomear para </translation>
+ <translation>Não é possÃvel renomear para </translation>
</message>
<message>
<source>Cannot delete file </source>
- <translation>Não é possivel apagar o ficheiro </translation>
+ <translation>Não é possÃvel apagar o ficheiro </translation>
</message>
<message>
<source>Room Name - Error</source>
@@ -1968,7 +2159,7 @@ Por favor verifica a tua instalação!</translation>
</message>
<message>
<source>Please select room from the list</source>
- <translation>Por favor selecciona uma sala da lista</translation>
+ <translation>Por favor seleciona uma sala da lista</translation>
</message>
<message>
<source>Room Name - Are you sure?</source>
@@ -2017,46 +2208,77 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
<message>
<source>Cannot open '%1' for writing</source>
- <translation>Impossivel abrir '%1' para escrita</translation>
+ <translation>ImpossÃvel abrir '%1' para escrita</translation>
</message>
<message>
<source>Cannot open '%1' for reading</source>
- <translation>Impossivel abrir '%1' para leitura</translation>
+ <translation>ImpossÃvel abrir '%1' para leitura</translation>
</message>
<message>
<source>Cannot use the ammo '%1'!</source>
- <translation>Impossivel utilizar as munições '%1'!</translation>
+ <translation>ImpossÃvel utilizar as munições '%1'!</translation>
</message>
<message>
<source>Weapons - Warning</source>
- <translation>Armas - Aviso</translation>
+ <translation>Armamento - Aviso</translation>
</message>
<message>
<source>Cannot overwrite default weapon set '%1'!</source>
- <translation>Não é possivel substituir o esquema de armas '%1'!</translation>
+ <translation>Não é possÃvel substituir o esquema de armas '%1'!</translation>
</message>
<message>
<source>Cannot delete default weapon set '%1'!</source>
- <translation>Não é possivel apagar o esquema de armas por omisão '%1'!</translation>
+ <translation>Não é possÃvel apagar o esquema de armas por omissão '%1'!</translation>
</message>
<message>
<source>Weapons - Are you sure?</source>
- <translation>Armas - Tens a certeza?</translation>
+ <translation>Armamento - Tens a certeza?</translation>
</message>
<message>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation>Desejas mesmo apagar o esquema de armas '%1'?</translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Nome de utilizador</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation>Hedgewars - Utilizador não registado</translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation>Pré-visualizar Informação do Sistema</translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation>Não foi possÃvel gerar o captcha</translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation>Não foi possÃvel descarregar o captcha</translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation>Por favor preenche todos os campos. O e-mail é opcional.</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation>Hedgewars - Aviso</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation>Hedgewars - Informação</translation>
+ </message>
+ <message>
+ <source>Hedgewars</source>
+ <translation type="obsolete">Hedgewars</translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation>Nem todos os jogadores se encontram prontos</translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Por favor insira o seu nome de utilizador</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation>Tens a certeza que queres iniciar este jogo?
+Nem todos os jogadores estão prontos.</translation>
</message>
</context>
<context>
@@ -2083,7 +2305,7 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
<message>
<source>Update</source>
- <translation>Actualizar</translation>
+ <translation>Atualizar</translation>
</message>
<message>
<source>Specify</source>
@@ -2114,36 +2336,20 @@ Desejas entrar na sala de qualquer maneira?</translation>
<translation>Carregar</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Configurar</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Preparado</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Equipa aleatória</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Associar com as extensões dos ficheiros</translation>
</message>
<message>
- <source>more</source>
- <translation>mais</translation>
- </message>
- <message>
<source>More info</source>
<translation>Mais informação</translation>
</message>
<message>
<source>Set default options</source>
- <translation>Restaurar opções por omisão</translation>
+ <translation>Restaurar opções por omissão</translation>
</message>
<message>
<source>Open videos directory</source>
- <translation>Abrir o directório dos vÃdeos</translation>
+ <translation>Abrir o diretório de vÃdeos</translation>
</message>
<message>
<source>Play</source>
@@ -2157,6 +2363,61 @@ Desejas entrar na sala de qualquer maneira?</translation>
<source>Cancel uploading</source>
<translation>Cancelar o upload</translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation>Restaurar os parâmetros de conversão por omissão</translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation>Abrir o diretório de vÃdeos do teu sistema</translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation>Reproduzir este vÃdeo</translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation>Apagar este vÃdeo</translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation>Enviar este vÃdeo para a tua conta do Youtube</translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation>Introduz um nome para a tua sala de jogo.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>Criar sala</translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2206,6 +2467,25 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation>A semente do mapa é a base de todos os valores aleatórios gerados pelo jogo.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation>Definir semente</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>Fechar</translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2217,7 +2497,7 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
<message>
<source>Ammo in boxes</source>
- <translation>Caixas de armas</translation>
+ <translation>Munições por caixa</translation>
</message>
<message>
<source>Delays</source>
@@ -2233,106 +2513,44 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampirismo</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artilharia</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Modo Forte</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Separar Equipas</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Terreno Sólido</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Adicionar Limites</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Baixa Gravidade</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Mira Laser</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Invulnerable</source>
- <translation>Invulnerabilidade</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Order</source>
- <translation>Ordem Aleatória</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Rei</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Posicionar Ouriços</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Clãs Partilham Armamento</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Desactivar Vigas</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Desactivar Objectos no Terreno</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Modo de Sobrevivência</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>Restaurar Vida</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>Ataques Ilimitados</translation>
- </message>
- <message>
- <source>Reset Weapons</source>
- <translation>Restaurar o Armamento</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Armamento Por Ouriço</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Desactivar Vento</translation>
+ <source>%1's team</source>
+ <translation>Equipa de %1</translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Mais Vento</translation>
+ <source>Cancel</source>
+ <translation>Cancelar</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tag Team</translation>
+ <source>Search for a theme:</source>
+ <translation>Procurar:</translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Adicionar limite inferior</translation>
+ <source>Use selected theme</source>
+ <translation>Utilizar o tema selecionado</translation>
</message>
</context>
<context>
@@ -2375,7 +2593,7 @@ Desejas entrar na sala de qualquer maneira?</translation>
</message>
<message>
<source>ammo menu</source>
- <translation>menu de armas</translation>
+ <translation>menu de armamento</translation>
</message>
<message>
<source>slot 1</source>
@@ -2466,12 +2684,6 @@ Desejas entrar na sala de qualquer maneira?</translation>
<translation>capturar</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>informação dos
-ouriços</translation>
- </message>
- <message>
<source>quit</source>
<translation>sair</translation>
</message>
@@ -2501,73 +2713,73 @@ ouriços</translation>
</message>
<message>
<source>mute audio</source>
- <translation>Silenciar audio</translation>
+ <translation>silenciar áudio</translation>
</message>
<message>
<source>record</source>
<translation>gravar</translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation>informação do ouriço</translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Controlos basicos</translation>
+ <source>Movement</source>
+ <translation>Movimento</translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Controlos de armas</translation>
+ <source>Weapons</source>
+ <translation>Armamento</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Controlos de camara e cursor</translation>
+ <source>Camera</source>
+ <translation>Câmara</translation>
</message>
<message>
- <source>Other</source>
- <translation>Outros</translation>
+ <source>Miscellaneous</source>
+ <translation>Outras opções</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Movimentar os teus ouriços e apontar:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
- <translation>Ultrapassar fendas e obstaculos saltando:</translation>
+ <translation>Ultrapassar fendas e obstáculos:</translation>
</message>
<message>
<source>Fire your selected weapon or trigger an utility item:</source>
- <translation>Disparar a arma currentemente seleccionada ou utilizar um utilitario:</translation>
+ <translation>Disparar a arma correntemente selecionada ou utilizar um utilitario:</translation>
</message>
<message>
<source>Pick a weapon or a target location under the cursor:</source>
- <translation>Seleccionar uma arma ou escolher um alvo com o cursor:</translation>
+ <translation>Selecionar uma arma ou escolher um alvo com o cursor:</translation>
</message>
<message>
<source>Switch your currently active hog (if possible):</source>
- <translation>Trocar de ouriço currentemente seleccionado (se possivel):</translation>
+ <translation>Trocar de ouriço correntemente selecionado (se possÃvel):</translation>
</message>
<message>
<source>Pick a weapon or utility item:</source>
- <translation>Apanhar armas ou utilitarios:</translation>
+ <translation>Selecionar armas ou utilitários:</translation>
</message>
<message>
<source>Set the timer on bombs and timed weapons:</source>
- <translation>Escolher o tempo nas bombas e outras armas temporizadas:</translation>
+ <translation>Definir o temporizador nas bombas e em outras armas temporizadas:</translation>
</message>
<message>
<source>Move the camera to the active hog:</source>
- <translation>Mover a camara para o ouriço currentemente activo:</translation>
+ <translation>Mover a câmara para o ouriço correntemente activo:</translation>
</message>
<message>
<source>Move the cursor or camera without using the mouse:</source>
- <translation>Mover o cursor ou camara sem usar o rato:</translation>
+ <translation>Mover o cursor ou câmara sem utilizar o rato:</translation>
</message>
<message>
<source>Modify the camera's zoom level:</source>
- <translation>Modificar o nÃvel de zoom da camara:</translation>
+ <translation>Modificar o nÃvel de zoom da câmara:</translation>
</message>
<message>
<source>Talk to your team or all participants:</source>
@@ -2583,7 +2795,7 @@ ouriços</translation>
</message>
<message>
<source>Toggle fullscreen mode:</source>
- <translation>Alterar para modo de ecrã inteiro:</translation>
+ <translation>Ativar ou desativar o modo ecrã inteiro:</translation>
</message>
<message>
<source>Take a screenshot:</source>
@@ -2597,6 +2809,10 @@ ouriços</translation>
<source>Record video:</source>
<translation>Gravar vÃdeo:</translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation>Movimentar ouriço</translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
@@ -2917,4 +3133,119 @@ ouriços</translation>
<translation>DPad</translation>
</message>
</context>
+<context>
+ <name>server</name>
+ <message>
+ <source>Not room master</source>
+ <translation type="obsolete">Não és o anfitrião da sala</translation>
+ </message>
+ <message>
+ <source>Corrupted hedgehogs info</source>
+ <translation type="obsolete">Informação dos ouriços corrompida</translation>
+ </message>
+ <message>
+ <source>too many teams</source>
+ <translation type="obsolete">demasiadas equipas</translation>
+ </message>
+ <message>
+ <source>too many hedgehogs</source>
+ <translation type="obsolete">demasiados ouriços</translation>
+ </message>
+ <message>
+ <source>There's already a team with same name in the list</source>
+ <translation type="obsolete">Já existe uma equipa com o mesmo nome na lista</translation>
+ </message>
+ <message>
+ <source>round in progress</source>
+ <translation type="obsolete">partida em progresso</translation>
+ </message>
+ <message>
+ <source>restricted</source>
+ <translation type="obsolete">limitada</translation>
+ </message>
+ <message>
+ <source>REMOVE_TEAM: no such team</source>
+ <translation type="obsolete">REMOVE_TEAM: equipa inexistente</translation>
+ </message>
+ <message>
+ <source>Not team owner!</source>
+ <translation type="obsolete">A equipa não te pertence!</translation>
+ </message>
+ <message>
+ <source>Less than two clans!</source>
+ <translation type="obsolete">Menos de 2 clãs!</translation>
+ </message>
+ <message>
+ <source>Room with such name already exists</source>
+ <translation type="obsolete">Já existe uma sala com esse nome</translation>
+ </message>
+ <message>
+ <source>Nickname already chosen</source>
+ <translation type="obsolete">Utilizador já em uso</translation>
+ </message>
+ <message>
+ <source>Illegal nickname</source>
+ <translation type="obsolete">Nome de utilizador ilegal</translation>
+ </message>
+ <message>
+ <source>Protocol already known</source>
+ <translation type="obsolete">Protocolo já conhecido</translation>
+ </message>
+ <message>
+ <source>Bad number</source>
+ <translation type="obsolete">Número inválido</translation>
+ </message>
+ <message>
+ <source>Nickname is already in use</source>
+ <translation type="obsolete">Nome de utilizador já em uso</translation>
+ </message>
+ <message>
+ <source>No checker rights</source>
+ <translation type="obsolete">Não possui permissões para verificar</translation>
+ </message>
+ <message>
+ <source>Authentication failed</source>
+ <translation type="obsolete">A autenticação falhou</translation>
+ </message>
+ <message>
+ <source>60 seconds cooldown after kick</source>
+ <translation type="obsolete">à necessário aguardar 60 segundos após uma expulsão</translation>
+ </message>
+ <message>
+ <source>kicked</source>
+ <translation type="obsolete">expulso</translation>
+ </message>
+ <message>
+ <source>Ping timeout</source>
+ <translation type="obsolete">Ping timeout</translation>
+ </message>
+ <message>
+ <source>bye</source>
+ <translation type="obsolete">tchau (bye)</translation>
+ </message>
+ <message>
+ <source>Illegal room name</source>
+ <translation type="obsolete">Nome da sala ilegal</translation>
+ </message>
+ <message>
+ <source>No such room</source>
+ <translation type="obsolete">Sala inexistente</translation>
+ </message>
+ <message>
+ <source>Joining restricted</source>
+ <translation type="obsolete">Entrada restrita</translation>
+ </message>
+ <message>
+ <source>Registered users only</source>
+ <translation type="obsolete">Apenas utilizadores registados</translation>
+ </message>
+ <message>
+ <source>You are banned in this room</source>
+ <translation type="obsolete">Estás banido desta sala</translation>
+ </message>
+ <message>
+ <source>Empty config entry</source>
+ <translation type="obsolete">Campo vazio na configuração</translation>
+ </message>
+</context>
</TS>
diff --git a/share/hedgewars/Data/Locale/hedgewars_ro.ts b/share/hedgewars/Data/Locale/hedgewars_ro.ts
index 5066be7..39e5cab 100644
--- a/share/hedgewars/Data/Locale/hedgewars_ro.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_ro.ts
@@ -2,6 +2,20 @@
<!DOCTYPE TS>
<TS version="2.0" language="ro">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>AbstractPage</name>
+ <message>
+ <source>Go back</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AmmoSchemeModel</name>
<message>
<source>new</source>
@@ -13,17 +27,91 @@
</message>
</context>
<context>
- <name>DrawMapWidget</name>
+ <name>BanDialog</name>
<message>
- <source>File error</source>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot open file '%1' for writing</source>
+ <source>Send us feedback!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot read file '%1'</source>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -38,6 +126,7 @@
<translation>
<numerusform>Each turn</numerusform>
<numerusform>Every %1 turns</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
</context>
@@ -48,44 +137,89 @@
<translation>Edit weapons</translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
- <source>Illegal ammo scheme</source>
- <translation>Illegal ammo scheme</translation>
- </message>
- <message>
<source>Edit schemes</source>
<translation>Edit schemes</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">Map</translation>
+ </message>
+ <message>
+ <source>Game options</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>HWChatWidget</name>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>%1 *** %2 has been removed from your ignore list</source>
- <translation type="obsolete">%1 *** %2 has been removed from your ignore list</translation>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has been added to your ignore list</source>
- <translation type="obsolete">%1 *** %2 has been added to your ignore list</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Cannot create directory %1</translation>
</message>
<message>
- <source>%1 *** %2 has been removed from your friends list</source>
- <translation type="obsolete">%1 *** %2 has been removed from your friends list</translation>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWAskQuitDialog</name>
<message>
- <source>%1 *** %2 has been added to your friends list</source>
- <translation type="obsolete">%1 *** %2 has been added to your friends list</translation>
+ <source>Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>HWChatWidget</name>
<message>
<source>%1 has been removed from your ignore list</source>
<translation type="unfinished"></translation>
@@ -127,41 +261,25 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Kicking %1 ...</source>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HWForm</name>
<message>
- <source>new</source>
- <translation type="obsolete">new</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>OK</translation>
- </message>
- <message>
- <source>Unable to start the server</source>
- <translation>Unable to start the server</translation>
- </message>
- <message>
<source>Cannot save record to file %1</source>
<translation>Cannot save record to file %1</translation>
</message>
<message>
- <source>Please select record from the list above</source>
- <translation>Please select record from the list above</translation>
- </message>
- <message>
<source>DefaultTeam</source>
<translation>Default Team</translation>
</message>
@@ -188,36 +306,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Password</source>
- <translation type="unfinished">Password</translation>
+ <source>Nickname</source>
+ <translation type="unfinished">Nickname</translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</translation>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">Nickname</translation>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Some one already uses
- your nickname %1
-on the server.
-Please pick another nickname:</source>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -235,18 +390,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Map</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Themes</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>All</translation>
</message>
@@ -271,10 +414,6 @@ Please pick another nickname:</source>
<translation>Wacky</translation>
</message>
<message>
- <source>Type</source>
- <translation>Type</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation type="unfinished"></translation>
</message>
@@ -283,27 +422,95 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Random</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -345,26 +552,12 @@ Please pick another nickname:</source>
<translation>You got kicked</translation>
</message>
<message>
- <source>Password</source>
- <translation type="obsolete">Password</translation>
- </message>
- <message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</source>
- <translation type="obsolete">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password
-or pick another nickname:</translation>
- </message>
- <message>
<source>%1 *** %2 has joined the room</source>
<translation>%1 *** %2 has joined the room</translation>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 has joined</translation>
+ <translation type="obsolete">%1 *** %2 has joined</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -375,21 +568,70 @@ or pick another nickname:</translation>
<translation>%1 *** %2 has left</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="obsolete">Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</translation>
+ <source>User quit</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="obsolete">Nickname</translation>
+ <source>Remote host has closed connection</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>User quit</source>
+ <source>The server is too old. Disconnecting now.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWPasswordDialog</name>
+ <message>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWUploadVideoDialog</name>
+ <message>
+ <source>Upload video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -401,15 +643,45 @@ or pick another nickname in game config:</translation>
</message>
</context>
<context>
- <name>PageAdmin</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
+ <message>
+ <source>Duration: %1m %2s
+</source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <source>Server message:</source>
- <translation type="obsolete">Server message:</translation>
+ <source>Video: %1x%2, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 fps, </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>MapModel</name>
<message>
- <source>Set message</source>
- <translation type="obsolete">Set message</translation>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageAdmin</name>
<message>
<source>Clear Accounts Cache</source>
<translation>Clear Accounts Cache</translation>
@@ -438,6 +710,38 @@ or pick another nickname in game config:</translation>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">General</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished">Refresh</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -445,9 +749,16 @@ or pick another nickname in game config:</translation>
<source>Connecting...</source>
<translation>Connecting...</translation>
</message>
+</context>
+<context>
+ <name>PageDataDownload</name>
<message>
- <source>Cancel</source>
- <translation type="obsolete">Cancel</translation>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -484,6 +795,10 @@ or pick another nickname in game config:</translation>
<source>All files</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Eraser</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageEditTeam</name>
@@ -492,30 +807,44 @@ or pick another nickname in game config:</translation>
<translation>General</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Advanced</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageGameStats</name>
<message>
- <source><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></source>
- <translation type="obsolete"><p>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</p></translation>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></source>
- <translation type="obsolete">
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kill in a turn.</p></numerusform>
- <numerusform><p>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</p></numerusform>
- </translation>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source><p>A total of <b>%1</b> hedgehog(s) were killed during this round.</p></source>
- <translation type="obsolete">
- <numerusform><p>A total of <b>%1</b> hedgehog was killed during this round.</p></numerusform>
- <numerusform><p>A total of <b>%1</b> hedgehogs were killed during this round.</p></numerusform>
- </translation>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Name</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Random Team</translation>
</message>
+</context>
+<context>
+ <name>PageGameStats</name>
<message>
<source>Details</source>
<translation>Details</translation>
@@ -537,6 +866,7 @@ or pick another nickname in game config:</translation>
<translation>
<numerusform>The best killer is <b>%1</b> with <b>%2</b> kill in a turn.</numerusform>
<numerusform>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -544,6 +874,7 @@ or pick another nickname in game config:</translation>
<translation>
<numerusform><b>%1</b> hedgehog was killed during this round.</numerusform>
<numerusform>A total of <b>%1</b> hedgehogs were killed during this round.</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -551,6 +882,7 @@ or pick another nickname in game config:</translation>
<translation>
<numerusform>(%1 kill)</numerusform>
<numerusform>(%1 kills)</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -558,6 +890,7 @@ or pick another nickname in game config:</translation>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -565,6 +898,7 @@ or pick another nickname in game config:</translation>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -572,8 +906,17 @@ or pick another nickname in game config:</translation>
<translation>
<numerusform><b>%1</b> was scared and skipped turn <b>%2</b> time.</numerusform>
<numerusform><b>%1</b> was scared and skipped turn <b>%2</b> times.</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -583,379 +926,290 @@ or pick another nickname in game config:</translation>
</message>
</context>
<context>
- <name>PageMain</name>
- <message>
- <source>Local Game (Play a game on a single computer)</source>
- <translation>Local Game (Play a game on a single computer)</translation>
- </message>
- <message>
- <source>Network Game (Play a game across a network)</source>
- <translation>Network Game (Play a game across a network)</translation>
- </message>
+ <name>PageInfo</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>Start</translation>
</message>
<message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">Control</translation>
</message>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">Start</translation>
</message>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Update</source>
+ <translation type="unfinished">Update</translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New team</source>
+ <translation>New team</translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Edit team</source>
+ <translation>Edit team</translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Delete team</source>
+ <translation>Delete team</translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <translation>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation type="unfinished">Advanced</translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
-</context>
-<context>
- <name>PageNet</name>
- <message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
<message>
- <source>Please select server from the list above</source>
- <translation>Please select server from the list above</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>Control</translation>
- </message>
- <message>
- <source>Error</source>
- <translation type="unfinished">Error</translation>
- </message>
- <message>
- <source>Please enter room name</source>
- <translation type="unfinished">Please enter room name</translation>
- </message>
- <message>
- <source>OK</source>
- <translation type="unfinished">OK</translation>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>LAN game</translation>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Official server</source>
- <translation>Official server</translation>
+ <source>Network</source>
+ <translation type="unfinished">Network</translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
<message>
- <source>New team</source>
- <translation>New team</translation>
+ <source>Teams</source>
+ <translation type="unfinished">Teams</translation>
</message>
<message>
- <source>Edit team</source>
- <translation>Edit team</translation>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delete team</source>
- <translation>Delete team</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Weapons</translation>
</message>
<message>
- <source>New weapon scheme</source>
- <translation type="obsolete">New weapon scheme</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon scheme</source>
- <translation type="obsolete">Edit weapon scheme</translation>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delete weapon scheme</source>
- <translation type="obsolete">Delete weapon scheme</translation>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
- <translation>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</translation>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>PagePlayDemo</name>
<message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>OK</translation>
- </message>
- <message>
<source>Rename dialog</source>
<translation>Rename dialog</translation>
</message>
@@ -963,40 +1217,16 @@ or pick another nickname in game config:</translation>
<source>Enter new file name:</source>
<translation>Enter new file name:</translation>
</message>
- <message>
- <source>Cannot rename to</source>
- <translation>Cannot rename to</translation>
- </message>
- <message>
- <source>Cannot delete file</source>
- <translation>Cannot delete file</translation>
- </message>
- <message>
- <source>Please select record from the list</source>
- <translation>Please select record from the list</translation>
- </message>
</context>
<context>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Create</translation>
+ <translation type="obsolete">Create</translation>
</message>
<message>
<source>Join</source>
- <translation>Join</translation>
- </message>
- <message>
- <source>Refresh</source>
- <translation>Refresh</translation>
- </message>
- <message>
- <source>Error</source>
- <translation>Error</translation>
- </message>
- <message>
- <source>OK</source>
- <translation>OK</translation>
+ <translation type="obsolete">Join</translation>
</message>
<message>
<source>Admin features</source>
@@ -1004,99 +1234,48 @@ or pick another nickname in game config:</translation>
</message>
<message>
<source>Room Name:</source>
- <translation>Room Name:</translation>
+ <translation type="obsolete">Room Name:</translation>
</message>
<message>
- <source>This game is in lobby.
-You may join and start playing once the game starts.</source>
- <translation>This game is in lobby.
-You may join and start playing once the game starts.</translation>
- </message>
- <message>
- <source>This game is in progress.
-You may join and spectate now but you'll have to wait for the game to end to start playing.</source>
- <translation>This game is in progress.
-You may join and spectate now but you'll have to wait for the game to end to start playing.</translation>
- </message>
- <message>
- <source>%1 is the host. He may adjust settings and start the game.</source>
- <translation>%1 is the host. He may adjust settings and start the game.</translation>
- </message>
- <message>
- <source>Random Map</source>
- <translation>Random Map</translation>
- </message>
- <message>
- <source>Games may be played on precreated or randomized maps.</source>
- <translation>Games may be played on precreated or randomized maps.</translation>
- </message>
- <message>
- <source>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</source>
- <translation>The Game Scheme defines general options and preferences like Round Time, Sudden Death or Vampirism.</translation>
+ <source>Rules:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Weapon Scheme defines available weapons and their ammunition count.</source>
- <translation>The Weapon Scheme defines available weapons and their ammunition count.</translation>
- </message>
- <message numerus="yes">
- <source>There are %1 clients connected to this room.</source>
- <translation>
- <numerusform>There is %1 client connected to this room.</numerusform>
- <numerusform>There are %1 clients connected to this room.</numerusform>
- </translation>
+ <source>Weapons:</source>
+ <translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <source>There are %1 teams participating in this room.</source>
- <translation>
- <numerusform>There is %1 team participating in this room.</numerusform>
- <numerusform>There are %1 teams participating in this room.</numerusform>
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
- <source>Please enter room name</source>
- <translation>Please enter room name</translation>
- </message>
- <message>
- <source>Please select room from the list</source>
- <translation>Please select room from the list</translation>
- </message>
- <message>
- <source>Random Maze</source>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules:</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons:</source>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
+ <source>Room state</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Clear filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Warning</source>
+ <source>Open server administration page</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>The game you are trying to join has started.
-Do you still want to join the room?</source>
- <translation>The game you are trying to join has started.
-Do you still want to join the room?</translation>
- </message>
- <message numerus="yes">
- <source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
</context>
<context>
<name>PageScheme</name>
@@ -1113,10 +1292,6 @@ Do you still want to join the room?</translation>
<translation>Land can not be destroyed!</translation>
</message>
<message>
- <source>Add an indestructable border around the terrain</source>
- <translation type="obsolete">Add an indestructable border around the terrain</translation>
- </message>
- <message>
<source>Lower gravity</source>
<translation>Lower gravity</translation>
</message>
@@ -1129,10 +1304,6 @@ Do you still want to join the room?</translation>
<translation>All hogs have a personal forcefield</translation>
</message>
<message>
- <source>Enable random mines</source>
- <translation type="obsolete">Enable random mines</translation>
- </message>
- <message>
<source>Gain 80% of the damage you do back in health</source>
<translation>Gain 80% of the damage you do back in health</translation>
</message>
@@ -1251,27 +1422,27 @@ Do you still want to join the room?</translation>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game (a quick game against the computer, settings are chosen for you)</source>
- <translation>Simple Game (a quick game against the computer, settings are chosen for you)</translation>
+ <source>Play a quick game against the computer with random settings</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer (play a hotseat game against your friends, or AI teams)</source>
- <translation>Multiplayer (play a hotseat game against your friends, or AI teams)</translation>
+ <source>Play a hotseat game against your friends, or AI teams</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode (Practice your skills in a range of training missions)</source>
- <translation>Training Mode (Practice your skills in a range of training missions)</translation>
+ <source>Campaign Mode</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Demos (Watch recorded demos)</source>
- <translation>Demos (Watch recorded demos)</translation>
+ <source>Practice your skills in a range of training missions</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Load (Load a previously saved game)</source>
- <translation>Load (Load a previously saved game)</translation>
+ <source>Watch recorded demos</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Campaign Mode (...)</source>
+ <source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1285,6 +1456,55 @@ Do you still want to join the room?</translation>
<source>Select a mission!</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Pick the mission or training to play</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start fighting</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PageVideos</name>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Name</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 bytes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>(in progress...)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>encoding</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>uploading</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1297,10 +1517,6 @@ Do you still want to join the room?</translation>
<translation>Info</translation>
</message>
<message>
- <source>Start</source>
- <translation>Start</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Restrict Joins</translation>
</message>
@@ -1334,7 +1550,19 @@ Do you still want to join the room?</translation>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Update</translation>
+ <translation type="obsolete">Update</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1348,18 +1576,6 @@ Do you still want to join the room?</translation>
<translation>Fullscreen</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Frontend fullscreen</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>Enable sound</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Enable music</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Show FPS</translation>
</message>
@@ -1372,74 +1588,78 @@ Do you still want to join the room?</translation>
<translation>Append date and time to record file name</translation>
</message>
<message>
- <source>Reduced quality</source>
- <translation type="obsolete">Reduced quality</translation>
- </message>
- <message>
<source>Show ammo menu tooltips</source>
<translation>Show ammo menu tooltips</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Enable frontend sounds</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Enable frontend music</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Frontend effects</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>generated map...</translation>
+ <source>Record audio</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>Human</translation>
+ <source>Use game resolution</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>Level</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
- <translation>(System default)</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
- <translation>Mission</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Any</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In lobby</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>In progress</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>Human</translation>
</message>
<message>
- <source>Default</source>
- <translation type="obsolete">Default</translation>
+ <source>Level</source>
+ <translation>Level</translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>(System default)</source>
+ <translation>(System default)</translation>
+ </message>
+ <message>
+ <source>Community</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1479,10 +1699,6 @@ Do you still want to join the room?</translation>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1518,22 +1734,6 @@ Do you still want to join the room?</translation>
<translation>Fort</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Key binds</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Teams</translation>
- </message>
- <message>
- <source>Weapons</source>
- <translation type="obsolete">Weapons</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Audio/Graphic options</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Net game</translation>
</message>
@@ -1554,11 +1754,11 @@ Do you still want to join the room?</translation>
<translation>Team Settings</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Misc</translation>
+ <source>Videos</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Schemes and Weapons</source>
+ <source>Description</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1574,31 +1774,7 @@ Do you still want to join the room?</translation>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>This program is distributed under the GNU General Public License</source>
- <translation type="obsolete">This program is distributed under the GNU General Public License</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Developers:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Art:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sounds:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Translations:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Special thanks:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Weapons</source>
@@ -1613,10 +1789,6 @@ Do you still want to join the room?</translation>
<translation>Port:</translation>
</message>
<message>
- <source>Net nick</source>
- <translation>Net nick</translation>
- </message>
- <message>
<source>Resolution</source>
<translation>Resolution</translation>
</message>
@@ -1641,236 +1813,452 @@ Do you still want to join the room?</translation>
<translation>Damage Modifier</translation>
</message>
<message>
- <source>Turn Time</source>
- <translation>Turn Time</translation>
+ <source>Turn Time</source>
+ <translation>Turn Time</translation>
+ </message>
+ <message>
+ <source>Initial Health</source>
+ <translation>Initial Health</translation>
+ </message>
+ <message>
+ <source>Sudden Death Timeout</source>
+ <translation>Sudden Death Timeout</translation>
+ </message>
+ <message>
+ <source>Scheme Name:</source>
+ <translation>Scheme Name:</translation>
+ </message>
+ <message>
+ <source>Crate Drops</source>
+ <translation>Crate Drops</translation>
+ </message>
+ <message>
+ <source>% Dud Mines</source>
+ <translation>% Dud Mines</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Name</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <source>Grave</source>
+ <translation>Grave</translation>
+ </message>
+ <message>
+ <source>Flag</source>
+ <translation>Flag</translation>
+ </message>
+ <message>
+ <source>Voice</source>
+ <translation>Voice</translation>
+ </message>
+ <message>
+ <source>Locale</source>
+ <translation>Locale</translation>
+ </message>
+ <message>
+ <source>Explosives</source>
+ <translation>Explosives</translation>
+ </message>
+ <message>
+ <source>Tip: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Quality</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Health Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Health in Crates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sudden Death Water Rise</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Sudden Death Health Decrease</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Rope Length</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Stereo rendering</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Style</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Scheme</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>% Get Away Time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>There are videos that are currently being processed.
+Exiting now will abort them.
+Do you really want to quit?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account name (or email): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video title: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video description: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Tags (comma separated): </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation type="unfinished">Nickname</translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Fullscreen</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QLineEdit</name>
+ <message>
+ <source>unnamed</source>
+ <translation>unnamed</translation>
+ </message>
+ <message>
+ <source>hedgehog %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>anonymous</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>QMainWindow</name>
+ <message>
+ <source>Hedgewars %1</source>
+ <translation>Hedgewars %1</translation>
</message>
<message>
- <source>Initial Health</source>
- <translation>Initial Health</translation>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QMessageBox</name>
<message>
- <source>Sudden Death Timeout</source>
- <translation>Sudden Death Timeout</translation>
+ <source>Connection to server is lost</source>
+ <translation>Connection to server is lost</translation>
</message>
<message>
- <source>Scheme Name:</source>
- <translation>Scheme Name:</translation>
+ <source>Error</source>
+ <translation>Error</translation>
</message>
<message>
- <source>Crate Drops</source>
- <translation>Crate Drops</translation>
+ <source>File association failed.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Game scheme</translation>
+ <source>Teams - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>% Dud Mines</source>
- <translation>% Dud Mines</translation>
+ <source>Do you really want to delete the team '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Name</source>
- <translation>Name</translation>
+ <source>Cannot delete default scheme '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
- <translation>Type</translation>
+ <source>Please select a record from the list</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Grave</source>
- <translation>Grave</translation>
+ <source>Unable to start server</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Flag</source>
- <translation>Flag</translation>
+ <source>Hedgewars - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Voice</source>
- <translation>Voice</translation>
+ <source>Hedgewars - Success</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Locale</source>
- <translation>Locale</translation>
+ <source>All file associations have been set</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Restart game to apply</source>
- <translation>Restart game to apply</translation>
+ <source>Cannot create directory %1</source>
+ <translation type="obsolete">Cannot create directory %1</translation>
</message>
<message>
- <source>Explosives</source>
- <translation>Explosives</translation>
+ <source>Unable to start the server: %1.</source>
+ <translation type="obsolete">Unable to start the server: %1.</translation>
</message>
<message>
- <source>Tip: </source>
+ <source>Error while authenticating at google.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
+ <source>Login or password is incorrect</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Quality</source>
+ <source>Video upload - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>% Health Crates</source>
+ <source>Error while sending metadata to youtube.com:
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Health in Crates</source>
+ <source>Netgame - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sudden Death Water Rise</source>
+ <source>Please select a server from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sudden Death Health Decrease</source>
- <translation type="unfinished"></translation>
+ <source>Please enter room name</source>
+ <translation type="unfinished">Please enter room name</translation>
</message>
<message>
- <source>% Rope Length</source>
+ <source>Record Play - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Stereo rendering</source>
- <translation type="unfinished"></translation>
+ <source>Please select record from the list</source>
+ <translation type="unfinished">Please select record from the list</translation>
</message>
<message>
- <source>Style</source>
+ <source>Cannot rename to </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Scheme</source>
+ <source>Cannot delete file </source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Password</source>
- <translation type="unfinished">Password</translation>
+ <source>Room Name - Error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>% Get Away Time</source>
- <translation type="unfinished"></translation>
+ <source>Please select room from the list</source>
+ <translation type="unfinished">Please select room from the list</translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
+ <source>Room Name - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QLineEdit</name>
<message>
- <source>unnamed</source>
- <translation>unnamed</translation>
+ <source>The game you are trying to join has started.
+Do you still want to join the room?</source>
+ <translation type="unfinished">The game you are trying to join has started.
+Do you still want to join the room?</translation>
</message>
<message>
- <source>hedgehog %1</source>
+ <source>Schemes - Warning</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMainWindow</name>
<message>
- <source>Hedgewars %1</source>
- <translation>Hedgewars %1</translation>
+ <source>Schemes - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QMessageBox</name>
<message>
- <source>Network</source>
- <translation>Network</translation>
+ <source>Do you really want to delete the game scheme '%1'?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Connection to server is lost</source>
- <translation>Connection to server is lost</translation>
+ <source>Videos - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Error</source>
- <translation>Error</translation>
+ <source>Do you really want to delete the video '%1'?</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>Do you really want to remove %1 file(s)?</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>Failed to open data directory:
-%1
-Please check your installation</source>
- <translation>Failed to open data directory:
- %1
-Please check your installation</translation>
+ <source>Do you really want to cancel uploading %1?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation>Weapons</translation>
+ <source>File error</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not edit default weapon set</source>
- <translation type="obsolete">Can not edit default weapon set</translation>
+ <source>Cannot open '%1' for writing</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default weapon set</source>
- <translation type="obsolete">Can not delete default weapon set</translation>
+ <source>Cannot open '%1' for reading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this weapon set?</source>
- <translation>Really delete this weapon set?</translation>
+ <source>Cannot use the ammo '%1'!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Can not overwrite default weapon set '%1'!</source>
+ <source>Weapons - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>All file associations have been set.</source>
+ <source>Cannot overwrite default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>File association failed.</source>
+ <source>Cannot delete default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Teams</source>
- <translation type="unfinished">Teams</translation>
+ <source>Weapons - Are you sure?</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this team?</source>
+ <source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Schemes</source>
+ <source>Hedgewars - Nick not registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default scheme '%1'!</source>
+ <source>System Information Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Really delete this game scheme?</source>
+ <source>Failed to generate captcha</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Can not delete default weapon set '%1'!</source>
+ <source>Failed to download captcha</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Error</source>
- <translation>Error</translation>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Cannot create directory %1</source>
- <translation>Cannot create directory %1</translation>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>OK</source>
- <translation>OK</translation>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation>Nickname</translation>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Please enter your nickname</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1928,203 +2316,220 @@ Please check your installation</translation>
<translation>Load</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Setup</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Ready</translation>
+ <source>Associate file extensions</source>
+ <translation>Associate file extensions</translation>
</message>
<message>
- <source>Random Team</source>
- <translation>Random Team</translation>
+ <source>More info</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Associate file extensions</source>
- <translation>Associate file extensions</translation>
+ <source>Set default options</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QTableWidget</name>
<message>
- <source>Room Name</source>
- <translation>Room Name</translation>
+ <source>Open videos directory</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
- <translation>C</translation>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
- <translation>T</translation>
+ <source>Play</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
- <translation>Owner</translation>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation>Map</translation>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
- <translation>Rules</translation>
+ <source>Upload to YouTube</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation>Weapons</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>SelWeaponWidget</name>
<message>
- <source>Weapon set</source>
- <translation>Weapon set</translation>
+ <source>Cancel uploading</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation>Probabilities</translation>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Ammo in boxes</source>
- <translation>Ammo in boxes</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Delays</source>
- <translation>Delays</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
- <translation type="unfinished">new</translation>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>TCPBase</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Error</source>
- <translation>Error</translation>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Unable to start the server: %1.</source>
- <translation>Unable to start the server: %1.</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
</message>
<message>
- <source>Unable to run engine: %1 (</source>
- <translation>Unable to run engine: %1 (</translation>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>RoomsListModel</name>
+ <message>
+ <source>In progress</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room Name</source>
+ <translation type="unfinished">Room Name</translation>
+ </message>
<message>
- <source>Vampirism</source>
- <translation>Vampirism</translation>
+ <source>C</source>
+ <translation type="unfinished">C</translation>
</message>
<message>
- <source>Karma</source>
- <translation>Karma</translation>
+ <source>T</source>
+ <translation type="unfinished">T</translation>
</message>
<message>
- <source>Artillery</source>
- <translation>Artillery</translation>
+ <source>Owner</source>
+ <translation type="unfinished">Owner</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>Fort Mode</translation>
+ <source>Map</source>
+ <translation type="unfinished">Map</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>Divide Teams</translation>
+ <source>Rules</source>
+ <translation type="unfinished">Rules</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>Solid Land</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Weapons</translation>
</message>
<message>
- <source>Add Border</source>
- <translation>Add Border</translation>
+ <source>Random Map</source>
+ <translation type="unfinished">Random Map</translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>Low Gravity</translation>
+ <source>Random Maze</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Laser Sight</source>
- <translation>Laser Sight</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Invulnerable</source>
- <translation>Invulnerable</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Mines</source>
- <translation type="obsolete">Add Mines</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
</message>
<message>
- <source>Random Order</source>
- <translation>Random Order</translation>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
- <translation>King</translation>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
- <translation>Place Hedgehogs</translation>
+ <source>Weapon set</source>
+ <translation>Weapon set</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation>Clan Shares Ammo</translation>
+ <source>Probabilities</source>
+ <translation>Probabilities</translation>
</message>
<message>
- <source>Disable Girders</source>
- <translation>Disable Girders</translation>
+ <source>Ammo in boxes</source>
+ <translation>Ammo in boxes</translation>
</message>
<message>
- <source>Disable Land Objects</source>
- <translation type="unfinished"></translation>
+ <source>Delays</source>
+ <translation>Delays</translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
+ <source>new</source>
+ <translation type="unfinished">new</translation>
</message>
<message>
- <source>Reset Health</source>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Cancel</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2259,12 +2664,6 @@ Please check your installation</translation>
<translation>capture</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>hedgehogs
-info</translation>
- </message>
- <message>
<source>quit</source>
<translation>quit</translation>
</message>
@@ -2292,33 +2691,41 @@ info</translation>
<source>slot 10</source>
<translation>slot 10</translation>
</message>
+ <message>
+ <source>mute audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>record</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Basic controls</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Weapon controls</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Weapons</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Camera and cursor controls</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Other</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Move your hogs and aim:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Traverse gaps and obstacles by jumping:</translation>
</message>
@@ -2378,6 +2785,14 @@ info</translation>
<source>Toggle labels above hedgehogs:</source>
<translation>Toggle labels above hedgehogs:</translation>
</message>
+ <message>
+ <source>Record video:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_ru.ts b/share/hedgewars/Data/Locale/hedgewars_ru.ts
index 42656e5..64c9e27 100644
--- a/share/hedgewars/Data/Locale/hedgewars_ru.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_ru.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="ru">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation>ÐеизвеÑÑнÑй компилÑÑоÑ</translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation>ÐÑевдоним</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/ÐÑевдоним</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>ÐÑиÑина</translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation>ÐлиÑелÑноÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation>ÐÐ</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>ÐÑедÑпÑеждение</translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation>ÐожалÑйÑÑа, ÑкажиÑе %1</translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation>пÑевдоним</translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation>поÑÑоÑннÑй</translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation>ÐÑполÑзоваÑÑ Ð·Ð½Ð°Ñение по ÑмолÑаниÑ</translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation>Ðид</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation>ÐÑоÑлаÑÑ Ð¾ÑзÑв</translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation>ÐÑ Ð²Ñегда ÑÐ°Ð´Ñ Ð½Ð¾Ð²Ñм пÑедложениÑм, идÑм или ÑообÑениÑм об оÑибкаÑ
.</translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation>ÐÑиÑлиÑе нам оÑзÑв!</translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation>ÐÑли Ð²Ñ Ð½Ð°Ñли оÑибкÑ, можеÑе пÑовеÑиÑÑ, не бÑло ли Ñже ÑообÑÐµÐ½Ð¸Ñ Ð¾ ней здеÑÑ:</translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation>ÐдÑÐµÑ e-mail необÑзаÑелен, но необÑ
одим, еÑли Ð²Ñ Ñ
оÑиÑе полÑÑиÑÑ Ð¾ÑвеÑ.</translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,15 +141,84 @@
<translation>РедакÑиÑоваÑÑ ÑÑ
емÑ</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>ÐÑи вклÑÑении ÑÑой опÑии вÑÐ±Ð¾Ñ Ð½Ð°ÑÑÑоек игÑÑ Ð°Ð²ÑомаÑиÑеÑки вÑбеÑÐµÑ ÑÑ
ÐµÐ¼Ñ Ð¾ÑÑжиÑ</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">ÐаÑÑÑойки игÑÑ</translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation>СÑ
ема игÑÑ Ð¾Ð¿ÑеделÑÐµÑ Ð½Ð°Ð±Ð¾Ñ Ð¾ÑÑжиÑ</translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation>ÐаÑÑа</translation>
+ </message>
+ <message>
+ <source>Game options</source>
<translation>ÐаÑÑÑойки игÑÑ</translation>
</message>
</context>
<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation>
+ <numerusform>%1 минÑÑа</numerusform>
+ <numerusform>%1 минÑÑÑ</numerusform>
+ <numerusform>%1 минÑÑ</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation>
+ <numerusform>%1 ÑаÑ</numerusform>
+ <numerusform>%1 ÑаÑа</numerusform>
+ <numerusform>%1 ÑаÑов</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation>
+ <numerusform>%1 ÑаÑ</numerusform>
+ <numerusform>%1 ÑаÑа</numerusform>
+ <numerusform>%1 ÑаÑов</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation>
+ <numerusform>%1 денÑ</numerusform>
+ <numerusform>%1 днÑ</numerusform>
+ <numerusform>%1 дней</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation>
+ <numerusform>%1 денÑ</numerusform>
+ <numerusform>%1 днÑ</numerusform>
+ <numerusform>%1 дней</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation>СÑ
ема "%1" не поддеÑживаеÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation>Ðе Ð¼Ð¾Ð³Ñ ÑоздаÑÑ Ð¿Ð°Ð¿ÐºÑ %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation>Ðе Ð¼Ð¾Ð³Ñ Ð¾ÑкÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ:
+%1
+
+ÐожалÑйÑÑа, пÑовеÑÑÑе ÑÑÑÐ°Ð½Ð¾Ð²ÐºÑ Ð¿ÑиложениÑ!</translation>
+ </message>
+</context>
+<context>
<name>HWAskQuitDialog</name>
<message>
<source>Do you really want to quit?</source>
@@ -103,8 +268,16 @@
<translation>ÐÑибка пÑи ÑоÑ
Ñанении ÑÑÐ¸Ð»Ñ Ð² %1</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 не ÑвлÑеÑÑÑ ÐºÐ¾ÑÑекÑной командой</translation>
+ <source>%1 has joined</source>
+ <translation>%1 воÑÑл</translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation>%1 вÑÑел</translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation>%1 вÑÑел (%2)</translation>
</message>
</context>
<context>
@@ -140,20 +313,6 @@
<translation>ÐгÑа пÑекÑаÑена</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>ÐаÑе Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ %1
-заÑегиÑÑÑиÑовано на ÑайÑе hedgewars.org
-ÐожалÑйÑÑа, ÑкажиÑе Ð²Ð°Ñ Ð¿Ð°ÑÐ¾Ð»Ñ Ð² поле ввода внизÑ
-или вÑбеÑиÑе иное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð² наÑÑÑойкаÑ
игÑÑ:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>ÐаÑÐ¾Ð»Ñ Ð½Ðµ Ñказан.</translation>
- </message>
- <message>
<source>Nickname</source>
<translation>ÐÑевдоним</translation>
</message>
@@ -167,6 +326,64 @@ Please pick another nickname:</source>
<translation>ÐÑо-Ñо Ñже иÑполÑзÑÐµÑ Ð²Ð°Ñ Ð¿Ñевдоним %1 на ÑеÑвеÑе.
ÐожалÑйÑÑа, вÑбеÑиÑе дÑÑгой пÑевдоним:</translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation>Ðоманда %1</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation>ÐÑ Ð¿ÐµÑеподклÑÑилиÑÑ ÑлиÑком бÑÑÑÑо.
+ÐожалÑйÑÑа, попÑобÑйÑе Ñнова ÑеÑез неÑколÑко ÑекÑнд.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -182,18 +399,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>ÐаÑÑа</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>ТемÑ</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>ФилÑÑÑ</translation>
- </message>
- <message>
<source>All</source>
<translation>ÐÑе</translation>
</message>
@@ -218,10 +423,6 @@ Please pick another nickname:</source>
<translation>ÐеобÑÑнÑе</translation>
</message>
<message>
- <source>Type</source>
- <translation>Тип</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>ÐаленÑкие ÑÑннели</translation>
</message>
@@ -230,28 +431,96 @@ Please pick another nickname:</source>
<translation>СÑедние ÑÑннели</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>ÐолÑÑие ÑÑннели</translation>
+ <source>Seed</source>
+ <translation>ÐеÑно</translation>
+ </message>
+ <message>
+ <source>Map type:</source>
+ <translation>Тип каÑÑÑ:</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>ÐаленÑкие оÑÑÑовки</translation>
+ <source>Image map</source>
+ <translation>ÐзобÑажение</translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>СÑедние оÑÑÑовки</translation>
+ <source>Mission map</source>
+ <translation>ÐиÑÑиÑ</translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>ÐолÑÑие оÑÑÑовки</translation>
+ <source>Hand-drawn</source>
+ <translation>РиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ ÐºÐ°ÑÑа</translation>
</message>
<message>
- <source>Seed</source>
- <translation>ÐеÑно</translation>
+ <source>Randomly generated</source>
+ <translation>СлÑÑайно ÑгенеÑиÑованнаÑ</translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation>СлÑÑайнÑй лабиÑинÑ</translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation>СлÑÑайно</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation>ÐÑедпÑоÑмоÑÑ ÐºÐ°ÑÑÑ:</translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation>ÐагÑÑзиÑÑ ÑиÑованнÑÑ ÐºÐ°ÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation>РедакÑиÑоваÑÑ ÑиÑованнÑÑ ÐºÐ°ÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation>ÐаленÑкие оÑÑÑова</translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation>СÑедние оÑÑÑова</translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation>ÐолÑÑие оÑÑÑова</translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation>Ð Ð°Ð·Ð¼ÐµÑ ÐºÐ°ÑÑÑ:</translation>
</message>
<message>
- <source>Set</source>
- <translation>УÑÑановиÑÑ</translation>
+ <source>Maze style:</source>
+ <translation>СÑÐ¸Ð»Ñ Ð»Ð°Ð±Ð¸ÑинÑа:</translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation>ÐиÑÑиÑ:</translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation>ÐаÑÑа:</translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation>ÐагÑÑзиÑÑ ÑиÑованнÑÑ ÐºÐ°ÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation>РиÑованнÑе каÑÑÑ</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation>ÐÑе ÑайлÑ</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation>ÐолÑÑие ÑÑннели</translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation>Тема: %1</translation>
</message>
</context>
<context>
@@ -297,7 +566,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 воÑÑл</translation>
+ <translation type="obsolete">%1 *** %2 воÑÑл</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -323,8 +592,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation>ÐаÑолÑ</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation>ÐÑевдоним:</translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation>ÐаÑолÑ:</translation>
</message>
</context>
<context>
@@ -339,6 +623,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation>СмениÑÑ ÑлÑÐ¿Ñ (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation>ÐÑполÑзоваÑÑ Ð²ÑбÑаннÑÑ ÑлÑпÑ</translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation>ÐоиÑк по ÑлÑпам:</translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -346,7 +652,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation>ÐаÑегоÑиÑ</translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -364,6 +677,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation>ÐÑдио: </translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation>неизвеÑÑно</translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation>ÐпиÑание оÑÑÑÑÑÑвÑеÑ.</translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -395,6 +719,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>УÑÑановиÑÑ Ð´Ð°Ð½Ð½Ñе</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation>ÐÑновнÑе наÑÑÑойки</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation>ÐанÑ</translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation>IP/ÐÑевдоним</translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation>ÐконÑание</translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation>ÐÑиÑина</translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation>ÐбновиÑÑ</translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation>ÐобавиÑÑ</translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation>УдалиÑÑ</translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -404,6 +760,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation>ÐдÑÑ Ð·Ð°Ð³ÑÑзка пожалÑйÑÑа, подождиÑе.</translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -449,8 +816,40 @@ Please pick another nickname:</source>
<translation>ÐÑновнÑе наÑÑÑойки</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>ÐополниÑелÑно</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation>ÐÑполÑзоваÑÑ Ð¼Ð¾Ð¸ наÑÑÑойки по ÑмолÑаниÑ</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>СбÑоÑиÑÑ Ð²Ñе пÑивÑзки</translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation>ÐаÑÑÑойка ÑпÑавлениÑ</translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation>ШлÑпа</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation>Ðазвание</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation>ÐÐ¼Ñ ÑÑого ежа</translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation>ÐÑбÑаÑÑ ÑлÑÑайное Ð¸Ð¼Ñ Ð´Ð»Ñ ÑÑого ежа</translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation>СлÑÑÐ°Ð¹Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°</translation>
</message>
</context>
<context>
@@ -479,325 +878,80 @@ Please pick another nickname:</source>
<numerusform>ÐÑÑÑий ÑбийÑа <b>%1</b> Ñ <b>%2</b> ÑбийÑÑвами за Ñ
од.</numerusform>
</translation>
</message>
- <message numerus="yes">
- <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
- <translation>
- <numerusform>ÐÑего <b>%1</b> Ñж бÑл ÑÐ±Ð¸Ñ Ð² ÑеÑение игÑÑ.</numerusform>
- <numerusform>ÐÑего <b>%1</b> ежа бÑли ÑбиÑÑ Ð² ÑеÑение игÑÑ.</numerusform>
- <numerusform>ÐÑего <b>%1</b> ежей бÑли ÑбиÑÑ Ð² ÑеÑение игÑÑ.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>(%1 kill)</source>
- <translation>
- <numerusform>(%1 ÑбийÑÑво)</numerusform>
- <numerusform>(%1 ÑбийÑÑва)</numerusform>
- <numerusform>(%1 ÑбийÑÑв)</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
- <translation>
- <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑÐ½ÐºÑ ÑÑона.</numerusform>
- <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑнкÑа ÑÑона.</numerusform>
- <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑнкÑов ÑÑона.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation>
- <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзника.</numerusform>
- <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзников.</numerusform>
- <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзников.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
од.</numerusform>
- <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
ода.</numerusform>
- <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
одов.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation>РигÑе...</translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation>ÐÑкÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ ÑкÑинÑоÑов</translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>ÐÑбеÑиÑе ÑÐ¾Ñ Ð¶Ðµ ÑÐ²ÐµÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°, ÑÑо Ñ Ð´ÑÑга, ÑÑÐ¾Ð±Ñ Ð¸Ð³ÑаÑÑ Ð² ÑоÑзе. ÐÑ Ð±ÑдеÑе ÑпÑавлÑÑÑ Ñвоими ежами, но вÑигÑаеÑе или пÑоигÑаеÑе вмеÑÑе.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>ÐекоÑоÑÑе Ð²Ð¸Ð´Ñ Ð¾ÑÑÐ¶Ð¸Ñ Ð½Ð°Ð½Ð¾ÑÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑой ÑÑон, но могÑÑ Ð½Ð°Ð½Ð¾ÑиÑÑ Ð±Ð¾Ð»ÑÑий ÑÑон в пÑавилÑной ÑиÑÑаÑии. ÐопÑобÑйÑе иÑполÑзоваÑÑ Ð¿Ð¸ÑÑÐ¾Ð»ÐµÑ ÐезеÑÑ Ðгл, ÑÑÐ¾Ð±Ñ ÑÑолкнÑÑÑ Ð½ÐµÑколÑко ежей в водÑ.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>ÐÑли Ð²Ñ Ð½Ðµ ÑвеÑÐµÐ½Ñ Ð² Ñом, ÑÑо Ñ
оÑиÑе ÑделаÑÑ Ð¸ не Ñ
оÑиÑе ÑÑаÑиÑÑ ÑнаÑÑдÑ, пÑопÑÑÑиÑе Ñ
од. Ðо не ÑеÑÑйÑе много вÑемени, Ñак как ÑмеÑÑÑ Ð½ÐµÐ¸Ð·Ð±ÐµÐ¶Ð½Ð°!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>ÐÑли Ð²Ñ Ñ
оÑиÑе пÑедоÑвÑаÑиÑÑ Ð¸ÑполÑзование ваÑего пÑевдонима дÑÑгими игÑоками на оÑиÑиалÑном игÑовом ÑеÑвеÑе, заÑегиÑÑÑиÑÑйÑеÑÑ Ð½Ð° http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>ÐаÑкÑÑила обÑÑÐ½Ð°Ñ Ð¸Ð³Ñа? ÐопÑобÑйÑе миÑÑии, имеÑÑие ÑазлиÑнÑе Ð²Ð¸Ð´Ñ ÑÑенаÑиев.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¸Ð³ÑÑ Ð²Ñегда запиÑÑÐ²Ð°ÐµÑ Ð¿Ð¾ÑледнÑÑ Ð¸Ð³ÑÑ Ð² виде демки. ÐÑбеÑиÑе "ÐокалÑнÑÑ Ð¸Ð³ÑÑ" и нажмиÑе ÐºÐ½Ð¾Ð¿ÐºÑ "Ðемки" в пÑавом нижнем ÑглÑ, ÑÑÐ¾Ð±Ñ Ð¿ÑоигÑаÑÑ Ð·Ð°Ð¿Ð¸ÑÑ.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars - ÑÑо оÑкÑÑÑое и Ñвободное пÑогÑаммное обеÑпеÑение, коÑоÑое Ð¼Ñ ÑоздаÑм в наÑе Ñвободное вÑемÑ. ÐÑли Ñ Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑ Ð²Ð¾Ð¿ÑоÑÑ, задавайÑе иÑ
на наÑем ÑоÑÑме, но пожалÑйÑÑа, не ожидайÑе кÑÑглоÑÑÑоÑной поддеÑжки!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars - ÑÑо оÑкÑÑÑое и Ñвободное пÑогÑаммное обеÑпеÑение, коÑоÑое Ð¼Ñ ÑоздаÑм в наÑе Ñвободное вÑемÑ. ÐÑли вам понÑавилаÑÑ Ð¸Ð³Ñа, помогиÑе нам денежнÑм вознагÑаждением или вкладом в виде ваÑей ÑабоÑÑ!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars - ÑÑо оÑкÑÑÑое и Ñвободное пÑогÑаммное обеÑпеÑение, коÑоÑое Ð¼Ñ ÑоздаÑм в наÑе Ñвободное вÑемÑ. РаÑпÑоÑÑÑанÑйÑе его ÑÑеди дÑÑзей и Ñленов ÑемÑи!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>ÐÑÐµÐ¼Ñ Ð¾Ñ Ð²Ñемени пÑоводÑÑÑÑ Ð¾ÑиÑиалÑнÑе ÑÑÑниÑÑ. ÐÑедÑÑоÑÑие ÑобÑÑÐ¸Ñ Ð°Ð½Ð¾Ð½ÑиÑÑÑÑÑÑ Ð½Ð° http://www.hedgewars.org/ за неÑколÑко дней.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars доÑÑÑпен на многиÑ
ÑзÑкаÑ
. ÐÑли пеÑевод на Ð²Ð°Ñ ÑзÑк оÑÑÑÑÑÑвÑÐµÑ Ð¸Ð»Ð¸ ÑÑÑаÑел, ÑообÑиÑе нам!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars запÑÑкаеÑÑÑ Ð½Ð° множеÑÑве ÑазлиÑнÑÑ
опеÑаÑионнÑÑ
ÑиÑÑем, вклÑÑÐ°Ñ Microsoft Windows, Mac OS X и Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>ÐомниÑе, ÑÑо Ñ Ð²Ð°Ñ ÐµÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ ÑоздаÑÑ ÑобÑÑвеннÑÑ Ð¸Ð³ÑÑ Ð»Ð¾ÐºÐ°Ð»Ñно или по ÑеÑи. ÐÑ Ð½Ðµ огÑаниÑÐµÐ½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¾Ð¹ "ÐÑоÑÑÐ°Ñ Ð¸Ð³Ñа".</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>ÐгÑаÑ, не забÑвайÑе делаÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑой пеÑеÑÑв Ñ
оÑÑ Ð±Ñ Ñаз в ÑаÑ.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>ÐÑли ваÑа видеокаÑÑа не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑÑкоÑение OpenGL, попÑобÑйÑе вклÑÑиÑÑ Ð¾Ð¿ÑÐ¸Ñ "низкое каÑеÑÑво", ÑÑÐ¾Ð±Ñ ÑлÑÑÑиÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>ÐÑ Ð¾ÑкÑÑÑÑ Ð´Ð»Ñ Ð¿Ñедложений и конÑÑÑÑкÑивной кÑиÑики. ÐÑли вам ÑÑо-Ñо не понÑавилоÑÑ Ð¸Ð»Ð¸ Ñ Ð²Ð°Ñ Ð¿Ð¾ÑвилаÑÑ Ð¾ÑлиÑÐ½Ð°Ñ Ð¸Ð´ÐµÑ, ÑообÑиÑе нам!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>ÐгÑÐ°Ñ Ð¿Ð¾ ÑеÑи, бÑдÑÑе оÑобенно Ð²ÐµÐ¶Ð»Ð¸Ð²Ñ Ð¸ вÑегда помниÑе, ÑÑо Ñ Ð²Ð°Ð¼Ð¸ или пÑоÑив Ð²Ð°Ñ Ð¼Ð¾Ð³ÑÑ Ð¸Ð³ÑаÑÑ Ð´ÐµÑи!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>ÐÑобÑе наÑÑÑойки игÑÑ "ÐампиÑизм" и "ÐаÑма" даÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð²ÑÑабоÑаÑÑ ÑовеÑÑенно новÑÑ ÑакÑикÑ. ÐопÑобÑйÑе иÑ
!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Ðе ÑледÑÐµÑ ÑÑÑанавливаÑÑ Hedgewars на компÑÑÑеÑÑ, не пÑинадлежаÑие вам (в Ñколе, на ÑабоÑе, в ÑнивеÑÑиÑеÑе и Ñ.п.). Ðе забÑÐ´Ñ ÑпÑоÑиÑÑ ÑазÑеÑÐµÐ½Ð¸Ñ Ñ Ð¾ÑвеÑÑÑвенного лиÑа!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑлиÑно подойÑи Ð´Ð»Ñ ÐºÐ¾ÑоÑкиÑ
маÑÑей на пеÑеÑÑваÑ
. ÐÑоÑÑо не добавлÑйÑе ÑлиÑком много ежей и не игÑайÑи на болÑÑиÑ
каÑÑаÑ
. Также можно ÑменÑÑиÑÑ Ð²ÑÐµÐ¼Ñ Ð¸Ð»Ð¸ колиÑеÑÑво наÑалÑного здоÑовÑÑ.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>ÐÑи подгоÑовке игÑÑ Ð½Ðµ поÑÑÑадал ни один Ñж.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars - ÑÑо оÑкÑÑÑое и Ñвободное пÑогÑаммное обеÑпеÑение, коÑоÑое Ð¼Ñ ÑоздаÑм в наÑе Ñвободное вÑемÑ. ÐÑли кÑо-Ñо пÑодал вам игÑÑ, поÑÑебÑйÑе возвÑÐ°Ñ Ð´ÐµÐ½ÐµÐ³!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>ÐодÑоединиÑе один или неÑколÑко геймпадов пеÑед запÑÑком игÑÑ, и Ð²Ñ ÑможеÑе наÑÑÑоиÑÑ Ð¸Ñ
Ð´Ð»Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ð¼Ð¸.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>ÐÑли Ð²Ñ Ñ
оÑиÑе пÑедоÑвÑаÑиÑÑ Ð¸ÑполÑзование ваÑего пÑевдонима дÑÑгими игÑоками на оÑиÑиалÑном игÑовом ÑеÑвеÑе, заÑегиÑÑÑиÑÑйÑеÑÑ Ð½Ð° http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>ÐÑли ваÑа видеокаÑÑа не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑÑкоÑение OpenGL, попÑобÑйÑе обновиÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´ÑайвеÑ.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>ÐÑÑÑ ÑÑи вида пÑÑжков. ÐажмиÑе [пÑÑжок ввеÑÑ
] дваждÑ, ÑÑÐ¾Ð±Ñ ÑделаÑÑ Ð¾ÑÐµÐ½Ñ Ð²ÑÑокий пÑÑжок назад.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>ÐоиÑеÑÑ ÑпаÑÑÑ Ñ Ð¾Ð±ÑÑва? ÐажмиÑе левÑй shift, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð²ÐµÑнÑÑÑÑÑ Ð²Ð»ÐµÐ²Ð¾ или впÑаво, не пеÑедвигаÑÑÑ.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>ÐекоÑоÑÑе Ð²Ð¸Ð´Ñ Ð¾ÑÑÐ¶Ð¸Ñ ÑÑебÑÑÑ Ð¾ÑобÑÑ
ÑÑÑаÑегий или пÑоÑÑо много ÑÑениÑовок, поÑÑÐ¾Ð¼Ñ Ð½Ðµ ÑазоÑаÑовÑвайÑеÑÑ Ð² инÑÑÑÑменÑе, еÑли Ñазок пÑомаÑ
нÑÑеÑÑ.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>ÐолÑÑинÑÑво видов оÑÑÐ¶Ð¸Ñ Ð½Ðµ ÑÑабоÑаÑÑ Ð¿Ñи попадании в водÑ. ÐÑела и ТоÑÑ - ÑÑо иÑклÑÑениÑ.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>СÑаÑÑй ÐимбÑÑÐ³ÐµÑ Ð²Ð·ÑÑваеÑÑÑ Ð½ÐµÑилÑно. Ðднако веÑеÑ, неÑÑÑий зловонное облако, Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑÑавиÑÑ Ð½ÐµÑколÑко ежей за Ñаз.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>ФоÑÑепÑÑновÑй ÑÐ´Ð°Ñ - ÑÑо наиболее моÑнÑй из ÑдаÑов Ñ Ð²Ð¾Ð·Ð´ÑÑ
а. ÐÑи иÑполÑзовании Ð²Ñ Ð¿Ð¾ÑеÑÑеÑе ежа, в ÑÑом его недоÑÑаÑок.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>ÐинÑ-липÑÑки - оÑлиÑнÑй инÑÑÑÑÐ¼ÐµÐ½Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑиÑ
ÑепнÑÑ
ÑеакÑий, Ð¾Ñ ÐºÐ¾ÑоÑÑÑ
Ñж Ð¿Ð¾Ð¿Ð°Ð´ÐµÑ Ð² непÑиÑÑнÑÑ ÑиÑÑаÑиÑ... или в водÑ.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>ÐÐ¾Ð»Ð¾Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ ÑÑÑекÑивен, когда иÑполÑзÑеÑÑÑ Ð½Ð° моÑÑÑ Ð¸Ð»Ð¸ балке. УдаÑеннÑй Ñж пÑолеÑÐ¸Ñ ÑÐºÐ²Ð¾Ð·Ñ Ð·ÐµÐ¼Ð»Ñ.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>ÐÑли Ð²Ñ Ð·Ð°ÑÑÑÑли позади ежа пÑоÑивника, иÑполÑзÑйÑе ÐолоÑ. ÑÑÐ¾Ð±Ñ Ð¾ÑвободиÑÑ ÑÐµÐ±Ñ Ð±ÐµÐ· ÑиÑка поÑеÑи здоÑовÑÑ Ð¾Ñ Ð²Ð·ÑÑва.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>ÐиÑÑанÑиÑ, коÑоÑÑÑ Ð¿ÑоÑ
Ð¾Ð´Ð¸Ñ Ð¢Ð¾ÑÑ, завиÑÐ¸Ñ Ð¾Ñ Ð¿Ð¾Ð²ÐµÑÑ
ноÑÑи. ÐÑполÑзÑйÑе клавиÑÑ Ð°Ñаки, ÑÑÐ¾Ð±Ñ ÑдеÑониÑоваÑÑ ÐµÐ³Ð¾ ÑанÑÑе.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>ÐгнемÑÑ - ÑÑо оÑÑжие, но он Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзован как инÑÑÑÑÐ¼ÐµÐ½Ñ Ð´Ð»Ñ ÑÑÑÑÑ ÑÑннелей.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>ХоÑиÑе ÑзнаÑÑ, кÑо ÑÑÐ¾Ð¸Ñ Ð·Ð° ÑазÑабоÑкой игÑÑ? ÐажмиÑе на логоÑип Hedgewars в главном менÑ, ÑÑÐ¾Ð±Ñ ÑвидеÑÑ ÑоÑÑав ÑазÑабоÑÑиков.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>ÐÑавиÑÑÑ Hedgewars? СÑанÑÑе ÑанаÑом на %1 или ÑледиÑе за нами на %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>РиÑÑйÑе Ñвои ваÑианÑÑ Ð½Ð°Ð´Ð³Ñобий, ÑлÑп, Ñлагов или даже каÑÑ Ð¸ Ñем! Ðо не забÑдÑÑе пеÑедаÑÑ Ð¸Ñ
ÑопеÑникам каким-либо обÑазом Ð´Ð»Ñ Ð¸Ð³ÑÑ Ð¿Ð¾ ÑеÑи.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>ÐÑÐµÐ½Ñ Ñ
оÑеÑÑÑ Ð¾ÑобеннÑÑ ÑлÑпÑ? СделайÑе пожеÑÑвование и полÑÑиÑе ÑкÑклÑзивнÑÑ ÑлÑÐ¿Ñ Ð½Ð° вÑбоÑ!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>ÐбновлÑйÑе видеодÑайвеÑа, ÑÑÐ¾Ð±Ñ Ð½Ðµ бÑло пÑоблем во вÑÐµÐ¼Ñ Ð¸Ð³ÑÑ.</translation>
+ <message numerus="yes">
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation>
+ <numerusform>ÐÑего <b>%1</b> Ñж бÑл ÑÐ±Ð¸Ñ Ð² ÑеÑение игÑÑ.</numerusform>
+ <numerusform>ÐÑего <b>%1</b> ежа бÑли ÑбиÑÑ Ð² ÑеÑение игÑÑ.</numerusform>
+ <numerusform>ÐÑего <b>%1</b> ежей бÑли ÑбиÑÑ Ð² ÑеÑение игÑÑ.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ð¤Ð°Ð¹Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии Hedgewars наÑ
одÑÑÑÑ Ð² папке "Ðои докÑменÑÑ\Hedgewars". СоздавайÑе бÑÐºÐ°Ð¿Ñ Ð¸Ð»Ð¸ пеÑеноÑиÑе ÑайлÑ, но не ÑедакÑиÑÑйÑе иÑ
вÑÑÑнÑÑ.</translation>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation>
+ <numerusform>(%1 ÑбийÑÑво)</numerusform>
+ <numerusform>(%1 ÑбийÑÑва)</numerusform>
+ <numerusform>(%1 ÑбийÑÑв)</numerusform>
+ </translation>
</message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Ðожно аÑÑоÑииÑоваÑÑ ÑÐ°Ð¹Ð»Ñ Hedgewars (ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¸ демки игÑ) Ñ Ð¸Ð³Ñой, ÑÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑÑкаÑÑ Ð¸Ñ
пÑÑмо из ваÑего лÑбимого Ñайлового менеджеÑа или бÑаÑзеÑа.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation>
+ <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑÐ½ÐºÑ ÑÑона.</numerusform>
+ <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑнкÑа ÑÑона.</numerusform>
+ <numerusform><b>%1</b> поÑÑиÑал нÑжнÑм подÑÑÑелиÑÑ Ð´ÑÑзей на <b>%2</b> пÑнкÑов ÑÑона.</numerusform>
+ </translation>
</message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>ХоÑиÑе ÑÑкономиÑÑ Ð²ÐµÑÑвки? ÐÑпÑÑÑиÑе веÑÑÐ²ÐºÑ Ð² воздÑÑ
е и ÑÑÑелÑйÑе Ñнова. Ðока Ð²Ñ Ð½Ðµ заÑÑонеÑе землÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ Ð²ÐµÑÑÐ²ÐºÑ ÑколÑко Ñгодно, не ÑÑаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ
!</translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation>
+ <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзника.</numerusform>
+ <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзников.</numerusform>
+ <numerusform><b>%1</b> Ñбил <b>%2</b> ÑоÑзников.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ð¤Ð°Ð¹Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии Hedgewars наÑ
одÑÑÑÑ Ð² папке ""Library/Application Support/Hedgewars". СоздавайÑе бÑÐºÐ°Ð¿Ñ Ð¸Ð»Ð¸ пеÑеноÑиÑе ÑайлÑ, но не ÑедакÑиÑÑйÑе иÑ
вÑÑÑнÑÑ.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
од.</numerusform>
+ <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
ода.</numerusform>
+ <numerusform><b>%1</b> иÑпÑгалÑÑ Ð¸ пÑопÑÑÑил <b>%2</b> Ñ
одов.</numerusform>
+ </translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ð¤Ð°Ð¹Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии Hedgewars наÑ
одÑÑÑÑ Ð² папке ".hedgewars". СоздавайÑе бÑÐºÐ°Ð¿Ñ Ð¸Ð»Ð¸ пеÑеноÑиÑе ÑайлÑ, но не ÑедакÑиÑÑйÑе иÑ
вÑÑÑнÑÑ.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>ÐеÑÑÐ¸Ñ Hedgewars под опеÑаÑионнÑÑ ÑиÑÑÐµÐ¼Ñ Windows поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Xfire. Ðе забÑдÑÑе добавиÑÑ Hedgewars в ÑпиÑок игÑ, ÑÑÐ¾Ð±Ñ Ð²Ð°Ñи дÑÑзÑÑ Ð²Ð¸Ð´ÐµÐ»Ð¸, когда Ð²Ñ Ð² игÑе.</translation>
+ <source>Save</source>
+ <translation type="unfinished">СоÑ
ÑаниÑÑ</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>ÐÑполÑзÑйÑе ÐокÑÐµÐ¹Ð»Ñ ÐолоÑова или ÐгнемÑÑ, ÑÑÐ¾Ð±Ñ Ð²Ñеменно не даÑÑ ÐµÐ¶Ð°Ð¼ пÑойÑи ÑеÑез ÑÑÐ½Ð½ÐµÐ»Ñ Ð¸Ð»Ð¸ по плаÑÑоÑме.</translation>
+ <source>In game...</source>
+ <translation>РигÑе...</translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>ÐÑÑÐ»ÐºÑ Ð¼Ð¾Ð¶ÐµÑÑ Ð±ÑÑÑ Ñложно иÑполÑзоваÑÑ. ÐÑ ÑадиÑÑ Ð¿Ð¾Ð²Ð¾ÑоÑа завиÑÐ¸Ñ Ð¾Ñ ÑкоÑоÑÑи, поÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ð¿ÑобÑйÑе не иÑполÑзоваÑÑ Ð¿Ð¾Ð»Ð½ÑÑ ÑÐ¸Ð»Ñ Ð±ÑоÑка.</translation>
+ <source>Open the snapshot folder</source>
+ <translation>ÐÑкÑÑÑÑ Ð¿Ð°Ð¿ÐºÑ ÑкÑинÑоÑов</translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
<source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
- <translation>ÐокалÑÐ½Ð°Ñ Ð¸Ð³Ñа</translation>
- </message>
- <message>
<source>Play a game on a single computer</source>
<translation>ÐгÑаÑÑ Ð½Ð° одном компÑÑÑеÑе</translation>
</message>
<message>
- <source>Network Game</source>
- <translation>СеÑÐµÐ²Ð°Ñ Ð¸Ð³Ñа</translation>
- </message>
- <message>
<source>Play a game across a network</source>
<translation>ÐгÑаÑÑ Ð¿Ð¾ ÑеÑи</translation>
</message>
@@ -825,6 +979,26 @@ Please pick another nickname:</source>
<source>Edit game preferences</source>
<translation>РедакÑиÑоваÑÑ Ð½Ð°ÑÑÑойки игÑÑ</translation>
</message>
+ <message>
+ <source>Play a game across a local area network</source>
+ <translation>ÐгÑаÑÑ Ð¿Ð¾ локалÑной ÑеÑи</translation>
+ </message>
+ <message>
+ <source>Play a game on an official server</source>
+ <translation>ÐгÑаÑÑ Ð½Ð° оÑиÑиалÑном ÑеÑвеÑе</translation>
+ </message>
+ <message>
+ <source>Feedback</source>
+ <translation>ÐÑзÑв</translation>
+ </message>
+ <message>
+ <source>Play local network game</source>
+ <translation>ÐгÑаÑÑ Ð¿Ð¾ локалÑной ÑеÑи</translation>
+ </message>
+ <message>
+ <source>Play official network game</source>
+ <translation>ÐгÑаÑÑ Ð½Ð° оÑиÑиалÑном ÑеÑвеÑе</translation>
+ </message>
</context>
<context>
<name>PageMultiplayer</name>
@@ -832,39 +1006,43 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>СÑаÑÑ</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation>РедакÑиÑоваÑÑ Ð½Ð°ÑÑÑойки игÑÑ</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>УпÑавление</translation>
+ <translation type="obsolete">УпÑавление</translation>
</message>
<message>
- <source>DLC</source>
- <translation type="unfinished"></translation>
+ <source>Edit game preferences</source>
+ <translation>РедакÑиÑоваÑÑ Ð½Ð°ÑÑÑойки игÑÑ</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>СÑаÑÑ</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>ÐгÑа в локалÑной ÑеÑи</translation>
+ <source>Update</source>
+ <translation>ÐбновиÑÑ</translation>
</message>
<message>
- <source>Official server</source>
- <translation>ÐÑиÑиалÑнÑй ÑеÑвеÑ</translation>
+ <source>Room controls</source>
+ <translation>УпÑавление комнаÑой</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
- <translation>ÐÑиÑоединиÑÑÑÑ Ðº ÑоÑнÑм игÑоков!</translation>
+ <source>Click here for details</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
- <translation>ÐÑиÑоединиÑÑÑÑ Ð¸Ð»Ð¸ ÑоздаÑÑ ÑобÑÑвеннÑй ÑеÑÐ²ÐµÑ Ð² локалÑной ÑеÑи.</translation>
+ <source>Insert your address here</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -910,10 +1088,6 @@ Please pick another nickname:</source>
<translation>УдалиÑÑ Ð½Ð°Ð±Ð¾Ñ Ð¾ÑÑжиÑ</translation>
</message>
<message>
- <source>General</source>
- <translation>ÐÑновнÑе наÑÑÑойки</translation>
- </message>
- <message>
<source>Advanced</source>
<translation>ÐополниÑелÑно</translation>
</message>
@@ -953,6 +1127,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation>СиÑÑемнÑе наÑÑÑойки</translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation>СбÑоÑиÑÑ Ð½Ð° знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ</translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation>СбÑоÑиÑÑ Ð²Ñе пÑивÑзки</translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation>ÐгÑа</translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation>ÐÑаÑика</translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation>ÐвÑк</translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation>УпÑавление</translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation>ÐапиÑÑ Ð²Ð¸Ð´ÐµÐ¾</translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation>СеÑÑ</translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation>ÐомандÑ</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation>СÑ
емÑ</translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation>ÐÑÑжие</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation>Свои ÑвеÑа</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation>ÐаÑÑÑойки пÑокÑи</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation>Разное</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation>ÐбновлениÑ</translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation>ÐÑовеÑиÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ</translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation>ÐаÑÑÑойки видео</translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -969,11 +1231,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>СоздаÑÑ</translation>
+ <translation type="obsolete">СоздаÑÑ</translation>
</message>
<message>
<source>Join</source>
- <translation>ÐÑиÑоединиÑÑÑÑ</translation>
+ <translation type="obsolete">ÐÑиÑоединиÑÑÑÑ</translation>
</message>
<message>
<source>Admin features</source>
@@ -981,7 +1243,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Ðазвание комнаÑÑ:</translation>
+ <translation type="obsolete">Ðазвание комнаÑÑ:</translation>
</message>
<message>
<source>Rules:</source>
@@ -993,11 +1255,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>ÐоиÑк:</translation>
+ <translation type="obsolete">ÐоиÑк:</translation>
</message>
<message>
<source>Clear</source>
- <translation>ÐÑиÑÑиÑÑ</translation>
+ <translation type="obsolete">ÐÑиÑÑиÑÑ</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1007,6 +1269,30 @@ Please pick another nickname:</source>
<numerusform>на ÑеÑвеÑе %1 игÑоков</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation>ÐÑкаÑÑ ÐºÐ¾Ð¼Ð½Ð°ÑÑ:</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>СоздаÑÑ ÐºÐ¾Ð¼Ð½Ð°ÑÑ</translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation>ÐойÑи в комнаÑÑ</translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation>СоÑÑоÑние комнаÑÑ</translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation>ÐÑиÑÑиÑÑ ÑилÑÑÑÑ</translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation>ÐÑкÑÑÑÑ ÑÑÑаниÑÑ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑеÑвеÑа</translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1153,18 +1439,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation>ÐÑоÑÑÐ°Ñ Ð¸Ð³Ñа</translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation>ÐгÑаÑÑ Ð¿ÑоÑив компÑÑÑеÑа</translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation>СÑ
ваÑка</translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation>ÐгÑаÑÑ Ñ Ð´ÑÑзÑÑми за одним компÑÑÑеÑом или пÑоÑив боÑов</translation>
</message>
@@ -1173,26 +1451,14 @@ Please pick another nickname:</source>
<translation>ÐампаниÑ</translation>
</message>
<message>
- <source>Training Mode</source>
- <translation>ТÑениÑовка</translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation>ТÑениÑовка маÑÑеÑÑÑва в ÑÑениÑовоÑнÑÑ
миÑÑиÑÑ
</translation>
</message>
<message>
- <source>Demos</source>
- <translation>Ðемки</translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation>СмоÑÑеÑÑ Ð·Ð°Ð¿Ð¸ÑаннÑе демки</translation>
</message>
<message>
- <source>Load</source>
- <translation>ÐагÑÑзиÑÑ</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation>ÐагÑÑзиÑÑ ÑоÑ
ÑанÑннÑÑ Ð¸Ð³ÑÑ</translation>
</message>
@@ -1239,14 +1505,6 @@ Please pick another nickname:</source>
<translation>(в игÑе...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation>ÐаÑа: </translation>
- </message>
- <message>
- <source>Size: </source>
- <translation>РазмеÑ: </translation>
- </message>
- <message>
<source>encoding</source>
<translation>кодиÑование</translation>
</message>
@@ -1254,6 +1512,16 @@ Please pick another nickname:</source>
<source>uploading</source>
<translation>оÑпÑавка</translation>
</message>
+ <message>
+ <source>Date: %1
+</source>
+ <translation>ÐаÑа: %1</translation>
+ </message>
+ <message>
+ <source>Size: %1
+</source>
+ <translation>РазмеÑ: %1</translation>
+ </message>
</context>
<context>
<name>QAction</name>
@@ -1262,10 +1530,6 @@ Please pick another nickname:</source>
<translation>ÐÑпнÑÑÑ</translation>
</message>
<message>
- <source>Start</source>
- <translation>СÑаÑÑ</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>ÐапÑеÑиÑÑ Ð²Ñ
од</translation>
</message>
@@ -1303,7 +1567,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>ÐбновиÑÑ</translation>
+ <translation type="obsolete">ÐбновиÑÑ</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation>ÐапÑеÑиÑÑ Ð²Ñ
од незаÑегиÑÑÑиÑованнÑм игÑокам</translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation>ÐоказаÑÑ ÑекÑÑие игÑÑ</translation>
</message>
</context>
<context>
@@ -1313,10 +1589,6 @@ Please pick another nickname:</source>
<translation>ÐÑовеÑÑÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñи запÑÑке</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>ÐклÑÑиÑÑ Ð·Ð²Ñк</translation>
- </message>
- <message>
<source>Fullscreen</source>
<translation>ÐолнÑй ÑкÑан</translation>
</message>
@@ -1329,14 +1601,6 @@ Please pick another nickname:</source>
<translation>ÐлÑÑеÑнаÑивнÑй показ ÑÑона</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>ÐклÑÑиÑÑ Ð¼ÑзÑкÑ</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>ÐолноÑкÑаннÑй ÑÑонÑенд</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>УказÑваÑÑ Ð´Ð°ÑÑ Ð¸ вÑÐµÐ¼Ñ Ð² названиÑÑ
демок и Ñейвов</translation>
</message>
@@ -1345,18 +1609,6 @@ Please pick another nickname:</source>
<translation>ÐоказÑваÑÑ Ð¿Ð¾Ð´Ñказки к оÑÑжиÑ</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>ÐклÑÑиÑÑ Ð·Ð²Ñки в менÑ</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation>ÐклÑÑиÑÑ Ð¼ÑзÑÐºÑ Ð² менÑ</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation>ÐÑÑекÑÑ Ð² менÑ</translation>
- </message>
- <message>
<source>Save password</source>
<translation>СоÑ
ÑаниÑÑ Ð¿Ð°ÑолÑ</translation>
</message>
@@ -1376,14 +1628,38 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation>ÐÑполÑзоваÑÑ ÑазÑеÑение игÑÑ</translation>
</message>
+ <message>
+ <source>Visual effects</source>
+ <translation>ÐизÑалÑнÑе ÑÑÑекÑÑ</translation>
+ </message>
+ <message>
+ <source>Sound</source>
+ <translation>ÐвÑк</translation>
+ </message>
+ <message>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation>ÐÑзÑка</translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>ÑлÑÑÐ°Ð¹Ð½Ð°Ñ ÐºÐ°ÑÑа...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Человек</translation>
</message>
@@ -1396,14 +1672,6 @@ Please pick another nickname:</source>
<translation>(СиÑÑемнÑй по ÑмолÑаниÑ)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>ÑлÑÑайнÑй лабиÑинÑ...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>ÐиÑÑиÑ</translation>
- </message>
- <message>
<source>Community</source>
<translation>СообÑеÑÑво</translation>
</message>
@@ -1413,15 +1681,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>ÐодгоÑовка</translation>
+ <translation type="obsolete">ÐодгоÑовка</translation>
</message>
<message>
<source>In progress</source>
- <translation>РигÑе</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>ÑиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ ÐºÐ°ÑÑа...</translation>
+ <translation type="obsolete">РигÑе</translation>
</message>
<message>
<source>Disabled</source>
@@ -1460,10 +1724,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1491,24 +1751,12 @@ Please pick another nickname:</source>
<context>
<name>QGroupBox</name>
<message>
- <source>Team Members</source>
- <translation>СоÑÑав командÑ</translation>
- </message>
- <message>
- <source>Fort</source>
- <translation>ФоÑÑ</translation>
- </message>
- <message>
- <source>Key binds</source>
- <translation>ÐÑивÑзки клавиÑ</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>ÐомандÑ</translation>
+ <source>Team Members</source>
+ <translation>СоÑÑав командÑ</translation>
</message>
<message>
- <source>Audio/Graphic options</source>
- <translation>ÐаÑÑÑойки звÑка и гÑаÑики</translation>
+ <source>Fort</source>
+ <translation>ФоÑÑ</translation>
</message>
<message>
<source>Playing teams</source>
@@ -1531,26 +1779,6 @@ Please pick another nickname:</source>
<translation>ÐаÑÑÑойки командÑ</translation>
</message>
<message>
- <source>Misc</source>
- <translation>Разное</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>СÑ
ÐµÐ¼Ñ Ð¸Ð³ÑÑ Ð¸ набоÑÑ Ð¾ÑÑжиÑ</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation>Свои ÑвеÑа</translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation>Разное</translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation>ÐаÑÑÑойки видео</translation>
- </message>
- <message>
<source>Videos</source>
<translation>Ðидео</translation>
</message>
@@ -1558,10 +1786,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation>ÐпиÑание</translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation>ÐаÑÑÑойки пÑокÑи</translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1582,22 +1806,6 @@ Please pick another nickname:</source>
<translation>ÐгÑаниÑение FPS</translation>
</message>
<message>
- <source>Developers:</source>
- <translation>РазÑабоÑÑики:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>ÐÑаÑика:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>ÐеÑеводÑ:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>ÐÑÐ¾Ð±Ð°Ñ Ð±Ð»Ð°Ð³Ð¾Ð´Ð°ÑноÑÑÑ:</translation>
- </message>
- <message>
<source>Server name:</source>
<translation>Ðазвание ÑеÑвеÑа:</translation>
</message>
@@ -1619,11 +1827,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>ÐеÑÑиÑ</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>ÐвÑки:</translation>
+ <translation type="obsolete">ÐеÑÑиÑ</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1654,10 +1858,6 @@ Please pick another nickname:</source>
<translation>ÐонÑÑ Ð²ÑпадаеÑ</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>ÐаÑÑÑойки игÑÑ</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% невзÑÑваÑÑиÑ
ÑÑ Ð¼Ð¸Ð½</translation>
</message>
@@ -1694,10 +1894,6 @@ Please pick another nickname:</source>
<translation>ÐодÑказка:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>ÐÑа ÑбоÑка ÑвлÑеÑÑÑ Ð¿ÑомежÑÑоÑнÑм ÑÑапом ÑабоÑÑ, и Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÑовмеÑÑима Ñ Ð´ÑÑгими веÑÑиÑми игÑÑ. ÐекоÑоÑÑе возможноÑÑи могÑÑ Ð±ÑÑÑ ÑÐ»Ð¾Ð¼Ð°Ð½Ñ Ð¸Ð»Ð¸ недоÑабоÑанÑ. ÐÑполÑзÑйÑе на Ñвой ÑиÑк!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>ÐаÑеÑÑво</translation>
</message>
@@ -1739,7 +1935,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>ÐÑа пÑогÑамма ÑаÑпÑоÑÑÑанÑеÑÑÑ Ð½Ð° ÑÑловиÑÑ
лиÑензии GNU General Public License, веÑÑÐ¸Ñ 2</translation>
+ <translation type="obsolete">ÐÑа пÑогÑамма ÑаÑпÑоÑÑÑанÑеÑÑÑ Ð½Ð° ÑÑловиÑÑ
лиÑензии GNU General Public License, веÑÑÐ¸Ñ 2</translation>
</message>
<message>
<source>There are videos that are currently being processed.
@@ -1774,10 +1970,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation>ÐÑаÑкое опиÑание</translation>
- </message>
- <message>
<source>Description</source>
<translation>ÐпиÑание</translation>
</message>
@@ -1805,6 +1997,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation>ÐолнÑй ÑкÑан</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation>РазÑеÑение в полноÑкÑанном Ñежиме</translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation>РазÑеÑение в оконном Ñежиме</translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1827,6 +2063,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1843,10 +2083,6 @@ Do you really want to quit?</source>
<translation>СопоÑÑавление не ÑдалоÑÑ.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation>ÐаполниÑе вÑе полÑ</translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1893,47 +2129,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation>Ðе Ð¼Ð¾Ð³Ñ ÑоздаÑÑ Ð¿Ð°Ð¿ÐºÑ %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ðе Ð¼Ð¾Ð³Ñ ÑоздаÑÑ Ð¿Ð°Ð¿ÐºÑ %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation>ÐÑибка запÑÑка ÑеÑвеÑа: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ÐÑибка запÑÑка ÑеÑвеÑа: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2009,6 +2210,8 @@ Do you still want to join the room?</source>
<source>Do you really want to remove %1 file(s)?</source>
<translation type="unfinished">
<numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -2051,25 +2254,48 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>ÐÑевдоним</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation>Ðе вÑе игÑоки гоÑовÑ</translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ÐожалÑйÑÑа введиÑе Ð²Ð°Ñ Ð¿Ñевдоним</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation>ÐÑ Ð´ÐµÐ¹ÑÑвиÑелÑно Ñ
оÑиÑе запÑÑÑиÑÑ Ð¸Ð³ÑÑ?
+Ðе вÑе игÑоки гоÑовÑ.</translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <source>Setup</source>
- <translation>ÐаÑÑÑойка</translation>
- </message>
- <message>
<source>Play demo</source>
<translation>ÐгÑаÑÑ Ð´ÐµÐ¼ÐºÑ</translation>
</message>
@@ -2122,22 +2348,10 @@ Do you still want to join the room?</source>
<translation>УдалиÑÑ</translation>
</message>
<message>
- <source>Ready</source>
- <translation>ÐоÑов</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>СлÑÑÐ°Ð¹Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>СопоÑÑавиÑÑ ÑаÑÑиÑÐµÐ½Ð¸Ñ Ñайлов</translation>
</message>
<message>
- <source>more</source>
- <translation>еÑÑ</translation>
- </message>
- <message>
<source>More info</source>
<translation>ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ</translation>
</message>
@@ -2161,6 +2375,61 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation>ÐÑмениÑÑ Ð¾ÑпÑавкÑ</translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation>ÐведиÑе название Ð´Ð»Ñ Ð²Ð°Ñей комнаÑÑ.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation>СоздаÑÑ ÐºÐ¾Ð¼Ð½Ð°ÑÑ</translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2210,6 +2479,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation>ÐеÑно каÑÑÑ - ÑÑо оÑнова Ð´Ð»Ñ Ð²ÑеÑ
пÑведоÑлÑÑайнÑÑ
знаÑений, иÑполÑзÑемÑÑ
в игÑе.</translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation>УÑÑановиÑÑ Ð·ÐµÑно</translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation>ÐакÑÑÑÑ</translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2237,106 +2525,44 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>ÐампиÑизм</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>ÐаÑма</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>ÐÑÑиллеÑиÑ</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Режим ÑоÑÑов</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>РазделиÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>ÐеÑазÑÑÑÐ°ÐµÐ¼Ð°Ñ Ð·ÐµÐ¼Ð»Ñ</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>ÐобавиÑÑ Ð³ÑаниÑÑ</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>ÐÐ¸Ð·ÐºÐ°Ñ Ð³ÑавиÑаÑиÑ</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>ÐазеÑнÑй пÑиÑел</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>ÐеÑÑзвимоÑÑÑ</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>СлÑÑайнÑй поÑÑдок</translation>
- </message>
- <message>
- <source>King</source>
- <translation>ÐоÑолÑ</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>РаÑÑÑавиÑÑ ÐµÐ¶ÐµÐ¹</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>ÐбÑее оÑÑжие в клане</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>УбÑаÑÑ Ð±Ð°Ð»ÐºÐ¸</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>ÐÑклÑÑиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе обÑекÑÑ</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Режим беÑÑмеÑÑÐ¸Ñ Ð±Ð¾Ñов</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>СбÑÐ¾Ñ ÑÑÐ¾Ð²Ð½Ñ Ð·Ð´Ð¾ÑовÑÑ</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>ÐеÑконеÑнÑе аÑаки</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>СбÑÐ¾Ñ Ð¾ÑÑжиÑ</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>ÐндивидÑалÑнÑй Ð½Ð°Ð±Ð¾Ñ Ð¾ÑÑжиÑ</translation>
+ <source>At least two teams are required to play!</source>
+ <translation>ÐÐ»Ñ Ð¸Ð³ÑÑ Ð½ÑÐ¶Ð½Ñ ÐºÐ°Ðº минимÑм две командÑ!</translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>ÐÑклÑÑиÑÑ Ð²ÐµÑеÑ</translation>
+ <source>%1's team</source>
+ <translation>Ðоманда %1</translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>ÐолÑÑе веÑÑа</translation>
+ <source>Cancel</source>
+ <translation>ÐÑмена</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>ÐÑÑаÑеÑа команд</translation>
+ <source>Search for a theme:</source>
+ <translation>ÐÑкаÑÑ ÑемÑ:</translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>ÐобавиÑÑ Ð½Ð¸Ð¶Ð½ÑÑ Ð³ÑаниÑÑ</translation>
+ <source>Use selected theme</source>
+ <translation>ÐÑполÑзоваÑÑ Ð²ÑбÑаннÑÑ ÑемÑ</translation>
</message>
</context>
<context>
@@ -2458,12 +2684,6 @@ Do you still want to join the room?</source>
<translation>ÑÐ»Ð¾Ñ 9</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>инÑоÑмаÑиÑ
-о ежаÑ
</translation>
- </message>
- <message>
<source>chat</source>
<translation>ÑаÑ</translation>
</message>
@@ -2511,33 +2731,33 @@ info</source>
<source>record</source>
<translation>запиÑаÑÑ</translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation>инÑоÑмаÑÐ¸Ñ Ð¾ еже</translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>ÐÑновное ÑпÑавление</translation>
+ <source>Movement</source>
+ <translation>ÐеÑедвижение</translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>УпÑавление оÑÑжием</translation>
+ <source>Weapons</source>
+ <translation>ÐÑÑжие</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>УпÑавление камеÑой и кÑÑÑоÑом</translation>
+ <source>Camera</source>
+ <translation>ÐамеÑа</translation>
</message>
<message>
- <source>Other</source>
+ <source>Miscellaneous</source>
<translation>Разное</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>ÐеÑедвижение ежа и пÑиÑеливание:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>ÐÑоÑ
ождение овÑагов и пÑепÑÑÑÑвий пÑÑжками:</translation>
</message>
@@ -2601,6 +2821,10 @@ info</source>
<source>Record video:</source>
<translation>ÐапиÑÑ Ð²Ð¸Ð´ÐµÐ¾:</translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation>Ðвижение ежа</translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_sk.ts b/share/hedgewars/Data/Locale/hedgewars_sk.ts
index 7602908..34bba37 100644
--- a/share/hedgewars/Data/Locale/hedgewars_sk.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_sk.ts
@@ -2,10 +2,17 @@
<!DOCTYPE TS>
<TS version="2.0" language="sk">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
- <translation type="unfinished"></translation>
+ <translation>Krok späť</translation>
</message>
</context>
<context>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,19 +141,88 @@
<translation>Upraviť schémy</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>KeÄ je vybraná táto voľba výberom hernej schémy vyberiete automaticky aj zbraÅ</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Voľby hry</translation>
</message>
<message>
- <source>Game Options</source>
- <translation>Voľby hry</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Mapa</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Nepodarilo sa vytvoriť adresár %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished">Chyba pri otváranà adresára s dátami:
+%1
+
+Skontrolujte, prosÃm, inÅ¡taláciu!</translation>
</message>
</context>
<context>
<name>HWAskQuitDialog</name>
<message>
<source>Do you really want to quit?</source>
- <translation type="unfinished"></translation>
+ <translation>Naozaj chcete odÃsÅ¥?</translation>
</message>
</context>
<context>
@@ -103,8 +268,16 @@
<translation>Nepodarilo sa uložiť súbor so štýlom do %1</translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
- <translation>%1 nie je platným prÃkazom!</translation>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -140,22 +313,6 @@
<translation>Hra zrušená</translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation>Prezývka %1, ktorú ste
-si vybrali je registrovaná na
-Hedgewars.org.
-ProsÃm, napÃÅ¡te heslo do poľa
-nižšie alebo si zvoľte inú prezývku
-v nastaveniach hry:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation>Nebolo zadané žiadne heslo.</translation>
- </message>
- <message>
<source>Nickname</source>
<translation>Prezývka</translation>
</message>
@@ -166,6 +323,63 @@ v nastaveniach hry:</translation>
<message>
<source>Someone already uses your nickname %1 on the server.
Please pick another nickname:</source>
+ <translation>Prezývku %1 už niekto na serveri použÃva. ProsÃm, zvoľte si inú prezývku:</translation>
+ </message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -183,18 +397,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Mapa</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Témy</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>VÅ¡etky</translation>
</message>
@@ -219,10 +421,6 @@ Please pick another nickname:</source>
<translation>Pojašená</translation>
</message>
<message>
- <source>Type</source>
- <translation>Typ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Malé tunely</translation>
</message>
@@ -231,28 +429,96 @@ Please pick another nickname:</source>
<translation>Stredné tunely</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Veľké tunely</translation>
+ <source>Seed</source>
+ <translation>Zrno</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Malé plávajúce ostrovÄeky</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Stredné plávajúce ostrovÄeky</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Veľké plávajúce ostrovÄeky</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>Zrno</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished">RuÄne kreslená</translation>
</message>
<message>
- <source>Set</source>
- <translation>Nastaviť</translation>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Náhodné</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">NaÄÃtaÅ¥ nakreslenú mapu</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished">Kreslené mapy</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished">Všetky súbory</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -298,7 +564,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 sa pridal</translation>
+ <translation type="obsolete">%1 *** %2 sa pridal</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -314,28 +580,65 @@ Please pick another nickname:</source>
</message>
<message>
<source>Remote host has closed connection</source>
- <translation type="unfinished"></translation>
+ <translation>Vzdialený hostiteľ ukonÄiÅ¥ spojenie</translation>
</message>
<message>
<source>The server is too old. Disconnecting now.</source>
- <translation type="unfinished"></translation>
+ <translation>Server je prÃliÅ¡ zastaraný. OdpojÃm sa.</translation>
</message>
</context>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Heslo</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HWUploadVideoDialog</name>
<message>
<source>Upload video</source>
- <translation type="unfinished"></translation>
+ <translation>Upload videa</translation>
</message>
<message>
<source>Upload</source>
+ <translation>Upload</translation>
+ </message>
+</context>
+<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -347,22 +650,40 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
- <translation type="unfinished"></translation>
+ <translation>Trvanie: %1m %2s</translation>
</message>
<message>
<source>Video: %1x%2, </source>
- <translation type="unfinished"></translation>
+ <translation>Video: %1x%2, </translation>
</message>
<message>
<source>%1 fps, </source>
- <translation type="unfinished"></translation>
+ <translation>%1 fps, </translation>
</message>
<message>
<source>Audio: </source>
+ <translation>Zvuk: </translation>
+ </message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -396,6 +717,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Nastaviť dáta</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Všeobecné</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -405,6 +758,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -440,7 +804,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Eraser</source>
- <translation type="unfinished"></translation>
+ <translation>Guma</translation>
</message>
</context>
<context>
@@ -450,8 +814,40 @@ Please pick another nickname:</source>
<translation>Všeobecné</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>PokroÄilé</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Klobúk</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Meno</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Náhodný tÃm</translation>
</message>
</context>
<context>
@@ -520,6 +916,14 @@ Please pick another nickname:</source>
<numerusform><b>%1</b> sa zľakol a preskoÄil Å¥ah <b>%2</b>krát.</numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished">Uložiť</translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -532,298 +936,65 @@ Please pick another nickname:</source>
<name>PageInfo</name>
<message>
<source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
+ <translation>OtvoriÅ¥ prieÄinok so snÃmkami</translation>
</message>
</context>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Ak chcete hraÅ¥ s priateľom ako tÃm, jednoducho si zvoľte tú istú farbu. I naÄalej budete ovládaÅ¥ svojich vlastných ježkov, ale vÃÅ¥azstvá Äi prehry budú spoloÄné.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Niektoré zbrane môžu spôsobovaÅ¥ málo Å¡kody, ale dokážu byÅ¥ oveľa úÄinnejÅ¡ie v tej správnej situácii. Skúste použiÅ¥ Desert Eagle na zostrelenie viacerých ježkov do vody.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Ak neviete, Äo robiÅ¥ a nechcete mrhaÅ¥ munÃciou, preskoÄte Å¥ah. Ale nerobte tak prÃliÅ¡ Äasto, pretože prÃde Náhla smrÅ¥!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Ak nechcete, aby niekto iný použÃval vaÅ¡u prezývku na oficiálnom serveri, registrujte si úÄet na http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Nudà vás štandardná hra? Vyskúšajte si jednu z misii - ponúkajú iný herný zážitok v závislosti na tom, akú si vyberiete.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Vo východzom nastavenà sa posledná hra automaticky ukladá ako demo. Vyberte 'Miestna hra' a kliknite na tlaÄidlo 'Demá' v pravom dolnom rohu, ak si chcete demo uložiÅ¥ alebo prehraÅ¥.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom Äase. Ak máte problém, spýtajte sa na fóre, ale neÄakajte podporu 24 hodÃn v týždni!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom Äase. Ak chcete pomôcÅ¥, môžete nám zaslaÅ¥ malú finanÄnú výpomoc alebo prispieÅ¥ vlastnou prácou!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom Äase. Podeľte sa oÅ so svojou rodinou a priateľmi!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Z Äasu na Äas bývajú usporiadavané oficiálne turnaje. Najbližšie akcie sú vždy uverejnené na http://www.hedgewars.org/ pár dnà dopredu.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je dostupný v mnohých jazykoch. Ak preklad do vaÅ¡ej reÄi chýba alebo nie je aktuálny, prosÃm, kontaktujte nás!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars bežà na množstve rozliÄných operaÄných systémov vrátane Microsoft Windows, Mac OS X a Linuxu.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Nezabudnite, že si vždy môžete vytvoriť vlastnú lokálnu alebo sieťovú/online hru. Nie ste obmedzený len na voľbu 'Jednoduchá hra'.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Mali by ste si dopriaÅ¥ krátky odpoÄinok po každej hodine hry.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Ak vaÅ¡a grafická karta nie je schopná poskytnúť hardvérovo akcelerované OpenGL, skúste povoliÅ¥ režim nÃzkej kvality, aby ste dosiahli požadovaný výkon.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Sme otvorenà novým nápadom a konÅ¡truktÃvnej kritike. Ak sa vám nieÄo nepáÄi alebo máte skvelý nápad, dajte nám vedieÅ¥!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Obzvlášť pri hre online buÄte sluÅ¡ný a pamätajte, že s vami alebo proti vám môžu hraÅ¥ tiež neplnoletÃ!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Å peciálne herné režimy ako 'VampÃrizmus' alebo 'Karma' vám umožnia vyvinúť úplne novú taktiku. Vyskúšajte ich vo vlastnej hre!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Nikdy by ste nemali inÅ¡talovaÅ¥ Hedgewars na cudzà poÄÃtaÄ (v Å¡kole, na univerzite, v práci, atÄ). ProsÃm, radÅ¡ej požiadajte zodpovednú osobu!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars môže byÅ¥ výborná hra, ak máte krátku chvÃľku poÄas prestávky. Iba sa uistite, že nepoužijete prÃliÅ¡ veľa ježkov alebo prÃliÅ¡ veľkú mapu. Rovnako môže pomocÅ¥ znÞenie Äasu a zdravia.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>PoÄas tvorby tejto hry nebolo ublÞené žiadnemu ježkovi.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars je Open Source a Freeware, ktorý vytvárame vo voľnom Äase. Ak vám niekto túto hru predal, skúste žiadaÅ¥ o refundáciu!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Ak chcete pre hru použiÅ¥ jeden alebo viacero gamepadov, pripojte ich pred spustenÃm hry.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Vytvorte si úÄet na %1, aby ste tak zabránili ostatným použÃvaÅ¥ vaÅ¡u obľúbenú prezývku poÄas hrania na oficiálnom serveri.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Ak vaÅ¡a grafická karta nie je schopná poskytnúť hardvérovo akcelerované OpenGL, skúste aktualizovaÅ¥ prÃsluÅ¡né ovládaÄe.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Dostupné sú tri rôzne výskoky. Dvakrát stlaÄte [vysoký skok] pre veľmi vysoký skok vzad.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>BojÃte sa pádu z útesu? Podržte [presné mierenie] a stlaÄte [doľava] alebo [doprava] pre otoÄenie na mieste.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Niektoré zbrane vyžaduju osobitnú stratégiu alebo len veľa tréningu, takže to s vybranou zbraÅou nevzdávajte, ak sa vám nepodarà trafiÅ¥ nepriateľa.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>VäÄÅ¡ina zbranà prestane fungovaÅ¥ pri kontakte s vodou. Navádzané vÄela a Torta sú výnimkami z tohto pravidla.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Starý cheeseburger spôsobà len malú explóziu. ObláÄik smradu, ktorý je ovplyvÅovaný vetrom, vÅ¡ak dokáže otráviÅ¥ množstvo ježkov.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>KlavÃrový útok je najniÄivejÅ¡Ã vzduÅ¡ný útok. Pri jeho použità prÃdete o ježka, Äo je jeho veľké mÃnus.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Lepkavé mÃny sú perfektným nástrojom na vytvorenie malých reÅ¥azových reakcii, vÄaka ktorým postavÃte ježkov do krajných situácii ... alebo vody.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Kladivo je najefektÃvnejÅ¡ie pri použità na mostoch alebo trámoch. Zasiahnutà ježkovia prerazia zem.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Ak ste zaseknutý za nepriateľským ježkom, použite kladivo, aby ste sa oslobodili bez toho, aby vám ublÞila explózia.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Maximálna prejdená vzdialenosť torty zavisà na zemi, ktorou musà prejsť. Použitie [útok], ak chcete spustiť detonáciu skôr.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>PlameÅomet je zbraÅ, no rovnako môže byÅ¥ použitý na kopanie tunelov.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Chcete vedieť, kto stojà za hrou? Kliknite na logo Hedgewars v hlavnom menu pre zobrazenie zásluh.</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Ak máte chuÅ¥, môžte si nakresliÅ¥ vlastné hrobÄeky, klobúky, vlajky alebo dokonca mapy a témy! Pamätajte vÅ¡ak, že ak ich budete chcieÅ¥ použiÅ¥ v hre online, budete ich musieÅ¥ zdieľaÅ¥ s ostatnými.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Chcete nosiÅ¥ Å¡pecifický klobúk? Prispejte nám a ako odmenu zÃskate exkluzÃvny klobúk podľa vášho výberu!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Aby ste sa vyhli problémom pri hre, udržujte ovládaÄe vaÅ¡ej grafickej karty vždy aktuálne.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>KonfiguraÄné súbory Hedgewars nájdete v "Moje Dokumenty\Hedgewars". Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi poÄÃtaÄmi, ale needitujte ich ruÄne.</translation>
- </message>
- <message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Chcete uÅ¡etriÅ¥ lano? Kým ste vo vzduchu, uvoľnite ho a opäť vystreľte. Kým sa nedotknete zeme, môžete to isté lano znovu použiÅ¥ bez toho, aby sa vám mÃÅali jeho zásoby!</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>PáÄia sa vám Hedgewars? StaÅte sa fanúšikom na %1 alebo sa pripojte k naÅ¡ej skupine na %2. Môžte nás tiež nasledovaÅ¥ na %3!</translation>
- </message>
- <message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Môžte priradiÅ¥ súbory patriace Hedgewars (uložené hry a nahrávky záznamov) ku hre, ÄÃm sa vám budú otváraÅ¥ priamo z vášho obľubeného prehliadaÄa súborov alebo internetu.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>KonfiguraÄné súbory Hedgewars nájdete v "Library/Application Support/Hedgewars" vo vaÅ¡om domovskom adresári. Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi poÄÃtaÄmi, ale needitujte ich ruÄne.</translation>
- </message>
- <message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>KonfiguraÄné súbory Hedgewars nájdete v ".hedgewars" vo vaÅ¡om domovskom adresári. Vytvárajte si zálohy alebo prenášajte si tieto súbory medzi poÄÃtaÄmi, ale needitujte ich ruÄne.</translation>
- </message>
- <message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Hedgewars vo verzii pre Windows podporujú Xfire. Pridajte si Hedgewars do vášho zoznamu hier tak, aby vás vaši priatelia videli hrať.</translation>
+ <source>Downloadable Content</source>
+ <translation>Stiahnuteľný obsah</translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Použite Molotovov koktejl alebo plameÅomet na doÄasné zabránenie ježkom prejsÅ¥ terénom ako sú tunely alebo ploÅ¡iny.</translation>
+ <source>Play a game on a single computer</source>
+ <translation>HraÅ¥ hru na tomto poÄÃtaÄi</translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>Navádzaná vÄela je troÅ¡ku zložitejÅ¡ia na použitie. Jej polomer otoÄenia závisà na jej rýchlosti, takže ju radÅ¡ej nepoužÃvajte pri plnej sile.</translation>
+ <source>Play a game across a network</source>
+ <translation>Hra cez sieť</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Stiahnuteľný obsah</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation>PreÄÃtajte si, kto stojà za projektom Hedgewars</translation>
</message>
<message>
- <source>Local Game</source>
- <translation type="unfinished"></translation>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <translation>Dajte nám späťnú väzbu formou hlásenia chýb, navrhovania nových vlastnostà alebo nám len napÃÅ¡te, Äo sa vám na Hedgewars páÄi</translation>
</message>
<message>
- <source>Play a game on a single computer</source>
- <translation type="unfinished"></translation>
+ <source>Access the user created content downloadable from our website</source>
+ <translation>StiahnuÅ¥ obsah vytvorený inými užÃvateľmi z naÅ¡ej stránky </translation>
</message>
<message>
- <source>Network Game</source>
- <translation type="unfinished"></translation>
+ <source>Exit game</source>
+ <translation>UkonÄiÅ¥ hru</translation>
</message>
<message>
- <source>Play a game across a network</source>
- <translation type="unfinished"></translation>
+ <source>Manage videos recorded from game</source>
+ <translation>SpravovaÅ¥ videá nahrané poÄas hrania</translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
- <translation type="unfinished"></translation>
+ <source>Edit game preferences</source>
+ <translation>Upraviť nastavenia hry</translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -833,38 +1004,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Å tart</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished">Upraviť nastavenia hry</translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Ovládanie</translation>
+ <translation type="obsolete">Ovládanie</translation>
</message>
<message>
- <source>DLC</source>
- <translation type="unfinished"></translation>
+ <source>Edit game preferences</source>
+ <translation type="unfinished">Upraviť nastavenia hry</translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished">Stiahnuteľný obsah</translation>
+ <source>Start</source>
+ <translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>LAN hra</translation>
+ <source>Update</source>
+ <translation type="unfinished">Obnoviť</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Oficiálny server</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -911,49 +1086,133 @@ Please pick another nickname:</source>
<translation>VymazaÅ¥ sadu zbranÃ</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Všeobecné</translation>
- </message>
- <message>
<source>Advanced</source>
- <translation type="unfinished">PokroÄilé</translation>
+ <translation>PokroÄilé</translation>
</message>
<message>
<source>Reset to default colors</source>
- <translation type="unfinished"></translation>
+ <translation>Nastaviť východzie farby</translation>
</message>
<message>
<source>Proxy host</source>
- <translation type="unfinished"></translation>
+ <translation>Hostiteľ proxy</translation>
</message>
<message>
<source>Proxy port</source>
- <translation type="unfinished"></translation>
+ <translation>Port proxy</translation>
</message>
<message>
<source>Proxy login</source>
- <translation type="unfinished"></translation>
+ <translation>Login pre proxy</translation>
</message>
<message>
<source>Proxy password</source>
- <translation type="unfinished"></translation>
+ <translation>Heslo pre proxy</translation>
</message>
<message>
<source>No proxy</source>
- <translation type="unfinished"></translation>
+ <translation>Bez proxy</translation>
</message>
<message>
<source>Socks5 proxy</source>
- <translation type="unfinished"></translation>
+ <translation>Socks5 proxy</translation>
</message>
<message>
<source>HTTP proxy</source>
- <translation type="unfinished"></translation>
+ <translation>HTTP proxy</translation>
</message>
<message>
<source>System proxy settings</source>
+ <translation>Systémové nastavenia proxy</translation>
+ </message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">TÃmy</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Výzbroj</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished">Vlastné farby</translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished">Nastavenia proxy</translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished">RozliÄné</translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished">Voľby nahrávania videa</translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -970,11 +1229,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Vytvoriť</translation>
+ <translation type="obsolete">Vytvoriť</translation>
</message>
<message>
<source>Join</source>
- <translation>Pripojiť sa</translation>
+ <translation type="obsolete">Pripojiť sa</translation>
</message>
<message>
<source>Admin features</source>
@@ -982,7 +1241,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Názov miestnosti:</translation>
+ <translation type="obsolete">Názov miestnosti:</translation>
</message>
<message>
<source>Rules:</source>
@@ -994,11 +1253,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Hľadať:</translation>
+ <translation type="obsolete">Hľadať:</translation>
</message>
<message>
<source>Clear</source>
- <translation>VyÄistiÅ¥</translation>
+ <translation type="obsolete">VyÄistiÅ¥</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1008,6 +1267,30 @@ Please pick another nickname:</source>
<numerusform>%1 hráÄov online</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1154,48 +1437,28 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
+ <translation>Zahrajte si rýchlu hru proti poÄÃtaÄu s náhodnými nastaveniami</translation>
</message>
<message>
<source>Play a hotseat game against your friends, or AI teams</source>
- <translation type="unfinished"></translation>
+ <translation>Zahrajte si hru za týmto poÄÃtaÄom proti kamarátom alebo poÄÃtaÄovým protivnÃkom</translation>
</message>
<message>
<source>Campaign Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Režim kampane</translation>
</message>
<message>
<source>Practice your skills in a range of training missions</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
+ <translation>Cibrite si svoje schopnosti v rade tréningových misiÃ</translation>
</message>
<message>
<source>Watch recorded demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Load</source>
- <translation type="unfinished">NaÄÃtaÅ¥</translation>
+ <translation>Prezerať nahrané demá</translation>
</message>
<message>
<source>Load a previously saved game</source>
- <translation type="unfinished"></translation>
+ <translation>NaÄÃtaÅ¥ uloženú hru</translation>
</message>
</context>
<context>
@@ -1210,49 +1473,51 @@ Please pick another nickname:</source>
</message>
<message>
<source>Pick the mission or training to play</source>
- <translation type="unfinished"></translation>
+ <translation>Vyberte si misiu alebo tréning</translation>
</message>
<message>
<source>Start fighting</source>
- <translation type="unfinished"></translation>
+ <translation>ZaÄaÅ¥ boj</translation>
</message>
</context>
<context>
<name>PageVideos</name>
<message>
<source>Name</source>
- <translation type="unfinished">Meno</translation>
+ <translation>Meno</translation>
</message>
<message>
<source>Size</source>
- <translation type="unfinished"></translation>
+ <translation>Veľkosť</translation>
</message>
<message numerus="yes">
<source>%1 bytes</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1 bajtov</numerusform>
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<source>(in progress...)</source>
- <translation type="unfinished"></translation>
+ <translation>(prebieha...)</translation>
</message>
<message>
- <source>Date: </source>
- <translation type="unfinished"></translation>
+ <source>encoding</source>
+ <translation>kódovanie</translation>
</message>
<message>
- <source>Size: </source>
- <translation type="unfinished"></translation>
+ <source>uploading</source>
+ <translation>uploadujem</translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1263,10 +1528,6 @@ Please pick another nickname:</source>
<translation>Vykopnúť</translation>
</message>
<message>
- <source>Start</source>
- <translation>Spustiť</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Obmedziť pripojenia</translation>
</message>
@@ -1304,7 +1565,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>Obnoviť</translation>
+ <translation type="obsolete">Obnoviť</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1318,10 +1591,6 @@ Please pick another nickname:</source>
<translation>Celá obrazovka</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Povoliť zvuky</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Zobrazovať FPS</translation>
</message>
@@ -1330,14 +1599,6 @@ Please pick another nickname:</source>
<translation>Iný spôsob zobrazovania škody</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Frontend na celú obrazovku</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>Povoliť hudbu</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>PripojiÅ¥ dátum a Äas k súboru so záznamom</translation>
</message>
@@ -1346,45 +1607,57 @@ Please pick another nickname:</source>
<translation>Zobrazovať nápovedu pre zbrane</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Povoliť zvuky vo frontende</translation>
+ <source>Save password</source>
+ <translation>Uložiť heslo</translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Povoliť hudbu vo frontende</translation>
+ <source>Save account name and password</source>
+ <translation>UložiÅ¥ meno úÄtu a heslo</translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Efekty vo frontende</translation>
+ <source>Video is private</source>
+ <translation>Video je súkromné</translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
+ <translation>Nahrať audio</translation>
+ </message>
+ <message>
+ <source>Use game resolution</source>
+ <translation>PoužiÅ¥ rozlÃÅ¡enie hry</translation>
+ </message>
+ <message>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>In-game sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>vygenerovaná mapa...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Älovek</translation>
</message>
@@ -1397,14 +1670,6 @@ Please pick another nickname:</source>
<translation>(Východzie nastavenie)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>vygenerované bludisko..</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Misia</translation>
- </message>
- <message>
<source>Community</source>
<translation>Komunita</translation>
</message>
@@ -1414,15 +1679,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>V lobby</translation>
+ <translation type="obsolete">V lobby</translation>
</message>
<message>
<source>In progress</source>
- <translation>Prebieha</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>ruÄne kreslená mapa...</translation>
+ <translation type="obsolete">Prebieha</translation>
</message>
<message>
<source>Disabled</source>
@@ -1461,10 +1722,6 @@ Please pick another nickname:</source>
<translation>Nad sebou</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Triasť</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Äervené/Azúrové (odtiene Å¡edej)</translation>
</message>
@@ -1496,22 +1753,10 @@ Please pick another nickname:</source>
<translation>Älenovia tÃmu</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Nastavenia kláves</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Pevnosť</translation>
</message>
<message>
- <source>Teams</source>
- <translation>TÃmy</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Nastavenia zvuku/grafiky</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Sieťová hra</translation>
</message>
@@ -1532,36 +1777,12 @@ Please pick another nickname:</source>
<translation>Nastavenia tÃmu</translation>
</message>
<message>
- <source>Misc</source>
- <translation>RozliÄné</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Schémy a zbrane</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
- <translation type="unfinished"></translation>
+ <translation>Videá</translation>
</message>
<message>
<source>Description</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
+ <translation>Popis</translation>
</message>
</context>
<context>
@@ -1571,24 +1792,8 @@ Please pick another nickname:</source>
<translation>Äas pre mÃny</translation>
</message>
<message>
- <source>Mines</source>
- <translation>MÃny</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>Vývojári:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafika:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Preklady:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Osobitné poÄakovanie:</translation>
+ <source>Mines</source>
+ <translation>MÃny</translation>
</message>
<message>
<source>Weapons</source>
@@ -1620,21 +1825,13 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Verzia</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Zvuky:</translation>
+ <translation type="obsolete">Verzia</translation>
</message>
<message>
<source>Initial sound volume</source>
<translation>Ãvodná hlasitosÅ¥ zvuku</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Schéma hry</translation>
- </message>
- <message>
<source>Damage Modifier</source>
<translation>Modifikátor poškodenia</translation>
</message>
@@ -1695,11 +1892,6 @@ Please pick another nickname:</source>
<translation>Tip: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Toto zostavenie je 'stále-vo-vývoji' a nemusà byť kompatibilné s inými verziami hry.
-Niektoré vlastnosti nemusia fungovaÅ¥ alebo nemusia byÅ¥ dokonÄené. PoužÃvajte na vlastné riziko!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Kvalita</translation>
</message>
@@ -1741,68 +1933,108 @@ Niektoré vlastnosti nemusia fungovaÅ¥ alebo nemusia byÅ¥ dokonÄené. PoužÃva
</message>
<message>
<source>This program is distributed under the GNU General Public License v2</source>
- <translation>Tento program je distribuovaný pod licenciou GNU General Public License v2</translation>
+ <translation type="obsolete">Tento program je distribuovaný pod licenciou GNU General Public License v2</translation>
</message>
<message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
- <translation type="unfinished"></translation>
+ <translation>Momentálne sa niektoré videá spracovávajú. UkonÄenÃm zruÅ¡Ãte spracovávanie. Naozaj chcete ukonÄiÅ¥ program?</translation>
</message>
<message>
<source>Please provide either the YouTube account name or the email address associated with the Google Account.</source>
- <translation type="unfinished"></translation>
+ <translation>ProsÃm zadajte buÄ názov YouTube úÄtu alebo e-mailovú adresu prepojenú s Google úÄtom.</translation>
</message>
<message>
<source>Account name (or email): </source>
- <translation type="unfinished"></translation>
+ <translation>Názov úÄtu (alebo e-mail): </translation>
</message>
<message>
<source>Password: </source>
- <translation type="unfinished"></translation>
+ <translation>Heslo:</translation>
</message>
<message>
<source>Video title: </source>
- <translation type="unfinished"></translation>
+ <translation>Názov videa: </translation>
</message>
<message>
<source>Video description: </source>
- <translation type="unfinished"></translation>
+ <translation>Popis videa: </translation>
</message>
<message>
<source>Tags (comma separated): </source>
+ <translation>ZnaÄky (oddelené Äiarkou): </translation>
+ </message>
+ <message>
+ <source>Description</source>
+ <translation>Popis</translation>
+ </message>
+ <message>
+ <source>Nickname</source>
+ <translation>Prezývka</translation>
+ </message>
+ <message>
+ <source>Format</source>
+ <translation>Formát</translation>
+ </message>
+ <message>
+ <source>Audio codec</source>
+ <translation>Audio kodek</translation>
+ </message>
+ <message>
+ <source>Video codec</source>
+ <translation>Video kodek</translation>
+ </message>
+ <message>
+ <source>Framerate</source>
+ <translation>SnÃmkovanie</translation>
+ </message>
+ <message>
+ <source>Bitrate (Kbps)</source>
+ <translation>Bitový tok (Kbps)</translation>
+ </message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Celá obrazovka</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Description</source>
+ <source>Windowed Resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">Prezývka</translation>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Format</source>
+ <source>Summary</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Audio codec</source>
+ <source>Send system information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video codec</source>
+ <source>Type the security code:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Framerate</source>
+ <source>Revision</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Bitrate (Kbps)</source>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1818,7 +2050,7 @@ Do you really want to quit?</source>
</message>
<message>
<source>anonymous</source>
- <translation type="unfinished"></translation>
+ <translation>anonymný</translation>
</message>
</context>
<context>
@@ -1827,6 +2059,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1843,226 +2079,239 @@ Do you really want to quit?</source>
<translation>Nastavenie súborových asociácii zlyhalo.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
- <translation type="unfinished"></translation>
+ <translation>Chyba pri autentizácii voÄi google.com:</translation>
</message>
<message>
<source>Login or password is incorrect</source>
- <translation type="unfinished"></translation>
+ <translation>Prihlasovacie meno alebo heslo je nesprávne</translation>
</message>
<message>
<source>Error while sending metadata to youtube.com:
</source>
- <translation type="unfinished"></translation>
+ <translation>Chyba pri posielanà metadát na youtube.com:</translation>
</message>
<message>
<source>Teams - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>TÃmy - Ste si istý?</translation>
</message>
<message>
<source>Do you really want to delete the team '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Naozaj chcete vymazaÅ¥ tÃm '%1'?</translation>
</message>
<message>
<source>Cannot delete default scheme '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Nemôžem vymazať východziu schému '%1'!</translation>
</message>
<message>
<source>Please select a record from the list</source>
- <translation type="unfinished"></translation>
+ <translation>ProsÃm, vyberte nahrávku zo zoznamu</translation>
</message>
<message>
<source>Unable to start server</source>
- <translation type="unfinished"></translation>
+ <translation>Nepodarilo sa spustiť server</translation>
</message>
<message>
<source>Hedgewars - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Chyba</translation>
</message>
<message>
<source>Hedgewars - Success</source>
- <translation type="unfinished"></translation>
+ <translation>Hedgewars - Ãspech</translation>
</message>
<message>
<source>All file associations have been set</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
+ <translation>Všeky súborové asociácie boli nastavené</translation>
</message>
<message>
<source>Main - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Hlavné okno - Chyba</translation>
</message>
<message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Nepodarilo sa vytvoriť adresár %1</translation>
+ <translation type="obsolete">Nepodarilo sa vytvoriť adresár %1</translation>
</message>
<message>
<source>Failed to open data directory:
%1
Please check your installation!</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Chyba pri otváranà adresára s dátami:
+%1
+
+Skontrolujte, prosÃm, inÅ¡taláciu!</translation>
</message>
<message>
<source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">TCP - Chyba</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Nie je možné spustiť server: %1.</translation>
+ <translation type="obsolete">Nepodarilo sa spustiť server: %1.</translation>
</message>
<message>
<source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Nepodarilo sa spustiť enginu na </translation>
</message>
<message>
<source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kód chyby: %1</translation>
</message>
<message>
<source>Video upload - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Upload videa - Chyba</translation>
</message>
<message>
<source>Netgame - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Sieťová hra - Chyba</translation>
</message>
<message>
<source>Please select a server from the list</source>
- <translation type="unfinished"></translation>
+ <translation>ProsÃm, vyberte server zo zoznamu</translation>
</message>
<message>
<source>Please enter room name</source>
- <translation type="unfinished">ProsÃm zadajte názov miestnosti</translation>
+ <translation>ProsÃm, zadajte názov miestnosti</translation>
</message>
<message>
<source>Record Play - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Prehrávanie záznamu - Chyba</translation>
</message>
<message>
<source>Please select record from the list</source>
- <translation type="unfinished">ProsÃm vyberte záznam zo zoznamu</translation>
+ <translation>ProsÃm, vyberte záznam zo zoznamu</translation>
</message>
<message>
<source>Cannot rename to </source>
- <translation type="unfinished"></translation>
+ <translation>Nepodarilo sa premenovať na</translation>
</message>
<message>
<source>Cannot delete file </source>
- <translation type="unfinished"></translation>
+ <translation>Nepodarilo sa vymazať súbor</translation>
</message>
<message>
<source>Room Name - Error</source>
- <translation type="unfinished"></translation>
+ <translation>Názov miestnosti - Chyba</translation>
</message>
<message>
<source>Please select room from the list</source>
- <translation type="unfinished">ProsÃm vyberte miestnosÅ¥ zo zoznamu</translation>
+ <translation>ProsÃm, vyberte miestnosÅ¥ zo zoznamu</translation>
</message>
<message>
<source>Room Name - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Názov miestnosti - Ste si istý?</translation>
</message>
<message>
<source>The game you are trying to join has started.
Do you still want to join the room?</source>
- <translation type="unfinished">Hra, ku ktorej sa snažÃte pripojiÅ¥, už zaÄala.
+ <translation>Hra, ku ktorej sa snažÃte pripojiÅ¥, už zaÄala.
Aj napriek tomu chcete vojsť do miestnosti?</translation>
</message>
<message>
<source>Schemes - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Schémy - Varovanie</translation>
</message>
<message>
<source>Schemes - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Schémy - Ste si istý?</translation>
</message>
<message>
<source>Do you really want to delete the game scheme '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Naozaj chcete vymazať hernú schému '%1'?</translation>
</message>
<message>
<source>Videos - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Videa - Ste si istý?</translation>
</message>
<message>
<source>Do you really want to delete the video '%1'?</source>
- <translation type="unfinished"></translation>
+ <translation>Naozaj chcete vymazať video '%1'?</translation>
</message>
<message numerus="yes">
<source>Do you really want to remove %1 file(s)?</source>
- <translation type="unfinished">
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Naozaj chcete vymazať %1 súbor(y)?</numerusform>
<numerusform></numerusform>
<numerusform></numerusform>
</translation>
</message>
<message>
<source>Do you really want to cancel uploading %1?</source>
- <translation type="unfinished"></translation>
+ <translation>Naozaj chcete zrušiť uploadovanie %1?</translation>
</message>
<message>
<source>File error</source>
- <translation type="unfinished">Chyba v súbore</translation>
+ <translation>Chyba v súbore</translation>
</message>
<message>
<source>Cannot open '%1' for writing</source>
- <translation type="unfinished"></translation>
+ <translation>Nepodarilo sa otvoriť '%1' pre zápis</translation>
</message>
<message>
<source>Cannot open '%1' for reading</source>
- <translation type="unfinished"></translation>
+ <translation>Nepodarilo sa otvoriÅ¥ '%1' pre ÄÃtanie</translation>
</message>
<message>
<source>Cannot use the ammo '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Nemôžem použiÅ¥ munÃciu '%1'!</translation>
</message>
<message>
<source>Weapons - Warning</source>
- <translation type="unfinished"></translation>
+ <translation>Zbrane - Varovanie</translation>
</message>
<message>
<source>Cannot overwrite default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Nemôžete prepÃsaÅ¥ východziu sadu zbranà '%1'!</translation>
</message>
<message>
<source>Cannot delete default weapon set '%1'!</source>
- <translation type="unfinished"></translation>
+ <translation>Nemôžete vymazať východziu sadu zbranà '%1'!</translation>
</message>
<message>
<source>Weapons - Are you sure?</source>
- <translation type="unfinished"></translation>
+ <translation>Zbrane - Ste si istý?</translation>
</message>
<message>
<source>Do you really want to delete the weapon set '%1'?</source>
+ <translation>Naozaj chcete vymazať sadu zbranà '%1'?</translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick not registered</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Prezývka</translation>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ProsÃm, zadajte vaÅ¡u prezývku</translation>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2120,225 +2369,221 @@ Aj napriek tomu chcete vojsť do miestnosti?</translation>
<translation>NaÄÃtaÅ¥</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Nastavenie</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Pripravený</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Náhodný tÃm</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>AsociovaÅ¥ prÃpony súborov.</translation>
</message>
<message>
- <source>more</source>
- <translation>viac</translation>
- </message>
- <message>
<source>More info</source>
- <translation type="unfinished"></translation>
+ <translation>Viac informácii</translation>
</message>
<message>
<source>Set default options</source>
- <translation type="unfinished"></translation>
+ <translation>Nastaviť východzie</translation>
</message>
<message>
<source>Open videos directory</source>
- <translation type="unfinished"></translation>
+ <translation>Otvoriť adresár s videami</translation>
</message>
<message>
<source>Play</source>
- <translation type="unfinished"></translation>
+ <translation>Prehrať</translation>
</message>
<message>
<source>Upload to YouTube</source>
- <translation type="unfinished"></translation>
+ <translation>Uploadovať na YouTube</translation>
</message>
<message>
<source>Cancel uploading</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>RoomsListModel</name>
- <message>
- <source>In progress</source>
- <translation type="unfinished">Prebieha</translation>
+ <translation>Zrušiť upload</translation>
</message>
<message>
- <source>Room Name</source>
- <translation type="unfinished">Názov miestnosti</translation>
+ <source>Restore default coding parameters</source>
+ <translation>Obnoviť pôvodné parametre pre kódovanie</translation>
</message>
<message>
- <source>C</source>
- <translation type="unfinished">C</translation>
+ <source>Open the video directory in your system</source>
+ <translation>Otvoriť adresár s videami vo vašom systéme</translation>
</message>
<message>
- <source>T</source>
- <translation type="unfinished">T</translation>
+ <source>Play this video</source>
+ <translation>Prehrať toto videa</translation>
</message>
<message>
- <source>Owner</source>
- <translation type="unfinished">Majiteľ</translation>
+ <source>Delete this video</source>
+ <translation>Vymazať toto video</translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">Mapa</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation>UploadovaÅ¥ video na váš úÄet YouTube</translation>
</message>
<message>
- <source>Rules</source>
- <translation type="unfinished">Pravidlá</translation>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
+ <source>Set the default server port for Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
- <translation type="unfinished">Náhodná mapa</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
- <translation type="unfinished">Náhodné bludisko</translation>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
- <translation>Sada zbranÃ</translation>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation>Pravdepodobnosti</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
</message>
<message>
- <source>Ammo in boxes</source>
- <translation>Zbrane v krabiciach</translation>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
- <translation>Oneskorenie</translation>
+ <source>In progress</source>
+ <translation>Prebieha</translation>
</message>
<message>
- <source>new</source>
- <translation>nový</translation>
+ <source>Room Name</source>
+ <translation>Názov miestnosti</translation>
</message>
<message>
- <source>copy of</source>
- <translation>kópia z</translation>
+ <source>C</source>
+ <translation>C</translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
- <translation>RežÃm vampÃra</translation>
+ <source>T</source>
+ <translation>T</translation>
</message>
<message>
- <source>Karma</source>
- <translation>Karma</translation>
+ <source>Owner</source>
+ <translation>Majiteľ</translation>
</message>
<message>
- <source>Artillery</source>
- <translation>Delostrelectvo</translation>
+ <source>Map</source>
+ <translation>Mapa</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>Režim pevnostÃ</translation>
+ <source>Rules</source>
+ <translation>Pravidlá</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>RozdeliÅ¥ tÃmy</translation>
+ <source>Weapons</source>
+ <translation>Výzbroj</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>NezniÄiteľná zem</translation>
+ <source>Random Map</source>
+ <translation>Náhodná mapa</translation>
</message>
<message>
- <source>Add Border</source>
- <translation>Pridať okraj</translation>
+ <source>Random Maze</source>
+ <translation>Náhodné bludisko</translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>NÃzka gravitácia</translation>
+ <source>Hand-drawn</source>
+ <translation>RuÄne kreslená</translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
- <translation>Laserové zameriavanie</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation>Nesmrteľnosť</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
</message>
<message>
- <source>Random Order</source>
- <translation>Náhodné poradie</translation>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
- <translation>Kráľ</translation>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
- <translation>UmiestÅovaÅ¥ ježkov</translation>
+ <source>Weapon set</source>
+ <translation>Sada zbranÃ</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation>Klan zdieľa výzbroj</translation>
+ <source>Probabilities</source>
+ <translation>Pravdepodobnosti</translation>
</message>
<message>
- <source>Disable Girders</source>
- <translation>Vypnúť trámy</translation>
+ <source>Ammo in boxes</source>
+ <translation>Zbrane v krabiciach</translation>
</message>
<message>
- <source>Disable Land Objects</source>
- <translation>Vypnúť objekty v krajine</translation>
+ <source>Delays</source>
+ <translation>Oneskorenie</translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation>Režim prežitia umelej inteligencie</translation>
+ <source>new</source>
+ <translation>nový</translation>
</message>
<message>
- <source>Reset Health</source>
- <translation>Resetovať zdravie</translation>
+ <source>copy of</source>
+ <translation>kópia z</translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>Neobmedzené útoky</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Resetovať zbrane</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Individuálne zbrane</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Vypnúť vietor</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Viac vetra</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Zrušiť</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Tag Team</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Pridať spodný okraj</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2456,12 +2701,6 @@ Aj napriek tomu chcete vojsť do miestnosti?</translation>
<translation>snÃmaÅ¥</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>Å¡tatistiky
-ježkov</translation>
- </message>
- <message>
<source>quit</source>
<translation>ukonÄiÅ¥</translation>
</message>
@@ -2507,39 +2746,39 @@ ježkov</translation>
</message>
<message>
<source>mute audio</source>
- <translation type="unfinished"></translation>
+ <translation>stlmiť zvuk</translation>
</message>
<message>
<source>record</source>
+ <translation>nahrať</translation>
+ </message>
+ <message>
+ <source>hedgehog info</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Základné ovládanie</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Ovládanie zbranÃ</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Výzbroj</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Ovládanie kurzora a kamery</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Iné</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished">RozliÄné</translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Presun ježka a mierenie:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Prekoná priepasti a prekážky skokom:</translation>
</message>
@@ -2601,6 +2840,10 @@ ježkov</translation>
</message>
<message>
<source>Record video:</source>
+ <translation>Nahrať video:</translation>
+ </message>
+ <message>
+ <source>Hedgehog movement</source>
<translation type="unfinished"></translation>
</message>
</context>
diff --git a/share/hedgewars/Data/Locale/hedgewars_sv.ts b/share/hedgewars/Data/Locale/hedgewars_sv.ts
index 202c4c2..8964f23 100644
--- a/share/hedgewars/Data/Locale/hedgewars_sv.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_sv.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="sv">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -44,12 +140,73 @@
<translation>Redigera spelscheman</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>När det här valet är aktivt kommer vapnen att ändras när du ändrar spelschema</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">Spelinställningar</translation>
</message>
<message>
- <source>Game Options</source>
- <translation type="unfinished">Spelinställningar</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Karta</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Kan inte skapa katalog %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -102,7 +259,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -139,20 +304,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">Ditt smeknamn (%1) är
-registrerat på Hedgewars.org
-Var god ange ditt lösenord eller välj
-ett annat smeknamn i spelinställningarna:</translation>
- </message>
- <message>
- <source>No password supplied.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Nickname</source>
<translation type="unfinished">Smeknamn</translation>
</message>
@@ -165,6 +316,63 @@ ett annat smeknamn i spelinställningarna:</translation>
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWGame</name>
@@ -180,18 +388,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Karta</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Teman</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filter</translation>
- </message>
- <message>
<source>All</source>
<translation>Alla</translation>
</message>
@@ -216,10 +412,6 @@ Please pick another nickname:</source>
<translation>Galen</translation>
</message>
<message>
- <source>Type</source>
- <translation>Typ</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>Små tunnlar</translation>
</message>
@@ -228,28 +420,96 @@ Please pick another nickname:</source>
<translation>Medelstora tunnlar</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>Stora tunnlar</translation>
+ <source>Seed</source>
+ <translation>Frö</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>Små flytande öar</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>Medelstora flytande öar</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>Stora flytande öar</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>Frö</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
- <translation>Ange</translation>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Slumpad</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">Läs in ritad karta</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished">Ritade kartor</translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished">Alla filer</translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -295,7 +555,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 har gått med</translation>
+ <translation type="obsolete">%1 *** %2 har gått med</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -321,8 +581,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Lösenord</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -337,6 +612,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -344,7 +641,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -362,6 +666,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -393,6 +708,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>Ange data</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Allmänt</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -402,6 +749,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -447,8 +805,40 @@ Please pick another nickname:</source>
<translation>Allmänt</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>Avancerat</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">Hatt</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Namn</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Slumpat lag</translation>
</message>
</context>
<context>
@@ -500,321 +890,96 @@ Please pick another nickname:</source>
<message numerus="yes">
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation>
- <numerusform><b>%1</b> dödade <b>%2</b> av sina egna igelkottar.</numerusform>
- <numerusform><b>%1</b> dödade <b>%2</b> av sina egna igelkottar.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> var rädd och hoppade över turer <b>%2</b> gånger.</numerusform>
- <numerusform><b>%1</b> var rädd och hoppade över turer <b>%2</b> gånger.</numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>Välj bara samma färg som en vän för att spela i som ett lag. Varje spelare kontrollerar fortfarande själva sina igelkottar men de vinner eller förlorar tillsammans.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>Några vapen kanske bara gör liten skada men de kan vara mycket mer förödande i rätt situation. Försök att använda Desert Eagle för att putta ner flera igelkottar ner i vattnet.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>Om du inte är säker på vad du ska göra och inte vill slösa på ammunition, hoppa över en tur. Men låt inte för lång tid passera eftersom sudden death kommer!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>Om du vill förhindra andra från att använda ditt favoritnamn på den officiella servern kan du registrera ett konto på http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Ãr du trött pÃ¥ att spela vanligt? Pröva ett av uppdragen - de erbjuder annorlunda spel beroende pÃ¥ vilken du väljer.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Som standard spelar spelet alltid in den senaste matchen som en demo. Välj 'Lokalt Spel' och tryck på 'Demo'-knappen nere till höger för att spela eller hantera dem.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars är ett öppet källkods- och gratisprogram som vi skapar på vår fritid. Om du har problem, fråga på vårat forum men snälla förvänta dig inte dygnet runt-support!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars är ett öppet källkods- och gratisprogram som vi skapar på vår fritid. Om du gillar det, hjälp oss med en liten donation eller bidra med något eget!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars är ett öppet källkods- och gratisprogram som vi skapar på vår fritid. Dela med dig av det till familj och vänner som du vill!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Då och då kommer det hållas officiella turneringer. Kommande händelser kommer att annonseras på http://www.hedgewars.org/ några dagar i förväg.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars finns på många språk. Om översättningen på ditt språk verkar saknas eller är gammal får du gärna kontakta oss!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars kan köras på många operativsystem som Microsoft Windows, Mac OS X och Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Kom alltid ihåg att du kan starta en egen match i lokalt och netverk/online-spel. Du är inte begränsad till 'Enkelt spel'-valet.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>När du spelar borde du ta en pause åt minståne en gång i timman.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>Om ditt grafikkort inte klarar av att ge hårdvaruaccellererad OpenGL, pröva att sänka kvaliteten för att öka prestandan.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Vi är öppna för förslag och konstruktiv kritik. Om du inte gillar något eller har en bra idé, hör av dig!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>Speciellt när du spelar över netet, var artig och kom alltid ihåg att det kan vara minderåriga som du spelar mot också!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>Speciella spellägen som 'Vampyrism' eller 'Karma' låter dig utveckla helt nya taktiker. Pröva dem i ett eget spel!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Du ska aldrig installera Hedgewars på en dator som du inte äger (skola, universitet, arbete, etc.). Fråga den ansvarige personen istället!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars kan vara perfekt för korta matcher under raster. Se bara till att du inte lägger till för många igelkottar eller använder en stor bana. Att minska tiden och hälsa kan också hjälpa.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>Inga igelkottar skadades under produktionen av spelet.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars är ett öppet källkods- och gratisprogram som vi skapar på vår fritid. Om någon sålde spelet till dig ska du försöka att få pengarna tillbaka!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>Koppla ihop en eller flera spelplattor innan du startar spelet för att kunna välja att kontrollera era lag med dem.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>Skapa ett konto på %1 för att förhindra andra från att använda ditt favoritnamn när du spelar på den officiella servern.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>Om ditt grafikkort inte klarar av att ge hårdvaruaccellererad OpenGL, pröva att uppdatera dina drivrutiner.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>Det finns tre olika hopp tillgängliga. Tryck på [högt hopp] två gånger för att göra ett ett högt bakåt-hopp.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>Ãr du rädd att falla ner för an kant? HÃ¥ll ner [exakt] för att vrida [vänster] eller [höger] utan att egentligen röra dig.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>Några vapen kräver speciella strategier eller bara mycket träning, så ge inte upp ett vapen bara för att du missade en fiende någon gång.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>De flesta vapen fungerar inte när de har rört vattenet. Målsökande bi och även Tårta är två undantag.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>Den gamla Limburgaren skapar bara en liten explosition. Men det vindpåverkade stinkmålnet kan förgifta många igelkottar samtidigt.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Pianoanfall är det farligaste luftanfallet. Du blir av med en igelkott när du använder det, så det finns en stor nackdel också.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>Fästande minor är ett perfekt verktyg för att skapa små kedjereaktioner som slår ner fiender i farliga situationer ... eller vatten.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>Hammaren är mest effektiv när den används på broar eller balkar. När du slår till igelkottarna kommer de att falla nergenom hålet.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>Om du är fast bakom en fiende, använd hammaren för att göra dig fri utan att skadas av en explosition.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>Tårtans längsta gångsträcka beror på vägen den måste ta. Använd [attack] för att spränga den tidigt.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>Eldkastaren är ett vapen, men den kan användas för att gräva tunnlar också.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>Vill du veta vilka som ligger bakom spelet? Tryck på Hedgewars-loggan i huvudmenyn för att se medverkande.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>Gillar du Hedgewars? Bli ett fan på %1 eller följ oss på %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Du är välkommen att rita dina egna gravar, hattar, flaggor eller till och med banor eller teman! Men notera att du måste lägga ut dem någonstans för att använda dem online.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>Vill du verkligen ha en specifik hatt? Ge os en donation och få en exklusiv hatt som du väljer!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>Se till att hålla dina grafikdrivrutiner uppdaterade för att undvika problem när du spalar.</translation>
+ <numerusform><b>%1</b> dödade <b>%2</b> av sina egna igelkottar.</numerusform>
+ <numerusform><b>%1</b> dödade <b>%2</b> av sina egna igelkottar.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan hitta dina konfigurationsfiler under "Mina Dokument\Hedgewars". Gör en säkerhetskopia eller ta med dig filerna, men redigera dem inte för hand.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> var rädd och hoppade över turer <b>%2</b> gånger.</numerusform>
+ <numerusform><b>%1</b> var rädd och hoppade över turer <b>%2</b> gånger.</numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Du kan associera Hedgewars-relaterade filer (sparfiler och demo-inspelningar) med spelet för att köra dem direkt från den filhanterare eller webbläsare du tycker bäst om.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>Vill du spara rep? Släpp repet i luften och sedan sjut igen. Så länge du inte nuddar marken använder du samma rep utan att slösa på ammunition!</translation>
+ <source>Save</source>
+ <translation type="unfinished">Spara</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan hitta dina konfigurationsfiler under "Library/Application Support/Hedgewars" i din hem-mapp. Gör en säkerhetskopia eller ta med dig filerna, men redigera dem inte för hand.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Du kan hitta dina konfigurationsfiler under ".hedgewars" i din hem-mapp. Gör en säkerhetskopia eller ta med dig filerna, men redigera dem inte för hand.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Windows-versionen av Hedgewars har stöd för Xfire. Se till att lägga till Hedgewars till spellistan så att dina vänner kan se dig spela.</translation>
+ <source>Downloadable Content</source>
+ <translation>Nedladdningsbart innehåll</translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>Använd molotov eller eldkastaren för att temporärt förhindra att igelkottar passerar terräng så som tunnlar eller platformar.</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>Målsökande bin kan vara kluriga att använda. Svängradien beror på hastigheten, så försök att inte använda full kraft.</translation>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation>Nedladdningsbart innehåll</translation>
+ <source>Read about who is behind the Hedgewars Project</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -824,38 +989,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>Starta</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>Kontroll</translation>
+ <translation type="obsolete">Kontroll</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished">Nedladdningsbart innehåll</translation>
+ <source>Start</source>
+ <translation type="unfinished">Starta</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>LAN-spel</translation>
+ <source>Update</source>
+ <translation type="unfinished">Uppdatera</translation>
</message>
<message>
- <source>Official server</source>
- <translation>Officiell server</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -902,10 +1071,6 @@ Please pick another nickname:</source>
<translation>Ta bort vapenset</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Allmänt</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">Avancerat</translation>
</message>
@@ -945,6 +1110,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Lag</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">Vapen</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -961,11 +1214,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>Skapa</translation>
+ <translation type="obsolete">Skapa</translation>
</message>
<message>
<source>Join</source>
- <translation>Anslut</translation>
+ <translation type="obsolete">Anslut</translation>
</message>
<message>
<source>Admin features</source>
@@ -973,7 +1226,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Rumnamn:</translation>
+ <translation type="obsolete">Rumnamn:</translation>
</message>
<message>
<source>Rules:</source>
@@ -985,11 +1238,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>Sök:</translation>
+ <translation type="obsolete">Sök:</translation>
</message>
<message>
<source>Clear</source>
- <translation>Rensa</translation>
+ <translation type="obsolete">Rensa</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -998,6 +1251,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1144,18 +1421,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1164,26 +1433,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Läs in</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1229,19 +1486,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1252,10 +1511,6 @@ Please pick another nickname:</source>
<translation>Släng ut</translation>
</message>
<message>
- <source>Start</source>
- <translation>Starta</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Begränsa tillkommande</translation>
</message>
@@ -1293,7 +1548,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>Uppdatera</translation>
+ <translation type="obsolete">Uppdatera</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1303,10 +1570,6 @@ Please pick another nickname:</source>
<translation>Helskärm</translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Aktivera ljud</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>Visa FPS (rutor per sekund)</translation>
</message>
@@ -1315,14 +1578,6 @@ Please pick another nickname:</source>
<translation>Visa alternativ skada</translation>
</message>
<message>
- <source>Enable music</source>
- <translation>Aktivera musik</translation>
- </message>
- <message>
- <source>Frontend fullscreen</source>
- <translation>Spelmenyn i helskärm</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>Bifoga datum och tid till namnet på inspelningsfiler</translation>
</message>
@@ -1335,45 +1590,57 @@ Please pick another nickname:</source>
<translation>Visa hjälp i ammunitionsmenyn</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>Aktivera ljud i spelmenyn</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>Aktivera musik i spelmenyn</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>Effekter i spelmenyn</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>genererad karta...</translation>
- </message>
- <message>
<source>Human</source>
<translation>Människa</translation>
</message>
@@ -1386,14 +1653,6 @@ Please pick another nickname:</source>
<translation>(Systemstandard)</translation>
</message>
<message>
- <source>generated maze...</source>
- <translation>genererad labyrint...</translation>
- </message>
- <message>
- <source>Mission</source>
- <translation>Uppdrag</translation>
- </message>
- <message>
<source>Community</source>
<translation>Gemenskap</translation>
</message>
@@ -1403,15 +1662,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>I lobby</translation>
+ <translation type="obsolete">I lobby</translation>
</message>
<message>
<source>In progress</source>
- <translation>Pågår</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>handritad karta...</translation>
+ <translation type="obsolete">Pågår</translation>
</message>
<message>
<source>Disabled</source>
@@ -1450,10 +1705,6 @@ Please pick another nickname:</source>
<translation>Uppe och nere</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>Vicka</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>Röd/Cyan gråskala</translation>
</message>
@@ -1485,22 +1736,10 @@ Please pick another nickname:</source>
<translation>Lagmedlemmar</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>Tangentbindningar</translation>
- </message>
- <message>
<source>Fort</source>
<translation>Fort</translation>
</message>
<message>
- <source>Teams</source>
- <translation>Lag</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Ljud/grafikinställningar</translation>
- </message>
- <message>
<source>Net game</source>
<translation>Internetspel</translation>
</message>
@@ -1510,35 +1749,15 @@ Please pick another nickname:</source>
</message>
<message>
<source>Game Modifiers</source>
- <translation>Spellägen</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>Allmäna inställningar</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>Laginställningar</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Diverse</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>Scheman och vapen</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <translation>Spellägen</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>Allmäna inställningar</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>Laginställningar</translation>
</message>
<message>
<source>Videos</source>
@@ -1548,30 +1767,10 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
<message>
- <source>Developers:</source>
- <translation>Utvecklare:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Grafik:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Ãversättningar:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Särskilt tack till:</translation>
- </message>
- <message>
<source>Weapons</source>
<translation>Vapen</translation>
</message>
@@ -1601,11 +1800,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Version</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Ljud:</translation>
+ <translation type="obsolete">Version</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1644,10 +1839,6 @@ Please pick another nickname:</source>
<translation>LÃ¥dor</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Spelschema</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% falska minor</translation>
</message>
@@ -1684,10 +1875,6 @@ Please pick another nickname:</source>
<translation>Tips:</translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Denna utvecklingsversion är inte färdig och kanske inte är kompatibel med andra versioner av spelet. Några delar kan vara trasiga eller ofullständiga. Använd på egen risk!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>Kvalitet</translation>
</message>
@@ -1728,10 +1915,6 @@ Please pick another nickname:</source>
<translation>% flykttid</translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1762,10 +1945,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1793,6 +1972,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Helskärm</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1815,6 +2038,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1831,10 +2058,6 @@ Do you really want to quit?</source>
<translation>Filassociationer har misslyckats.</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1881,47 +2104,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Kan inte skapa katalog %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kan inte skapa katalog %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Kunde inte starta servern: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Kunde inte starta servern: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2040,16 +2228,42 @@ Vill du fortfarande gå med i rummet?</translation>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Smeknamn</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>Var god ange ditt smeknamn</translation>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2107,26 +2321,10 @@ Vill du fortfarande gå med i rummet?</translation>
<translation>Läs in</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Inställningar</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Redo</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Slumpat lag</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>Associera filextentioner</translation>
</message>
<message>
- <source>more</source>
- <translation>mer</translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2150,6 +2348,61 @@ Vill du fortfarande gå med i rummet?</translation>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2199,6 +2452,25 @@ Vill du fortfarande gå med i rummet?</translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2226,106 +2498,44 @@ Vill du fortfarande gå med i rummet?</translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <source>Vampirism</source>
- <translation>Vampyrism</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>Karma</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>Artilleri</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Fortläge</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>Dela upp lag</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>Solitt land</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>Lägg till kant</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>LÃ¥g gravitation</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>Lasersikte</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>Osårbar</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Slumpad ordning</translation>
- </message>
- <message>
- <source>King</source>
- <translation>Kung</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>Placera igelkottar</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Klan delar ammunition</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>Avaktivera balkar</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>Avaktivera landföremål</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>AI-överlevnad</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>Ã
terställ hälsa</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
- <translation>Obegränsade attacker</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>Ã
terställ vapen</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>Ammunition per igelkott</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>Avaktivera vind</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>Mer vind</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Avbryt</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>Maraton</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
- <translation>Lägg till undre barriär</translation>
+ <source>Use selected theme</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2443,11 +2653,6 @@ Vill du fortfarande gå med i rummet?</translation>
<translation>ta bild</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>information om igelkottar</translation>
- </message>
- <message>
<source>quit</source>
<translation>avsluta</translation>
</message>
@@ -2499,33 +2704,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>Allmäna kontroller</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>Vanenkontroller</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Vapen</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>Kamera och pilkontroller</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>Annat</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>Flytta dina igelkottar och sikta:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>Undvik hål och hinder genom att hoppa:</translation>
</message>
@@ -2589,6 +2794,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts b/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts
index 1f997ee..cca5147 100644
--- a/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_tr_TR.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="tr_TR">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -43,11 +139,63 @@
<translation>Düzeni deÄiÅtir</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Map</source>
+ <translation type="unfinished">Harita</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">%1 dizini oluÅturulamadı</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -101,7 +249,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -138,27 +294,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>%1's Team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -176,18 +378,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Harita</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Temalar</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>Filtre</translation>
- </message>
- <message>
<source>All</source>
<translation>Tümü</translation>
</message>
@@ -212,39 +402,103 @@ Please pick another nickname:</source>
<translation>Uçuk Kaçık</translation>
</message>
<message>
- <source>Type</source>
+ <source>Small tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small tunnels</source>
+ <source>Medium tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium tunnels</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Rastgele</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -290,10 +544,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 *** %2 has joined</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>%1 *** %2 has left</source>
<translation type="unfinished"></translation>
</message>
@@ -317,8 +567,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">Parola</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -333,6 +598,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -340,7 +627,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -358,6 +652,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -389,6 +694,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">Genel</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -398,6 +735,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -443,496 +791,391 @@ Please pick another nickname:</source>
<translation>Genel</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>GeliÅmiÅ</translation>
- </message>
-</context>
-<context>
- <name>PageGameStats</name>
- <message>
- <source>Details</source>
+ <source>Select an action to choose a custom key bind for this team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Health graph</source>
+ <source>Use my default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Ranking</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
+ <source>Custom Controls</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>(%1 kill)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
<message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
+ <source>Hat</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
+ <source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
+ <source>This hedgehog's name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
+ <source>Randomize this hedgehog's name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
+ <source>Random Team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageGameStats</name>
<message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
+ <source>Details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
+ <source>Health graph</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
+ <source>Ranking</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
+ <source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source>(%1 kill)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
+ <source>Play again</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
+ <source>Save</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
+ <source>In game...</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
+ <source>Open the snapshot folder</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>BaÅla</translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">Kontrol</translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">BaÅla</translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Update</source>
+ <translation type="unfinished">Güncelle</translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New team</source>
+ <translation>Yeni takım</translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Edit team</source>
+ <translation>Takımı düzenle</translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation type="unfinished">GeliÅmiÅ</translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <source>Start</source>
- <translation>BaÅla</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>Kontrol</translation>
- </message>
<message>
- <source>DLC</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
- <message>
- <source>LAN game</source>
- <translation>LAN oyunu</translation>
- </message>
- <message>
- <source>Official server</source>
- <translation>Resmi sunucu</translation>
- </message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
- <message>
- <source>New team</source>
- <translation>Yeni takım</translation>
- </message>
- <message>
- <source>Edit team</source>
- <translation>Takımı düzenle</translation>
- </message>
<message>
- <source>Delete team</source>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
- <translation type="unfinished"></translation>
+ <source>Teams</source>
+ <translation type="unfinished">Takımlar</translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">Genel</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Silahlar</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">GeliÅmiÅ</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -951,41 +1194,53 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>OluÅtur</translation>
+ <translation type="obsolete">OluÅtur</translation>
</message>
<message>
<source>Join</source>
- <translation>Katıl</translation>
+ <translation type="obsolete">Katıl</translation>
</message>
<message>
<source>Admin features</source>
<translation>Yönetici görevleri</translation>
</message>
<message>
- <source>Room Name:</source>
+ <source>Rules:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Rules:</source>
+ <source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
+ <message numerus="yes">
+ <source>%1 players online</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
- <source>Weapons:</source>
+ <source>Search for a room:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear</source>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
- <message numerus="yes">
- <source>%1 players online</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- </translation>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1133,18 +1388,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1153,26 +1400,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">Yükle</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1217,19 +1452,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1244,10 +1481,6 @@ Please pick another nickname:</source>
<translation>Bilgi</translation>
</message>
<message>
- <source>Start</source>
- <translation>BaÅla</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>Katılmaları Kısıtla</translation>
</message>
@@ -1281,26 +1514,26 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">Güncelle</translation>
+ <translation type="obsolete">Güncelle</translation>
</message>
-</context>
-<context>
- <name>QCheckBox</name>
<message>
- <source>Fullscreen</source>
- <translation>Tam ekran</translation>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>Oyun giriÅi tam ekran</translation>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable sound</source>
- <translation>Sesleri etkinleÅtir</translation>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QCheckBox</name>
<message>
- <source>Enable music</source>
- <translation>MüziÄi etkinleÅtir</translation>
+ <source>Fullscreen</source>
+ <translation>Tam ekran</translation>
</message>
<message>
<source>Show FPS</source>
@@ -1323,18 +1556,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1354,51 +1575,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>rastgele harita...</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>Ä°nsan</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>Bilgisayar</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
+ <message>
+ <source>Human</source>
+ <translation>Ä°nsan</translation>
+ </message>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Level</source>
+ <translation>Bilgisayar</translation>
</message>
<message>
- <source>In lobby</source>
+ <source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In progress</source>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1438,10 +1663,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1477,18 +1698,6 @@ Please pick another nickname:</source>
<translation>Kale</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>TuÅlar</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Takımlar</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>Ses/Görüntü seçenekleri</translation>
- </message>
- <message>
<source>Net game</source>
<translation>AÄ oyunu</translation>
</message>
@@ -1509,26 +1718,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
@@ -1536,10 +1725,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1553,27 +1738,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>Sürüm</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>GeliÅtiriciler:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>Sanat:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>Sesler:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>Ãeviriler:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>Ãzel teÅekkür:</translation>
+ <translation type="obsolete">Sürüm</translation>
</message>
<message>
<source>Weapons</source>
@@ -1608,10 +1773,6 @@ Please pick another nickname:</source>
<translation>BaÅlangıçtaki ses seviyesi</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>Oyun teması</translation>
- </message>
- <message>
<source>Damage Modifier</source>
<translation>Hasar Ãarpanı</translation>
</message>
@@ -1672,10 +1833,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1716,10 +1873,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1750,10 +1903,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,6 +1930,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Tam ekran</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1803,6 +1996,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1819,10 +2016,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1869,47 +2062,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">%1 dizini oluÅturulamadı</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">%1 dizini oluÅturulamadı</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Sunucu baÅlatılamadı: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Sunucu baÅlatılamadı: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2026,15 +2184,41 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2093,26 +2277,10 @@ Do you still want to join the room?</source>
<translation>Yükle</translation>
</message>
<message>
- <source>Setup</source>
- <translation>Ayarla</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>Hazır</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2136,181 +2304,193 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>RoomsListModel</name>
<message>
- <source>In progress</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Room Name</source>
+ <source>Open the video directory in your system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>C</source>
+ <source>Play this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
+ <source>Delete this video</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
+ <source>Upload this video to your Youtube account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">Harita</translation>
- </message>
- <message>
- <source>Rules</source>
+ <source>Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">Silahlar</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
+ <source>Invite your friends to your server in just 1 click!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
+ <source>Enter a name for your room.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
</message>
<message>
- <source>Ammo in boxes</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
+ <source>In progress</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
- <translation type="unfinished">yeni</translation>
+ <source>Room Name</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>copy of</source>
+ <source>C</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
- <translation>Vampircilik</translation>
+ <source>T</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Karma</source>
- <translation>Karma</translation>
+ <source>Owner</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Artillery</source>
- <translation>Topçuluk</translation>
+ <source>Map</source>
+ <translation type="unfinished">Harita</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>Kale Modu</translation>
+ <source>Rules</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>Takımları Böl</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Silahlar</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>Parçalanmaz Yüzey</translation>
+ <source>Random Map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Border</source>
- <translation>Sınır Ekle</translation>
+ <source>Random Maze</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>AzaltılmıŠYerçekimi</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
- <translation>Lazer GörüÅü</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation>Ãlümsüzlük</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
</message>
<message>
- <source>Random Order</source>
+ <source>Set seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
+ <source>Close</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
+ <source>Weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
+ <source>Probabilities</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Girders</source>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
+ <source>new</source>
+ <translation type="unfinished">yeni</translation>
</message>
<message>
- <source>Reset Health</source>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">Ä°ptal</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2445,12 +2625,6 @@ Do you still want to join the room?</source>
<translation>yakala</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>kirpi
-bilgileri</translation>
- </message>
- <message>
<source>quit</source>
<translation>çıkıÅ</translation>
</message>
@@ -2486,33 +2660,33 @@ bilgileri</translation>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
+ <source>Movement</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation type="unfinished"></translation>
+ <source>Weapons</source>
+ <translation type="unfinished">Silahlar</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
+ <source>Camera</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation type="unfinished">DiÄer</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished"></translation>
</message>
@@ -2576,6 +2750,10 @@ bilgileri</translation>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_uk.ts b/share/hedgewars/Data/Locale/hedgewars_uk.ts
index 4b2cb39..5a94ac2 100644
--- a/share/hedgewars/Data/Locale/hedgewars_uk.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_uk.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="uk">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -45,12 +141,78 @@
<translation>РедагÑваÑи ÑÑ
еми</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
- <translation>Ðоли ввÑмкнена ÑÑ Ð¾Ð¿ÑÑÑ Ð¿Ñи вибоÑÑ ÑÑ
еми гÑи збÑÐ¾Ñ Ð±Ñде вибÑана авÑомаÑиÑно</translation>
+ <source>Game Options</source>
+ <translation type="obsolete">ÐаÑамеÑÑи гÑи</translation>
</message>
<message>
- <source>Game Options</source>
- <translation type="unfinished">ÐаÑамеÑÑи гÑи</translation>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">Ðапа</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">Ðе Ð¼Ð¾Ð¶Ñ ÑÑвоÑиÑи диÑекÑоÑÑÑ %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -103,7 +265,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -140,30 +310,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
- <translation type="unfinished">ÐÐ°Ñ Ð½Ñк %1 вже
-заÑеÑÑÑÑований на Hedgewars.org
-ÐведÑÑÑ Ð²Ð°Ñ Ð¿Ð°ÑÐ¾Ð»Ñ Ð½Ð¸Ð¶Ñе або
-вибеÑÑÑÑ ÑнÑий нÑк в налаÑÑÑваннÑÑ
гÑи:</translation>
+ <source>Nickname</source>
+ <translation type="unfinished">Ðм'Ñ</translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>%1's Team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -181,18 +394,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>Ðапа</translation>
- </message>
- <message>
- <source>Themes</source>
- <translation>Теми</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>ФÑлÑÑÑ</translation>
- </message>
- <message>
<source>All</source>
<translation>ÐÑÑ</translation>
</message>
@@ -217,10 +418,6 @@ Please pick another nickname:</source>
<translation>ÐезглÑздÑ</translation>
</message>
<message>
- <source>Type</source>
- <translation>Тип</translation>
- </message>
- <message>
<source>Small tunnels</source>
<translation>ÐÐ°Ð»Ñ ÑÑнелÑ</translation>
</message>
@@ -229,28 +426,96 @@ Please pick another nickname:</source>
<translation>СеÑÐµÐ´Ð½Ñ ÑÑнелÑ</translation>
</message>
<message>
- <source>Large tunnels</source>
- <translation>ÐÐµÐ»Ð¸ÐºÑ ÑÑнелÑ</translation>
+ <source>Seed</source>
+ <translation>ÐеÑемÑÑаÑи</translation>
</message>
<message>
- <source>Small floating islands</source>
- <translation>ÐÐ°Ð»Ñ Ð¿Ð»Ð°Ð²ÑÑÑ Ð¾ÑÑÑова</translation>
+ <source>Map type:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
- <translation>СеÑÐµÐ´Ð½Ñ Ð¿Ð»Ð°Ð²ÑÑÑ Ð¾ÑÑÑова</translation>
+ <source>Image map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
- <translation>ÐÐµÐ»Ð¸ÐºÑ Ð¿Ð»Ð°Ð²ÑÑÑ Ð¾ÑÑÑова</translation>
+ <source>Mission map</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
- <translation>ÐеÑемÑÑаÑи</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomly generated</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">Ðипадково</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
- <translation>ÐадаÑи</translation>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished">ÐаванÑажиÑи намалÑÐ¾Ð²Ð°Ð½Ñ Ð¼Ð°Ð¿Ñ</translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -296,7 +561,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1 *** %2 пÑиÑднавÑÑ</translation>
+ <translation type="obsolete">%1 *** %2 пÑиÑднавÑÑ</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -322,8 +587,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">ÐаÑолÑ</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -338,6 +618,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -345,7 +647,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -363,6 +672,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -394,6 +714,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation>ÐÑÑановиÑи данÑ</translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">ÐÑновнÑ</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -403,6 +755,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -448,8 +811,40 @@ Please pick another nickname:</source>
<translation>ÐÑновнÑ</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>РозÑиÑенÑ</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">ÐапелÑÑ
</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished">Ðазва</translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">Ðипадкова Ðоманда</translation>
</message>
</context>
<context>
@@ -505,323 +900,98 @@ Please pick another nickname:</source>
<message numerus="yes">
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation>
- <numerusform><b>%1</b> вбив <b>%2</b> Ñжака Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
- <numerusform><b>%1</b> вбив <b>%2</b> ÑжакÑв Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
- <numerusform><b>%1</b> вбив <b>%2</b> ÑжакÑв Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
- <translation>
- <numerusform><b>%1</b> злÑкавÑÑ Ñ Ð¿ÑопÑÑÑив Ñ
Ñд <b>%2</b> ÑазÑв.</numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
- </translation>
- </message>
-</context>
-<context>
- <name>PageInGame</name>
- <message>
- <source>In game...</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageInfo</name>
- <message>
- <source>Open the snapshot folder</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>PageMain</name>
- <message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation>ÐибеÑÑÑÑ Ñой же колÑÑ Ñо Ñ Ð² дÑÑга Ñоб гÑаÑи в однÑй командÑ. Ðожен з Ð²Ð°Ñ Ð±Ñде кеÑÑваÑи влаÑними Ñжаками але вони вигÑаÑÑÑ Ñи пÑогÑаÑÑÑ Ñазом.</translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation>ÐеÑка збÑÐ¾Ñ Ð½Ð°Ð½Ð¾ÑиÑÑ Ð¼Ð°Ð»Ð¾ Ñкоди, але вона може бÑÑи бÑлÑÑ ÑÑйнÑÐ²Ð½Ð¾Ñ Ð² пÑавилÑнÑй ÑиÑÑаÑÑÑ. СпÑобÑйÑе викоÑиÑÑаÑи ÐÑÑÑелÑного ÐÑла Ð´Ð»Ñ ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ ÐºÑлÑкоÑ
ÑжакÑв Ñ Ð²Ð¾Ð´Ñ.</translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation>ЯкÑо ви не знаÑÑе Ñо ÑобиÑи Ñ Ð½Ðµ Ñ
оÑеÑе виÑÑаÑаÑи боÑпÑипаÑи, пÑопÑÑÑÑÑÑ Ð¾Ð´Ð¸Ð½ ÑаÑнд. Ðле не маÑнÑйÑе занадÑо багаÑо ÑаÑÑ, ÑомÑ-Ñо пÑийде РапÑова СмеÑÑÑ!</translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation>ЯкÑо ви Ñ
оÑеÑе закÑÑпиÑи за ÑÐ¾Ð±Ð¾Ñ Ð½Ñк на оÑÑÑÑÐ¹Ð½Ð¾Ð¼Ñ ÑеÑвеÑÑ, заÑеÑÑÑÑÑйÑе аккаÑÐ½Ñ Ð½Ð° http://www.hedgewars.org/.</translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation>Ðи вÑомилиÑÑ Ð²Ñд гÑи за замовÑÑваннÑм? СпÑобÑйÑе Ð¾Ð´Ð½Ñ Ð· мÑÑÑй - вони пÑопонÑÑÑÑ ÑÑÐ·Ð½Ñ Ð²Ð¸Ð´Ð¸ гÑи залежно вÑд ваÑого вибоÑÑ.</translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation>Ðа замовÑÑваннÑм оÑÑÐ°Ð½Ð½Ñ Ð³Ñа завжди бÑде запиÑÑваÑиÑÑ Ð² ÑкоÑÑÑ Ð´ÐµÐ¼Ð¾. ÐибеÑÑÑÑ 'ÐокалÑÐ½Ñ ÐÑÑ' Ñ Ð½Ð°ÑиÑнÑÑÑ ÐºÐ½Ð¾Ð¿ÐºÑ 'ÐемонÑÑÑаÑÑÑ' Ñ Ð½Ð¸Ð¶Ð½ÑÐ¾Ð¼Ñ Ð¿ÑÐ°Ð²Ð¾Ð¼Ñ ÐºÑÑÑ Ñоб гÑаÑи або кеÑÑваÑи ними.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation>Hedgewars Ñ Ð²ÑдкÑиÑÐ¾Ñ Ñа безплаÑноÑ, ми ÑÑвоÑÑÑмо ÑÑ Ñ Ð²ÑлÑний ÑаÑ. ЯкÑо Ñ Ð²Ð°Ñ Ñ Ð¿Ñоблеми, запиÑайÑе на наÑÐ¾Ð¼Ñ ÑоÑÑмÑ, але бÑдÑ-лаÑка, не ÑекайÑе пÑдÑÑимки 24/7!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation>Hedgewars Ñ Ð²ÑдкÑиÑÐ¾Ñ Ñа безплаÑноÑ, ми ÑÑвоÑÑÑмо ÑÑ Ñ Ð²ÑлÑний ÑаÑ. ЯкÑо вона вам подобаÑÑÑÑÑ, допоможÑÑÑ Ð½Ð°Ð¼ невеликим внеÑком або вкладÑÑÑ ÑÐ²Ð¾Ñ ÑобоÑÑ!</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation>Hedgewars Ñ Ð²ÑдкÑиÑÐ¾Ñ Ñа безплаÑноÑ, ми ÑÑвоÑÑÑмо ÑÑ Ñ Ð²ÑлÑний ÑаÑ. ÐодÑлÑÑÑÑÑ Ð³ÑÐ¾Ñ Ð· ÑÐ¾Ð´Ð¸Ð½Ð¾Ñ Ñа дÑÑзÑми!</translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation>Ð§Ð°Ñ Ð²Ñд ÑаÑÑ Ð¿ÑоводÑÑÑÑÑ Ð¾ÑÑÑÑÐ¹Ð½Ñ ÑÑÑнÑÑи. ÐайбÑÑÐ½Ñ Ð¿Ð¾Ð´ÑÑ Ð±ÑдÑÑÑ Ð¾Ð³Ð¾Ð»Ð¾ÑÐµÐ½Ñ Ð½Ð° http://www.hedgewars.org/ за кÑлÑка днÑв пеÑед пÑоведеннÑм.</translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation>Hedgewars доÑÑÑпна на багаÑÑоÑ
моваÑ
. ЯкÑо пеÑеклад на ваÑÑ Ð¼Ð¾Ð²Ñ Ð·Ð°ÑÑаÑÑв Ñи вÑдÑÑÑнÑй, не ÑоÑомÑеÑÑ Ð·Ð²ÐµÑÑаÑиÑÑ Ð´Ð¾ наÑ!</translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation>Hedgewars може бÑÑи запÑÑений на багаÑÑоÑ
опеÑаÑÑйниÑ
ÑиÑÑемаÑ
, вклÑÑаÑÑи Microsoft Windows, Mac OS X Ñ Linux.</translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation>Ðавжди пам'ÑÑайÑе, ви можеÑе ÑÑвоÑиÑи ÑÐ²Ð¾Ñ Ð²Ð»Ð°ÑÐ½Ñ Ð³ÑÑ Ð² локалÑÐ½Ð¾Ð¼Ñ Ñа меÑежномÑ/онлайн-ÑежимаÑ
. Ðи не Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ñ Ð¾Ð¿ÑÑÑÑ 'ÐÑоÑÑа ÐÑа'.</translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation>Ðоки гÑаÑÑе гÑÑ Ð·ÑобÑÑÑ ÐºÐ¾ÑоÑÐºÑ Ð¿ÐµÑеÑÐ²Ñ Ñ
оÑа б Ñаз на годинÑ.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation>ЯкÑо ваÑа вÑдеокаÑÑа не може забезпеÑиÑи апаÑаÑне пÑиÑкоÑÐµÐ½Ð½Ñ OpenGL, ÑпÑобÑйÑе вклÑÑиÑи Ñежим низÑÐºÐ¾Ñ ÑкоÑÑÑ Ð´Ð»Ñ Ð¿ÑдвиÑÐµÐ½Ð½Ñ Ð¿ÑодÑкÑивноÑÑÑ.</translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation>Ðи вÑдкÑиÑÑ Ð´Ð»Ñ Ð¿ÑопозиÑÑй Ñ ÐºÐ¾Ð½ÑÑÑÑкÑивного звоÑоÑнÑого зв'ÑзкÑ. ЯкÑо вам не подобаÑÑÑÑÑ ÑоÑÑ Ð°Ð±Ð¾ Ñ Ð²ÑдмÑнна ÑдеÑ, дайÑе нам знаÑи!</translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation>ÐÑобливо пÑд ÑÐ°Ñ Ð³Ñи онлайн бÑдÑÑе ввÑÑÐ»Ð¸Ð²Ñ Ñ Ð·Ð°Ð²Ð¶Ð´Ð¸ пам'ÑÑайÑе, з вами Ñи пÑоÑи Ð²Ð°Ñ Ð¼Ð¾Ð¶ÑÑÑ Ð³ÑаÑи неповнолÑÑнÑ!</translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation>СпеÑÑалÑÐ½Ñ Ñежими гÑи, ÑÐ°ÐºÑ Ñк 'ÐампÑÑизм' Ñи 'ÐаÑма' дозволÑÑÑÑ ÑозÑоблÑÑи ÑÑлком Ð½Ð¾Ð²Ñ ÑакÑикÑ. СпÑобÑйÑе ÑÑ
в налаÑÑованÑй гÑÑ!</translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
- <translation>Ðи не Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð²ÑÑановлÑваÑи Hedgewars на комп'ÑÑеÑаÑ
, ÑÐºÑ Ð²Ð°Ð¼ не належаÑÑ (Ñкола, ÑнÑвеÑÑиÑеÑ, ÑобоÑа ÑоÑо). ÐÑÐ´Ñ Ð»Ð°Ñка, звеÑÑайÑеÑÑ Ð´Ð¾ вÑдповÑдалÑÐ½Ð¾Ñ Ð¾Ñоби!</translation>
- </message>
- <message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation>Hedgewars ÑÑдово пÑдÑ
одиÑÑ Ð´Ð»Ñ ÐºÐ¾ÑоÑÐºÐ¾Ñ Ð³Ñи пÑд ÑÐ°Ñ Ð¿ÐµÑеÑв. ÐеÑеконайÑеÑÑ, Ñо ви не додали занадÑо багаÑо ÑжакÑв Ñ Ð½Ðµ взÑли Ð²ÐµÐ»Ð¸ÐºÑ ÐºÐ°ÑÑÑ. СкоÑоÑÐµÐ½Ð½Ñ ÑаÑÑ Ñ Ð·Ð´Ð¾Ñов'Ñ Ñакож пÑдÑйде.</translation>
- </message>
- <message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation>ÐÑд ÑÐ°Ñ ÑозÑобки гÑи не поÑÑÑаждав жодний Ñжак.</translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation>Hedgewars Ñ Ð²ÑдкÑиÑÐ¾Ñ Ñа безплаÑноÑ, ми ÑÑвоÑÑÑмо ÑÑ Ñ Ð²ÑлÑний ÑаÑ. ЯкÑо Ñ
ÑоÑÑ Ð¿Ñодав вам гÑÑ, ви Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ ÑпÑобÑваÑи оÑÑимаÑи вÑдÑкодÑваннÑ!</translation>
- </message>
- <message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation>ÐÑдклÑÑÑÑÑ Ð¾Ð´Ð¸Ð½ або кÑлÑка геймпадÑв пеÑед поÑаÑком гÑи, Ñоб ваÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ могли ними коÑиÑÑÑваÑиÑÑ.</translation>
- </message>
- <message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation>СÑвоÑÑÑÑ Ð°ÐºÐ°ÑÐ½Ñ Ð½Ð° %1 Ñоб запобÑгÑи викоÑиÑÑÐ°Ð½Ð½Ñ ÑнÑими оÑобами ваÑого ÑлÑбленого нÑÐºÑ Ð¿Ñд ÑÐ°Ñ Ð³Ñи на оÑÑÑÑÐ¹Ð½Ð¾Ð¼Ñ ÑеÑвеÑÑ.</translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation>ЯкÑо ваÑа вÑдеокаÑÑа не може забезпеÑиÑи апаÑаÑне пÑиÑкоÑÐµÐ½Ð½Ñ OpenGL, ÑпÑобÑйÑе оновиÑи вÑдповÑÐ´Ð½Ñ Ð´ÑайвеÑи.</translation>
- </message>
- <message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
- <translation>РгÑÑ ÑÑнÑÑÑÑ ÑÑи ÑÑзниÑ
види ÑÑÑибкÑв. ÐаÑиÑнÑÑÑ [виÑокий ÑÑÑибок] двÑÑÑ Ñоб зÑобиÑи дÑже виÑокий ÑÑÑибок назад.</translation>
- </message>
- <message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
- <translation>ÐоÑÑеÑÑ Ð¿Ð°Ð´ÑÐ½Ð½Ñ Ð·Ñ ÑкелÑ? УÑÑимÑйÑе [ÑоÑно] Ñоб повеÑнÑÑиÑÑ [влÑво] Ñи [впÑаво] без ÑакÑиÑного пеÑемÑÑеннÑ.</translation>
- </message>
- <message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
- <translation>ÐеÑка збÑÐ¾Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ ÑпеÑÑалÑниÑ
ÑÑÑаÑегÑй або пÑоÑÑо багаÑо ÑÑенÑванÑ, ÑÐ¾Ð¼Ñ Ð½Ðµ вÑдмовлÑйÑеÑÑ Ð²Ñд конкÑеÑного ÑнÑÑÑÑменÑÑ, ÑкÑо ви Ñаз не знеÑкодили воÑога.</translation>
- </message>
- <message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
- <translation>ÐÑлÑÑÑÑÑÑ Ð·Ð±ÑÐ¾Ñ Ð½Ðµ бÑде пÑаÑÑваÑи пÑÑÐ»Ñ ÑоÑÐºÐ°Ð½Ð½Ñ Ð²Ð¾Ð´Ð¸. Ðджола Ñа ТоÑÑ Ñ Ð²Ð¸ÐºÐ»ÑÑеннÑми з ÑÑого пÑавила.</translation>
- </message>
- <message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
- <translation>СÑаÑий лÑмбÑÑгÑÑкий ÑÐ¸Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ Ð»Ð¸Ñе невеликий вибÑÑ
. Ðднак ÑмеÑдÑÑа Ñ
маÑа, ÑÐºÑ Ð²ÑдноÑиÑÑ Ð²ÑÑеÑ, може оÑÑÑÑÑи багаÑо ÑжакÑв за Ñаз.</translation>
- </message>
- <message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
- <translation>Ðапад пÑанÑно Ñ Ð½Ð°Ð¹Ð±ÑлÑÑ ÑÑйнÑвним повÑÑÑÑним ÑдаÑом. Ðле ви вÑÑаÑиÑе Ñжака, ÑÐ¾Ð¼Ñ Ð²Ñн Ð¼Ð°Ñ Ñ Ð½ÐµÐ³Ð°ÑÐ¸Ð²Ð½Ñ ÑÑоÑонÑ.</translation>
- </message>
- <message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
- <translation>ÐÐ¸Ð¿ÐºÑ ÐÑни ÑÑдовий ÑнÑÑÑÑÐ¼ÐµÐ½Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð¼Ð°Ð»Ð¸Ñ
ланÑÑговиÑ
ÑеакÑÑй Ð´Ð»Ñ Ð·Ð°ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð²Ð¾ÑогÑв Ñ ÑÐºÐ»Ð°Ð´Ð½Ñ ÑиÑÑаÑÑÑ ... або Ñ Ð²Ð¾Ð´Ñ.</translation>
- </message>
- <message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation>ÐолоÑок найбÑлÑÑ ÐµÑекÑивний пÑи викоÑиÑÑÐ°Ð½Ð½Ñ Ð½Ð° моÑÑаÑ
Ñи балкаÑ
. Ð£Ð´Ð°Ñ Ñжака пÑоÑÑо пÑовалиÑÑ Ð¹Ð¾Ð³Ð¾ кÑÑÐ·Ñ Ð·ÐµÐ¼Ð»Ñ.</translation>
- </message>
- <message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation>ЯкÑо ви заÑÑÑÑгли за воÑожим Ñжаком, викоÑиÑÑайÑе ÐолоÑок, Ñоб звÑлÑниÑи Ñебе без поÑÐºÐ¾Ð´Ð¶ÐµÐ½Ñ Ð²Ñд вибÑÑ
Ñ.</translation>
- </message>
- <message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation>ÐайбÑлÑÑий ÑлÑÑ
Ñ
одÑби ТоÑÑа залежиÑÑ Ð²Ñд землÑ, по ÑкÑй вÑн повинен пÑойÑи. ÐикоÑиÑÑовÑйÑе [аÑака] Ñоб пÑдÑÑваÑи його ÑанÑÑе.</translation>
- </message>
- <message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
- <translation>ÐÐ¾Ð³Ð½ÐµÐ¼ÐµÑ Ñе збÑоÑ, але його можна Ñакож викоÑиÑÑаÑи Ð´Ð»Ñ ÑиÑÑÑ ÑÑнелÑ.</translation>
- </message>
- <message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation>ХоÑеÑе знаÑи Ñ
Ñо ÑобиÑÑ Ð³ÑÑ? ÐаÑиÑнÑÑÑ Ð½Ð° логоÑип Hedgewars в Ð³Ð¾Ð»Ð¾Ð²Ð½Ð¾Ð¼Ñ Ð¼ÐµÐ½Ñ, Ñоб побаÑиÑи ÑпиÑок.</translation>
- </message>
- <message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation>ÐодобаÑÑÑÑÑ Hedgewars? СÑанÑÑе ÑанаÑом на %1 або ÑлÑдÑйÑе за нами на %2!</translation>
- </message>
- <message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
- <translation>Ðи можеÑе ÑÐ°Ð¼Ñ Ð½Ð°Ð¼Ð°Ð»ÑваÑи надгÑобки, Ñапки, пÑапоÑи Ñа навÑÑÑ Ð¼Ð°Ð¿Ð¸ Ñ Ñеми! Ðле вÑаÑ
ÑйÑе, вам доведеÑÑÑÑ Ð¿Ð¾Ð´ÑлиÑиÑÑ Ð½Ð¸Ð¼Ð¸ з кимоÑÑ Ñоб викоÑиÑÑаÑи ÑÑ
в ÑнÑеÑнеÑ-гÑÑ.</translation>
- </message>
- <message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
- <translation>ХоÑеÑе ноÑиÑи оÑобливий капелÑÑ
? ÐнеÑÑÑÑ Ð¿Ð¾Ð¶ÐµÑÑÐ²Ñ Ñ Ð¾ÑÑимайÑе екÑклÑзивний капелÑÑ
на Ð²Ð°Ñ Ð²Ð¸Ð±ÑÑ!</translation>
- </message>
- <message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
- <translation>ÐикоÑиÑÑовÑйÑе оÑÑÐ°Ð½Ð½Ñ Ð²Ñдео дÑайвеÑи Ñоб ÑникнÑÑи пÑоблем пÑд ÑÐ°Ñ Ð³Ñи.</translation>
+ <numerusform><b>%1</b> вбив <b>%2</b> Ñжака Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
+ <numerusform><b>%1</b> вбив <b>%2</b> ÑжакÑв Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
+ <numerusform><b>%1</b> вбив <b>%2</b> ÑжакÑв Ð·Ñ ÑвоÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸.</numerusform>
+ </translation>
</message>
- <message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ðи можеÑе знайÑи Ñайли конÑÑгÑÑаÑÑÑ Hedgewars в "My Documents\Hedgewars". Ðи можеÑе ÑÑвоÑиÑи ÑезеÑÐ²Ð½Ñ ÐºÐ¾Ð¿ÑÑ Ð°Ð±Ð¾ взÑÑи Ñайли з ÑобоÑ, але не ÑедагÑйÑе ÑÑ
.</translation>
+ <message numerus="yes">
+ <source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
+ <translation>
+ <numerusform><b>%1</b> злÑкавÑÑ Ñ Ð¿ÑопÑÑÑив Ñ
Ñд <b>%2</b> ÑазÑв.</numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation>Ðи можеÑе зв'ÑзаÑи вÑдповÑÐ´Ð½Ñ Ñайли Hedgewars (Ñайли збеÑÐµÐ¶ÐµÐ½Ð½Ñ Ñа демо-запиÑи) з гÑÐ¾Ñ Ñоб запÑÑкаÑи ÑÑ
з ваÑÐ¾Ñ ÑлÑÐ±Ð»ÐµÐ½Ð¾Ñ Ñеки Ñи ÑнÑеÑнеÑ-бÑаÑзеÑÑ.</translation>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation>ХоÑеÑе заоÑадиÑи моÑÑзки? ÐипÑÑÑÑÑÑ Ð¼Ð¾ÑÑÐ·ÐºÑ Ð² повÑÑÑÑ Ð° поÑÑм Ð·Ð½Ð¾Ð²Ñ ÑÑÑÑлÑйÑе. Ðоки ви не ÑоÑкнÑлиÑÑ Ð³ÑÑнÑÑ Ð²Ð¸ можеÑе Ð·Ð½Ð¾Ð²Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи моÑÑзкÑ, не виÑÑаÑаÑÑи боÑпÑипаÑи!</translation>
+ <source>Save</source>
+ <translation type="unfinished">ÐбеÑегÑи</translation>
</message>
+</context>
+<context>
+ <name>PageInGame</name>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ðи можеÑе знайÑи Ñайли конÑÑгÑÑаÑÑÑ Hedgewars в "Library/Application Support/Hedgewars" в домаÑнÑй ÑеÑÑ. Ðи можеÑе ÑÑвоÑиÑи ÑезеÑÐ²Ð½Ñ ÐºÐ¾Ð¿ÑÑ Ð°Ð±Ð¾ взÑÑи Ñайли з ÑобоÑ, але не ÑедагÑйÑе ÑÑ
.</translation>
+ <source>In game...</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageInfo</name>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation>Ðи можеÑе знайÑи Ñайли конÑÑгÑÑаÑÑÑ Hedgewars в ".hedgewars" в домаÑнÑй ÑеÑÑ. Ðи можеÑе ÑÑвоÑиÑи ÑезеÑÐ²Ð½Ñ ÐºÐ¾Ð¿ÑÑ Ð°Ð±Ð¾ взÑÑи Ñайли з ÑобоÑ, але не ÑедагÑйÑе ÑÑ
.</translation>
+ <source>Open the snapshot folder</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMain</name>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
- <translation>Windows-веÑÑÑÑ Hedgewars пÑдÑÑимÑÑ Xfire. ÐеÑеконайÑеÑÑ Ð² ÑомÑ, Ñо ви додали Hedgewars до ÑпиÑÐºÑ ÑгоÑ, Ñоб ваÑÑ Ð´ÑÑÐ·Ñ Ð¼Ð¾Ð³Ð»Ð¸ баÑиÑи Ð²Ð°Ñ Ð² гÑÑ.</translation>
+ <source>Downloadable Content</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
- <translation>ÐикоÑиÑÑайÑе ÐокÑÐµÐ¹Ð»Ñ ÐолоÑова або ÐÐ¾Ð³Ð½ÐµÐ¼ÐµÑ Ñоб ÑимÑаÑово ÑÑÑимаÑи ÑжакÑв вÑд пÑоÑ
Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ ÑÐ°ÐºÐ¾Ñ Ð¼ÑÑÑевоÑÑÑ Ñк ÑÑÐ½ÐµÐ»Ñ Ð°Ð±Ð¾ плаÑÑоÑми.</translation>
+ <source>Play a game on a single computer</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
- <translation>ÐавÑдна ÐджÑлка може бÑÑи ÑÐºÐ»Ð°Ð´Ð½Ð¾Ñ Ñ ÐºÐµÑÑваннÑ. РадÑÑÑ Ð¿Ð¾Ð²Ð¾ÑоÑÑ Ð·Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð²Ñд ÑÑ ÑвидкоÑÑÑ, ÑÐ¾Ð¼Ñ Ð¿Ð¾ÑÑаÑайÑеÑÑ Ð½Ðµ ÑÑÑÑлÑÑи на Ð¿Ð¾Ð²Ð½Ñ ÑилÑ.</translation>
+ <source>Play a game across a network</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -831,38 +1001,42 @@ Please pick another nickname:</source>
<source>Start</source>
<translation>СÑаÑÑ</translation>
</message>
+ <message>
+ <source>Edit game preferences</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageNetGame</name>
<message>
<source>Control</source>
- <translation>ÐеÑÑваннÑ</translation>
+ <translation type="obsolete">ÐеÑÑваннÑ</translation>
</message>
<message>
- <source>DLC</source>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">СÑаÑÑ</translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
<message>
- <source>LAN game</source>
- <translation>ÐокалÑна гÑа</translation>
+ <source>Update</source>
+ <translation type="unfinished">ÐновиÑи</translation>
</message>
<message>
- <source>Official server</source>
- <translation>ÐÑÑÑÑйний ÑеÑвеÑ</translation>
+ <source>Room controls</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -909,10 +1083,6 @@ Please pick another nickname:</source>
<translation>ÐидалиÑи набÑÑ Ð·Ð±ÑоÑ</translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">ÐÑновнÑ</translation>
- </message>
- <message>
<source>Advanced</source>
<translation type="unfinished">РозÑиÑенÑ</translation>
</message>
@@ -952,6 +1122,94 @@ Please pick another nickname:</source>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Select an action to change what key controls it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset to default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Graphics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video Recording</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Teams</source>
+ <translation type="unfinished">Ðоманди</translation>
+ </message>
+ <message>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Weapons</source>
+ <translation type="unfinished">ÐбÑоÑ</translation>
+ </message>
+ <message>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -968,11 +1226,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>СÑвоÑиÑи</translation>
+ <translation type="obsolete">СÑвоÑиÑи</translation>
</message>
<message>
<source>Join</source>
- <translation>ÐÑиÑднаÑиÑÑ</translation>
+ <translation type="obsolete">ÐÑиÑднаÑиÑÑ</translation>
</message>
<message>
<source>Admin features</source>
@@ -980,7 +1238,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation>Ðазва ÐÑмнаÑи:</translation>
+ <translation type="obsolete">Ðазва ÐÑмнаÑи:</translation>
</message>
<message>
<source>Rules:</source>
@@ -992,11 +1250,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>Search:</source>
- <translation>ÐоÑÑк:</translation>
+ <translation type="obsolete">ÐоÑÑк:</translation>
</message>
<message>
<source>Clear</source>
- <translation>ÐÑиÑÑиÑи</translation>
+ <translation type="obsolete">ÐÑиÑÑиÑи</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -1006,6 +1264,30 @@ Please pick another nickname:</source>
<numerusform>%1 гÑавÑÑв в меÑежÑ</numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1152,18 +1434,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1172,26 +1446,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">ÐаванÑажиÑи</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1238,19 +1500,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1265,10 +1529,6 @@ Please pick another nickname:</source>
<translation>ÐнÑо</translation>
</message>
<message>
- <source>Start</source>
- <translation>СÑаÑÑ</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>ÐбмежиÑи ÐÑиÑднаннÑ</translation>
</message>
@@ -1302,7 +1562,19 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation>ÐновиÑи</translation>
+ <translation type="obsolete">ÐновиÑи</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1316,18 +1588,6 @@ Please pick another nickname:</source>
<translation>Ðовний екÑан</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>ÐÐµÐ½Ñ Ð½Ð° повний екÑан</translation>
- </message>
- <message>
- <source>Enable sound</source>
- <translation>ÐклÑÑиÑи звÑк</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation>ÐклÑÑиÑи мÑзикÑ</translation>
- </message>
- <message>
<source>Show FPS</source>
<translation>ÐоказÑваÑи знаÑÐµÐ½Ð½Ñ FPS</translation>
</message>
@@ -1344,45 +1604,57 @@ Please pick another nickname:</source>
<translation>ÐоказÑваÑи пÑдказки в Ð¼ÐµÐ½Ñ Ð·Ð±ÑоÑ</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation>ÐклÑÑиÑи звÑки в менÑ</translation>
+ <source>Save password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Enable frontend music</source>
- <translation>ÐклÑÑиÑи мÑÐ·Ð¸ÐºÑ Ð² менÑ</translation>
+ <source>Save account name and password</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Frontend effects</source>
- <translation>ÐÑекÑи менÑ</translation>
+ <source>Video is private</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Save password</source>
+ <source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save account name and password</source>
+ <source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Video is private</source>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Record audio</source>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use game resolution</source>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>згенеÑована мапа...</translation>
- </message>
- <message>
<source>Human</source>
<translation>ÐÑдина</translation>
</message>
@@ -1395,14 +1667,6 @@ Please pick another nickname:</source>
<translation>(СиÑÑÐµÐ¼Ð½Ñ Ð·Ð°Ð¼Ð¾Ð²ÑÑваннÑ)</translation>
</message>
<message>
- <source>Mission</source>
- <translation>ÐÑÑÑÑ</translation>
- </message>
- <message>
- <source>generated maze...</source>
- <translation>згенеÑований лабÑÑинÑ...</translation>
- </message>
- <message>
<source>Community</source>
<translation>СпÑлÑноÑа</translation>
</message>
@@ -1412,15 +1676,11 @@ Please pick another nickname:</source>
</message>
<message>
<source>In lobby</source>
- <translation>РвеÑÑибÑлÑ</translation>
+ <translation type="obsolete">РвеÑÑибÑлÑ</translation>
</message>
<message>
<source>In progress</source>
- <translation>РпÑоÑеÑÑ</translation>
- </message>
- <message>
- <source>hand drawn map...</source>
- <translation>вÑÑÑÐ½Ñ Ð½Ð°Ð¼Ð°Ð»Ñована мапа...</translation>
+ <translation type="obsolete">РпÑоÑеÑÑ</translation>
</message>
<message>
<source>Disabled</source>
@@ -1459,10 +1719,6 @@ Please pick another nickname:</source>
<translation>ÐеÑÑ
-низ</translation>
</message>
<message>
- <source>Wiggle</source>
- <translation>ÐогойдÑваннÑ</translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation>ЧеÑв./Ðлак. вÑдÑÑнки ÑÑÑого</translation>
</message>
@@ -1498,18 +1754,6 @@ Please pick another nickname:</source>
<translation>ФоÑÑ</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>ÐÑив'Ñзки клавÑÑ</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>Ðоманди</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ ÐвÑÐºÑ Ñа ÐÑаÑÑки</translation>
- </message>
- <message>
<source>Net game</source>
<translation>ÐеÑежна гÑа</translation>
</message>
@@ -1519,35 +1763,15 @@ Please pick another nickname:</source>
</message>
<message>
<source>Game Modifiers</source>
- <translation>ÐодиÑÑкаÑоÑи ÐÑи</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>ÐÑÐ½Ð¾Ð²Ð½Ñ ÐаÑамеÑÑи</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation>ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ðоманди</translation>
- </message>
- <message>
- <source>Misc</source>
- <translation>Ð Ñзне</translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation>СÑ
еми Ñа ÐбÑоÑ</translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <translation>ÐодиÑÑкаÑоÑи ÐÑи</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>ÐÑÐ½Ð¾Ð²Ð½Ñ ÐаÑамеÑÑи</translation>
</message>
<message>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
+ <source>Team Settings</source>
+ <translation>ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ðоманди</translation>
</message>
<message>
<source>Videos</source>
@@ -1557,10 +1781,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1574,27 +1794,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>ÐеÑÑÑÑ</translation>
- </message>
- <message>
- <source>Developers:</source>
- <translation>РозÑобники:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>ÐÑаÑÑка:</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>ÐвÑки:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>ÐеÑеклади:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>ÐÑоблива вдÑÑнÑÑÑÑ:</translation>
+ <translation type="obsolete">ÐеÑÑÑÑ</translation>
</message>
<message>
<source>Weapons</source>
@@ -1653,10 +1853,6 @@ Please pick another nickname:</source>
<translation>ÐÑлÑкÑÑÑÑ ÐодаÑÑнкÑв</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>СÑ
ема гÑи</translation>
- </message>
- <message>
<source>% Dud Mines</source>
<translation>% ÐÑакованиÑ
ÐÑн</translation>
</message>
@@ -1693,10 +1889,6 @@ Please pick another nickname:</source>
<translation>ÐоÑада: </translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation>Ð¦Ñ ÑозÑобниÑÑка збÑÑка Ñ Ð¿ÑомÑÐ¶Ð½Ð¾Ñ Ñ Ð¼Ð¾Ð¶Ðµ бÑÑи неÑÑмÑÑÐ½Ð¾Ñ Ð· ÑнÑими веÑÑÑÑми гÑи. ÐеÑÐºÑ ÑÑнкÑÑÑ Ð¼Ð¾Ð¶ÑÑÑ Ð±ÑÑи Ð·Ð»Ð°Ð¼Ð°Ð½Ñ Ñи неповнÑ. ÐикоÑиÑÑовÑйÑе ÑÑ Ð½Ð° ÑвÑй ÑÑÑаÑ
Ñ Ñизик!</translation>
- </message>
- <message>
<source>Quality</source>
<translation>ЯкÑÑÑÑ</translation>
</message>
@@ -1737,10 +1929,6 @@ Please pick another nickname:</source>
<translation>% Ð§Ð°Ñ Ð¢ÑкаÑи</translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1771,16 +1959,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Nickname</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Ðм'Ñ</translation>
</message>
<message>
<source>Format</source>
@@ -1802,6 +1986,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">Ðовний екÑан</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1824,6 +2052,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>Hedgewars %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1840,10 +2072,6 @@ Do you really want to quit?</source>
<translation>Файлове аÑоÑÑÑÐ²Ð°Ð½Ð½Ñ Ð½Ðµ вдалоÑÑ</translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1890,47 +2118,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">Ðе Ð¼Ð¾Ð¶Ñ ÑÑвоÑиÑи диÑекÑоÑÑÑ %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ðе Ð¼Ð¾Ð¶Ñ ÑÑвоÑиÑи диÑекÑоÑÑÑ %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">Ðомилка запÑÑÐºÑ ÑеÑвеÑа: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">Ðомилка запÑÑÐºÑ ÑеÑвеÑа: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2050,16 +2243,42 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation>Ðм'Ñ</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation>ÐÑÐ´Ñ Ð»Ð°Ñка введÑÑÑ Ð²Ð°Ñе Ñм'Ñ</translation>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -2117,26 +2336,10 @@ Do you still want to join the room?</source>
<translation>ÐаванÑажиÑи</translation>
</message>
<message>
- <source>Setup</source>
- <translation>ÐалаÑÑÑваннÑ</translation>
- </message>
- <message>
- <source>Ready</source>
- <translation>ÐоÑовий</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation>Ðипадкова Ðоманда</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation>ÐÑоÑÑÑваÑи ÑÐ°Ð¹Ð»Ð¾Ð²Ñ ÑозÑиÑеннÑ</translation>
</message>
<message>
- <source>more</source>
- <translation>бÑлÑÑе</translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2160,6 +2363,61 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Restore default coding parameters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>RoomsListModel</name>
@@ -2209,6 +2467,25 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
+ </message>
+ <message>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<source>Weapon set</source>
@@ -2236,105 +2513,43 @@ Do you still want to join the room?</source>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
+ <name>TCPBase</name>
<message>
- <source>Vampirism</source>
- <translation>ÐампÑÑизм</translation>
- </message>
- <message>
- <source>Karma</source>
- <translation>ÐаÑма</translation>
- </message>
- <message>
- <source>Artillery</source>
- <translation>ÐÑÑилеÑÑÑ</translation>
- </message>
- <message>
- <source>Fort Mode</source>
- <translation>Режим ФоÑÑÑ</translation>
- </message>
- <message>
- <source>Divide Teams</source>
- <translation>РоздÑÐ»ÐµÐ½Ð½Ñ Ðоманд</translation>
- </message>
- <message>
- <source>Solid Land</source>
- <translation>ЩÑлÑний ÐÑÑнÑ</translation>
- </message>
- <message>
- <source>Add Border</source>
- <translation>ÐодаÑи ÐоÑдон</translation>
- </message>
- <message>
- <source>Low Gravity</source>
- <translation>Слабка ÐÑавÑÑаÑÑÑ</translation>
- </message>
- <message>
- <source>Laser Sight</source>
- <translation>ÐазеÑний ÐÑиÑÑл</translation>
- </message>
- <message>
- <source>Invulnerable</source>
- <translation>ÐевÑазливÑÑÑÑ</translation>
- </message>
- <message>
- <source>Random Order</source>
- <translation>Ðипадковий ÐоÑÑдок</translation>
- </message>
- <message>
- <source>King</source>
- <translation>ÐоÑолÑ</translation>
- </message>
- <message>
- <source>Place Hedgehogs</source>
- <translation>РозмÑÑÑиÑи ÐжакÑв</translation>
- </message>
- <message>
- <source>Clan Shares Ammo</source>
- <translation>Ðлан ÐÑлиÑÑÑÑ ÐоÑпÑипаÑами</translation>
- </message>
- <message>
- <source>Disable Girders</source>
- <translation>ÐимкнÑÑи Ðалки</translation>
- </message>
- <message>
- <source>Disable Land Objects</source>
- <translation>ÐимкнÑÑи ÐекоÑаÑÑÑ</translation>
- </message>
- <message>
- <source>AI Survival Mode</source>
- <translation>Режим AI ÐиживаннÑ</translation>
- </message>
- <message>
- <source>Reset Health</source>
- <translation>СкинÑÑи ÐдоÑов'Ñ</translation>
- </message>
- <message>
- <source>Unlimited Attacks</source>
- <translation>ÐÐµÐ¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ñ ÐÑаки</translation>
+ <source>Unable to start server at %1.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
- <translation>СкинÑÑи ÐбÑоÑ</translation>
+ <source>Unable to run engine at %1
+Error code: %2</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
- <translation>ÐоÑпÑипаÑи на Ðжака</translation>
+ <source>At least two teams are required to play!</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
- <translation>ÐимкнÑÑи ÐÑÑеÑ</translation>
+ <source>%1's team</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation>ÐÑлÑÑе ÐÑÑÑÑ</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">СкаÑÑваÑи</translation>
</message>
<message>
- <source>Tag Team</source>
- <translation>ÐбÑÑна Ðоманда</translation>
+ <source>Search for a theme:</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2469,12 +2684,6 @@ Do you still want to join the room?</source>
<translation>знÑмок</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>ÑнÑоÑмаÑÑÑ
-пÑо ÑжаÑкÑв</translation>
- </message>
- <message>
<source>quit</source>
<translation>виÑ
Ñд</translation>
</message>
@@ -2510,33 +2719,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation>ÐÑÐ½Ð¾Ð²Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи кеÑÑваннÑ</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation>ÐеÑÑÐ²Ð°Ð½Ð½Ñ Ð·Ð±ÑоÑÑ</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">ÐбÑоÑ</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation>ÐеÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐ°Ð¼ÐµÑÐ¾Ñ Ñ ÐºÑÑÑоÑом</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation>ÐнÑе</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation>ÐеÑемÑÑÐµÐ½Ð½Ñ Ð²Ð°ÑиÑ
ÑжакÑв Ñа ÑÑлÑ:</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation>ÐÐ¾Ð´Ð¾Ð»Ð°Ð½Ð½Ñ Ð¿Ñогалин Ñ Ð¿ÐµÑеÑкод ÑÑÑибками:</translation>
</message>
@@ -2600,6 +2809,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts b/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts
index d1721a4..4452c76 100644
--- a/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_zh_CN.ts
@@ -2,9 +2,17 @@
<!DOCTYPE TS>
<TS version="2.0" language="zh_CN">
<context>
+ <name>About</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="93"/>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/AbstractPage.cpp" line="51"/>
+ <location filename="../../../../QTfrontend/ui/page/AbstractPage.cpp" line="55"/>
<source>Go back</source>
<translation type="unfinished"></translation>
</message>
@@ -23,6 +31,116 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="35"/>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="39"/>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="40"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="41"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="42"/>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="48"/>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="49"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="77"/>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="84"/>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="151"/>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="91"/>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="90"/>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="92"/>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="93"/>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="124"/>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="150"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="178"/>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<location filename="../../../../QTfrontend/ui/widget/FreqSpinBox.cpp" line="36"/>
@@ -40,27 +158,93 @@
<context>
<name>GameCFGWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="54"/>
- <source>Game Options</source>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="67"/>
+ <source>Map</source>
+ <translation type="unfinished">å°å¾</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="68"/>
+ <source>Game options</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="94"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="147"/>
<source>Edit weapons</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="102"/>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="155"/>
+ <source>Game scheme will auto-select a weapon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="79"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="132"/>
<source>Edit schemes</source>
<translation>ä¿®æ¹æ¸¸æ设置</translation>
</message>
</context>
<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="25"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="26"/>
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="27"/>
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="28"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="29"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="30"/>
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="31"/>
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/ui/dialog/bandialog.cpp" line="34"/>
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/HWApplication.cpp" line="92"/>
+ <source>Scheme '%1' not supported</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="102"/>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/main.cpp" line="253"/>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>HWAskQuitDialog</name>
<message>
<location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="33"/>
@@ -71,128 +255,195 @@
<context>
<name>HWChatWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="627"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="502"/>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="523"/>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="525"/>
+ <source>%1 has left (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="652"/>
<source>%1 has been removed from your ignore list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="637"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="662"/>
<source>%1 has been added to your ignore list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="667"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="692"/>
<source>%1 has been removed from your friends list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="676"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="701"/>
<source>%1 has been added to your friends list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="742"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="767"/>
<source>Stylesheet imported from %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="743"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="768"/>
<source>Enter %1 if you want to use the current StyleSheet in future, enter %2 to reset!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="751"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="776"/>
<source>Couldn't read %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="759"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="784"/>
<source>StyleSheet discarded</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="784"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="808"/>
<source>StyleSheet saved to %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="787"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="811"/>
<source>Failed to save StyleSheet to %1</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="807"/>
- <source>%1 is not a valid command!</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>HWForm</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="463"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="465"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="478"/>
<source>DefaultTeam</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="569"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="482"/>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="636"/>
<source>Game aborted</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="981"/>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1075"/>
+ <source>Hedgewars - Nick registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1076"/>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1104"/>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="985"/>
- <source>No password supplied.</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1109"/>
+ <source>
+
+Your password wasn't saved either.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1011"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1011"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1121"/>
<source>Someone already uses your nickname %1 on the server.
Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1015"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
<source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1660"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1126"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1435"/>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1152"/>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1173"/>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1539"/>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1945"/>
<source>Hedgewars Demo File</source>
<comment>File Types</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1661"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1946"/>
<source>Hedgewars Save File</source>
<comment>File Types</comment>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1709"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
<source>Demo name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1709"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2007"/>
<source>Demo name:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1430"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1717"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2075"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1696"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2015"/>
<source>Cannot save record to file %1</source>
<translation>æ æ³å½å
¥æ件 %1</translation>
</message>
@@ -200,13 +451,13 @@ Please pick another nickname:</source>
<context>
<name>HWGame</name>
<message>
- <location filename="../../../../QTfrontend/game.cpp" line="350"/>
- <location filename="../../../../QTfrontend/net/recorder.cpp" line="118"/>
+ <location filename="../../../../QTfrontend/game.cpp" line="386"/>
+ <location filename="../../../../QTfrontend/net/recorder.cpp" line="112"/>
<source>en.txt</source>
<translation>zh_CN.txt</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/game.cpp" line="361"/>
+ <location filename="../../../../QTfrontend/game.cpp" line="427"/>
<source>Cannot open demofile %1</source>
<translation>DEMO %1 æä¸å¼</translation>
</message>
@@ -214,95 +465,161 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="82"/>
- <source>Map</source>
- <translation>å°å¾</translation>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="220"/>
+ <source>Small tunnels</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="99"/>
- <source>Type</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="221"/>
+ <source>Medium tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="103"/>
- <source>Small tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="126"/>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="104"/>
- <source>Medium tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="94"/>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="105"/>
- <source>Large tunnels</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="97"/>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="106"/>
- <source>Small floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="98"/>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="107"/>
- <source>Medium floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="99"/>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="108"/>
- <source>Large floating islands</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="100"/>
+ <source>Randomly generated</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="118"/>
- <source>Themes</source>
- <translation>主é¢</translation>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="101"/>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="162"/>
- <source>Seed</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="111"/>
+ <source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="555"/>
- <source>Set</source>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="135"/>
+ <source>Map preview:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="85"/>
- <source>Filter</source>
- <translation>è¿æ»¤</translation>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="188"/>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="89"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="194"/>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="207"/>
<source>All</source>
<translation>å
¨é¨</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="90"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="208"/>
<source>Small</source>
<translation>å°å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="91"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="209"/>
<source>Medium</source>
<translation>ä¸å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="92"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="210"/>
<source>Large</source>
<translation>大å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="93"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="211"/>
<source>Cavern</source>
<translation>æ´ç©´</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="94"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="212"/>
<source>Wacky</source>
<translation>æ²æ</translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="222"/>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="223"/>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="224"/>
+ <source>Medium islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="225"/>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="710"/>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="717"/>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="730"/>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="740"/>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="804"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="935"/>
+ <source>Theme: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="886"/>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>HWNetServersModel</name>
@@ -325,65 +642,58 @@ Please pick another nickname:</source>
<context>
<name>HWNewNet</name>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="75"/>
<source>User quit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="212"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="218"/>
<source>Remote host has closed connection</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="215"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="221"/>
<source>The host was not found. Please check the host name and port settings.</source>
<translation>é误没æ¾å°è¿ä¸ªä¸»æºã请æ£æ¥ä¸»æºåå端å£è®¾ç½®ã</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="218"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="224"/>
<source>Connection refused</source>
<translation>è¿æ¥è¢«æç»</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="276"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="283"/>
<source>The server is too old. Disconnecting now.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="471"/>
- <source>%1 *** %2 has joined</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="518"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="739"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="797"/>
<source>%1 *** %2 has left</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="520"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="741"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="799"/>
<source>%1 *** %2 has left (%3)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="597"/>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="724"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="651"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="782"/>
<source>%1 *** %2 has joined the room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1285"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
<source>Quit reason: </source>
<translation>éåºåå ï¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="648"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="707"/>
<source>Room destroyed</source>
<translation>æ¿é´æå</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="447"/>
+ <location filename="../../../../QTfrontend/net/newnetclient.cpp" line="484"/>
<source>You got kicked</source>
<translation>被踢åº</translation>
</message>
@@ -392,8 +702,26 @@ Please pick another nickname:</source>
<name>HWPasswordDialog</name>
<message>
<location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="30"/>
- <source>Password</source>
- <translation type="unfinished">å¯ç </translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="35"/>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="39"/>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="47"/>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -410,6 +738,32 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatbutton.cpp" line="40"/>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="83"/>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="119"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/hatprompt.cpp" line="123"/>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<location filename="../../../../QTfrontend/KB.h" line="28"/>
@@ -418,66 +772,127 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/keybinder.cpp" line="100"/>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="282"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="281"/>
<source>Duration: %1m %2s
</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="294"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="293"/>
<source>Video: %1x%2, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="298"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="297"/>
<source>%1 fps, </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/libav_iteraction.cpp" line="302"/>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="301"/>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/util/LibavInteraction.cpp" line="305"/>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <location filename="../../../../QTfrontend/model/MapModel.cpp" line="193"/>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="34"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="40"/>
+ <source>General</source>
+ <translation type="unfinished">常è§</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="41"/>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="48"/>
<source>Fetch data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="52"/>
<source>Server message for latest version:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="46"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="60"/>
<source>Server message for previous versions:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="54"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="68"/>
<source>Latest version protocol number:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="62"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="76"/>
<source>MOTD preview:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="85"/>
<source>Clear Accounts Cache</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="74"/>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="88"/>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="97"/>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="98"/>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="99"/>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="108"/>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="109"/>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageadmin.cpp" line="110"/>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -488,6 +903,19 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="66"/>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagedata.cpp" line="126"/>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagedrawmap.cpp" line="32"/>
@@ -541,13 +969,53 @@ Please pick another nickname:</source>
<name>PageEditTeam</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="45"/>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="47"/>
<source>General</source>
<translation>常è§</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="46"/>
- <source>Advanced</source>
- <translation>è¿é¶</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="48"/>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="66"/>
+ <source>Hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="67"/>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="78"/>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="84"/>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="88"/>
+ <source>Random Team</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -568,47 +1036,57 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="173"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="113"/>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="118"/>
+ <source>Save</source>
+ <translation type="unfinished">ä¿å</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="193"/>
<source>The best shot award was won by <b>%1</b> with <b>%2</b> pts.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="181"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="201"/>
<source>The best killer is <b>%1</b> with <b>%2</b> kills in a turn.</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="188"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="208"/>
<source>A total of <b>%1</b> hedgehog(s) were killed during this round.</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="272"/>
<source>(%1 kill)</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="263"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="283"/>
<source><b>%1</b> thought it's good to shoot his own hedgehogs with <b>%2</b> pts.</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="271"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="291"/>
<source><b>%1</b> killed <b>%2</b> of his own hedgehogs.</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="279"/>
+ <location filename="../../../../QTfrontend/ui/page/pagegamestats.cpp" line="299"/>
<source><b>%1</b> was scared and skipped turn <b>%2</b> times.</source>
<translation type="unfinished">
<numerusform></numerusform>
@@ -635,510 +1113,341 @@ Please pick another nickname:</source>
<name>PageMain</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="45"/>
- <source>Local Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="46"/>
<source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="50"/>
- <source>Network Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="51"/>
<source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="58"/>
- <source>Read about who is behind the Hedgewars Project</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="63"/>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="64"/>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="67"/>
- <source>Downloadable Content</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="65"/>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="69"/>
- <source>Access the user created content downloadable from our website</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="89"/>
- <source>Exit game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="93"/>
- <source>Manage videos recorded from game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="97"/>
- <source>Edit game preferences</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="128"/>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="129"/>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="130"/>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="131"/>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="132"/>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="133"/>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="134"/>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="135"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="136"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="137"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="138"/>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="139"/>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="140"/>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="141"/>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="142"/>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="143"/>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="144"/>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="145"/>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="146"/>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="147"/>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="148"/>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="149"/>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="150"/>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="151"/>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="152"/>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="70"/>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="153"/>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="154"/>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="155"/>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="77"/>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="156"/>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="80"/>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="157"/>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="82"/>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="158"/>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="85"/>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="159"/>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="87"/>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="160"/>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="107"/>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="161"/>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="111"/>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="162"/>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="115"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="163"/>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="50"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="164"/>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="62"/>
+ <source>Start</source>
+ <translation>å¼å§</translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="165"/>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="62"/>
+ <source>Update</source>
+ <translation type="unfinished">æ´æ°</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="166"/>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="80"/>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="167"/>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="116"/>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="168"/>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">Ctrl</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="169"/>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="141"/>
+ <source>Start</source>
+ <translation type="unfinished">å¼å§</translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="170"/>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="87"/>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="171"/>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="138"/>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="175"/>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="176"/>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="178"/>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="91"/>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="180"/>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="96"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="239"/>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="182"/>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="99"/>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="55"/>
- <source>Start</source>
- <translation>å¼å§</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="65"/>
- <source>DLC</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="102"/>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="66"/>
- <source>Downloadable Content</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="104"/>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="87"/>
- <source>Control</source>
- <translation>Ctrl</translation>
- </message>
-</context>
-<context>
- <name>PageNetType</name>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="35"/>
- <source>LAN game</source>
- <translation>å±åç½æ¸¸æ</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="36"/>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="108"/>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="37"/>
- <source>Official server</source>
- <translation>å®æ¹æå¡å¨</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenettype.cpp" line="38"/>
- <source>Join hundreds of players online!</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="112"/>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="50"/>
- <source>General</source>
- <translation type="unfinished">常è§</translation>
- </message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="51"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="115"/>
<source>Advanced</source>
<translation type="unfinished">è¿é¶</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="77"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="128"/>
+ <source>Teams</source>
+ <translation type="unfinished">éä¼</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="138"/>
<source>New team</source>
<translation>æ°éä¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="85"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="146"/>
<source>Edit team</source>
<translation>ä¿®æ¹éä¼è®¾å®</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="93"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="154"/>
<source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="101"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="162"/>
<source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="127"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="169"/>
+ <source>Schemes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="178"/>
<source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="134"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="185"/>
<source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="141"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="192"/>
<source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="155"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="200"/>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="209"/>
<source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="162"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="216"/>
<source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="169"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="223"/>
<source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="405"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="371"/>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="388"/>
+ <source>Custom colors</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="418"/>
<source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="454"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="431"/>
+ <source>Game audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="469"/>
+ <source>Frontend audio</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="492"/>
+ <source>Account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="518"/>
+ <source>Proxy settings</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="524"/>
<source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="455"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="525"/>
<source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="456"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="526"/>
<source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="457"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="527"/>
<source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="468"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="540"/>
<source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="469"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="541"/>
<source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="470"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="542"/>
<source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="471"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="543"/>
<source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="578"/>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="624"/>
+ <source>Updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="637"/>
+ <source>Check for updates</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="651"/>
+ <source>Video recording options</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PagePlayDemo</name>
@@ -1156,49 +1465,62 @@ Please pick another nickname:</source>
<context>
<name>PageRoomsList</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="44"/>
- <source>Room Name:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="64"/>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="91"/>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="95"/>
+ <source>Join room</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="153"/>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="177"/>
<source>Rules:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="79"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="191"/>
<source>Weapons:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="87"/>
- <source>Search:</source>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="202"/>
+ <source>Clear filters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="102"/>
- <source>Create</source>
- <translation>建ç«</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="222"/>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="103"/>
- <source>Join</source>
- <translation>å å
¥</translation>
+ <source>Create</source>
+ <translation type="obsolete">建ç«</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="104"/>
- <source>Clear</source>
- <translation type="unfinished"></translation>
+ <source>Join</source>
+ <translation type="obsolete">å å
¥</translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="492"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="609"/>
<source>%1 players online</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="129"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="220"/>
<source>Admin features</source>
<translation>管çååè½</translation>
</message>
@@ -1206,152 +1528,152 @@ Please pick another nickname:</source>
<context>
<name>PageScheme</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="72"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="71"/>
<source>Defend your fort and destroy the opponents, two team colours max!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="77"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="75"/>
<source>Teams will start on opposite sides of the terrain, two team colours max!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="82"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="79"/>
<source>Land can not be destroyed!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="87"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="83"/>
<source>Add an indestructible border around the terrain</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="92"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="87"/>
<source>Lower gravity</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="97"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="91"/>
<source>Assisted aiming with laser sight</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="102"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="95"/>
<source>All hogs have a personal forcefield</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="107"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="99"/>
<source>All (living) hedgehogs are fully restored at the end of turn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="112"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="103"/>
<source>Gain 80% of the damage you do back in health</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="117"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="107"/>
<source>Share your opponents pain, share their damage</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="122"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="111"/>
<source>Your hogs are unable to move, put your artillery skills to the test</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="127"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="115"/>
<source>Order of play is random instead of in room order.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="132"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="119"/>
<source>Play with a King. If he dies, your side dies.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="137"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="123"/>
<source>Take turns placing your hedgehogs before the start of play.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="142"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="127"/>
<source>Ammo is shared between all teams that share a colour.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="147"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="131"/>
<source>Disable girders when generating random maps.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="152"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="135"/>
<source>Disable land objects when generating random maps.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="157"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="139"/>
<source>AI respawns on death.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="162"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="143"/>
<source>Attacking does not end your turn.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="167"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="147"/>
<source>Weapons are reset to starting values each turn.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="172"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="151"/>
<source>Each hedgehog has its own ammo. It does not share with the team.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="177"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="155"/>
<source>You will not have to worry about wind anymore.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="182"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="159"/>
<source>Wind will affect almost everything.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="187"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="163"/>
<source>Teams in each clan take successive turns sharing their turn time.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="192"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="167"/>
<source>Add an indestructible border along the bottom</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="350"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="325"/>
<source>Random</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="351"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="326"/>
<source>Seconds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="427"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="402"/>
<source>Copy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="428"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="403"/>
<source>New</source>
<translation>æ°æ¸¸æ</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="429"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="404"/>
<source>Delete</source>
<translation>å é¤</translation>
</message>
@@ -1383,60 +1705,34 @@ Please pick another nickname:</source>
<name>PageSinglePlayer</name>
<message>
<location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="39"/>
- <source>Simple Game</source>
- <translation type="unfinished">ç®å游æ</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="40"/>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="42"/>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="49"/>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="50"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="47"/>
<source>Campaign Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="54"/>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="51"/>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="67"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="62"/>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="70"/>
- <source>Load</source>
- <translation type="unfinished">读å</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="71"/>
+ <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="65"/>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="43"/>
- <source>Multiplayer</source>
- <translation type="unfinished">å¤äººæ¸¸æ</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagesingleplayer.cpp" line="66"/>
- <source>Demos</source>
- <translation type="unfinished">Demo</translation>
- </message>
</context>
<context>
<name>PageTraining</name>
@@ -1451,12 +1747,12 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="211"/>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="206"/>
<source>No description available</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="219"/>
+ <location filename="../../../../QTfrontend/ui/page/pagetraining.cpp" line="214"/>
<source>Select a mission!</source>
<translation type="unfinished"></translation>
</message>
@@ -1464,44 +1760,46 @@ Please pick another nickname:</source>
<context>
<name>PageVideos</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="233"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="121"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="234"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="122"/>
<source>Size</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="492"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="263"/>
<source>%1 bytes</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="736"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="507"/>
<source>(in progress...)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="740"/>
- <source>Date: </source>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="511"/>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="741"/>
- <source>Size: </source>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="512"/>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="955"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="731"/>
<source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="957"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="733"/>
<source>uploading</source>
<translation type="unfinished"></translation>
</message>
@@ -1509,133 +1807,149 @@ Please pick another nickname:</source>
<context>
<name>QAction</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="257"/>
<source>Kick</source>
<translation>踢</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="82"/>
<source>Update</source>
- <translation type="unfinished">æ´æ°</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="90"/>
- <source>Start</source>
- <translation>å¼å§</translation>
+ <translation type="obsolete">æ´æ°</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="112"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="169"/>
<source>Restrict Joins</source>
<translation>éå¶åä¸</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="114"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="171"/>
<source>Restrict Team Additions</source>
<translation>éå¶å¢éæ件</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="248"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="173"/>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="253"/>
<source>Info</source>
<translation>ä¿¡æ¯</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="256"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="261"/>
<source>Ban</source>
<translation>å±è½</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="260"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="265"/>
<source>Follow</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="264"/>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="865"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="269"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="885"/>
<source>Ignore</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="268"/>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="877"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="273"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="897"/>
<source>Add friend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="860"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="880"/>
<source>Unignore</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="872"/>
+ <location filename="../../../../QTfrontend/ui/widget/chatwidget.cpp" line="892"/>
<source>Remove friend</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="162"/>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="165"/>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QCheckBox</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="349"/>
- <source>Enable sound</source>
- <translation>å¼å¯é³æ</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="291"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="377"/>
<source>Fullscreen</source>
<translation>游æå
¨å±å¹</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="424"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="349"/>
<source>Show FPS</source>
<translation>æ¾ç¤ºå¸§ç (FPS)</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="365"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="360"/>
<source>Alternative damage show</source>
<translation>å¦ä¸ç§ä¼¤å®³æ¾ç¤ºæ¹å¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="241"/>
- <source>Check for updates at startup</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="383"/>
+ <source>Visual effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="265"/>
- <source>Frontend effects</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="456"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="473"/>
+ <source>Sound</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="269"/>
- <source>Enable frontend sounds</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="457"/>
+ <source>In-game sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="273"/>
- <source>Enable frontend music</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="463"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="478"/>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="353"/>
- <source>Enable music</source>
- <translation>å¼å¯é³ä¹</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="464"/>
+ <source>In-game music</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="431"/>
- <source>Show ammo menu tooltips</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="474"/>
+ <source>Frontend sound effects</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="479"/>
+ <source>Frontend music</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="630"/>
+ <source>Check for updates at startup</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="261"/>
- <source>Frontend fullscreen</source>
- <translation>çé¢å
¨å±å¹</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="366"/>
+ <source>Show ammo menu tooltips</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="436"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="610"/>
<source>Append date and time to record file name</source>
<translation>è®°å½å称ä¸å
å«å
·ä½æ¶é´æ¥æ</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="43"/>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="231"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_password.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="509"/>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1650,12 +1964,12 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="151"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="691"/>
<source>Record audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="192"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="740"/>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
@@ -1663,202 +1977,126 @@ Please pick another nickname:</source>
<context>
<name>QComboBox</name>
<message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="50"/>
- <source>generated map...</source>
- <translation>çæå°å¾...</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="52"/>
- <source>generated maze...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="54"/>
- <source>hand drawn map...</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/model/MapModel.cpp" line="116"/>
- <source>Mission</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="115"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="122"/>
<source>Human</source>
<translation>ç©å®¶</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="323"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="284"/>
<source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="119"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="126"/>
<source>Level</source>
<translation>Lv 级å«</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="199"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="590"/>
<source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="312"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="313"/>
<source>Disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="313"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="314"/>
<source>Red/Cyan</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="314"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="315"/>
<source>Cyan/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="315"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="316"/>
<source>Red/Blue</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="316"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="317"/>
<source>Blue/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="317"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="318"/>
<source>Red/Green</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="318"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="319"/>
<source>Green/Red</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="319"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="326"/>
<source>Side-by-side</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="320"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="327"/>
<source>Top-Bottom</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="321"/>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="322"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="320"/>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="323"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="321"/>
<source>Cyan/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="324"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="322"/>
<source>Red/Blue grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="323"/>
<source>Blue/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="326"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="324"/>
<source>Red/Green grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="327"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="325"/>
<source>Green/Red grayscale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="111"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="112"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="176"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="211"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="286"/>
<source>Any</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="113"/>
- <source>In lobby</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="114"/>
- <source>In progress</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QGroupBox</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="60"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="61"/>
<source>Team Members</source>
<translation>æå</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="89"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="96"/>
<source>Team Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="143"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="150"/>
<source>Fort</source>
<translation>åå ¡æ¨¡å¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="162"/>
- <source>Key binds</source>
- <translation>é®ä½ç»å®</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="69"/>
- <source>Teams</source>
- <translation>éä¼</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="116"/>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="184"/>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="253"/>
- <source>Audio/Graphic options</source>
- <translation>é³é¢/è§é¢é项</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="381"/>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="412"/>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="448"/>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="253"/>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="259"/>
<source>Playing teams</source>
<translation>ç©å®¶éä¼</translation>
</message>
@@ -1878,17 +2116,12 @@ Please pick another nickname:</source>
<translation>åºæ¬è®¾ç½®</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="120"/>
- <source>Video recording options</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="230"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="118"/>
<source>Videos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="265"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="154"/>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1896,18 +2129,22 @@ Please pick another nickname:</source>
<context>
<name>QLabel</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="189"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="584"/>
<source>Locale</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="221"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="498"/>
<source>Nickname</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="283"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="172"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="599"/>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="716"/>
<source>Resolution</source>
<translation>å辨ç</translation>
</message>
@@ -1917,167 +2154,155 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="308"/>
- <source>Stereo rendering</source>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="250"/>
+ <source>Fullscreen</source>
+ <translation type="unfinished">游æå
¨å±å¹</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="418"/>
- <source>FPS limit</source>
- <translation>FPS ä¸é</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="255"/>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="55"/>
- <source>This program is distributed under the GNU General Public License v2</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="265"/>
+ <source>Windowed Resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="70"/>
- <source>Developers:</source>
- <translation>å¼åè
:</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="309"/>
+ <source>Stereo rendering</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="90"/>
- <source>Art:</source>
- <translation>èºæ¯:</translation>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="340"/>
+ <source>FPS limit</source>
+ <translation>FPS ä¸é</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="118"/>
- <source>Translations:</source>
- <translation>ç¿»è¯:</translation>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="71"/>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="142"/>
- <source>Special thanks:</source>
- <translation>ç¹å«æè°¢:</translation>
+ <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="73"/>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="51"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="56"/>
<source>Server name:</source>
<translation>æå¡å¨å:</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="58"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="63"/>
<source>Server port:</source>
<translation>æå¡å¨ç«¯å£:</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="33"/>
<source>Host:</source>
<translation>主æº:</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="36"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="37"/>
<source>Port:</source>
<translation>端å£:</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="148"/>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="86"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="139"/>
<source>Weapons</source>
<translation>æ¦å¨</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="53"/>
<source>Version</source>
- <translation>çæ¬</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/widget/about.cpp" line="108"/>
- <source>Sounds:</source>
- <translation>声é³:</translation>
+ <translation type="obsolete">çæ¬</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="340"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="439"/>
<source>Initial sound volume</source>
<translation>åå§é³é</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="200"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="175"/>
<source>Damage Modifier</source>
<translation>伤害修æ¹</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="214"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="189"/>
<source>Turn Time</source>
<translation>ååæ¶é´</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="228"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="203"/>
<source>Initial Health</source>
<translation>åå§çå½å¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="242"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="217"/>
<source>Sudden Death Timeout</source>
<translation>æ»äº¡æ¨¡å¼å计æ¶</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="256"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="231"/>
<source>Sudden Death Water Rise</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="270"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="245"/>
<source>Sudden Death Health Decrease</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="284"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="259"/>
<source>% Rope Length</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="311"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="286"/>
<source>% Health Crates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="300"/>
<source>Health in Crates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="339"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="314"/>
<source>Mines Time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="355"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="330"/>
<source>Mines</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="369"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="344"/>
<source>% Dud Mines</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="383"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="358"/>
<source>Explosives</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="397"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="372"/>
<source>% Get Away Time</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="411"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="386"/>
<source>Scheme Name:</source>
<translation>设置å称ï¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="298"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="273"/>
<source>Crate Drops</source>
<translation>ç®±åéè½</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="120"/>
- <source>Game scheme</source>
- <translation>游æ设置</translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="38"/>
<source>There are videos that are currently being processed.
Exiting now will abort them.
@@ -2115,82 +2340,97 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="93"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="100"/>
<source>Name</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="96"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="103"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="99"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="106"/>
<source>Grave</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="102"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="109"/>
<source>Flag</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="105"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="112"/>
<source>Voice</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagefeedback.cpp" line="45"/>
- <source>Summary </source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="103"/>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="111"/>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="121"/>
+ <source>Send system information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagefeedback.cpp" line="52"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="136"/>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="116"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="164"/>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="139"/>
<source>Tip: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="120"/>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
+ <location filename="../../../../QTfrontend/ui/page/pagemain.cpp" line="137"/>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="125"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="660"/>
<source>Format</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="142"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="680"/>
<source>Audio codec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="163"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="705"/>
<source>Video codec</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="197"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="746"/>
<source>Framerate</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="208"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="760"/>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="55"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="108"/>
<source>Style</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="74"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="127"/>
<source>Scheme</source>
<translation type="unfinished"></translation>
</message>
@@ -2198,18 +2438,18 @@ Do you really want to quit?</source>
<context>
<name>QLineEdit</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="882"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="952"/>
<source>unnamed</source>
<translation>æ å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/team.cpp" line="42"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="335"/>
+ <location filename="../../../../QTfrontend/team.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="296"/>
<source>hedgehog %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="226"/>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="503"/>
<source>anonymous</source>
<translation type="unfinished"></translation>
</message>
@@ -2217,96 +2457,116 @@ Do you really want to quit?</source>
<context>
<name>QMainWindow</name>
<message>
- <location filename="../../../../QTfrontend/ui_hwform.cpp" line="59"/>
+ <location filename="../../../../QTfrontend/ui_hwform.cpp" line="57"/>
<source>Hedgewars %1</source>
<translation>åºç¬å¤§ä½æ %1</translation>
</message>
+ <message>
+ <location filename="../../../../QTfrontend/ui_hwform.cpp" line="59"/>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="276"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="367"/>
<source>Error</source>
<translation>é误</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="277"/>
+ <location filename="../../../../QTfrontend/ui/widget/gamecfgwidget.cpp" line="368"/>
<source>Cannot use the ammo '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="904"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="388"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="346"/>
<source>Teams - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="905"/>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="389"/>
+ <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="347"/>
<source>Do you really want to delete the team '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="921"/>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="525"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="981"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="500"/>
<source>Cannot delete default scheme '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="947"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1007"/>
<source>Please select a record from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1241"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1102"/>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1498"/>
<source>Unable to start server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1285"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1559"/>
<source>Connection to server is lost</source>
<translation>æå¡å¨è¿æ¥ä¸¢å¤±</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1392"/>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2082"/>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="2083"/>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="352"/>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="24"/>
<source>Hedgewars - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1692"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1783"/>
- <source>Hedgewars - Success</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="362"/>
+ <source>System Information Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1693"/>
- <source>All file associations have been set</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="377"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="388"/>
+ <source>Failed to generate captcha</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1784"/>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="405"/>
+ <source>Failed to download captcha</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1796"/>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1809"/>
- <source>Error during authentication at google.com</source>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="469"/>
+ <source>Please fill out all fields. Email is optional.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1812"/>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1985"/>
+ <location filename="../../../../QTfrontend/ui/widget/feedbackdialog.cpp" line="439"/>
+ <source>Hedgewars - Success</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1698"/>
- <source>File association failed.</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1986"/>
+ <source>All file associations have been set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1734"/>
- <source>Please fill out all fields</source>
+ <location filename="../../../../QTfrontend/hwform.cpp" line="1991"/>
+ <source>File association failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2333,59 +2593,18 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/main.cpp" line="96"/>
- <location filename="../../../../QTfrontend/main.cpp" line="212"/>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/main.cpp" line="97"/>
- <source>Cannot create directory %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/main.cpp" line="213"/>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="50"/>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="122"/>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="51"/>
- <source>Unable to start the server: %1.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="123"/>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="124"/>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="113"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="162"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="118"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="244"/>
<source>Netgame - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="114"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="119"/>
<source>Please select a server from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="163"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="431"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="245"/>
<source>Please enter room name</source>
<translation type="unfinished"></translation>
</message>
@@ -2414,69 +2633,69 @@ Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="430"/>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="445"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="560"/>
<source>Room Name - Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="446"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="561"/>
<source>Please select room from the list</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="479"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="596"/>
<source>Room Name - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="480"/>
+ <location filename="../../../../QTfrontend/ui/page/pageroomslist.cpp" line="597"/>
<source>The game you are trying to join has started.
Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="524"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="499"/>
<source>Schemes - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="533"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="508"/>
<source>Schemes - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="534"/>
+ <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="509"/>
<source>Do you really want to delete the game scheme '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="844"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="868"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="1093"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="615"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="644"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="869"/>
<source>Videos - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="845"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="616"/>
<source>Do you really want to delete the video '%1'?</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="869"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="645"/>
<source>Do you really want to remove %1 file(s)?</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="1094"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="870"/>
<source>Do you really want to cancel uploading %1?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="101"/>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="121"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="896"/>
<source>File error</source>
<translation type="unfinished"></translation>
</message>
@@ -2487,58 +2706,50 @@ Do you still want to join the room?</source>
</message>
<message>
<location filename="../../../../QTfrontend/ui/widget/drawmapwidget.cpp" line="122"/>
+ <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="897"/>
<source>Cannot open '%1' for reading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="199"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="254"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="229"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="266"/>
<source>Weapons - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="200"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="230"/>
<source>Cannot overwrite default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="255"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="267"/>
<source>Cannot delete default weapon set '%1'!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="263"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="275"/>
<source>Weapons - Are you sure?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="264"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="276"/>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1203"/>
- <source>Nickname</source>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="32"/>
+ <source>Hedgewars - Warning</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/hwform.cpp" line="1204"/>
- <source>Please enter your nickname</source>
+ <location filename="../../../../QTfrontend/util/MessageDialog.cpp" line="40"/>
+ <source>Hedgewars - Information</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagemultiplayer.cpp" line="40"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="51"/>
- <source>Setup</source>
- <translation>设置</translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="45"/>
<location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="87"/>
<source>Play demo</source>
@@ -2556,11 +2767,36 @@ Do you still want to join the room?</source>
<translation>ä¸åºï¼</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="77"/>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="73"/>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="74"/>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="78"/>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="79"/>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="99"/>
<source>Start</source>
<translation>å¼å§</translation>
</message>
<message>
+ <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="100"/>
+ <source>Start private server</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<location filename="../../../../QTfrontend/ui/page/pagenet.cpp" line="73"/>
<source>Start server</source>
<translation>å¼å§æå¡ç«¯</translation>
@@ -2581,8 +2817,7 @@ Do you still want to join the room?</source>
<translation>æå®</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="48"/>
- <location filename="../../../../QTfrontend/ui/page/pagenetserver.cpp" line="67"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="49"/>
<source>default</source>
<translation>é»è®¤</translation>
</message>
@@ -2592,72 +2827,101 @@ Do you still want to join the room?</source>
<translation>éå½å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="52"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="53"/>
<source>OK</source>
<translation>ç¡®å®</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="57"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="729"/>
+ <location filename="../../../../QTfrontend/ui/dialog/input_ip.cpp" line="58"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
<source>Cancel</source>
<translation>åæ¶</translation>
</message>
<message>
<location filename="../../../../QTfrontend/ui/page/pageplayrecord.cpp" line="53"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="300"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="729"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="190"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="500"/>
<source>Delete</source>
<translation>å é¤</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagenetgame.cpp" line="75"/>
- <source>Ready</source>
- <translation>åå¤å¥½äº</translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/ui/dialog/ask_quit.cpp" line="50"/>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageeditteam.cpp" line="84"/>
- <source>Random Team</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="616"/>
+ <source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="440"/>
- <source>Associate file extensions</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="773"/>
+ <source>Set default options</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="219"/>
- <source>Set default options</source>
+ <location filename="../../../../QTfrontend/ui/page/pageoptions.cpp" line="774"/>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="252"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="140"/>
<source>Open videos directory</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="297"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="141"/>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="186"/>
<source>Play</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="303"/>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="730"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="188"/>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="192"/>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="194"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="877"/>
<source>Upload to YouTube</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="730"/>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="196"/>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/page/pagevideos.cpp" line="501"/>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomNamePrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="42"/>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
+ </message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/mapContainer.cpp" line="170"/>
- <source>more</source>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="61"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/roomnameprompt.cpp" line="62"/>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2704,22 +2968,45 @@ Do you still want to join the room?</source>
<translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="131"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="132"/>
<source>Random Map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="132"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="133"/>
<source>Random Maze</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="133"/>
+ <location filename="../../../../QTfrontend/model/roomslistmodel.cpp" line="134"/>
<source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>SeedPrompt</name>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="42"/>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="61"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="62"/>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/ui/widget/seedprompt.cpp" line="76"/>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SelWeaponWidget</name>
<message>
<location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="119"/>
@@ -2742,143 +3029,63 @@ Do you still want to join the room?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="277"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="282"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="289"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="294"/>
<source>new</source>
<translation type="unfinished">æ°</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="313"/>
- <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="318"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="325"/>
+ <location filename="../../../../QTfrontend/ui/widget/selectWeapon.cpp" line="330"/>
<source>copy of</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>ToggleButtonWidget</name>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="71"/>
- <source>Fort Mode</source>
- <translation>åå ¡æ¨¡å¼</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="76"/>
- <source>Divide Teams</source>
- <translation>å¢ä½è¡å¨</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="81"/>
- <source>Solid Land</source>
- <translation>åºå®å°é¢</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="86"/>
- <source>Add Border</source>
- <translation>æ·»å è¾¹ç</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="91"/>
- <source>Low Gravity</source>
- <translation>ä½éå</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="96"/>
- <source>Laser Sight</source>
- <translation>æ¿å
çå</translation>
- </message>
+ <name>TCPBase</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="101"/>
- <source>Invulnerable</source>
- <translation>åæªä¸å
¥</translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="106"/>
- <source>Reset Health</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="111"/>
- <source>Vampirism</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="116"/>
- <source>Karma</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="121"/>
- <source>Artillery</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="126"/>
- <source>Random Order</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="131"/>
- <source>King</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="136"/>
- <source>Place Hedgehogs</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="141"/>
- <source>Clan Shares Ammo</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="146"/>
- <source>Disable Girders</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="151"/>
- <source>Disable Land Objects</source>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="91"/>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="156"/>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="161"/>
- <source>Unlimited Attacks</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="166"/>
- <source>Reset Weapons</source>
+ <location filename="../../../../QTfrontend/net/tcpBase.cpp" line="168"/>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="171"/>
- <source>Per Hedgehog Ammo</source>
+ <location filename="../../../../QTfrontend/ui/widget/teamselect.cpp" line="264"/>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="176"/>
- <source>Disable Wind</source>
+ <location filename="../../../../QTfrontend/ui/widget/teamselhelper.cpp" line="58"/>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="181"/>
- <source>More Wind</source>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="84"/>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="186"/>
- <source>Tag Team</source>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="120"/>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/ui/page/pagescheme.cpp" line="191"/>
- <source>Add Bottom Border</source>
+ <location filename="../../../../QTfrontend/ui/widget/themeprompt.cpp" line="124"/>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2909,87 +3116,87 @@ Do you still want to join the room?</source>
<translation>ä¸</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
<source>attack</source>
<translation>æ»å»</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
<source>put</source>
<translation>æ¾</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
<source>switch</source>
<translation>åæ¢</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="34"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
<source>slot 1</source>
<translation>slot 1</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="35"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
<source>slot 2</source>
<translation>slot 2</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="36"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="34"/>
<source>slot 3</source>
<translation>slot 3</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="37"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="35"/>
<source>slot 4</source>
<translation>slot 4</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="38"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="36"/>
<source>slot 5</source>
<translation>slot 5</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="39"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="37"/>
<source>slot 6</source>
<translation>slot 6</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="40"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="38"/>
<source>slot 7</source>
<translation>slot 7</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="41"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="39"/>
<source>slot 8</source>
<translation>slot 8</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="43"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="41"/>
<source>slot 10</source>
<translation type="unfinished">slot 10</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
<source>timer 1 sec</source>
<translation>å®æ¶1ç§</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="45"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="43"/>
<source>timer 2 sec</source>
<translation>å®æ¶2ç§</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="46"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
<source>timer 3 sec</source>
<translation>å®æ¶3ç§</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="45"/>
<source>timer 4 sec</source>
<translation>å®æ¶4ç§</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="46"/>
<source>timer 5 sec</source>
<translation>å®æ¶5ç§</translation>
</message>
@@ -3019,7 +3226,12 @@ Do you still want to join the room?</source>
<translation>夺å</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="69"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="68"/>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
<source>record</source>
<translation type="unfinished"></translation>
</message>
@@ -3034,7 +3246,7 @@ Do you still want to join the room?</source>
<translation>æ¾å° åºç¬</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
<source>ammo menu</source>
<translation>å¼¹è¯èå</translation>
</message>
@@ -3069,18 +3281,11 @@ Do you still want to join the room?</source>
<translation>æå</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="40"/>
<source>slot 9</source>
<translation>slot 9</translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="68"/>
- <source>hedgehogs
-info</source>
- <translation>åºç¬å¤§ä½æ
-ä¿¡æ¯</translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/binds.cpp" line="58"/>
<source>chat</source>
<translation>è天</translation>
@@ -3105,59 +3310,59 @@ info</source>
<name>binds (categories)</name>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="23"/>
- <source>Basic controls</source>
+ <source>Movement</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
- <source>Weapon controls</source>
- <translation type="unfinished"></translation>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="49"/>
- <source>Camera and cursor controls</source>
+ <source>Camera</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../../../QTfrontend/binds.cpp" line="58"/>
- <source>Other</source>
- <translation type="unfinished">å
¶ä»</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../../../../QTfrontend/binds.cpp" line="28"/>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="47"/>
<source>Fire your selected weapon or trigger an utility item:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="48"/>
<source>Pick a weapon or a target location under the cursor:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="32"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="30"/>
<source>Switch your currently active hog (if possible):</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="33"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="23"/>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../../../../QTfrontend/binds.cpp" line="31"/>
<source>Pick a weapon or utility item:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="44"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="42"/>
<source>Set the timer on bombs and timed weapons:</source>
<translation type="unfinished"></translation>
</message>
@@ -3207,7 +3412,7 @@ info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/binds.cpp" line="69"/>
+ <location filename="../../../../QTfrontend/binds.cpp" line="70"/>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
@@ -3570,44 +3775,44 @@ info</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/DataManager.cpp" line="193"/>
+ <location filename="../../../../QTfrontend/util/DataManager.cpp" line="158"/>
<source>Keyboard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="129"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="133"/>
<source>Axis</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="133"/>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="148"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="137"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="152"/>
<source>(Up)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="137"/>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="152"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="141"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="156"/>
<source>(Down)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="144"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="148"/>
<source>Hat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="156"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="160"/>
<source>(Left)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="160"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="164"/>
<source>(Right)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="168"/>
+ <location filename="../../../../QTfrontend/util/SDLInteraction.cpp" line="172"/>
<source>Button</source>
<translation type="unfinished"></translation>
</message>
diff --git a/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts b/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts
index fdb50c6..9025d18 100644
--- a/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts
+++ b/share/hedgewars/Data/Locale/hedgewars_zh_TW.ts
@@ -2,6 +2,13 @@
<!DOCTYPE TS>
<TS version="2.0" language="zh_TW">
<context>
+ <name>About</name>
+ <message>
+ <source>Unknown Compiler</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>AbstractPage</name>
<message>
<source>Go back</source>
@@ -20,6 +27,95 @@
</message>
</context>
<context>
+ <name>BanDialog</name>
+ <message>
+ <source>IP</source>
+ <translation type="unfinished">IP</translation>
+ </message>
+ <message>
+ <source>Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ok</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <source>you know why</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please, specify %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>permanent</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>DataManager</name>
+ <message>
+ <source>Use Default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>FeedbackDialog</name>
+ <message>
+ <source>View</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <source>Send Feedback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>We are always happy about suggestions, ideas, or bug reports.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send us feedback!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>If you found a bug, you can see if it's already been reported here: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your email address is optional, but necessary if you want us to get back at you.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FreqSpinBox</name>
<message>
<source>Never</source>
@@ -43,11 +139,63 @@
<translation type="unfinished">ä¿®æ¹éæ²è¨ç½®</translation>
</message>
<message>
- <source>When this option is enabled selecting a game scheme will auto-select a weapon</source>
+ <source>Game scheme will auto-select a weapon</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map</source>
+ <translation type="unfinished">å°å</translation>
+ </message>
+ <message>
+ <source>Game options</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HWApplication</name>
+ <message numerus="yes">
+ <source>%1 minutes</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hour</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 hours</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 day</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1 days</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Scheme '%1' not supported</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Game Options</source>
+ <source>Cannot create directory %1</source>
+ <translation type="unfinished">ç¡æ³åµå»ºè·¯å¾ %1</translation>
+ </message>
+ <message>
+ <source>Failed to open data directory:
+%1
+
+Please check your installation!</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -101,7 +249,15 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>%1 is not a valid command!</source>
+ <source>%1 has joined</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 has left (%2)</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -138,27 +294,73 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Your nickname %1 is
-registered on Hedgewars.org
-Please provide your password below
-or pick another nickname in game config:</source>
+ <source>Nickname</source>
+ <translation type="unfinished">å¿ç¨±</translation>
+ </message>
+ <message>
+ <source>No nickname supplied.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No password supplied.</source>
+ <source>Someone already uses your nickname %1 on the server.
+Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Nickname</source>
- <translation type="unfinished">å¿ç¨±</translation>
+ <source>%1's Team</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>No nickname supplied.</source>
+ <source>Hedgewars - Nick registered</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Someone already uses your nickname %1 on the server.
-Please pick another nickname:</source>
+ <source>This nick is registered, and you haven't specified a password.
+
+If this nick isn't yours, please register your own nick at www.hedgewars.org
+
+Password:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your nickname is not registered.
+To prevent someone else from using it,
+please register it at www.hedgewars.org</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>
+
+Your password wasn't saved either.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Empty nickname</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Wrong password</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You entered a wrong password.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Try Again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Connection error</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You reconnected too fast.
+Please wait a few seconds and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -176,14 +378,6 @@ Please pick another nickname:</source>
<context>
<name>HWMapContainer</name>
<message>
- <source>Map</source>
- <translation>å°å</translation>
- </message>
- <message>
- <source>Filter</source>
- <translation>é濾</translation>
- </message>
- <message>
<source>All</source>
<translation>å
¨é¨</translation>
</message>
@@ -208,43 +402,103 @@ Please pick another nickname:</source>
<translation>æ²æ</translation>
</message>
<message>
- <source>Themes</source>
- <translation>主é¡</translation>
+ <source>Small tunnels</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Type</source>
+ <source>Medium tunnels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small tunnels</source>
+ <source>Seed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium tunnels</source>
+ <source>Map type:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large tunnels</source>
+ <source>Image map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Small floating islands</source>
+ <source>Mission map</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Medium floating islands</source>
+ <source>Hand-drawn</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Large floating islands</source>
+ <source>Randomly generated</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Seed</source>
+ <source>Random maze</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random</source>
+ <translation type="unfinished">é¨æ©</translation>
+ </message>
+ <message>
+ <source>Map preview:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Edit map drawing</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Small islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Medium islands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Set</source>
+ <source>Large islands</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map size:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maze style:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Mission:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Map:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Load drawn map</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Drawn Maps</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Large tunnels</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Theme: %1</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -291,7 +545,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>%1 *** %2 has joined</source>
- <translation>%1***%2å·²ç¶é²å
¥</translation>
+ <translation type="obsolete">%1***%2å·²ç¶é²å
¥</translation>
</message>
<message>
<source>%1 *** %2 has left (%3)</source>
@@ -317,8 +571,23 @@ Please pick another nickname:</source>
<context>
<name>HWPasswordDialog</name>
<message>
- <source>Password</source>
- <translation type="unfinished">å¯ç¢¼</translation>
+ <source>Login</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>To connect to the server, please log in.
+
+If you don't have an account on www.hedgewars.org,
+just enter your nickname.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Nickname:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Password:</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -333,6 +602,28 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>HatButton</name>
+ <message>
+ <source>Change hat (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>HatPrompt</name>
+ <message>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
+ </message>
+ <message>
+ <source>Use selected hat</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Search for a hat:</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>KB</name>
<message>
<source>SDL_ttf returned error while rendering text, most propably it is related to the bug in freetype2. It's recommended to update your freetype lib.</source>
@@ -340,7 +631,14 @@ Please pick another nickname:</source>
</message>
</context>
<context>
- <name>LibavIteraction</name>
+ <name>KeyBinder</name>
+ <message>
+ <source>Category</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>LibavInteraction</name>
<message>
<source>Duration: %1m %2s
</source>
@@ -358,6 +656,17 @@ Please pick another nickname:</source>
<source>Audio: </source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>unknown</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MapModel</name>
+ <message>
+ <source>No description available.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageAdmin</name>
@@ -389,6 +698,38 @@ Please pick another nickname:</source>
<source>Set data</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>General</source>
+ <translation type="unfinished">常è¦</translation>
+ </message>
+ <message>
+ <source>Bans</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>IP/Nick</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Expiration</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reason</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remove</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageConnecting</name>
@@ -398,6 +739,17 @@ Please pick another nickname:</source>
</message>
</context>
<context>
+ <name>PageDataDownload</name>
+ <message>
+ <source>Loading, please wait.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This page requires an internet connection.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>PageDrawMap</name>
<message>
<source>Undo</source>
@@ -443,8 +795,40 @@ Please pick another nickname:</source>
<translation>常è¦</translation>
</message>
<message>
- <source>Advanced</source>
- <translation>é²é</translation>
+ <source>Select an action to choose a custom key bind for this team</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Use my default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Reset all binds</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Custom Controls</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hat</source>
+ <translation type="unfinished">帽å</translation>
+ </message>
+ <message>
+ <source>Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Randomize this hedgehog's name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Random Team</source>
+ <translation type="unfinished">é¨æ©éä¼åé
</translation>
</message>
</context>
<context>
@@ -501,6 +885,14 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Play again</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageInGame</name>
@@ -519,420 +911,275 @@ Please pick another nickname:</source>
<context>
<name>PageMain</name>
<message>
- <source>Simply pick the same color as a friend to play together as a team. Each of you will still control his or her own hedgehogs but they'll win or lose together.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Some weapons might do only low damage but they can be a lot more devastating in the right situation. Try to use the Desert Eagle to knock multiple hedgehogs into the water.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you're unsure what to do and don't want to waste ammo, skip one round. But don't let too much time pass as there will be Sudden Death!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If you'd like to keep others from using your preferred nickname on the official server, register an account at http://www.hedgewars.org/.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You're bored of default gameplay? Try one of the missions - they'll offer different gameplay depending on the one you picked.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>By default the game will always record the last game played as a demo. Select 'Local Game' and pick the 'Demos' button on the lower right corner to play or manage them.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you've got problems, ask on our forums but please don't expect 24/7 support!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If you like it, help us with a small donation or contribute your own work!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. Share it with your family and friends as you like!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>From time to time there will be official tournaments. Upcoming events will be announced at http://www.hedgewars.org/ some days in advance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars is available in many languages. If the translation in your language seems to be missing or outdated, feel free to contact us!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Hedgewars can be run on lots of different operating systems including Microsoft Windows, Mac OS X and Linux.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Always remember you're able to set up your own games in local and network/online play. You're not restricted to the 'Simple Game' option.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>While playing you should give yourself a short break at least once an hour.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to enable the low quality mode to improve performance.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>We're open to suggestions and constructive feedback. If you don't like something or got a great idea, let us know!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Especially while playing online be polite and always remember there might be some minors playing with or against you as well!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Special game modes such as 'Vampirism' or 'Karma' allow you to develop completely new tactics. Try them in a custom game!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>You should never install Hedgewars on computers you don't own (school, university, work, etc.). Please ask the responsible person instead!</source>
- <comment>Tips</comment>
+ <source>Downloadable Content</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars can be perfect for short games during breaks. Just ensure you don't add too many hedgehogs or use an huge map. Reducing time and health might help as well.</source>
- <comment>Tips</comment>
+ <source>Play a game on a single computer</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No hedgehogs were harmed in making this game.</source>
- <comment>Tips</comment>
+ <source>Play a game across a network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hedgewars is Open Source and Freeware we create in our spare time. If someone sold you the game, you should try get a refund!</source>
- <comment>Tips</comment>
+ <source>Read about who is behind the Hedgewars Project</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Connect one or more gamepads before starting the game to be able to assign their controls to your teams.</source>
- <comment>Tips</comment>
+ <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Create an account on %1 to keep others from using your most favourite nickname while playing on the official server.</source>
- <comment>Tips</comment>
+ <source>Access the user created content downloadable from our website</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>If your graphics card isn't able to provide hardware accelerated OpenGL, try to update the associated drivers.</source>
- <comment>Tips</comment>
+ <source>Exit game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>There are three different jumps available. Tap [high jump] twice to do a very high/backwards jump.</source>
- <comment>Tips</comment>
+ <source>Manage videos recorded from game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Afraid of falling off a cliff? Hold down [precise] to turn [left] or [right] without actually moving.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Some weapons require special strategies or just lots of training, so don't give up on a particular tool if you miss an enemy once.</source>
- <comment>Tips</comment>
+ <source>Play a game across a local area network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Most weapons won't work once they touch the water. The Homing Bee as well as the Cake are exceptions to this.</source>
- <comment>Tips</comment>
+ <source>Play a game on an official server</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Old Limbuger only causes a small explosion. However the wind affected smelly cloud can poison lots of hogs at once.</source>
- <comment>Tips</comment>
+ <source>Feedback</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Piano Strike is the most damaging air strike. You'll lose the hedgehog performing it, so there's a huge downside as well.</source>
- <comment>Tips</comment>
+ <source>Play local network game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Sticky Mines are a perfect tool to create small chain reactions knocking enemy hedgehogs into dire situations ... or water.</source>
- <comment>Tips</comment>
+ <source>Play official network game</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageMultiplayer</name>
<message>
- <source>The Hammer is most effective when used on bridges or girders. Hit hogs will just break through the ground.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation>éå§</translation>
</message>
<message>
- <source>If you're stuck behind an enemy hedgehog, use the Hammer to free yourself without getting damaged by an explosion.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetGame</name>
<message>
- <source>The Cake's maximum walking distance depends on the ground it has to pass. Use [attack] to detonate it early.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Control</source>
+ <translation type="obsolete">æ¿é管ç</translation>
</message>
<message>
- <source>The Flame Thrower is a weapon but it can be used for tunnel digging as well.</source>
- <comment>Tips</comment>
+ <source>Edit game preferences</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Want to know who's behind the game? Click on the Hedgewars logo in the main menu to see the credits.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Start</source>
+ <translation type="unfinished">éå§</translation>
</message>
<message>
- <source>Like Hedgewars? Become a fan on %1 or follow us on %2!</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Update</source>
+ <translation type="unfinished">æ´æ°</translation>
</message>
<message>
- <source>Feel free to draw your own graves, hats, flags or even maps and themes! But note that you'll have to share them somewhere to use them online.</source>
- <comment>Tips</comment>
+ <source>Room controls</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageNetServer</name>
<message>
- <source>Really want to wear a specific hat? Donate to us and receive an exclusive hat of your choice!</source>
- <comment>Tips</comment>
+ <source>Click here for details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Keep your video card drivers up to date to avoid issues playing the game.</source>
- <comment>Tips</comment>
+ <source>Insert your address here</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>PageOptions</name>
<message>
- <source>You can find your Hedgewars configuration files under "My Documents\Hedgewars". Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>New team</source>
+ <translation>æ°éä¼</translation>
</message>
<message>
- <source>You're able to associate Hedgewars related files (savegames and demo recordings) with the game to launch them right from your favorite file or internet browser.</source>
- <comment>Tips</comment>
- <translation type="unfinished"></translation>
+ <source>Edit team</source>
+ <translation>ä¿®æ¹éä¼è¨å®</translation>
</message>
<message>
- <source>Want to save ropes? Release the rope in mid air and then shoot again. As long as you don't touch the ground you'll reuse your rope without wasting ammo!</source>
- <comment>Tips</comment>
+ <source>Delete team</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under "Library/Application Support/Hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can find your Hedgewars configuration files under ".hedgewars" in your home directory. Create backups or take the files with you, but don't edit them by hand.</source>
- <comment>Tips</comment>
+ <source>New scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Windows version of Hedgewars supports Xfire. Make sure to add Hedgewars to its game list so your friends can see you playing.</source>
- <comment>Tips</comment>
+ <source>Edit scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Use the Molotov or Flame Thrower to temporary keep hedgehogs from passing terrain such as tunnels or platforms.</source>
- <comment>Tips</comment>
+ <source>Delete scheme</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>The Homing Bee can be tricky to use. Its turn radius depends on its velocity, so try to not use full power.</source>
- <comment>Tips</comment>
+ <source>New weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Edit weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Local Game</source>
+ <source>Delete weapon set</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game on a single computer</source>
- <translation type="unfinished"></translation>
+ <source>Advanced</source>
+ <translation type="unfinished">é²é</translation>
</message>
<message>
- <source>Network Game</source>
+ <source>Reset to default colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Play a game across a network</source>
+ <source>Proxy host</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Read about who is behind the Hedgewars Project</source>
+ <source>Proxy port</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Leave a feedback here reporting issues, suggesting features or just saying how you like Hedgewars</source>
+ <source>Proxy login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access the user created content downloadable from our website</source>
+ <source>Proxy password</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Exit game</source>
+ <source>No proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Manage videos recorded from game</source>
+ <source>Socks5 proxy</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit game preferences</source>
+ <source>HTTP proxy</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageMultiplayer</name>
- <message>
- <source>Start</source>
- <translation>éå§</translation>
- </message>
-</context>
-<context>
- <name>PageNetGame</name>
- <message>
- <source>Control</source>
- <translation>æ¿é管ç</translation>
- </message>
<message>
- <source>DLC</source>
+ <source>System proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Downloadable Content</source>
+ <source>Select an action to change what key controls it</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageNetType</name>
- <message>
- <source>LAN game</source>
- <translation>å±å網éæ²</translation>
- </message>
- <message>
- <source>Official server</source>
- <translation>å®æ¹ä¼ºæå¨</translation>
- </message>
<message>
- <source>Join hundreds of players online!</source>
+ <source>Reset to default</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Join or host your own game server in a Local Area Network.</source>
+ <source>Reset all binds</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>PageOptions</name>
- <message>
- <source>New team</source>
- <translation>æ°éä¼</translation>
- </message>
- <message>
- <source>Edit team</source>
- <translation>ä¿®æ¹éä¼è¨å®</translation>
- </message>
<message>
- <source>Delete team</source>
+ <source>Game</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>You can't edit teams from team selection. Go back to main menu to add, edit or delete teams.</source>
+ <source>Graphics</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New scheme</source>
+ <source>Audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit scheme</source>
+ <source>Controls</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Delete scheme</source>
+ <source>Video Recording</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>New weapon set</source>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Edit weapon set</source>
- <translation type="unfinished"></translation>
+ <source>Teams</source>
+ <translation type="unfinished">éä¼</translation>
</message>
<message>
- <source>Delete weapon set</source>
+ <source>Schemes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>General</source>
- <translation type="unfinished">常è¦</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Advanced</source>
- <translation type="unfinished">é²é</translation>
+ <source>Frontend</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Reset to default colors</source>
+ <source>Custom colors</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy host</source>
+ <source>Game audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy port</source>
+ <source>Frontend audio</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy login</source>
+ <source>Account</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Proxy password</source>
+ <source>Proxy settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>No proxy</source>
+ <source>Miscellaneous</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Socks5 proxy</source>
+ <source>Updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>HTTP proxy</source>
+ <source>Check for updates</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System proxy settings</source>
+ <source>Video recording options</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -951,11 +1198,11 @@ Please pick another nickname:</source>
<name>PageRoomsList</name>
<message>
<source>Create</source>
- <translation>建ç«</translation>
+ <translation type="obsolete">建ç«</translation>
</message>
<message>
<source>Join</source>
- <translation>å å
¥</translation>
+ <translation type="obsolete">å å
¥</translation>
</message>
<message>
<source>Admin features</source>
@@ -963,7 +1210,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Room Name:</source>
- <translation type="unfinished">æ¿éåï¼</translation>
+ <translation type="obsolete">æ¿éåï¼</translation>
</message>
<message>
<source>Rules:</source>
@@ -974,12 +1221,8 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Search:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Clear</source>
- <translation type="unfinished">æ¸
é¤</translation>
+ <translation type="obsolete">æ¸
é¤</translation>
</message>
<message numerus="yes">
<source>%1 players online</source>
@@ -987,6 +1230,30 @@ Please pick another nickname:</source>
<numerusform></numerusform>
</translation>
</message>
+ <message>
+ <source>Search for a room:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Create room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Join room</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Room state</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear filters</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open server administration page</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>PageScheme</name>
@@ -1133,18 +1400,10 @@ Please pick another nickname:</source>
<context>
<name>PageSinglePlayer</name>
<message>
- <source>Simple Game</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a quick game against the computer with random settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiplayer</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Play a hotseat game against your friends, or AI teams</source>
<translation type="unfinished"></translation>
</message>
@@ -1153,26 +1412,14 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Training Mode</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Practice your skills in a range of training missions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Demos</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Watch recorded demos</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Load</source>
- <translation type="unfinished">è®å</translation>
- </message>
- <message>
<source>Load a previously saved game</source>
<translation type="unfinished"></translation>
</message>
@@ -1217,19 +1464,21 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Date: </source>
+ <source>encoding</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Size: </source>
+ <source>uploading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>encoding</source>
+ <source>Date: %1
+</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>uploading</source>
+ <source>Size: %1
+</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -1244,10 +1493,6 @@ Please pick another nickname:</source>
<translation>ä¿¡æ¯</translation>
</message>
<message>
- <source>Start</source>
- <translation>éå§</translation>
- </message>
- <message>
<source>Restrict Joins</source>
<translation>éå¶åè</translation>
</message>
@@ -1281,16 +1526,24 @@ Please pick another nickname:</source>
</message>
<message>
<source>Update</source>
- <translation type="unfinished">æ´æ°</translation>
+ <translation type="obsolete">æ´æ°</translation>
+ </message>
+ <message>
+ <source>Restrict Unregistered Players Join</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in lobby</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Show games in-progress</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QCheckBox</name>
<message>
- <source>Enable sound</source>
- <translation type="unfinished">éåéæ²é³æ</translation>
- </message>
- <message>
<source>Fullscreen</source>
<translation>éæ²å
¨è¢å¹</translation>
</message>
@@ -1303,14 +1556,6 @@ Please pick another nickname:</source>
<translation>å¦ä¸ç¨®å·å®³é¡¯ç¤ºæ¹å¼</translation>
</message>
<message>
- <source>Frontend fullscreen</source>
- <translation>ä»é¢å
¨è¢å¹</translation>
- </message>
- <message>
- <source>Enable music</source>
- <translation type="unfinished">éåéæ²é³æ¨</translation>
- </message>
- <message>
<source>Append date and time to record file name</source>
<translation>è¨éå稱ä¸å
å«å
·é«æéæ¥æ</translation>
</message>
@@ -1323,18 +1568,6 @@ Please pick another nickname:</source>
<translation type="unfinished">顯示æ¦å¨æ示è¨æ¯</translation>
</message>
<message>
- <source>Enable frontend sounds</source>
- <translation type="unfinished">åç¨èå®é³æ</translation>
- </message>
- <message>
- <source>Enable frontend music</source>
- <translation type="unfinished">åç¨èå®é³æ¨</translation>
- </message>
- <message>
- <source>Frontend effects</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Save password</source>
<translation type="unfinished"></translation>
</message>
@@ -1354,51 +1587,55 @@ Please pick another nickname:</source>
<source>Use game resolution</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QComboBox</name>
<message>
- <source>generated map...</source>
- <translation>çæå°å...</translation>
+ <source>Visual effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Human</source>
- <translation>ç©å®¶</translation>
+ <source>Sound</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Level</source>
- <translation>Lv ç´å¥</translation>
+ <source>In-game sound effects</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>(System default)</source>
+ <source>Music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>generated maze...</source>
+ <source>In-game music</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Mission</source>
+ <source>Frontend sound effects</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Community</source>
+ <source>Frontend music</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>QComboBox</name>
<message>
- <source>Any</source>
- <translation type="unfinished"></translation>
+ <source>Human</source>
+ <translation>ç©å®¶</translation>
+ </message>
+ <message>
+ <source>Level</source>
+ <translation>Lv ç´å¥</translation>
</message>
<message>
- <source>In lobby</source>
+ <source>(System default)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>In progress</source>
+ <source>Community</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>hand drawn map...</source>
+ <source>Any</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1438,10 +1675,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Wiggle</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Red/Cyan grayscale</source>
<translation type="unfinished"></translation>
</message>
@@ -1477,18 +1710,6 @@ Please pick another nickname:</source>
<translation>åå ¡æ¨¡å¼</translation>
</message>
<message>
- <source>Key binds</source>
- <translation>éµä½ç¶å®</translation>
- </message>
- <message>
- <source>Teams</source>
- <translation>éä¼</translation>
- </message>
- <message>
- <source>Audio/Graphic options</source>
- <translation>é³è¨/è¦é »é¸é
</translation>
- </message>
- <message>
<source>Playing teams</source>
<translation>ç©å®¶éä¼</translation>
</message>
@@ -1498,34 +1719,14 @@ Please pick another nickname:</source>
</message>
<message>
<source>Game Modifiers</source>
- <translation>éæ²ä¿®æ¹</translation>
- </message>
- <message>
- <source>Basic Settings</source>
- <translation>åºæ¬è¨ç½®</translation>
- </message>
- <message>
- <source>Team Settings</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Misc</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Schemes and Weapons</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Custom colors</source>
- <translation type="unfinished"></translation>
+ <translation>éæ²ä¿®æ¹</translation>
</message>
<message>
- <source>Miscellaneous</source>
- <translation type="unfinished"></translation>
+ <source>Basic Settings</source>
+ <translation>åºæ¬è¨ç½®</translation>
</message>
<message>
- <source>Video recording options</source>
+ <source>Team Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1536,10 +1737,6 @@ Please pick another nickname:</source>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>Proxy settings</source>
- <translation type="unfinished"></translation>
- </message>
</context>
<context>
<name>QLabel</name>
@@ -1552,22 +1749,6 @@ Please pick another nickname:</source>
<translation>FPS ä¸é</translation>
</message>
<message>
- <source>Developers:</source>
- <translation>éç¼è
:</translation>
- </message>
- <message>
- <source>Art:</source>
- <translation>èè¡:</translation>
- </message>
- <message>
- <source>Translations:</source>
- <translation>ç¿»è¯:</translation>
- </message>
- <message>
- <source>Special thanks:</source>
- <translation>ç¹å¥æè¬:</translation>
- </message>
- <message>
<source>Server name:</source>
<translation>伺æå¨å:</translation>
</message>
@@ -1589,11 +1770,7 @@ Please pick another nickname:</source>
</message>
<message>
<source>Version</source>
- <translation>çæ¬</translation>
- </message>
- <message>
- <source>Sounds:</source>
- <translation>è²é³:</translation>
+ <translation type="obsolete">çæ¬</translation>
</message>
<message>
<source>Initial sound volume</source>
@@ -1624,10 +1801,6 @@ Please pick another nickname:</source>
<translation>ç®±åéè½</translation>
</message>
<message>
- <source>Game scheme</source>
- <translation>éæ²è¨ç½®</translation>
- </message>
- <message>
<source>Mines Time</source>
<translation>ä½é·æé</translation>
</message>
@@ -1672,10 +1845,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This development build is 'work in progress' and may not be compatible with other versions of the game. Some features might be broken or incomplete. Use at your own risk!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Quality</source>
<translation type="unfinished"></translation>
</message>
@@ -1716,10 +1885,6 @@ Please pick another nickname:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>This program is distributed under the GNU General Public License v2</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>There are videos that are currently being processed.
Exiting now will abort them.
Do you really want to quit?</source>
@@ -1750,10 +1915,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Summary </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Description</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,6 +1942,50 @@ Do you really want to quit?</source>
<source>Bitrate (Kbps)</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>This development build is 'work in progress' and may not be compatible with other versions of the game, while some features might be broken or incomplete!</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Fullscreen</source>
+ <translation type="unfinished">éæ²å
¨è¢å¹</translation>
+ </message>
+ <message>
+ <source>Fullscreen Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Windowed Resolution</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your Email</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Summary</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Send system information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type the security code:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Revision</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This program is distributed under the %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>This setting will be effective at next restart.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QLineEdit</name>
@@ -1803,6 +2008,10 @@ Do you really want to quit?</source>
<source>Hedgewars %1</source>
<translation>åºè大ä½æ° %1</translation>
</message>
+ <message>
+ <source>-r%1 (%2)</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>QMessageBox</name>
@@ -1819,10 +2028,6 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Please fill out all fields</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Error while authenticating at google.com:
</source>
<translation type="unfinished"></translation>
@@ -1869,47 +2074,12 @@ Do you really want to quit?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Successfully posted the issue on hedgewars.googlecode.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error during authentication at google.com</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Main - Error</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Cannot create directory %1</source>
- <translation type="unfinished">ç¡æ³åµå»ºè·¯å¾ %1</translation>
- </message>
- <message>
- <source>Failed to open data directory:
-%1
-
-Please check your installation!</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TCP - Error</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ç¡æ³åµå»ºè·¯å¾ %1</translation>
</message>
<message>
<source>Unable to start the server: %1.</source>
- <translation type="unfinished">ç¡æ³éå§æå端: %1.</translation>
- </message>
- <message>
- <source>Unable to run engine at </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Error code: %1</source>
- <translation type="unfinished"></translation>
+ <translation type="obsolete">ç¡æ³éå§æå端: %1.</translation>
</message>
<message>
<source>Video upload - Error</source>
@@ -2026,25 +2196,47 @@ Do you still want to join the room?</source>
<source>Do you really want to delete the weapon set '%1'?</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>QObject</name>
<message>
- <source>Nickname</source>
- <translation type="unfinished">å¿ç¨±</translation>
+ <source>Hedgewars - Nick not registered</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>System Information Preview</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to generate captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Failed to download captcha</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please fill out all fields. Email is optional.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hedgewars - Warning</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Please enter your nickname</source>
- <translation type="unfinished">è«è¼¸å
¥æ¨çå¿ç¨±</translation>
+ <source>Hedgewars - Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Not all players are ready</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Are you sure you want to start this game?
+Not all players are ready.</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>QPushButton</name>
<message>
- <source>Setup</source>
- <translation>è¨ç½®</translation>
- </message>
- <message>
<source>Play demo</source>
<translation>ææ¾ demo</translation>
</message>
@@ -2097,22 +2289,10 @@ Do you still want to join the room?</source>
<translation>åªé¤</translation>
</message>
<message>
- <source>Ready</source>
- <translation>æºå好äº</translation>
- </message>
- <message>
- <source>Random Team</source>
- <translation type="unfinished">é¨æ©éä¼åé
</translation>
- </message>
- <message>
<source>Associate file extensions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>more</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>More info</source>
<translation type="unfinished"></translation>
</message>
@@ -2136,181 +2316,193 @@ Do you still want to join the room?</source>
<source>Cancel uploading</source>
<translation type="unfinished"></translation>
</message>
-</context>
-<context>
- <name>RoomsListModel</name>
<message>
- <source>In progress</source>
+ <source>Restore default coding parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Room Name</source>
- <translation type="unfinished">æ¿éå</translation>
- </message>
- <message>
- <source>C</source>
- <translation type="unfinished">人æ¸</translation>
+ <source>Open the video directory in your system</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>T</source>
- <translation type="unfinished">éä¼</translation>
+ <source>Play this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Owner</source>
- <translation type="unfinished">åµå»ºè
</translation>
+ <source>Delete this video</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Map</source>
- <translation type="unfinished">å°å</translation>
+ <source>Upload this video to your Youtube account</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Rules</source>
- <translation type="unfinished">è¦å</translation>
+ <source>Reset</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapons</source>
- <translation type="unfinished">æ¦å¨</translation>
+ <source>Set the default server port for Hedgewars</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Map</source>
- <translation type="unfinished">é¨æ©å°å</translation>
+ <source>Invite your friends to your server in just 1 click!</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Random Maze</source>
+ <source>Click to copy your unique server URL in your clipboard. Send this link to your friends ands and they will be able to join you.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Hand-drawn</source>
+ <source>Start private server</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>SelWeaponWidget</name>
+ <name>RoomNamePrompt</name>
<message>
- <source>Weapon set</source>
- <translation type="unfinished">æ¦å¨è¨ç½®</translation>
+ <source>Enter a name for your room.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Probabilities</source>
- <translation type="unfinished">å¹¾ç</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
</message>
<message>
- <source>Ammo in boxes</source>
+ <source>Create room</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>RoomsListModel</name>
<message>
- <source>Delays</source>
+ <source>In progress</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>new</source>
- <translation type="unfinished">æ°</translation>
+ <source>Room Name</source>
+ <translation type="unfinished">æ¿éå</translation>
</message>
<message>
- <source>copy of</source>
- <translation type="unfinished"></translation>
+ <source>C</source>
+ <translation type="unfinished">人æ¸</translation>
</message>
-</context>
-<context>
- <name>ToggleButtonWidget</name>
<message>
- <source>Vampirism</source>
- <translation>å¸è¡é¬¼</translation>
+ <source>T</source>
+ <translation type="unfinished">éä¼</translation>
</message>
<message>
- <source>Karma</source>
- <translation>å æå ±æ</translation>
+ <source>Owner</source>
+ <translation type="unfinished">åµå»ºè
</translation>
</message>
<message>
- <source>Artillery</source>
- <translation>å°è¡</translation>
+ <source>Map</source>
+ <translation type="unfinished">å°å</translation>
</message>
<message>
- <source>Fort Mode</source>
- <translation>åå ¡æ¨¡å¼</translation>
+ <source>Rules</source>
+ <translation type="unfinished">è¦å</translation>
</message>
<message>
- <source>Divide Teams</source>
- <translation>åé«è¡å</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Solid Land</source>
- <translation>åºå¯¦å°é¢</translation>
+ <source>Random Map</source>
+ <translation type="unfinished">é¨æ©å°å</translation>
</message>
<message>
- <source>Add Border</source>
- <translation>æ·»å éç</translation>
+ <source>Random Maze</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Low Gravity</source>
- <translation>ä½éå</translation>
+ <source>Hand-drawn</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SeedPrompt</name>
<message>
- <source>Laser Sight</source>
- <translation>é³å°çæº</translation>
+ <source>The map seed is the basis for all random values generated by the game.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Invulnerable</source>
- <translation>åæ§ä¸å
¥</translation>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
</message>
<message>
- <source>Random Order</source>
- <translation type="unfinished">é¨æ©é åº</translation>
+ <source>Set seed</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>King</source>
- <translation type="unfinished">åç模å¼</translation>
+ <source>Close</source>
+ <translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>SelWeaponWidget</name>
<message>
- <source>Place Hedgehogs</source>
- <translation type="unfinished">æåæ¾ç½®</translation>
+ <source>Weapon set</source>
+ <translation type="unfinished">æ¦å¨è¨ç½®</translation>
</message>
<message>
- <source>Clan Shares Ammo</source>
- <translation type="unfinished"></translation>
+ <source>Probabilities</source>
+ <translation type="unfinished">å¹¾ç</translation>
</message>
<message>
- <source>Disable Girders</source>
+ <source>Ammo in boxes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Disable Land Objects</source>
+ <source>Delays</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>AI Survival Mode</source>
- <translation type="unfinished"></translation>
+ <source>new</source>
+ <translation type="unfinished">æ°</translation>
</message>
<message>
- <source>Reset Health</source>
+ <source>copy of</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TCPBase</name>
<message>
- <source>Unlimited Attacks</source>
+ <source>Unable to start server at %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset Weapons</source>
+ <source>Unable to run engine at %1
+Error code: %2</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamSelWidget</name>
<message>
- <source>Per Hedgehog Ammo</source>
+ <source>At least two teams are required to play!</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>TeamShowWidget</name>
<message>
- <source>Disable Wind</source>
+ <source>%1's team</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>ThemePrompt</name>
<message>
- <source>More Wind</source>
- <translation type="unfinished"></translation>
+ <source>Cancel</source>
+ <translation type="unfinished">åæ¶</translation>
</message>
<message>
- <source>Tag Team</source>
+ <source>Search for a theme:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add Bottom Border</source>
+ <source>Use selected theme</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -2449,12 +2641,6 @@ Do you still want to join the room?</source>
<translation>確èª</translation>
</message>
<message>
- <source>hedgehogs
-info</source>
- <translation>åºè大ä½æ°
-ä¿¡æ¯</translation>
- </message>
- <message>
<source>zoom in</source>
<translation type="unfinished">æ¾å¤§</translation>
</message>
@@ -2486,33 +2672,33 @@ info</source>
<source>record</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>hedgehog info</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (categories)</name>
<message>
- <source>Basic controls</source>
- <translation type="unfinished">åºæ¬æ§å¶</translation>
+ <source>Movement</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Weapon controls</source>
- <translation type="unfinished">æ¦å¨æ§å¶</translation>
+ <source>Weapons</source>
+ <translation type="unfinished">æ¦å¨</translation>
</message>
<message>
- <source>Camera and cursor controls</source>
- <translation type="unfinished">é¡é åéæ¨æ§å¶</translation>
+ <source>Camera</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Other</source>
- <translation type="unfinished">å
¶ä»</translation>
+ <source>Miscellaneous</source>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
<name>binds (descriptions)</name>
<message>
- <source>Move your hogs and aim:</source>
- <translation type="unfinished">移åãçæºï¼</translation>
- </message>
- <message>
<source>Traverse gaps and obstacles by jumping:</source>
<translation type="unfinished">è¶ééç¤ï¼</translation>
</message>
@@ -2576,6 +2762,10 @@ info</source>
<source>Record video:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Hedgehog movement</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>binds (keys)</name>
diff --git a/share/hedgewars/Data/Locale/hu.txt b/share/hedgewars/Data/Locale/hu.txt
index ed83577..85b0c7f 100644
--- a/share/hedgewars/Data/Locale/hu.txt
+++ b/share/hedgewars/Data/Locale/hu.txt
@@ -108,7 +108,7 @@
02:00=%1 lejárt a szavatossága
02:00=Nyugodj békében, %1
02:00=%1 nem bÃrta a kiképzést
-02:00=%1 nem volt macska, hogy kilenc élete legyen
+02:00=%1 nem volt macska, hogy kilenc élete legyen
02:00=Van itt orvos?
; Hog (%1) drowned
@@ -146,7 +146,6 @@
02:01=%1 Eccot, a delfint játssza
02:01=%1 meglátogatja Aquaria-t
02:01=%1 meglelte Atlantiszt
-02:01=%1 a Bioshock 3 fÅszerepére vágyik
02:01=A kutyaúszásod még nem tÅkéletes, %1
02:01=%1 hozhatott volna jet ski-t is
02:01=%1 nem szereti a vÃzisportokat
diff --git a/share/hedgewars/Data/Locale/it.lua b/share/hedgewars/Data/Locale/it.lua
index 1a37945..d6b7249 100644
--- a/share/hedgewars/Data/Locale/it.lua
+++ b/share/hedgewars/Data/Locale/it.lua
@@ -1,81 +1,81 @@
locale = {
["..."] = "...",
[":("] = ":(",
- ["!!!"] = "!!!",
--- ["011101000"] = "", -- A_Classic_Fairytale:dragon
--- ["011101001"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
--- ["30 minutes later..."] = "", -- A_Classic_Fairytale:shadow
--- ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "", -- A_Classic_Fairytale:enemy
+ ["!!!"] = "!!!",
+ ["011101000"] = "011101000",
+ ["011101001"] = "011101001",
+ ["30 minutes later..."] = "30 minuti più tardi...",
+ ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "Circa un mese fa, è arrivato un cyborg e ci ha detto che siete voi i cannibali!",
["Accuracy Bonus!"] = "Bonus Precisione!",
--- ["Ace"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
- ["Achievement Unlocked"] = "Archivio Sbloccato", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_That_Sinking_Feeling, Tumbler
--- ["A Classic Fairytale"] = "", -- A_Classic_Fairytale:first_blood
--- ["???"] = "", -- A_Classic_Fairytale:backstab
--- ["Actually, you aren't worthy of life! Take this..."] = "", -- A_Classic_Fairytale:shadow
--- ["A cy-what?"] = "", -- A_Classic_Fairytale:enemy
--- ["Adventurous"] = "", -- A_Classic_Fairytale:journey
--- ["Africa"] = "", -- Continental_supplies
+ ["Ace"] = "Asso",
+ ["Achievement Unlocked"] = "Archivio Sbloccato",
+ ["A Classic Fairytale"] = "Una favola classica",
+ ["???"] = "???",
+ ["Actually, you aren't worthy of life! Take this..."] = "In realtà , non siete degni di vivere! Prendete questo...",
+ ["A cy-what?"] = "Un cy-cosa?",
+ ["Adventurous"] = "Avventuroso",
+ ["Africa"] = "Africa",
-- ["After Leaks A Lot betrayed his tribe, he joined the cannibals..."] = "", -- A_Classic_Fairytale:first_blood
-- ["After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."] = "", -- A_Classic_Fairytale:shadow
--- ["Again with the 'cannibals' thing!"] = "", -- A_Classic_Fairytale:enemy
--- ["a Hedgewars challenge"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
- ["a Hedgewars mini-game"] = "un mini-gioco di Hedgewars", -- Space_Invasion, The_Specialists
- ["Aiming Practice"] = "Pratica la tua mira", --Bazooka, Shotgun, SniperRifle
+ ["Again with the 'cannibals' thing!"] = "Ancora colla storia dei 'cannibali'!",
+ ["a Hedgewars challenge"] = "una sfida Hedgewars",
+ ["a Hedgewars mini-game"] = "un mini-gioco di Hedgewars",
+ ["Aiming Practice"] = "Pratica la tua mira",
-- ["A leap in a leap"] = "", -- A_Classic_Fairytale:first_blood
--- ["A little gift from the cyborgs"] = "", -- A_Classic_Fairytale:shadow
--- ["All gone...everything!"] = "", -- A_Classic_Fairytale:enemy
--- ["All right, we just need to get to the other side of the island!"] = "", -- A_Classic_Fairytale:journey
--- ["All walls touched!"] = "", -- WxW
+ ["A little gift from the cyborgs"] = "Un piccolo regalo dai cyborg",
+ ["All gone...everything!"] = "E' finito... tutto!",
+ ["All right, we just need to get to the other side of the island!"] = "Va bene, dobbiamo solo raggiungere l'altro lato dell'isola!",
+ ["All walls touched!"] = "Tutti i muri toccati!",
["Ammo Depleted!"] = "Munizioni scarse!",
["ammo extended!"] = "Munizioni aggiuntive!",
["Ammo is reset at the end of your turn."] = "Le munizioni si azzeranno alla fine del tuo turno",
["Ammo Maniac!"] = "Maniaco delle munizioni!",
["Ammo"] = "Munizioni",
--- ["And how am I alive?!"] = "", -- A_Classic_Fairytale:enemy
+ ["And how am I alive?!"] = "E com'è che sono vivo?!",
-- ["And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."] = "", -- A_Classic_Fairytale:first_blood
--- ["And so it began..."] = "", -- A_Classic_Fairytale:first_blood
--- ["...and so the cyborgs took over the world..."] = "", -- A_Classic_Fairytale:shadow
--- ["And so they discovered that cyborgs weren't invulnerable..."] = "", -- A_Classic_Fairytale:journey
+ ["And so it began..."] = "E così ebbe inizio...",
+ ["...and so the cyborgs took over the world..."] = "... e così i cyborg conquistarono il mondo...",
+ ["And so they discovered that cyborgs weren't invulnerable..."] = "E così scoprirono che i cyborg non erano invulnerabili...",
-- ["And where's all the weed?"] = "", -- A_Classic_Fairytale:dragon
--- ["And you believed me? Oh, god, that's cute!"] = "", -- A_Classic_Fairytale:journey
--- ["Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"] = "", -- Continental_supplies
--- ["Antarctica"] = "", -- Continental_supplies
--- ["Are we there yet?"] = "", -- A_Classic_Fairytale:shadow
--- ["Are you accusing me of something?"] = "", -- A_Classic_Fairytale:backstab
--- ["Are you saying that many of us have died for your entertainment?"] = "", -- A_Classic_Fairytale:enemy
+ ["And you believed me? Oh, god, that's cute!"] = "E mi credi? Oddio, che bello!",
+ ["Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"] = "Anno 1032: [L'esplosione genererà un forte colpo a lungo raggio, non influierà sui ricci vicini all'obiettivo]",
+ ["Antarctica"] = "Antartico",
+ ["Are we there yet?"] = "Siamo già lì?",
+ ["Are you accusing me of something?"] = "Mi stai accusando di qualcosa?",
+ ["Are you saying that many of us have died for your entertainment?"] = "Stai dicendo che molti di noi sono morti per il tuo divertimento?",
-- ["Artur Detour"] = "", -- A_Classic_Fairytale:queen
--- ["As a reward for your performance, here's some new technology!"] = "", -- A_Classic_Fairytale:dragon
+ ["As a reward for your performance, here's some new technology!"] = "Come ricompensa per le tue prestazioni, ecco della tecnologia nuova!",
-- ["a shoppa minigame"] = "", -- WxW
--- ["Asia"] = "", -- Continental_supplies
--- ["Assault Team"] = "", -- A_Classic_Fairytale:backstab
--- ["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "", -- A_Classic_Fairytale:dragon
+ ["Asia"] = "Asia",
+ ["Assault Team"] = "Squadra d'assalto",
+ ["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "Siccome ci sono poche munizioni, potreste voler riutilizzare le corde intanto che siete a mezz'aria.|",
-- ["As the challenge was completed, Leaks A Lot set foot on the ground..."] = "", -- A_Classic_Fairytale:first_blood
--- ["As you can see, there is no way to get on the other side!"] = "", -- A_Classic_Fairytale:dragon
--- ["Attack From Rope"] = "", -- WxW
--- ["Australia"] = "", -- Continental_supplies
+ ["As you can see, there is no way to get on the other side!"] = "Come potete vedere, non c'è modo di andare dall'altra parte!",
+ ["Attack From Rope"] = "Attacco dalla corda",
+ ["Australia"] = "Australia",
["Available points remaining: "] = "Punti disponibili rimasti: ",
-- ["Back Breaker"] = "", -- A_Classic_Fairytale:backstab
--- ["Back in the village, after telling the villagers about the threat..."] = "", -- A_Classic_Fairytale:united
+ ["Back in the village, after telling the villagers about the threat..."] = "Tornati al villaggio, dopo aver detto agli abitanti della minaccia...",
["[Backspace]"] = "[Cancella]",
-- ["Backstab"] = "", -- A_Classic_Fairytale:backstab
-- ["Bad Team"] = "", -- User_Mission_-_The_Great_Escape
- ["Bamboo Thicket"] = "Boschetto di Bambu'",
+ ["Bamboo Thicket"] = "Boschetto di Bambù",
["Barrel Eater!"] = "Mangiatore di Barili!",
["Barrel Launcher"] = "Lanciatore di Barili",
--- ["Baseballbat"] = "", -- Continental_supplies
- ["Bat balls at your enemies and|push them into the sea!"] = "Lancia delle palline ai tuoi nemici|e spingili in acqua!",
- ["Bat your opponents through the|baskets and out of the map!"] = "Manda (colpendoli) i tuoi nemici|in acqua attraverso i canestri laterali!",
- ["Bazooka Training"] = "Addestramento sull'utilizzo del Bazooka",
+ ["Baseballbat"] = "Mazza da baseball",
+ ["Bat balls at your enemies and|push them into the sea!"] = "Lancia delle palline ai tuoi nemici|e spingili in acqua!",
+ ["Bat your opponents through the|baskets and out of the map!"] = "Manda (colpendoli) i tuoi nemici|in acqua attraverso i canestri laterali!",
+ ["Bazooka Training"] = "Addestramento sull'utilizzo del Bazooka",
-- ["Beep Loopers"] = "", -- A_Classic_Fairytale:queen
- ["Best laps per team: "] = "Tempo migliore per squadra: ",
+ ["Best laps per team: "] = "Tempo migliore per squadra: ",
["Best Team Times: "] = "Tempi della squadra migliore: ",
--- ["Beware, though! If you are slow, you die!"] = "", -- A_Classic_Fairytale:dragon
--- ["Biomechanic Team"] = "", -- A_Classic_Fairytale:family
+ ["Beware, though! If you are slow, you die!"] = "Attenzione, comunque! Se siete lenti, morirete!",
+ ["Biomechanic Team"] = "Squadra biomeccanica",
-- ["Blender"] = "", -- A_Classic_Fairytale:family
-- ["Bloodpie"] = "", -- A_Classic_Fairytale:backstab
-- ["Bloodrocutor"] = "", -- A_Classic_Fairytale:shadow
-- ["Bloodsucker"] = "", -- A_Classic_Fairytale:shadow
- ["Bloody Rookies"] = "Reclute Sanguinose", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree
+ ["Bloody Rookies"] = "Reclute Sanguinose",
-- ["Bone Jackson"] = "", -- A_Classic_Fairytale:backstab
-- ["Bonely"] = "", -- A_Classic_Fairytale:shadow
["Boom!"] = "Kaboom!",
@@ -88,33 +88,33 @@ locale = {
-- ["Brain Stu"] = "", -- A_Classic_Fairytale:united
-- ["Brain Teaser"] = "", -- A_Classic_Fairytale:backstab
-- ["Brutal Lily"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil
--- ["Brutus"] = "", -- A_Classic_Fairytale:backstab
+ ["Brutus"] = "Bruto",
["Build a track and race."] = "Costruisci una pista e corri.",
--- ["Bullseye"] = "", -- A_Classic_Fairytale:dragon
--- ["But it proved to be no easy task!"] = "", -- A_Classic_Fairytale:dragon
--- ["But that's impossible!"] = "", -- A_Classic_Fairytale:backstab
--- ["But the ones alive are stronger in their heart!"] = "", -- A_Classic_Fairytale:enemy
--- ["But...we died!"] = "", -- A_Classic_Fairytale:backstab
--- ["But where can we go?"] = "", -- A_Classic_Fairytale:united
--- ["But why would they help us?"] = "", -- A_Classic_Fairytale:backstab
--- ["But you're cannibals. It's what you do."] = "", -- A_Classic_Fairytale:enemy
--- ["But you said you'd let her go!"] = "", -- A_Classic_Fairytale:journey
+ ["Bullseye"] = "Bersaglio", -- A_Classic_Fairytale:dragon
+ ["But it proved to be no easy task!"] = "Ma si è dimostrato essere un compito non facile!",
+ ["But that's impossible!"] = "Ma è impossibile!",
+ ["But the ones alive are stronger in their heart!"] = "Ma i vivi sono più forti nel loro cuore!",
+ ["But...we died!"] = "Ma... siamo morti!",
+ ["But where can we go?"] = "Ma dove possiamo andare?",
+ ["But why would they help us?"] = "Ma perché dovrebbero aiutarci?",
+ ["But you're cannibals. It's what you do."] = "Ma voi siete cannibali. E' quello che fate.",
+ ["But you said you'd let her go!"] = "Avete detto che l'avreste lasciata andare!",
-- ["Call me Beep! Well, 'cause I'm such a nice...person!"] = "", -- A_Classic_Fairytale:family
--- ["Cannibals"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood
--- ["Cannibal Sentry"] = "", -- A_Classic_Fairytale:journey
--- ["Cannibals?! You're the cannibals!"] = "", -- A_Classic_Fairytale:enemy
- ["CAPTURE THE FLAG"] = "Cattura la Bandiera",
+ ["Cannibals"] = "Cannibali",
+ ["Cannibal Sentry"] = "Sentinella cannibale",
+ ["Cannibals?! You're the cannibals!"] = "Cannibali? Voi siete i cannibali!",
+ ["CAPTURE THE FLAG"] = "Cattura la Bandiera",
["Careless"] = "Incauto",
-- ["Carol"] = "", -- A_Classic_Fairytale:family
--- ["CHALLENGE COMPLETE"] = "", -- User_Mission_-_RCPlane_Challenge
+ ["CHALLENGE COMPLETE"] = "SFIDA COMPLETATA",
["Change Weapon"] = "Cambia Arma",
--- ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "", -- A_Classic_Fairytale:shadow
+ ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "Scegli da che parte vuoi stare! Se vuoi stare con quell'uomo strano, vai con lui.|Altrimenti, allontanatene. Se decidi di attacc... niente...",
["Clumsy"] = "Goffo",
-- ["Cluster Bomb MASTER!"] = "", -- Basic_Training_-_Cluster_Bomb
--- ["Cluster Bomb Training"] = "", -- Basic_Training_-_Cluster_Bomb
- ["Codename: Teamwork"] = "Nome in Codice: Lavoro di Squadra",
--- ["Collateral Damage"] = "", -- A_Classic_Fairytale:journey
--- ["Collateral Damage II"] = "", -- A_Classic_Fairytale:journey
+ ["Cluster Bomb Training"] = "Addestramento bomba a grappolo",
+ ["Codename: Teamwork"] = "Nome in Codice: Lavoro di Squadra",
+ ["Collateral Damage"] = "Danno collaterale",
+ ["Collateral Damage II"] = "Danno collaterale II",
-- ["Collect all the crates, but remember, our time in this life is limited!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Collect or destroy all the health crates."] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"] = "", -- A_Classic_Fairytale:first_blood
@@ -123,29 +123,29 @@ locale = {
-- ["Compete to use as few planes as possible!"] = "", -- User_Mission_-_RCPlane_Challenge
["Complete the track as fast as you can!"] = "Completa la pista più veloce che puoi!",
-- ["COMPLETION TIME"] = "", -- User_Mission_-_Rope_Knock_Challenge
--- ["Configuration accepted."] = "", -- WxW
--- ["Congratulations"] = "", -- Basic_Training_-_Rope
- ["Congratulations!"] = "Complimenti!",
+ ["Configuration accepted."] = "Configurazione accettata",
+ ["Congratulations"] = "Complimenti",
+ ["Congratulations!"] = "Complimenti!",
-- ["Congratulations! You needed only half of time|to eliminate all targets."] = "", -- Basic_Training_-_Cluster_Bomb
-- ["Congratulations! You've completed the Rope tutorial! |- Tutorial ends in 10 seconds!"] = "", -- Basic_Training_-_Rope
- ["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Complimenti! Hai distrutto tutti gli obiettivi|entro il tempo previsto.", --Bazooka, Shotgun, SniperRifle
+ ["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Complimenti! Hai distrutto tutti gli obiettivi|entro il tempo previsto.",
-- ["Continental supplies"] = "", -- Continental_supplies
- ["Control pillars to score points."] = "Ottieni il controllo dei pilastri per guadagnare punti.",
+ ["Control pillars to score points."] = "Ottieni il controllo dei pilastri per guadagnare punti.",
-- ["Corporationals"] = "", -- A_Classic_Fairytale:queen
-- ["Corpsemonger"] = "", -- A_Classic_Fairytale:shadow
--- ["Corpse Thrower"] = "", -- A_Classic_Fairytale:epil
+ ["Corpse Thrower"] = "Lanciatore di cadaveri",
-- ["Crates Left:"] = "", -- User_Mission_-_RCPlane_Challenge
- ["Cybernetic Empire"] = "Impero Cibernetico",
--- ["Cyborg. It's what the aliens call themselves."] = "", -- A_Classic_Fairytale:enemy
+ ["Cybernetic Empire"] = "Impero Cibernetico",
+ ["Cyborg. It's what the aliens call themselves."] = "Cyborg. E' come gli alieni chiamano loro stessi.",
-- ["Dahmer"] = "", -- A_Classic_Fairytale:backstab
- ["DAMMIT, ROOKIE!"] = "ACCIDENTI, RECLUTA!",
- ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "MALEDIZIONE, RECLUTA! VIA DALLA MIA TESTA!",
- ["Dangerous Ducklings"] = "Anatroccoli Pericolosi",
+ ["DAMMIT, ROOKIE!"] = "ACCIDENTI, RECLUTA!",
+ ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "MALEDIZIONE, RECLUTA! VIA DALLA MIA TESTA!",
+ ["Dangerous Ducklings"] = "Anatroccoli Pericolosi",
["Deadweight"] = "Peso morto",
--- ["Defeat the cannibals"] = "", -- A_Classic_Fairytale:backstab
--- ["Defeat the cannibals!|"] = "", -- A_Classic_Fairytale:united
+ ["Defeat the cannibals"] = "Sconfiggi i cannibali",
+ ["Defeat the cannibals!|"] = "Sconfiggi i cannibali!|",
-- ["Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow
--- ["Defeat the cyborgs!"] = "", -- A_Classic_Fairytale:enemy
+ ["Defeat the cyborgs!"] = "Sconfiggi i cyborg!",
-- ["Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"] = "", -- A_Classic_Fairytale:shadow
["Demolition is fun!"] = "Demolire è divertente!",
-- ["Dense Cloud"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
@@ -155,19 +155,19 @@ locale = {
["Destroy invaders to score points."] = "Distruggi gli invasori per guadagnare dei punti.",
-- ["Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."] = "", -- A_Classic_Fairytale:first_blood
-- ["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "", -- A_Classic_Fairytale:first_blood
--- ["Did anyone follow you?"] = "", -- A_Classic_Fairytale:united
--- ["Did you see him coming?"] = "", -- A_Classic_Fairytale:shadow
--- ["Did you warn the village?"] = "", -- A_Classic_Fairytale:shadow
--- ["Die, die, die!"] = "", -- A_Classic_Fairytale:dragon
+ ["Did anyone follow you?"] = "Ti ha seguito qualcuno?",
+ ["Did you see him coming?"] = "L'hai visto arrivare?",
+ ["Did you warn the village?"] = "Hai avvisato il villaggio?",
+ ["Die, die, die!"] = "Muori, muori, muori!",
-- ["Disguise as a Rockhopper Penguin: [Swap place with a random enemy hog in the circle]"] = "", -- Continental_supplies
-- ["Dist: "] = "", -- Space_Invasion
--- ["Do not laugh, inexperienced one, for he speaks the truth!"] = "", -- A_Classic_Fairytale:backstab
+ ["Do not laugh, inexperienced one, for he speaks the truth!"] = "Non ridere, pivello, perché lui dice la verità !",
-- ["Do not let his words fool you, young one! He will stab you in the back as soon as you turn away!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Do the deed"] = "", -- A_Classic_Fairytale:first_blood
["Double Kill!"] = "Doppia Uccisione!",
--- ["DOUBLE KILL"] = "", -- Mutant
--- ["Do you have any idea how valuable grass is?"] = "", -- A_Classic_Fairytale:enemy
--- ["Do you think you're some kind of god?"] = "", -- A_Classic_Fairytale:enemy
+ ["DOUBLE KILL"] = "DOPPIA UCCISIONE",
+ ["Do you have any idea how valuable grass is?"] = "Hai una pallida idea di quanto vale l'erba?",
+ ["Do you think you're some kind of god?"] = "Pensi di essere un qualche dio?",
-- ["Dragon's Lair"] = "", -- A_Classic_Fairytale:dragon
-- ["Drills"] = "", -- A_Classic_Fairytale:backstab
["Drone Hunter!"] = "Cacciatore di Droni!",
@@ -177,42 +177,42 @@ locale = {
-- ["Dude, can you see Ramon and Spiky?"] = "", -- A_Classic_Fairytale:journey
-- ["Dude, that's so cool!"] = "", -- A_Classic_Fairytale:backstab
-- ["Dude, we really need a new shaman..."] = "", -- A_Classic_Fairytale:shadow
--- ["Dude, what's this place?!"] = "", -- A_Classic_Fairytale:dragon
--- ["Dude, where are we?"] = "", -- A_Classic_Fairytale:backstab
+ ["Dude, what's this place?!"] = "Ehi, cos'è questo posto?",
+ ["Dude, where are we?"] = "Ehi, dove siamo?",
-- ["Dude, wow! I just had the weirdest high!"] = "", -- A_Classic_Fairytale:backstab
--- ["Duration"] = "", -- Continental_supplies
+ ["Duration"] = "Durata",
-- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "", -- Continental_supplies
["Each turn you get 1-3 random weapons"] = "In ogni turno hai da 1 a 3 armi casuali",
["Each turn you get one random weapon"] = "In ogno turno hai una sola arma casuale",
--- ["Eagle Eye"] = "", -- A_Classic_Fairytale:backstab
+ ["Eagle Eye"] = "Occhio di falco",
-- ["Eagle Eye: [Blink to the impact ~ one shot]"] = "", -- Continental_supplies
-- ["Ear Sniffer"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:epil
-- ["Elderbot"] = "", -- A_Classic_Fairytale:family
-- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape
- ["Eliminate all enemies"] = "Elimina tutti i nemici",
- ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Distruggi tutti gli obiettivi entro il tempo previsto.|Hai armi illimitate per questa missione.", --Bazooka, Shotgun, SniperRifle
--- ["Eliminate enemy hogs and take their weapons."] = "", -- Highlander
- ["Eliminate Poison before the time runs out"] = "Elimina Veleno prima che il tempo finisca",
- ["Eliminate the Blue Team"] = "Elimina la Squadra Blu",
- ["Eliminate the enemy before the time runs out"] = "Elimina il nemico prima che il tempo scada", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
+ ["Eliminate all enemies"] = "Elimina tutti i nemici",
+ ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Distruggi tutti gli obiettivi entro il tempo previsto.|Hai armi illimitate per questa missione.",
+ ["Eliminate enemy hogs and take their weapons."] = "Elimina i ricci nemici e prendi le loro armi",
+ ["Eliminate Poison before the time runs out"] = "Elimina Veleno prima che il tempo finisca",
+ ["Eliminate the Blue Team"] = "Elimina la Squadra Blu",
+ ["Eliminate the enemy before the time runs out"] = "Elimina il nemico prima che il tempo scada",
["Eliminate the enemy hogs to win."] = "Elimina i ricci nemici per vincere.",
["Eliminate the enemy specialists."] = "Elimina tutti i nemici specialisti.",
- ["- Eliminate Unit 3378 |- Feeble Resistance must survive"] = "- Elimina l'Unità 3378 |- La Resistenza Finale deve sopravvivere",
--- ["Elmo"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["- Eliminate Unit 3378 |- Feeble Resistance must survive"] = "- Elimina l'Unità 3378 |- La Resistenza Finale deve sopravvivere",
+ ["Elmo"] = "Elmo",
["Energetic Engineer"] = "Ingegnere Energetico",
- ["Enjoy the swim..."] = "Spero che tu gradisca una nuotata...",
+ ["Enjoy the swim..."] = "Spero che tu gradisca una nuotata...",
["[Enter]"] = "[Enter]",
--- ["Europe"] = "", -- Continental_supplies
+ ["Europe"] = "Europa",
-- [" ever done to you?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Everyone knows this."] = "", -- A_Classic_Fairytale:enemy
+ ["Everyone knows this."] = "Lo sanno tutti.",
-- ["Every single time!"] = "", -- A_Classic_Fairytale:dragon
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
- ["Fastest lap: "] = "Giro migliore: ",
- ["Feeble Resistance"] = "Resistenza Finale",
+ ["Fastest lap: "] = "Giro migliore: ",
+ ["Feeble Resistance"] = "Resistenza Finale",
-- ["Fell From Grace"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["Fell From Heaven"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen
-- ["Fell From Heaven is the best! Fell From Heaven is the greatest!"] = "", -- A_Classic_Fairytale:family
@@ -222,14 +222,14 @@ locale = {
-- ["Find your tribe!|Cross the lake!"] = "", -- A_Classic_Fairytale:dragon
-- ["Finish your training|Hint: Animations can be skipped with the [Precise] key."] = "", -- A_Classic_Fairytale:first_blood
-- ["Fire a mine: [Does what it says ~ Cant be dropped close to an enemy ~ 1 sec]"] = "", -- Continental_supplies
- ["Fire"] = "Fuoco",
--- ["First aid kits?!"] = "", -- A_Classic_Fairytale:united
--- ["First Blood"] = "", -- A_Classic_Fairytale:first_blood
+ ["Fire"] = "Fuoco",
+ ["First aid kits?!"] = "Kit di pronto soccorso?!",
+ ["First Blood"] = "Primo sangue",
-- ["FIRST BLOOD MUTATES"] = "", -- Mutant
--- ["First Steps"] = "", -- A_Classic_Fairytale:first_blood
- ["Flag captured!"] = "Bandiera catturata!",
- ["Flag respawned!"] = "Bandiera restituita!",
- ["Flag returned!"] = "Bandiera recuperata!",
+ ["First Steps"] = "Primi passi",
+ ["Flag captured!"] = "Bandiera catturata!",
+ ["Flag respawned!"] = "Bandiera restituita!",
+ ["Flag returned!"] = "Bandiera recuperata!",
["Flags, and their home base will be placed where each team ends their first turn."] = "Le bandiere saranno piazzate nel luogo in cui le squadre finiscono il loro primo turno.",
["Flamer"] = "Incendiario",
-- ["Flaming Worm"] = "", -- A_Classic_Fairytale:backstab
@@ -241,29 +241,29 @@ locale = {
["fuel extended!"] = "carburante aggiuntivo!",
["GAME BEGUN!!!"] = "IL GIOCO E' INIZIATO!!!",
["Game Modifiers: "] = "Modificatori di Gioco: ",
- ["GAME OVER!"] = "GAME OVER!",
- ["Game Started!"] = "Gioco Iniziato!",
+ ["GAME OVER!"] = "GAME OVER!",
+ ["Game Started!"] = "Gioco Iniziato!",
-- ["Game? Was this a game to you?!"] = "", -- A_Classic_Fairytale:enemy
-- ["GasBomb"] = "", -- Continental_supplies
-- ["Gas Gargler"] = "", -- A_Classic_Fairytale:queen
-- ["Get Dense Cloud out of the pit!"] = "", -- A_Classic_Fairytale:journey
- ["Get on over there and take him out!"] = "Vai fuori da qui ed eliminalo!",
+ ["Get on over there and take him out!"] = "Vai fuori da qui ed eliminalo!",
-- ["Get on the head of the mole"] = "", -- A_Classic_Fairytale:first_blood
--- ["Get out of there!"] = "", -- User_Mission_-_The_Great_Escape
+ ["Get out of there!"] = "Fuori di lì!",
-- ["Get that crate!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Get the crate on the other side of the island!|"] = "", -- A_Classic_Fairytale:journey
-- ["Get to the target using your rope! |Controls: Left & Right to swing the rope - Up & Down to Contract and Expand!"] = "", -- Basic_Training_-_Rope
-- ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"] = "", -- A_Classic_Fairytale:family
--- ["GG!"] = "", -- User_Mission_-_Rope_Knock_Challenge
+ ["GG!"] = "GG!",
-- ["Gimme Bones"] = "", -- A_Classic_Fairytale:backstab
-- ["Glark"] = "", -- A_Classic_Fairytale:shadow
["Goal"] = "Goal",
- ["GO! GO! GO!"] = "VAI! VAI! VAI!",
- ["Good birdy......"] = "Bell'uccellino......",
--- ["Good Dude"] = "", -- User_Mission_-_The_Great_Escape
+ ["GO! GO! GO!"] = "VAI! VAI! VAI!",
+ ["Good birdy......"] = "Bell'uccellino......",
+ ["Good Dude"] = "Bravo ragazzo",
-- ["Good idea, they'll never find us there!"] = "", -- A_Classic_Fairytale:united
-- ["Good luck...or else!"] = "", -- A_Classic_Fairytale:journey
- ["Good luck out there!"] = "Buona fortuna!",
+ ["Good luck out there!"] = "Buona fortuna!",
["Good so far!"] = "Molto bene finora!",
["Good to go!"] = "Vai!!",
-- ["Go on top of the flower"] = "", -- A_Classic_Fairytale:first_blood
@@ -276,20 +276,19 @@ locale = {
-- ["Great work! Now hit it with your Baseball Bat! |Tip: You can change weapon with 'Right Click'!"] = "", -- Basic_Training_-_Rope
-- ["Great! You will be contacted soon for assistance."] = "", -- A_Classic_Fairytale:shadow
-- ["Green lipstick bullet: [Is poisonous]"] = "", -- Continental_supplies
--- ["Greetings, "] = "", -- A_Classic_Fairytale:dragon
+ ["Greetings, "] = "Saluti, ",
-- ["Greetings, cloudy one!"] = "", -- A_Classic_Fairytale:shadow
-- ["Grenade Training"] = "", -- Basic_Training_-_Grenade
-- ["Grenadiers"] = "", -- Basic_Training_-_Grenade
-- ["Guys, do you think there's more of them?"] = "", -- A_Classic_Fairytale:backstab
--- ["HAHA!"] = "", -- A_Classic_Fairytale:enemy
--- ["Haha!"] = "", -- A_Classic_Fairytale:united
- ["Hahahaha!"] = "Hahahaha!",
+ ["HAHA!"] = "AHAH!",
+ ["Haha!"] = "Ahah!",
+ ["Hahahaha!"] = "Ahahahah!",
["Haha, now THAT would be something!"] = "Haha, allora questa pioggia ha DAVVERO qualcosa di strano!",
--- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
- ["Hapless Hogs left!"] = "Ricci Sfortunati rimanenti!",
--- [" Hapless Hogs left!"] = "", -- User_Mission_-_That_Sinking_Feeling
+ ["Hannibal"] = "Annibale",
+ [" Hapless Hogs left!"] = "Ricci Sfortunati rimanenti!",
["Hapless Hogs"] = "Ricci Sfortunati",
--- [" HAS MUTATED\" )"] = "", --
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -298,21 +297,21 @@ locale = {
["Heavy"] = "Pesante",
-- ["Hedge-cogs"] = "", -- A_Classic_Fairytale:enemy
-- ["Hedgehog projectile: [fire your hog like a Sticky Bomb]"] = "", -- Continental_supplies
- ["Hedgewars-Basketball"] = "Hedgewars-Pallacanestro",
- ["Hedgewars-Knockball"] = "Hedgewars-Knockball",
--- ["Hedgibal Lecter"] = "", -- A_Classic_Fairytale:backstab
+ ["Hedgewars-Basketball"] = "Hedgewars-Pallacanestro",
+ ["Hedgewars-Knockball"] = "Hedgewars-Knockball",
+ ["Hedgibal Lecter"] = "Riccibal Lecter",
["Heh, it's not that bad."] = "Beh, alla fine non piove così forte.",
--- ["Hello again, "] = "", -- A_Classic_Fairytale:family
+ ["Hello again, "] = "Salve di nuovo, ",
-- ["Help me, Leaks!"] = "", -- A_Classic_Fairytale:journey
--- ["Help me, please!!!"] = "", -- A_Classic_Fairytale:journey
--- ["Help me, please!"] = "", -- A_Classic_Fairytale:journey
+ ["Help me, please!!!"] = "Aiutami, per favore!!!",
+ ["Help me, please!"] = "Aiutami, per favore!",
-- ["He moves like an eagle in the sky."] = "", -- A_Classic_Fairytale:first_blood
-- ["He must be in the village already."] = "", -- A_Classic_Fairytale:journey
-- ["Here, let me help you!"] = "", -- A_Classic_Fairytale:backstab
-- ["Here, let me help you save her!"] = "", -- A_Classic_Fairytale:family
-- ["Here...pick your weapon!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Hero Team"] = "", -- User_Mission_-_The_Great_Escape
--- ["He's so brave..."] = "", -- A_Classic_Fairytale:first_blood
+ ["He's so brave..."] = "E' così coraggioso...",
-- ["He won't be selling us out anymore!"] = "", -- A_Classic_Fairytale:backstab
-- ["Hey, guys!"] = "", -- A_Classic_Fairytale:backstab
-- ["Hey guys!"] = "", -- A_Classic_Fairytale:united
@@ -323,18 +322,18 @@ locale = {
-- ["Hint: Select the BlowTorch, aim and press [Fire]. Press [Fire] again to stop.|Don't blow up the crate."] = "", -- A_Classic_Fairytale:journey
-- ["Hint: Select the LowGravity and press [Fire]."] = "", -- A_Classic_Fairytale:journey
-- ["Hint: you might want to stay out of sight and take all the crates...|"] = "", -- A_Classic_Fairytale:journey
--- ["His arms are so strong!"] = "", -- A_Classic_Fairytale:first_blood
+ ["His arms are so strong!"] = "Le sue braccia sono così forti!",
["Hit Combo!"] = "Hit Combo!",
-- ["Hmmm...actually...I didn't either."] = "", -- A_Classic_Fairytale:enemy
-- ["Hmmm, I'll have to find some way of moving him off this anti-portal surface..."] = "", -- portal
--- ["Hmmm...it's a draw. How unfortunate!"] = "", -- A_Classic_Fairytale:enemy
- ["Hmmm..."] = "Mmmmm...",
+ ["Hmmm...it's a draw. How unfortunate!"] = "Mmm... è un pareggio. Che sfortunato!",
+ ["Hmmm..."] = "Mmmmm...",
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
--- ["Hogminator"] = "", -- A_Classic_Fairytale:family
--- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+ ["Hogminator"] = "Ricc-minator",
+ ["Hogs in sight!"] = "Ricci in vista!",
+ ["HOLY SHYTE!"] = "SANTA POLENTA!",
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
- ["Hooray!"] = "Hurrà !!!",
+ ["Hooray!"] = "Hurrà !!!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
-- ["How can I ever repay you for saving my life?"] = "", -- A_Classic_Fairytale:journey
-- ["How come in a village full of warriors, it's up to me to save it?"] = "", -- A_Classic_Fairytale:dragon
@@ -344,13 +343,13 @@ locale = {
-- ["However, if you fail to do so, she dies a most violent death! Muahahaha!"] = "", -- A_Classic_Fairytale:journey
-- ["However, my mates don't agree with me on letting you go..."] = "", -- A_Classic_Fairytale:dragon
-- [" HP"] = "", -- Mutant
- ["Hunter"] = "Cacciatore", --Bazooka, Shotgun, SniperRifle
+ ["Hunter"] = "Cacciatore",
-- ["I believe there's more of them."] = "", -- A_Classic_Fairytale:backstab
-- ["I can see you have been training diligently."] = "", -- A_Classic_Fairytale:first_blood
--- ["I can't believe it worked!"] = "", -- A_Classic_Fairytale:shadow
--- ["I can't believe this!"] = "", -- A_Classic_Fairytale:enemy
--- ["I can't believe what I'm hearing!"] = "", -- A_Classic_Fairytale:backstab
--- ["I can't wait any more, I have to save myself!"] = "", -- A_Classic_Fairytale:shadow
+ ["I can't believe it worked!"] = "Non posso credere che abbia funzionato!",
+ ["I can't believe this!"] = "Non posso crederci!",
+ ["I can't believe what I'm hearing!"] = "Non credo alle mie orecchie!",
+ ["I can't wait any more, I have to save myself!"] = "Non posso più aspettare, devo salvarmi!",
-- ["I could just teleport myself there..."] = "", -- A_Classic_Fairytale:family
-- ["I'd better get going myself."] = "", -- A_Classic_Fairytale:journey
-- ["I didn't until about a month ago."] = "", -- A_Classic_Fairytale:enemy
@@ -365,12 +364,11 @@ locale = {
-- ["If you decide to help us, though, we will no longer need to find a new governor for the island."] = "", -- A_Classic_Fairytale:shadow
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+ ["If you say so..."] = "Se lo dici tu...",
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
--- ["I have to follow that alien."] = "", -- A_Classic_Fairytale:backstab
+ ["I have to follow that alien."] = "Devo seguire quell'alieno.",
-- ["I have to get back to the village!"] = "", -- A_Classic_Fairytale:shadow
-- ["I hope you are prepared for a small challenge, young one."] = "", -- A_Classic_Fairytale:first_blood
-- ["I just don't want to sink to your level."] = "", -- A_Classic_Fairytale:backstab
@@ -379,45 +377,45 @@ locale = {
-- ["I'll hold them off while you return to the village!"] = "", -- A_Classic_Fairytale:shadow
-- ["Imagine those targets are the wolves that killed your parents! Take your anger out on them!"] = "", -- A_Classic_Fairytale:first_blood
-- ["I'm...alive? How? Why?"] = "", -- A_Classic_Fairytale:backstab
--- ["I'm a ninja."] = "", -- A_Classic_Fairytale:dragon
+ ["I'm a ninja."] = "Sono un ninja.",
-- ["I marked the place of their arrival. You're welcome!"] = "", -- A_Classic_Fairytale:backstab
-- ["I'm certain that this is a misunderstanding, fellow hedgehogs!"] = "", -- A_Classic_Fairytale:first_blood
--- ["I mean, none of you ceased to live."] = "", -- A_Classic_Fairytale:enemy
--- ["I'm getting old for this!"] = "", -- A_Classic_Fairytale:family
--- ["I'm getting thirsty..."] = "", -- A_Classic_Fairytale:family
--- ["I'm here to help you rescue her."] = "", -- A_Classic_Fairytale:family
--- ["I'm not sure about that!"] = "", -- A_Classic_Fairytale:united
+ ["I mean, none of you ceased to live."] = "Voglio dire, nessuno di voi ha cessato di vivere.", -- A_Classic_Fairytale:enemy
+ ["I'm getting old for this!"] = "Sto diventando vecchio per queste cose!",
+ ["I'm getting thirsty..."] = "Ho sete...",
+ ["I'm here to help you rescue her."] = "Sono qui per aiutarvi a salvarla.",
+ ["I'm not sure about that!"] = "Non sono sicuro di quello!",
-- ["Impressive...you are still dry as the corpse of a hawk after a week in the desert..."] = "", -- A_Classic_Fairytale:first_blood
--- ["I'm so scared!"] = "", -- A_Classic_Fairytale:united
--- ["Incredible..."] = "", -- A_Classic_Fairytale:shadow
--- ["I need to find the others!"] = "", -- A_Classic_Fairytale:backstab
+ ["I'm so scared!"] = "Ho tanta paura!",
+ ["Incredible..."] = "Incredibile...",
+ ["I need to find the others!"] = "Devo trovare gli altri!",
-- ["I need to get to the other side of this island, fast!"] = "", -- A_Classic_Fairytale:journey
--- ["I need to move the tribe!"] = "", -- A_Classic_Fairytale:united
--- ["I need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
--- ["I need to warn the others."] = "", -- A_Classic_Fairytale:backstab
+ ["I need to move the tribe!"] = "Devo spostare la tribù!",
+ ["I need to prevent their arrival!"] = "Devo prevenire il loro arrivo!",
+ ["I need to warn the others."] = "Devo avvisare gli altri.",
-- ["In fact, you are the only one that's been acting strangely."] = "", -- A_Classic_Fairytale:backstab
-- ["In order to get to the other side, you need to collect the crates first.|"] = "", -- A_Classic_Fairytale:dragon
- ["Instructor"] = "Istruttore", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings
--- ["Interesting idea, haha!"] = "", -- A_Classic_Fairytale:enemy
+ ["Instructor"] = "Istruttore",
+ ["Interesting idea, haha!"] = "Idea interessante, ahah!",
-- ["Interesting! Last time you said you killed a cannibal!"] = "", -- A_Classic_Fairytale:backstab
-- ["In the meantime, take these and return to your \"friend\"!"] = "", -- A_Classic_Fairytale:shadow
["invaders destroyed"] = "invasori distrutti",
--- ["Invasion"] = "", -- A_Classic_Fairytale:united
--- ["I saw it with my own eyes!"] = "", -- A_Classic_Fairytale:shadow
--- ["I see..."] = "", -- A_Classic_Fairytale:shadow
+ ["Invasion"] = "Invasione",
+ ["I saw it with my own eyes!"] = "L'ho visto coi miei occhi!",
+ ["I see..."] = "Capisco...",
-- ["I see you have already taken the leap of faith."] = "", -- A_Classic_Fairytale:first_blood
-- ["I see you would like his punishment to be more...personal..."] = "", -- A_Classic_Fairytale:first_blood
-- ["I sense another wave of cannibals heading my way!"] = "", -- A_Classic_Fairytale:backstab
-- ["I sense another wave of cannibals heading our way!"] = "", -- A_Classic_Fairytale:backstab
--- ["I shouldn't have drunk that last pint."] = "", -- A_Classic_Fairytale:dragon
--- ["Is this place in my head?"] = "", -- A_Classic_Fairytale:dragon
+ ["I shouldn't have drunk that last pint."] = "Non avrei dovuto bere l'ultima pinta.",
+ ["Is this place in my head?"] = "Questo posto è nella mia testa?",
-- ["It doesn't matter. I won't let that alien hurt my daughter!"] = "", -- A_Classic_Fairytale:dragon
--- ["I think we are safe here."] = "", -- A_Classic_Fairytale:backstab
+ ["I think we are safe here."] = "Penso che qui siamo al sicuro.",
-- ["I thought their shaman died when he tried our medicine!"] = "", -- A_Classic_Fairytale:shadow
-- ["It is called 'Hogs of Steel'."] = "", -- A_Classic_Fairytale:enemy
--- ["It is time to practice your fighting skills."] = "", -- A_Classic_Fairytale:first_blood
--- ["It must be a childhood trauma..."] = "", -- A_Classic_Fairytale:family
--- ["It must be the aliens!"] = "", -- A_Classic_Fairytale:backstab
+ ["It is time to practice your fighting skills."] = "E' ora di mettere in pratica le vostre abilità di combattimento.",
+ ["It must be a childhood trauma..."] = "Dev'essere un trauma infantile...",
+ ["It must be the aliens!"] = "Devono essere gli alieni!",
-- ["It must be the aliens' deed."] = "", -- A_Classic_Fairytale:backstab
-- ["It must be the cyborgs again!"] = "", -- A_Classic_Fairytale:enemy
-- ["I told you, I just found them."] = "", -- A_Classic_Fairytale:backstab
@@ -425,10 +423,10 @@ locale = {
-- ["It's always up to women to clear up the mess men created!"] = "", -- A_Classic_Fairytale:dragon
-- ["It's a shame, I forgot how to do that!"] = "", -- A_Classic_Fairytale:family
-- ["It's impossible to communicate with the spirits without a shaman."] = "", -- A_Classic_Fairytale:shadow
--- ["It's over..."] = "", -- A_Classic_Fairytale:shadow
+ ["It's over..."] = "E' finita...",
-- ["It's time you learned that your actions have consequences!"] = "", -- A_Classic_Fairytale:journey
-- ["It's worth more than wood!"] = "", -- A_Classic_Fairytale:enemy
--- ["It wants our brains!"] = "", -- A_Classic_Fairytale:shadow
+ ["It wants our brains!"] = "Vuole i nostri cervelli!",
-- ["It was not a dream, unwise one!"] = "", -- A_Classic_Fairytale:backstab
-- ["I've seen this before. They just appear out of thin air."] = "", -- A_Classic_Fairytale:united
-- ["I want to play a game..."] = "", -- A_Classic_Fairytale:journey
@@ -437,19 +435,19 @@ locale = {
-- ["I wonder where Dense Cloud is..."] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
-- ["I wonder why I'm so angry all the time..."] = "", -- A_Classic_Fairytale:family
-- ["I won't let you kill her!"] = "", -- A_Classic_Fairytale:journey
--- ["Jack"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
--- ["Jeremiah"] = "", -- A_Classic_Fairytale:dragon
--- ["John"] = "", -- A_Classic_Fairytale:journey
--- ["Judas"] = "", -- A_Classic_Fairytale:backstab
+ ["Jack"] = "Giacomo",
+ ["Jeremiah"] = "Geremia",
+ ["John"] = "Giovanni",
+ ["Judas"] = "Giuda",
["Jumping is disabled"] = "Il salto è disattivato",
-- ["Just kidding, none of you have died!"] = "", -- A_Classic_Fairytale:enemy
-- ["Just on a walk."] = "", -- A_Classic_Fairytale:united
-- ["Just wait till I get my hands on that trauma! ARGH!"] = "", -- A_Classic_Fairytale:family
["Kamikaze Expert!"] = "Kamikaze Esperto!",
["Keep it up!"] = "Mantienilo al sicuro!",
--- ["Kerguelen"] = "", -- Continental_supplies
+ ["Kerguelen"] = "Kerguelen",
["Killing spree!"] = "Furia Omicida!",
--- ["KILL IT!"] = "", -- A_Classic_Fairytale:first_blood
+ ["KILL IT!"] = "UCCIDILO!",
["KILLS"] = "UCCISIONI",
-- ["Kill the aliens!"] = "", -- A_Classic_Fairytale:dragon
-- ["Kill the cannibal!"] = "", -- A_Classic_Fairytale:first_blood
@@ -473,7 +471,7 @@ locale = {
-- ["Let them have a taste of my fury!"] = "", -- A_Classic_Fairytale:backstab
-- ["Let us help, too!"] = "", -- A_Classic_Fairytale:backstab
-- ["Light Cannfantry"] = "", -- A_Classic_Fairytale:united
- ["Listen up, maggot!!"] = "Recluta, Attenzione!!",
+ ["Listen up, maggot!!"] = "Recluta, Attenzione!!",
-- ["Little did they know that this hunt will mark them forever..."] = "", -- A_Classic_Fairytale:shadow
["Lively Lifeguard"] = "Bagnino Vivace",
-- ["Lonely Cries: [Rise the water if no hog is in the circle and deal 1 damage to all hogs]"] = "", -- Continental_supplies
@@ -488,13 +486,13 @@ locale = {
-- ["MEGA KILL"] = "", -- Mutant
-- ["Meiwes"] = "", -- A_Classic_Fairytale:backstab
-- ["Mindy"] = "", -- A_Classic_Fairytale:united
- ["Mine Deployer"] = "Spintore di Mine",
+ ["Mine Deployer"] = "Posatore di Mine",
["Mine Eater!"] = "Mangiatore di Mine!",
- ["|- Mines Time:"] = "|- Timer delle mine:", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
- ["MISSION FAILED"] = "MISSIONE FALLITA", -- User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
- ["MISSION SUCCESSFUL"] = "MISSIONE COMPLETATA CON SUCCESSO", -- User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
- ["MISSION SUCCESS"] = "MISSIONE COMPLETATA", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
--- ["Molotov"] = "", -- Continental_supplies
+ ["|- Mines Time:"] = "|- Timer delle mine:",
+ ["MISSION FAILED"] = "MISSIONE FALLITA",
+ ["MISSION SUCCESSFUL"] = "MISSIONE COMPLETATA CON SUCCESSO",
+ ["MISSION SUCCESS"] = "MISSIONE COMPLETATA",
+ ["Molotov"] = "Molotov",
-- ["MONSTER KILL"] = "", -- Mutant
-- ["More Natives"] = "", -- A_Classic_Fairytale:epil
["Movement: [Up], [Down], [Left], [Right]"] = "Movimenti: [Su], [Giù], [Sinistra], [Destra]",
@@ -510,7 +508,7 @@ locale = {
-- ["Natives"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
["New Barrels Per Turn"] = "Nuovi Barili ad Ogni Turno",
["NEW CLAN RECORD: "] = "NUOVO RECORD DEL CLAN: ",
- ["NEW fastest lap: "] = "Nuovo giro migliore: ",
+ ["NEW fastest lap: "] = "Nuovo giro migliore: ",
["New Mines Per Turn"] = "Nuove Mine ad Ogni Turno",
["NEW RACE RECORD: "] = "NUOVO RACE RECORD: ",
["Newton's Hammock"] = "Newton e l'Amaca",
@@ -529,7 +527,7 @@ locale = {
-- ["Not all hogs are born equal."] = "", -- Highlander
["NOT ENOUGH WAYPOINTS"] = "NON CI SONO ABBASTANZA PUNTI!",
-- ["Not now, Fiery Water!"] = "", -- A_Classic_Fairytale:backstab
- ["Not So Friendly Match"] = "Partita (quasi) amichevole", -- Basketball, Knockball
+ ["Not So Friendly Match"] = "Partita (quasi) amichevole",
-- ["Not you again! My head still hurts from last time!"] = "", -- A_Classic_Fairytale:shadow
-- ["No, we made sure of that!"] = "", -- A_Classic_Fairytale:united
-- ["Now find the next target! |Tip: Normally you lose health by falling down, so be careful!"] = "", -- Basic_Training_-_Rope
@@ -543,33 +541,32 @@ locale = {
-- ["OH, COME ON!"] = "", -- A_Classic_Fairytale:journey
-- ["Oh, my!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Oh, my! This is even more entertaining than I've expected!"] = "", -- A_Classic_Fairytale:backstab
- ["Oh no! Just try again!"] = "Oh no! Prova ancora!", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["Oh no! Just try again!"] = "Oh no! Prova ancora!",
-- ["Oh no, not "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
- ["Oh no! Time's up! Just try again."] = "Oh no! Tempo scaduto! Prova ancora!", --Bazooka, Shotgun, SniperRifle
+ ["Oh no! Time's up! Just try again."] = "Oh no! Tempo scaduto! Prova ancora!",
-- ["Oh no! You failed! Just try again."] = "", -- Basic_Training_-_Cluster_Bomb
-- ["Oh, silly me! I forgot that I'm the shaman."] = "", -- A_Classic_Fairytale:backstab
-- ["Olive"] = "", -- A_Classic_Fairytale:united
--- ["Omnivore"] = "", -- A_Classic_Fairytale:first_blood
+ ["Omnivore"] = "Onnivoro",
-- ["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "", -- A_Classic_Fairytale:first_blood
-- ["ONE HOG PER TEAM! KILLING EXCESS HEDGES"] = "", -- Mutant
-- ["One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."] = "", -- A_Classic_Fairytale:first_blood
-- ["Oops...I dropped them."] = "", -- A_Classic_Fairytale:united
-- ["Open that crate and we will continue!"] = "", -- A_Classic_Fairytale:first_blood
- ["Operation Diver"] = "Operazione Sub",
- ["Opposing Team: "] = "Squadra Nemica: ",
+ ["Operation Diver"] = "Operazione Sub",
+ ["Opposing Team: "] = "Squadra Nemica: ",
-- ["Orlando Boom!"] = "", -- A_Classic_Fairytale:queen
-- ["Ouch!"] = "", -- User_Mission_-_Rope_Knock_Challenge
-- ["Our tribe, our beautiful island!"] = "", -- A_Classic_Fairytale:enemy
-- ["Parachute"] = "", -- Continental_supplies
- ["Pathetic Hog #%d"] = "Riccio Patetico #%d",
- ["Pathetic Resistance"] = "Resistenza Patetica", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
+ ["Pathetic Hog #%d"] = "Riccio Patetico #%d",
+ ["Pathetic Resistance"] = "Resistenza Patetica",
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Munizioni per Riccio",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
--- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
+-- ["Piñata bullet: [Contains some sweet candy!]"] = "Proiettile pentolaccia: [Contiene alcune caramelle deliziose!]", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Piazza più punti usando [ENTER]",
["Place more waypoints using the 'Air Attack' weapon."] = "Piazza più punti usando l'Attacco Aereo",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -578,11 +575,11 @@ locale = {
-- ["Please place the way-point in the open, within the map boundaries."] = "", -- Racer
-- ["Please, stop releasing your \"smoke signals\"!"] = "", -- A_Classic_Fairytale:shadow
-- ["Point Blank Combo!"] = "", -- Space_Invasion
- ["points"] = "punti", -- Control, Space_Invasion
- ["Poison"] = "Veleno",
+ ["points"] = "punti",
+ ["Poison"] = "Veleno",
-- ["Portal hint: one goes to the destination, and one is the entrance.|"] = "", -- A_Classic_Fairytale:dragon
-- ["Portal mission"] = "", -- portal
- ["Power Remaining"] = "Potenza Rimasta",
+ ["Power Remaining"] = "Potenza Rimasta",
["Prepare yourself"] = "Preparati",
-- ["Press [Enter] to accept this configuration."] = "", -- WxW
-- ["Press [Left] or [Right] to move around, [Enter] to jump"] = "", -- A_Classic_Fairytale:first_blood
@@ -601,7 +598,7 @@ locale = {
-- ["Reinforcements"] = "", -- A_Classic_Fairytale:backstab
-- ["Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!"] = "", -- Basic_Training_-_Rope
-- ["Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"] = "", -- A_Classic_Fairytale:shadow
- [" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = " - Riporta la bandiera nemica alla tua base per guadagnare un punto| - La prima squadra a catturarne 3 vince! | - Puoi guadagnare punti solo quando la tua bandiera si trova nella tua base! | - I ricci lasceranno cadere la bandiera se uccisi o caduti in acqua! | - Le bandiere cadute possono essere restituite o ricatturate! | - I ricci risorgono dalla morte!",
+ [" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = " - Riporta la bandiera nemica alla tua base per guadagnare un punto| - La prima squadra a catturarne 3 vince! | - Puoi guadagnare punti solo quando la tua bandiera si trova nella tua base! | - I ricci lasceranno cadere la bandiera se uccisi o caduti in acqua! | - Le bandiere cadute possono essere restituite o ricatturate! | - I ricci risorgono dalla morte!",
-- ["Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"] = "", -- A_Classic_Fairytale:shadow
-- ["Righteous Beard"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
-- ["ROPE-KNOCKING"] = "", -- User_Mission_-_Rope_Knock_Challenge
@@ -611,8 +608,7 @@ locale = {
["Round Limit"] = "Limite del Round",
["Rounds Complete: "] = "Round Completati: ",
["Rounds Complete"] = "Round Completati",
- ["RULES OF THE GAME [Press ESC to view]"] = "REGOLE DEL GIOCO [Premi ESC per visualizzarle] ",
- ["RULES OF THE GAME [Press ESC to view]"] = "REGOLE DEL GIOCO (Premi ESC per visualizzarle)",
+ ["RULES OF THE GAME [Press ESC to view]"] = "REGOLE DEL GIOCO (Premi ESC per visualizzarle)",
-- ["Rusty Joe"] = "", -- A_Classic_Fairytale:queen
-- ["Sabotage: [Sabotage all hogs in the circle and deal ~10 dmg]"] = "", -- Continental_supplies
-- ["Salivaslurper"] = "", -- A_Classic_Fairytale:united
@@ -627,11 +623,11 @@ locale = {
-- ["Score"] = "", -- Mutant
["SCORE"] = "PUNTEGGIO",
-- ["Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"] = "", -- Continental_supplies
- ["sec"] = "sec", -- CTF_Blizzard, TrophyRace, Basic_Training_-_Bazooka, Basic_Training_-_Shotgun, Basic_Training_-_Sniper_Rifle, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork, Capture_the_Flag
+ ["sec"] = "sec",
-- ["Seduction"] = "", -- Continental_supplies
-- ["Seems like every time you take a \"walk\", the enemy find us!"] = "", -- A_Classic_Fairytale:backstab
-- ["See that crate farther on the right?"] = "", -- A_Classic_Fairytale:first_blood
- ["See ya!"] = "Ci vediamo!",
+ ["See ya!"] = "Ci vediamo!",
-- ["Segmentation Paul"] = "", -- A_Classic_Fairytale:dragon
-- ["Select continent!"] = "", -- Continental_supplies
-- ["Select difficulty: [Left] - easier or [Right] - harder"] = "", -- A_Classic_Fairytale:first_blood
@@ -641,20 +637,20 @@ locale = {
["Shield boosted! +30 power"] = "Scudo ricaricato! Potenza +30",
["Shield Depleted"] = "Scudo Esaurito",
["Shield is fully recharged!"] = "Lo scudo è stato completamente ricaricato!",
- ["Shield Master!"] = "Shield Master!",
- ["Shield Miser!"] = "Scudo Piccolo",
- ["Shield OFF:"] = "Scudo OFF",
- ["Shield ON:"] = "Scudo ON",
- ["Shield Seeker!"] = "Cercatore di Scudi",
--- ["Shotgun"] = "", -- Continental_supplies
- ["Shotgun Team"] = "Squadra Shotgun",
- ["Shotgun Training"] = "Addestramento sull'utilizzo del Fucile a Pompa",
+ ["Shield Master!"] = "Maestro di scudo!",
+ ["Shield Miser!"] = "Povero scudo!",
+ ["Shield OFF:"] = "Scudo OFF:",
+ ["Shield ON:"] = "Scudo ON:",
+ ["Shield Seeker!"] = "Cercatore di Scudi!",
+-- ["Shotgun"] = "",
+ ["Shotgun Team"] = "Squadra Shotgun",
+ ["Shotgun Training"] = "Addestramento sull'utilizzo del Fucile a Pompa",
["shots remaining."] = "colpi rimasti.",
["Silly"] = "Stupido",
["Sinky"] = "Affondato",
-- ["Sirius Lee"] = "", -- A_Classic_Fairytale:enemy
- ["%s is out and Team %d|scored a penalty!| |Score:"] = "%s è fuori dal campo e la squadra %d|prende una penalità !| |Punteggio:", -- Basketball, Knockball
- ["%s is out and Team %d|scored a point!| |Score:"] = "%s è fuori dal campo e la squadra %d|guadagna un punto!| |Puntuación:", -- Basketball, Knockball
+ ["%s is out and Team %d|scored a penalty!| |Score:"] = "%s è fuori dal campo e la squadra %d|prende una penalità !| |Punteggio:",
+ ["%s is out and Team %d|scored a point!| |Score:"] = "%s è fuori dal campo e la squadra %d|guadagna un punto!| |Puntuación:",
-- ["Slippery"] = "", -- A_Classic_Fairytale:journey
-- ["Smith 0.97"] = "", -- A_Classic_Fairytale:enemy
-- ["Smith 0.98"] = "", -- A_Classic_Fairytale:enemy
@@ -664,8 +660,8 @@ locale = {
-- ["Smith 1.0"] = "", -- A_Classic_Fairytale:enemy
-- ["Sniper Rifle"] = "", -- Continental_supplies
-- ["Sniper!"] = "", -- Space_Invasion
- ["Sniper Training"] = "Addestramento sull'utilizzo del Fucile di Precisione",
- ["Sniperz"] = "Cecchini",
+ ["Sniper Training"] = "Addestramento sull'utilizzo del Fucile di Precisione",
+ ["Sniperz"] = "Cecchini",
-- ["So humiliating..."] = "", -- A_Classic_Fairytale:first_blood
-- ["South America"] = "", -- Continental_supplies
-- ["So? What will it be?"] = "", -- A_Classic_Fairytale:shadow
@@ -674,10 +670,10 @@ locale = {
-- ["Spiky Cheese"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
-- ["Spleenlover"] = "", -- A_Classic_Fairytale:united
["Sponge"] = "Spugna",
- ["Spooky Tree"] = "Albero Stregato",
+ ["Spooky Tree"] = "Albero Stregato",
["s|"] = "s|",
- ["s"] = "s", -- GaudyRacer, Space_Invasion
- ["STATUS UPDATE"] = "STATUS AGGIORNATO", -- GaudyRacer, Space_Invasion
+ ["s"] = "s",
+ ["STATUS UPDATE"] = "STATUS AGGIORNATO",
-- ["Steel Eye"] = "", -- A_Classic_Fairytale:queen
-- ["Step By Step"] = "", -- A_Classic_Fairytale:first_blood
-- ["Steve"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
@@ -693,31 +689,31 @@ locale = {
["Switched to "] = "Cambiato in",
-- ["Syntax Errol"] = "", -- A_Classic_Fairytale:dragon
-- ["Talk about mixed signals..."] = "", -- A_Classic_Fairytale:dragon
- ["Team %d: "] = "Squadra %d: ",
- ["Team Scores"] = "Punteggi della Squadra", -- Control, Space_Invasion
+ ["Team %d: "] = "Squadra %d: ",
+ ["Team Scores"] = "Punteggi della Squadra",
-- ["Teleport hint: just use the mouse to select the destination!"] = "", -- A_Classic_Fairytale:dragon
--- ["Thanks!"] = "", -- A_Classic_Fairytale:family
--- ["Thank you, my hero!"] = "", -- A_Classic_Fairytale:family
+ ["Thanks!"] = "Grazie!",
+ ["Thank you, my hero!"] = "Grazie, mio eroe!",
-- ["Thank you, oh, thank you, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
-- ["Thank you, oh, thank you, my heroes!"] = "", -- A_Classic_Fairytale:journey
-- ["That is, indeed, very weird..."] = "", -- A_Classic_Fairytale:united
-- ["That makes it almost invaluable!"] = "", -- A_Classic_Fairytale:enemy
-- ["That ought to show them!"] = "", -- A_Classic_Fairytale:backstab
--- ["That's for my father!"] = "", -- A_Classic_Fairytale:backstab
+ ["That's for my father!"] = "Questo è per mio padre!",
-- ["That shaman sure knows what he's doing!"] = "", -- A_Classic_Fairytale:shadow
["That Sinking Feeling"] = "Quella Sensazione di Affogare...",
-- ["That's not our problem!"] = "", -- A_Classic_Fairytale:enemy
-- ["That's typical of you!"] = "", -- A_Classic_Fairytale:family
--- ["That was just mean!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["That was just mean!"] = "E' semplicemente penoso!",
["That was pointless."] = "Era senza senso.",
-- ["The answer is...entertaintment. You'll see what I mean."] = "", -- A_Classic_Fairytale:backstab
-- ["The anti-portal zone is all over the floor, and I have nothing to kill him...Droping something could hurt him enough to kill him..."] = "", -- portal
-- ["The Bull's Eye"] = "", -- A_Classic_Fairytale:first_blood
-- ["The caves are well hidden, they won't find us there!"] = "", -- A_Classic_Fairytale:united
-- ["The Crate Frenzy"] = "", -- A_Classic_Fairytale:first_blood
--- ["The Dilemma"] = "", -- A_Classic_Fairytale:shadow
+ ["The Dilemma"] = "Il dilemma",
-- ["The enemy can't move but it might be a good idea to stay out of sight!|"] = "", -- A_Classic_Fairytale:dragon
- ["The enemy is hiding out on yonder ducky!"] = "Il nemico si sta nascondendo dietro a quella papera!",
+ ["The enemy is hiding out on yonder ducky!"] = "Il nemico si sta nascondendo dietro a quella papera!",
-- ["The Enemy Of My Enemy"] = "", -- A_Classic_Fairytale:enemy
-- ["The First Blood"] = "", -- A_Classic_Fairytale:first_blood
-- ["The First Encounter"] = "", -- A_Classic_Fairytale:shadow
@@ -788,15 +784,15 @@ locale = {
-- ["Torn Muscle"] = "", -- A_Classic_Fairytale:journey
-- [" to save the village."] = "", -- A_Classic_Fairytale:dragon
-- ["To the caves..."] = "", -- A_Classic_Fairytale:united
- ["Toxic Team"] = "Team Velenoso", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["Toxic Team"] = "Team Velenoso", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
["TRACK COMPLETED"] = "PISTA COMPLETATA",
["TRACK FAILED!"] = "PISTA FALLITA!",
--- ["training"] = "", -- portal
--- ["Traitors"] = "", -- A_Classic_Fairytale:epil
--- ["Tribe"] = "", -- A_Classic_Fairytale:backstab
- ["TrophyRace"] = "TrophyRace",
+ ["training"] = "addestramento",
+ ["Traitors"] = "Traditori",
+ ["Tribe"] = "Tribù",
+ ["TrophyRace"] = "TrophyRace",
-- ["Try to protect the chief! You won't lose if he dies, but it is advised that he survives."] = "", -- A_Classic_Fairytale:united
- ["T_T"] = "T_T",
+ ["T_T"] = "T_T",
["Tumbling Time Extended!"] = "Tempo di Caduta Prolungato!",
-- ["Turns until Sudden Death: "] = "", -- A_Classic_Fairytale:dragon
-- [" turns until Sudden Death! Better hurry!"] = "", -- A_Classic_Fairytale:dragon
@@ -809,7 +805,7 @@ locale = {
-- ["Unexpected Igor"] = "", -- A_Classic_Fairytale:dragon
-- ["Unit 0x0007"] = "", -- A_Classic_Fairytale:family
-- ["Unit 334a$7%;.*"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
- ["Unit 3378"] = "Unità 3378",
+ ["Unit 3378"] = "Unità 3378",
["Unit 835"] = "Unità 835",
-- ["United We Stand"] = "", -- A_Classic_Fairytale:united
["Unit"] = "Unità ",
@@ -821,16 +817,15 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Sfida Utente",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
- ["Use your rope to get from start to finish as fast as you can!"] = "Usa la tua corda per raggiungere il traguardo il più velocemente possibile!",
+ ["Use your rope to get from start to finish as fast as you can!"] = "Usa la tua corda per raggiungere il traguardo il più velocemente possibile!",
-- ["Vedgies"] = "", -- A_Classic_Fairytale:journey
-- ["Vegan Jack"] = "", -- A_Classic_Fairytale:enemy
-- ["Victory!"] = "", -- Basic_Training_-_Rope
- ["Victory for the"] = "La vittoria è di",
- ["Victory for the "] = "La vittoria è di ", -- CTF_Blizzard, Capture_the_Flag
+ ["Victory for the "] = "La vittoria è di ",
-- ["Violence is not the answer to your problems!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Walls Left"] = "", -- WxW
-- ["Walls Required"] = "", -- WxW
@@ -855,7 +850,7 @@ locale = {
-- ["Welcome, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
["Well done."] = "Ben fatto.",
-- ["We'll give you a problem then!"] = "", -- A_Classic_Fairytale:enemy
--- ["We'll spare your life for now!"] = "", -- A_Classic_Fairytale:backstab
+ ["We'll spare your life for now!"] = "Ti risparmieremo la vita per ora!",
-- ["Well, that was a waste of time."] = "", -- A_Classic_Fairytale:dragon
-- ["Well, well! Isn't that the cutest thing you've ever seen?"] = "", -- A_Classic_Fairytale:journey
-- ["Well, yes. This was a cyborg television show."] = "", -- A_Classic_Fairytale:enemy
@@ -864,13 +859,13 @@ locale = {
-- ["We need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
-- ["We need to warn the village."] = "", -- A_Classic_Fairytale:shadow
-- ["We should head back to the village now."] = "", -- A_Classic_Fairytale:shadow
--- ["We were trying to save her and we got lost."] = "", -- A_Classic_Fairytale:family
--- ["We won't let you hurt her!"] = "", -- A_Classic_Fairytale:journey
+ ["We were trying to save her and we got lost."] = "Stavamo cercando di salvarla e ci siamo persi.",
+ ["We won't let you hurt her!"] = "Non vi lasceremo farle del male!",
-- ["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "", -- A_Classic_Fairytale:first_blood
-- ["What a douche!"] = "", -- A_Classic_Fairytale:enemy
--- ["What am I gonna...eat, yo?"] = "", -- A_Classic_Fairytale:family
--- ["What are you doing at a distance so great, young one?"] = "", -- A_Classic_Fairytale:first_blood
--- ["What are you doing? Let her go!"] = "", -- A_Classic_Fairytale:journey
+ ["What am I gonna...eat, yo?"] = "Cosa mengerò... te?",
+ ["What are you doing at a distance so great, young one?"] = "Cosa state facendo a questa enorme distanza, voi?",
+ ["What are you doing? Let her go!"] = "Cosa state facendo? Lasciatela andare!",
-- ["What a ride!"] = "", -- A_Classic_Fairytale:shadow
-- ["What a strange cave!"] = "", -- A_Classic_Fairytale:dragon
-- ["What a strange feeling!"] = "", -- A_Classic_Fairytale:backstab
@@ -879,64 +874,64 @@ locale = {
-- [" What !! For all of this struggle i just win some ... TIME o0"] = "", -- portal
-- ["What has "] = "", -- A_Classic_Fairytale:backstab
-- ["What? Here? How did they find us?!"] = "", -- A_Classic_Fairytale:backstab
--- ["What is this place?"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy
+ ["What is this place?"] = "Cos'è questo posto?",
-- ["What shall we do with the traitor?"] = "", -- A_Classic_Fairytale:backstab
-- ["WHAT?! You're the ones attacking us!"] = "", -- A_Classic_Fairytale:enemy
-- ["When?"] = "", -- A_Classic_Fairytale:enemy
-- ["When I find it..."] = "", -- A_Classic_Fairytale:dragon
-- ["Where are all these crates coming from?!"] = "", -- A_Classic_Fairytale:shadow
--- ["Where are they?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Where did that alien run?"] = "", -- A_Classic_Fairytale:dragon
--- ["Where did you get the exploding apples?"] = "", -- A_Classic_Fairytale:shadow
+ ["Where are they?!"] = "Dove sono loro?!",
+ ["Where did that alien run?"] = "Dov'è corso quell'alieno?",
+ ["Where did you get the exploding apples?"] = "Dove avete preso le mele explosive?",
-- ["Where did you get the exploding apples and the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
-- ["Where did you get the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
-- ["Where did you get the weapons in the forest, Dense Cloud?"] = "", -- A_Classic_Fairytale:backstab
--- ["Where do you get that?!"] = "", -- A_Classic_Fairytale:enemy
--- ["Where have you been?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Where have you been?"] = "", -- A_Classic_Fairytale:united
--- ["? Why?"] = "", -- A_Classic_Fairytale:backstab
--- ["Why "] = "", -- A_Classic_Fairytale:backstab
--- ["! Why?!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
--- ["Why are you doing this?"] = "", -- A_Classic_Fairytale:journey
--- ["Why are you helping us, uhm...?"] = "", -- A_Classic_Fairytale:family
+ ["Where do you get that?!"] = "Dove avete preso quello?!",
+ ["Where have you been?!"] = "Dove siete stati?!",
+ ["Where have you been?"] = "Dove siete stati?",
+ ["? Why?"] = "? Perché?",
+ ["Why "] = "Perché ",
+ ["! Why?!"] = "! Perché?!",
+ ["Why are you doing this?"] = "Perché stai facendo questo?",
+ ["Why are you helping us, uhm...?"] = "Perché ci stai aiutando, mmm...?",
-- ["Why can't he just let her go?!"] = "", -- A_Classic_Fairytale:family
-- ["Why do men keep hurting me?"] = "", -- A_Classic_Fairytale:first_blood
--- ["Why do you not like me?"] = "", -- A_Classic_Fairytale:shadow
+ ["Why do you not like me?"] = "Perché non ti piaccio?",
-- ["Why do you want to take over our island?"] = "", -- A_Classic_Fairytale:enemy
--- ["Why me?!"] = "", -- A_Classic_Fairytale:backstab
+ ["Why me?!"] = "Perché io?!",
-- ["Why would they do this?"] = "", -- A_Classic_Fairytale:backstab
-- ["- Will Get 1-3 random weapons"] = "", -- Continental_supplies
-- ["- Will refresh Parachute each turn."] = "", -- Continental_supplies
-- ["- Will refresh portalgun each turn."] = "", -- Continental_supplies
["Will this ever end?"] = "Finirà mai?",
--- ["WINNER IS "] = "", -- Mutant
+ ["WINNER IS "] = "IL VINCITORE E' ",
["WINNING TIME: "] = "TEMPO VINCENTE: ",
-- ["Wise Oak"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["With Dense Cloud on the land of shadows, I'm the village's only hope..."] = "", -- A_Classic_Fairytale:journey
-- ["With the rest of the tribe gone, it was up to "] = "", -- A_Classic_Fairytale:dragon
-- ["Worry not, for it is a peaceful animal! There is no reason to be afraid..."] = "", -- A_Classic_Fairytale:first_blood
--- ["Wow, what a dream!"] = "", -- A_Classic_Fairytale:backstab
--- ["Y3K1337"] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
--- ["Yay, we won!"] = "", -- A_Classic_Fairytale:enemy
--- ["Y Chwiliad"] = "", -- A_Classic_Fairytale:dragon
+ ["Wow, what a dream!"] = "Wow, che sogno!",
+ ["Y3K1337"] = "Y3K1337", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
+ ["Yay, we won!"] = "Sì, abbiamo vinto!",
+ ["Y Chwiliad"] = "Y Cwhiliad", -- A_Classic_Fairytale:dragon
-- ["Yeah...I think it's a 'he', lol."] = "", -- A_Classic_Fairytale:shadow
--- ["Yeah, sure! I died. Hillarious!"] = "", -- A_Classic_Fairytale:backstab
--- ["Yeah, take that!"] = "", -- A_Classic_Fairytale:dragon
--- ["Yeah? Watcha gonna do? Cry?"] = "", -- A_Classic_Fairytale:journey
--- ["Yes!"] = "", -- A_Classic_Fairytale:enemy
--- ["Yes, yeees! You are now ready to enter the real world!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Yo, dude, we're here, too!"] = "", -- A_Classic_Fairytale:family
+ ["Yeah, sure! I died. Hillarious!"] = "Sì, davvero! Sono morto! Divertente!", -- A_Classic_Fairytale:backstab
+ ["Yeah, take that!"] = "Sì, prendilo!", -- A_Classic_Fairytale:dragon
+ ["Yeah? Watcha gonna do? Cry?"] = "Sì? Cosa pensate di fare? Piangere?", -- A_Classic_Fairytale:journey
+ ["Yes!"] = "Sì!",
+ ["Yes, yeees! You are now ready to enter the real world!"] = "S^, sìì! Ora siete pronti per entrare nel mondo reale!",
+ ["Yo, dude, we're here, too!"] = "Ehi, tu, ci siamo anche noi, qui!",
-- ["You are given the chance to turn your life around..."] = "", -- A_Classic_Fairytale:shadow
-- ["You are playing with our lives here!"] = "", -- A_Classic_Fairytale:enemy
--- ["! You bastards!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["! You bastards!"] = "! Bastardi!",
-- ["You bear impressive skills, "] = "", -- A_Classic_Fairytale:dragon
-- ["You can't fire a portal on the blue surface"] = "", -- portal
-- ["You couldn't possibly believe that after refusing my offer I'd just let you go!"] = "", -- A_Classic_Fairytale:journey
["You'd almost swear the water was rising!"] = "Guarda, l'acqua si sta alzando rapidamente!",
-- ["You'd better watch your steps..."] = "", -- A_Classic_Fairytale:journey
--- ["You did not make it in time, try again!"] = "", -- Basic_Training_-_Rope
+ ["You did not make it in time, try again!"] = "Non hai fatto in tempo, prova ancora!",
-- ["You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."] = "", -- A_Classic_Fairytale:backstab
--- ["You have "] = "", -- A_Classic_Fairytale:dragon
+ ["You have "] = "Hai ",
-- ["You have been giving us out to the enemy, haven't you!"] = "", -- A_Classic_Fairytale:backstab
-- ["You have been respawned, at your last checkpoint!"] = "", -- Basic_Training_-_Rope
-- ["You have been respawned, be more carefull next time!"] = "", -- Basic_Training_-_Rope
@@ -948,8 +943,8 @@ locale = {
-- ["You have killed an innocent hedgehog!"] = "", -- A_Classic_Fairytale:backstab
-- ["You have proven yourself worthy to see our most ancient secret!"] = "", -- A_Classic_Fairytale:first_blood
-- ["You have proven yourselves worthy!"] = "", -- A_Classic_Fairytale:enemy
- ["You have SCORED!!"] = "Hai guadagnato un PUNTO!!",
--- ["You have to destroy 12 targets in 180 seconds"] = "", -- Basic_Training_-_Cluster_Bomb
+ ["You have SCORED!!"] = "Hai guadagnato un PUNTO!!",
+ ["You have to destroy 12 targets in 180 seconds"] = "Devi distruggere 12 bersagli in 180 secondi",
-- ["You have won the game by proving true cooperative skills!"] = "", -- A_Classic_Fairytale:enemy
-- ["You just appeared out of thin air!"] = "", -- A_Classic_Fairytale:backstab
-- ["You just committed suicide..."] = "", -- A_Classic_Fairytale:shadow
@@ -957,30 +952,30 @@ locale = {
-- ["You know...taking a stroll."] = "", -- A_Classic_Fairytale:backstab
-- ["You know what? I don't even regret anything!"] = "", -- A_Classic_Fairytale:backstab
-- ["You'll see what I mean!"] = "", -- A_Classic_Fairytale:enemy
--- ["You may only attack from a rope!"] = "", -- WxW
+ ["You may only attack from a rope!"] = "Puoi attaccare solo da una corda!",
-- ["You meatbags are pretty slow, you know!"] = "", -- A_Classic_Fairytale:enemy
-- ["You might want to find a way to instantly kill arriving cannibals!"] = "", -- A_Classic_Fairytale:backstab
-- ["Young one, you are telling us that they can instantly change location without a shaman?"] = "", -- A_Classic_Fairytale:united
-- ["You probably know what to do next..."] = "", -- A_Classic_Fairytale:first_blood
-- ["Your deaths will be avenged, cannibals!"] = "", -- A_Classic_Fairytale:enemy
-- ["Your death will not be in vain, Dense Cloud!"] = "", -- A_Classic_Fairytale:shadow
--- ["You're...alive!? But we saw you die!"] = "", -- A_Classic_Fairytale:backstab
--- ["You're a pathetic liar!"] = "", -- A_Classic_Fairytale:backstab
--- ["You're funny!"] = "", -- A_Classic_Fairytale:journey
+ ["You're...alive!? But we saw you die!"] = "Sei...vivo!? Ma noi ti abbiamo visto morire!",
+ ["You're a pathetic liar!"] = "Sei un patetico bugiardo!",
+ ["You're funny!"] = "Sei divertente!",
-- ["You're getting pretty good! |Tip: When you shorten you rope you move faster! |and when you lengthen it you move slower"] = "", -- Basic_Training_-_Rope
-- ["You're pathetic! You are not worthy of my attention..."] = "", -- A_Classic_Fairytale:shadow
-- ["You're probably wondering why I bought you back..."] = "", -- A_Classic_Fairytale:backstab
-- ["You're terrorizing the forest...We won't catch anything like this!"] = "", -- A_Classic_Fairytale:shadow
--- ["Your hogs must survive!"] = "", -- A_Classic_Fairytale:journey
+ ["Your hogs must survive!"] = "I vostri ricci devono sopravvivere!",
-- ["Your movement skills will be evaluated now."] = "", -- A_Classic_Fairytale:first_blood
["You saved"] = "Hai salvato",
-- ["You've been assaulting us, we have been just defending ourselves!"] = "", -- A_Classic_Fairytale:enemy
- ["You've failed. Try again."] = "Hai fallito. Prova di nuovo.",
- ["You've reached the goal!| |Time: "] = "Hai raggiunto il traguardo!| |Tempo: ",
--- ["You will be avenged!"] = "", -- A_Classic_Fairytale:shadow
--- ["You won't believe what happened to me!"] = "", -- A_Classic_Fairytale:backstab
+ ["You've failed. Try again."] = "Hai fallito. Prova di nuovo.",
+ ["You've reached the goal!| |Time: "] = "Hai raggiunto il traguardo!| |Tempo: ",
+ ["You will be avenged!"] = "Sarai vendicato!",
+ ["You won't believe what happened to me!"] = "Non crederete a quello che mi è successo!",
-- ["Yuck! I bet they'll keep worshipping her even after I save the village!"] = "", -- A_Classic_Fairytale:family
--- ["Zealandia"] = "", -- Continental_supplies
- ["'Zooka Team"] = "Squadra 'Zooka",
--- ["Zork"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["Zealandia"] = "Zealandia",
+ ["'Zooka Team"] = "Squadra 'Zooka",
+ ["Zork"] = "Zork",
}
diff --git a/share/hedgewars/Data/Locale/it.txt b/share/hedgewars/Data/Locale/it.txt
index 83f2568..b39848f 100644
--- a/share/hedgewars/Data/Locale/it.txt
+++ b/share/hedgewars/Data/Locale/it.txt
@@ -54,10 +54,10 @@
00:51=Palla di Fango
00:52=Nessuna Arma Selezionata
00:53=Macchina Spazio-Temporale
-00:54=Attrezzi da Costruzione
-00:55=Land Spray
-00:56=Congelatore
-00:57=Mannarino
+; 00:54=Attrezzi da Costruzione
+00:54=Terreno Spray
+00:55=Raggio Congelatore
+00:56=Mannarino
01:00=Combattiamo!
01:01=Round in paritÃ
@@ -389,7 +389,7 @@
02:10=Proprio un bel colpo!
; Hog (%1) has to leave (team is gone)
-02:11=%1 deve andare a dormire!
+02:11=%1 deve andare a dormire!
02:11=%1 sembra che non abbia tempo per giocare
02:11=%1 se ne deve andare
02:11=%1 stava giocando sui PC della scuola ed è stato beccato
@@ -451,10 +451,10 @@
03:51=Terreno al 100%
03:52=NON USATO
03:53=TARDIS Modello 40
-03:54=(Arma in sviluppo)
-03:55=Utilità di costruzione
-03:56=(Arma in sviluppo)
-03:57=Ecco il grande chef!
+;03:54=(Arma in sviluppo)
+03:54=Utilità di costruzione
+03:55=Arma di ibernazione di massa
+03:56=Ecco il grande chef!
; Weapon Descriptions (use | as line breaks)
04:00=Attacca i tuoi nemici con una semplice granata.|Esploderà quando il timer arriverà a zero secondi.|1-5: Imposta il timer della granata|Attacco: Tieni premuto per lanciare con più forza|Mirino di Precisione + 1-5: Imposta livello di rimbalzo
@@ -511,10 +511,10 @@
04:51=Spingete i nemici in acqua o sopra le mine!|Questa semplice arma non farà molti danni ma|spingerà con forza i nemici che colpisce!|Nei temi Snow e Christmas è una palla di neve!|Attacco: Tieni premuto per lanciare con più forza
04:52=NON USATO
04:53=Parti per un'avventura unica attraverso spazio e tempo,|lasciando i tuoi compagni da soli a combattere.|Preparati a ritornare in qualsiasi momento,|o per il Sudden Death o se sei l'ultimo sopravvissuto.|Attenzione! Non è utilizzabile durante il Sudden Death,|se sei rimasto da solo, o se sei il Re.|Attacco: Inzia la tua avventura nello spazio-tempo!
-04:54=DESCRIZIONE NON DISPONIBILE (arma ancora in sviluppo)
-04:55=Con questo terreno spray non ti mancherà mai la terra |sotto ai piedi. Utilissimo per costruire ponti, |seppellire nemici e sigillare tunnel.|Ma fai attenzione a non usarlo a tuo svantaggio!|Attacco: Attiva|Su/Giù: Continua a mirare|Sinistra/Destra: Modifica la potenza di fuoriuscita del terreno
-04:56=DESCRIZIONE NON DISPONIBILE (arma ancora in sviluppo)
-04:57=Lancia due mannarini da cucina verso i tuoi nemici, se |lanciati con potenza possono rappresentare una... tagliente sorpresa!|Ricorda che rimarranno sul terreno dopo averli lanciati!|Attacco: Tieni premuto per lanciare con più forza
+;04:54=DESCRIZIONE NON DISPONIBILE (arma ancora in sviluppo)
+04:54=Con questo terreno spray non ti mancherà mai la terra |sotto ai piedi. Utilissimo per costruire ponti, |seppellire nemici e sigillare tunnel.|Ma fai attenzione a non usarlo a tuo svantaggio!|Attacco: Attiva|Su/Giù: Continua a mirare|Sinistra/Destra: Modifica la potenza di fuoriuscita del terreno
+04:55=L'era glaciale non è mai stata così imminente!|Con questo potente raggio potrai congelare i ricci nemici,|rendere il terreno scivoloso e salvarti dalle cadute|in acqua trasformando il mare in una distesa di ghiaccio!|Attacco: Attiva|Su/Giù: Continua a mirare
+04:56=Lancia due mannarini da cucina verso i tuoi nemici, se |lanciati con potenza possono rappresentare una... tagliente sorpresa!|Ricorda che rimarranno sul terreno dopo averli lanciati!|Attacco: Tieni premuto per lanciare con più forza
; Game goal strings
05:00=Modalità di Gioco
diff --git a/share/hedgewars/Data/Locale/ja.txt b/share/hedgewars/Data/Locale/ja.txt
index efe0841..853e522 100644
--- a/share/hedgewars/Data/Locale/ja.txt
+++ b/share/hedgewars/Data/Locale/ja.txt
@@ -54,8 +54,8 @@
00:51=åå°ç
00:52=æ¦å¨ãæºããªã
00:53=TARDIS
-00:54=æ§é
-00:55=åå°ã¹ãã¬ã¼
+; 00:54=æ§é
+00:54=åå°ã¹ãã¬ã¼
01:00=ã¨ã·ããã¡ã¤ãï¼
01:01=ããã¼ï¼
@@ -177,7 +177,6 @@
02:01=%1ã¯ã¨ã³ã¼ã¶ã®ã¤ã«ã«ãåçããã
02:01=%1ã¯æ°´æ館ã訪åãã¦ãã¾ã£ã
02:01=%1ãã¢ãã©ã³ãã£ã¹ã®å¤±ãããé½å¸ãçºè¦ãã
-02:01=%1ã§Bioshock3ã®å
å°çãªå½¹å²ãç®æãã¦
02:01=ããªãã®ç¬ã®ããã«ã¯ãå°ãä½æ¥ã¯ã%1ã使ç¨ãããã¨ãã§ãã¾ã
02:01=%1ã¯ã¸ã§ããã¹ãã¼ãæã£ã¦ããå¿
è¦ãããã¾ã
02:01=%1ã¯ã¦ã©ã¼ã¿ã¼ã¹ãã¼ãã好ãã§ã¯ããã¾ããã
@@ -466,66 +465,66 @@
03:51=å°ä¸ã§çºè¦
03:52=UNUSED
03:53=ã¿ã¤ã40
-03:54=ä½ããæ§ç¯
-03:55=ã¦ã¼ãã£ãªãã£
+;03:54=ä½ããæ§ç¯
+03:54=ã¦ã¼ãã£ãªãã£
; Weapon Descriptions (use | as line breaks)
-04:00=ã·ã³ãã«ãªæ榴弾ã使ã£ã¦æµãæ»æããã®ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããççºããã1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
-04:01=ã¯ã©ã¹ã¿ã¼çå¼¾ã使ç¨ãã¦æµãæ»æããã®ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããã¯å°ããªçå¼¾ã«åå²ããã¾ãã1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
-04:02=風ã«å½±é¿ããããããããªãå¼¾éçºå°ä½ã使ç¨ãã¦æµãæ»æãæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:03=é¸æããã¿ã¼ã²ããã«ããã¯ããççºçãªèãèµ·åãã¾ãããã®ç²¾åº¦ãåä¸ãããããã«ãã«ãã¯ã¼ã使ã£ã¦æ®å½±ããªãã§ãã ãããã«ã¼ã½ã«ï¼ããã¯ã¿ã¼ã²ããæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:04=2ã·ã§ããã§ã·ã§ããã¬ã³ã使ã£ã¦æµãæ»æããããã®åºããããªãã®ãããã§ãããªãã®å¯¾æ¦ç¸æã«å±å®³ãç´æ¥ãããããå¿
è¦ã¯ããã¾ãããæ»æï¼ã·ã¥ã¼ãï¼è¤æ°åï¼
-04:05=å°ä¸ã«ç§»åï¼å°é¢ã«ç©´ãéããã¨ä»ã®é åã«å°éããã使ç¨ãã¦ãã¾ããæ»æã®éå§ã¾ãã¯åæ¢æã
-04:06=éå±ï¼æ»æããæ¹æ³ã¯ããã¾ããï¼ããªãã®å¼¾è¬ãä¿åãã¾ããï¼åé¡ããã¾ããï¼ã¡ããã©ããªãã®ã¿ã¼ã³ãèç
è
ãã¹ããããã¦ï¼æ»æï¼æ¦éããã«ã¿ã¼ã³ãã¹ããã
-04:07=ãã¼ãã§ã¿ã¤ã ã¢ã¦ãã·ã§ããã使ç¨ãã¦ã巨大ãªè·é¢ãåãããä»ã®è±ã¾ãã¯ããããæ榴弾ããã³ãããã®ä»ã®æ¦å¨ã«ã¹ã©ã¤ãããããã«å¢ãã使ç¨ãã¦ãã¾ããæ»æï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ãã¼ããã³ã°ã¸ã£ã³ãã·ã¥ã¼ãã¾ãã¯è§£æ¾
-04:08=çãéè·¯ã®å³ã¾ãã¯ãããã®è¶³ã®ä¸é±å±±ããããããããã¨ã§ãé¢ãã¦ããªãã®æµãä¿ã¤ãããªãèªèº«ã§ãããããªã¬ããåã«æ¤éãã¦ãã ããï¼æ»æï¼ããªãã®è¶³ã®é£ã«å°é·ãåé¤ãã¾ãã
-04:09=ããªãã®ç
§æºãåãããªãï¼4æå·®ã¾ã§ã使ç¨ãã¦æ»æããããã«ãã¶ã¼ãã¤ã¼ã°ã«ã使ç¨ãã¦ãã¾ããæ»æï¼ã·ã¥ã¼ãï¼è¤æ°åï¼
-04:10=ãã«ã¼ããã©ã¼ã¹ã¯å¸¸ã«ãªãã·ã§ã³ã§ããããªãã®æµã¨å¾éã®é£ã«ãããã®å¤å
¸çãªççºç©ããããããã¾ããæ»æï¼ããªãã®è¶³ã®é£ã«ãããããããã¤ããã¤ã
-04:11=ãããã®å½å¢ãè¶ãã¦ã¾ãã¯æ°´ã®ä¸ã«ãããããããã£ã³ã°ãã¦æµã®è±ãåãé¤ããã¾ãã¯ã©ã®ããã«ãåéã«ããã¤ãã®é±å±±ãããã¯ã§ããããï¼æ»æï¼ããªãã®åã«ããããã¹ã¦ã
-04:12=ãã®ã»ã¨ãã©è´å½çãªæ¦éæè¡ã®åã解ãæ¾ã¤ã«è¿ãã¨å人çãªåå¾ãã¾ããæ»æï¼ç´ æ´ããããå®è¡ãã¾ãã
+04:00=ã·ã³ãã«ãªæ榴弾ã使ã£ã¦æµãæ»æã|ãã®ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããççºããã|1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
+04:01=ã¯ã©ã¹ã¿ã¼çå¼¾ã使ç¨ãã¦æµãæ»æã|ãã®ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããã¯å°ããªçå¼¾ã«åå²ããã¾ãã|1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
+04:02=風ã«å½±é¿ããããããããªãå¼¾éçºå°ä½ã使ç¨ãã¦æµãæ»æã|æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:03=é¸æããã¿ã¼ã²ããã«ããã¯ããççºçãªèãèµ·åãã¾ãã|ãã®ç²¾åº¦ãåä¸ãããããã«ãã«ãã¯ã¼ã使ã£ã¦æ®å½±ããªãã§ãã ããã|ã«ã¼ã½ã«ï¼ããã¯ã¿ã¼ã²ããæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:04=2ã·ã§ããã§ã·ã§ããã¬ã³ã使ã£ã¦æµãæ»æããã|ãã®åºããããªãã®ãããã§ãããªãã®å¯¾æ¦ç¸æã«å±å®³ãç´æ¥ãããããå¿
è¦ã¯ããã¾ããã|æ»æï¼ã·ã¥ã¼ãï¼è¤æ°åï¼
+04:05=å°ä¸ã«ç§»åï¼|å°é¢ã«ç©´ãéããã¨ä»ã®é åã«å°éããã使ç¨ãã¦ãã¾ãã|æ»æã®éå§ã¾ãã¯åæ¢æã
+04:06=éå±ï¼æ»æããæ¹æ³ã¯ããã¾ããï¼ããªãã®å¼¾è¬ãä¿åãã¾ããï¼åé¡ããã¾ããï¼|ã¡ããã©ããªãã®ã¿ã¼ã³ãèç
è
ãã¹ããããã¦ï¼|æ»æï¼æ¦éããã«ã¿ã¼ã³ãã¹ããã
+04:07=ãã¼ãã§ã¿ã¤ã ã¢ã¦ãã·ã§ããã使ç¨ãã¦ã巨大ãªè·é¢ãåããã|ä»ã®è±ã¾ãã¯ããããæ榴弾ããã³ãããã®ä»ã®æ¦å¨ã«ã¹ã©ã¤ãããããã«å¢ãã使ç¨ãã¦ãã¾ãã|æ»æï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ãã¼ããã³ã°ã¸ã£ã³ãã·ã¥ã¼ãã¾ãã¯è§£æ¾
+04:08=çãéè·¯ã®å³ã¾ãã¯ãããã®è¶³ã®ä¸é±å±±ããããããããã¨ã§ãé¢ãã¦ããªãã®æµãä¿ã¤ã|ããªãèªèº«ã§ãããããªã¬ããåã«æ¤éãã¦ãã ããï¼|æ»æï¼ããªãã®è¶³ã®é£ã«å°é·ãåé¤ãã¾ãã
+04:09=ããªãã®ç
§æºãåãããªãï¼4æå·®ã¾ã§ã使ç¨ãã¦æ»æããããã«ãã¶ã¼ãã¤ã¼ã°ã«ã使ç¨ãã¦ãã¾ãã|æ»æï¼ã·ã¥ã¼ãï¼è¤æ°åï¼
+04:10=ãã«ã¼ããã©ã¼ã¹ã¯å¸¸ã«ãªãã·ã§ã³ã§ãã|ããªãã®æµã¨å¾éã®é£ã«ãããã®å¤å
¸çãªççºç©ããããããã¾ãã|æ»æï¼ããªãã®è¶³ã®é£ã«ãããããããã¤ããã¤ã
+04:11=ãããã®å½å¢ãè¶ãã¦ã¾ãã¯æ°´ã®ä¸ã«ãããããããã£ã³ã°ãã¦æµã®è±ãåãé¤ãã|ã¾ãã¯ã©ã®ããã«ãåéã«ããã¤ãã®é±å±±ãããã¯ã§ããããï¼æ»æï¼ããªãã®åã«ããããã¹ã¦ã
+04:12=ãã®ã»ã¨ãã©è´å½çãªæ¦éæè¡ã®åã解ãæ¾ã¤ã«è¿ãã¨å人çãªåå¾ãã¾ãã|æ»æï¼ç´ æ´ããããå®è¡ãã¾ãã
04:13=UNUSED
-04:14=é«æææçï¼åªãããã©ã·ã¥ã¼ããã¤ãããããã¯ããªããé ããããè½ã¡ãå±éã¨ç§ã®ãã¡ã¼ã¸ãåãã¦ããè±ãä¿åãã¾ããæ»æï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ãã©ã·ã¥ã¼ããã³ã°ã¸ã£ã³ãã伸ã°ã
-04:15=çæã®å®è¡ã使ç¨ãã¦æµãæ»æããé£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ããå·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
-04:16=ã¿ã¼ã²ããã¨ãªã¢ã«ããã¤ãã®é±å±±ãããããããã«ã¯é£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ããå·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
-04:17=é¿é£ãå¿
è¦ã§ããï¼ããªããã«ãã¼ä»ä¸åºä½å°é¢ã«ãã³ãã«ãæãããã«ããã¼ãã¼ãã使ç¨ãã¦ãã¾ããæ»æã®éå§ã¾ãã¯åæ¢æã
-04:18=追å ã®ä¿è·ãå¿
è¦ãªå ´åãã¾ãã¯å°é¢ãééãããã§ããï¼å¥½ããªããã«ãããã¤ãã®æ¡ã«ç½®ãã¾ããæå¹ãªä½ç½®ã«é
ç½®æ¡ï¼å·¦å³ï¼ã«ã¼ã½ã«ãé
ç½®ããé¸ææ¡
-04:19=ããã¯ããªããæ°ç§ä»¥å
ã«å±éºãªç¶æ³ããè±ãä¿åãããã¨ãã§ãã¾ãããã«ãå³ç¬éãã¬ãã¼ãã¼ã·ã§ã³ã§ä½¿ç¨ããã»ã¼ãã¹ã¦ã®æ¦å¨ãããå¼·åã«ãããã¨ãã§ãã¾ããã«ã¼ã½ã«ï¼é¸æãã¦ã¿ã¼ã²ããé å
-04:20=å¥ã®è±ã¨ãç¾å¨ã®ã¿ã¼ã³ãåçãããã¨ãã§ãã¾ããæ»æï¼ã¹ã¤ããã³ã°è±ãæå¹ã«ãã
-04:21=ã¤ã³ãã¯ãæã«è¤æ°ã®çå¼¾ã解æ¾ãã¾ãæ榴弾ã®ãããªå¼¾ä¸¸ãæã¤ãæ»æï¼ãã«ãã¯ã¼ã§æã¤
-04:22=ã ãã§ãªããã¤ã³ãã£ã¸ã§ã¼ã³ãºã®ããã«ï¼éã¯å¤ãã®ç¶æ³ã§æç¨ãªæ¦å¨ã§ãããããªããå´ãã誰ããçªãåºããããå ´åã¯ç¹ã«ãæ»æï¼ããªãã®åã«ã¹ãã©ã¤ã¯ã®ãã¹ã¦
-04:23=ããªãã失ããã®ã¯ä½ããªãå ´åãããã¯ããªã便å©ããããã¾ãããå½¼ã®æ¹æ³ä¸ã®ãã¹ã¦ãå·ã¤ããã¨çµäºæã«ççºããç¹å®ã®æ¹åã«å½¼ãèµ·åãããã¨ã§ãè±ãçãè´ã«æ§ãããæ»æï¼å£æ»
çãªãè´å½çãªæ»æãéå§
-04:24=èªçæ¥ããã§ã¨ãï¼ãã®ã±ã¼ããèµ·åãããããå³ã®æµã®é£ã«æ©ãã¦ãå½¼ããççºçãã¼ãã£ãæããã¦ã¿ã¾ããããã±ã¼ãã¯ãã»ã¼ãã¹ã¦ã®å°å½¢ãééãããã¨ãã§ãã¾ãããå½¼ã¯ä»¥åããã®æ¹æ³ãççºãããããããã¾ãããæ»æï¼ã±ã¼ããèµ·åããããåæ¢ãããã¨ççºãã
-04:25=ï¼ããã¦ãããã¤ãã®ã®ã£ãããç©´ï¼ãè±ã«åãã£ã¦ã¸ã£ã³ããããã¨ãããªãã®æµãåå¾ããã«ã¯ããã®å¤è£
ãããã使ç¨ãã¦ãã¾ããæ»æï¼ãããã使ç¨ãã¦ãå¥ã®è±ãèªæããã
-04:26=ããªãã®æµã§ããã®ã¸ã¥ã¼ã·ã¼ãªã¹ã¤ã«ãã¹ãã¼ãã¾ããã¿ã¤ãã¼ã®æéãåããã¨ãããã¯ããã¤ãã®ççºçãªæçã«åå²ããã¾ãã1-5ï¼ã»ããã¹ã¤ã«ã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:27=ãã®æªéã®ããççºã使ç¨ãã¦ãããªãã®å¯¾æ¦ç¸æã«æ¥ç«ã®é¨ãã¦ã¿ã¾ããããè¿ãããå°ããªç«ç½ãé·ãç¶ããããããªãã¨ççºã«å¾ããã¨ã¯ããã¾ãããæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:28=ãã®ãã±ãããæã¡ä¸ããå¾ã®çãæéãããã¯åºä½å°é¢ãæåãéå§ãããã®ãã¥ã¼ãºãããªã¬ãããã¨ççºããããåã³åæµ®ä¸ãã¾ããæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:29=ããã¯å°ããªåä¾ã®ããã®ãã®ã§ã¯ããã¾ããï¼ãã¼ã«éã¯çè¬ãå
å¡«ããå°ããªè²ã®ãã¼ã«ã®ãã³ãçºçããã¾ããæ»æï¼ã¢ãããã¦ã³ããã«ãã¯ã¼ã§ã·ã¥ã¼ããç®æãã¦é²ã¿ã¾ã
-04:30=å¼·åãªããã¼ã ã¹ãã©ã¤ããèµ·åããã«ã¯é£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ããé©åã«ãã®æ»æãç®æãã¦ããã«åº§ã£ã¦ä¸éãªè±ãå«ã風æ¯ã®å·¨å¤§ãªé¨åãæ ¹çµ¶ãããã¨ãã§ãã¾ããå·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
-04:31=RCãã¬ã¼ã³ã¯ç®±ãåéããããé ãé¢ããè±ãæ»æããã®ã«çæ³çãªæ¦å¨ã§ããã©ã¡ãã®æµã«ãããæ縦ããããæåã®ããã¤ãã®çå¼¾ããããããã¾ããæ»æï¼ã¯ã«ãã¥ã¼ã¬ãæ¦éã«ä¹ãã¾ãããå·¦å³ï¼å¹³é¢ã¹ãã¢ã¸ã£ã³ãå¹³é¢ã¾ãã¯ãããããã³ã°çå¼¾ãèµ·åãã¾ãã
-04:32=ä½éåã¯ã©ããªãã¤ã¨ãããããå¹æçã§ãï¼é«ããé·ãè·é¢ãé£ã³è¶ããããæµãããã«é£ã¶ãã¾ããããæ»æï¼ã¢ã¯ãã£ã
-04:33=æã«ã¯ãããã¤ãã®ããå¤ãã®ãã¡ã¼ã¸ãä¸ããããã«ãã®å°ãä½åãªãã¼ã¹ããã¡ããã©å¿
è¦ãããã¾ããæ»æï¼ã¢ã¯ãã£ã
-04:34=ç§ã«è§¦ãããã¨ãã§ããªãï¼æ»æï¼ã¢ã¯ãã£ã
-04:35=æã«ã¯æéãæ©ãããå®è¡ãã¦ãããããªãã®æ»æãå®äºããããã«ãããã¤ãã®ä½åãªç§ãã¤ãããæ»æï¼ã¢ã¯ãã£ã
-04:36=ãã¦ãæã«ã¯ããªããç®æãã®ã¯ãã¾ãã«ãæªãã§ããç¾ä»£ã®æè¡ã使ç¨ãã¦ããã¤ãã®æ¯æ´ãå¾ããæ»æï¼ã¢ã¯ãã£ã
-04:37=æ¥å
ãæãã¦ã¯ããã¾ãããããã¯ã¡ããã©1ã¿ã¼ã³æç¶ãã¾ãããããªããä»ã®è±ã«ä½ã®ãã¡ã¼ã¸ãå¸åãããã¨ãã§ããããã«ãªãã¾ããæ»æï¼ã¢ã¯ãã£ã
-04:38=ã¹ãã¤ãã¼ã©ã¤ãã«ã¯ãããªãã®å
¨ä½ã®å
µå¨åº«ã®ä¸ã§æãå£æ»
çãªæ¦å¨ã«ãªãã¾ããããããããã¯æ¥è¿æ¦ã§é常ã«å¹æçã§ãããã¡ã¼ã¸ã¯ããã®ã¿ã¼ã²ããã¾ã§ã®è·é¢ã¨ã¨ãã«å¢å ãä¸ãããæ»æï¼ã·ã¥ã¼ãï¼åï¼
-04:39=空é£ã¶åç¤ã使ç¨ãã¦ãããã®ä»ã®é¨åã«é£ã¶ãããã¯ããã¹ã¿ã¼ã¦ã¼ãã£ãªãã£ã®ãã¼ãæ¦å ´ã®ã»ã¼ä»»æã®ä½ç½®ã«è¡ããã¨ãã§ããããã«ãªãã¾ãããæ»æï¼æ大ã¢ã¯ãã£ãå·¦å³ï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ä¸æ¹åã«ãã³ã°ã¸ã£ã³ãåãé©ç¨ãã¾ãã
-04:40=ï¼ããã«ãªãï¼ãçç¼æ¶²ã§æºãããããã®ããã«ã使ç¨ãã¦ãç«ç½ã®ããã¤ãã®å°ãè¨å®ãã¾ããæ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
-04:41=証æ ã®æ§è³ªãã空é£ã¶åç¤ãä¸åãããããã¾ããããã¼ãã£ã¯ãè±ãæã¡æ©ãã¨ããªãã®æµã«åµããããããããã¨ãã§ãã¾ãï¼ãã¼ãã£ã¼ã使ç¨ããã¨ãããªãã®ã¿ã¼ã³ã®æéã«é£ã¹ãããã«ãè¿
éã§ããï¼æ»æï¼ããã³ããããåµã¢ããå·¦å³ï¼ä¸æ¹åã«ãã©ãã
-04:42=ãã®æºå¸¯ãã¼ã¿ã«è£
ç½®ã¯ãç¬æã«ãããªãã®æµãã¾ãã¯å°å½¢ä¸ã®2ç¹éã®ããªãã®æ¦å¨ããªãã輸éãããã¨ãå¯è½ã§ããè³¢æã«ããã使ç¨ãã¦ããã£ã³ãã¼ã³ãããã¾ã...大æåï¼æ»æï¼ãµã¤ã¯ã«ãã¼ã¿ã«ã®è²ï¼ãã¼ã¿ã«ã¹ã¤ãããæã¤
-04:43=ããªãã®é³æ¥½ããã¥ã¼ççºãæåãããï¼å¤©ãããã¢ãããããããã¾ããã注æãã¦ãã ãã...誰ãããããåçããå¿
è¦ããããããã¯ããªãã®äººçãè¦ãããããããªãï¼ã«ã¼ã½ã«ï¼é¸æãã¦ã¿ã¼ã²ããé åF1-F9ãã¼ãæ¼ãã¦ï¼ãã¢ããå¼¾ã
-04:44=ããã¯ãã ã®ãã¼ãºã§ã¯ãªããçç©å
µå¨ã ï¼ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããã¯ééããªãèããã¿ãããã誰ããä¸å¹¸ã«æ¯ãããããããã¯è¢«å®³ã®è¨å¤§ãªéãçºçãããã¨ã¯ããã¾ããï¼1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
-04:45=ãã¹ã¦ã®ãããã®ç©çå¦ã®ã¯ã©ã¹ã¯æçµçã«å ±ããã¦ãããããªãã®æµã«å£æ»
çãªæ£å¼¦æ³¢ãèµ·åãã¾ããæ°ãä»ããããã®æ¦å¨ã¯é常ã«ããã¯ãããã¯ãã¾ããï¼ãã®æ¦å¨ã¯ä¸å®å
¨ã§ãï¼æ»æåï¼ã·ã¥ã¼ã
-04:46=液ä½çãé常ã«æãã¨ããªãã®æµãã«ãã¼ãã¦ãã¾ããã»ã®ã¼ã®ï¼ã¢ã¿ãã¯ãä¸ä¸ã«ã¢ã¯ãã£ãã«ãã¾ããå·¦å³ãç®æãã¦é²ã¿ã¾ãï¼å¾ã®é»æºãå¤æ´ãã¾ãã
-04:47=2å
端ã®ã¨ãã£ããåå£ãªãç²çå°é·ã®æ¥½ãã¿ãåå¢ãé£éåå¿ãè¨å®ãããï¼ãããã¯ä¸¡æ¹ï¼ï¼æ»æãå®ãï¼ããå¤ãã®é»åï¼åï¼ã§æ®å½±ãããã¼ã«ã
-04:48=ãªãã¢ã«ãã¹ã¦ã®èå¾
ãåå¾ããå¿
è¦ãããã¾ãï¼è±ãã¯ãåã«æ¥½ãã¿ã¨ãã¦ãããã¨ãã§ãã¾ãï¼ãã®ãã³ãã¼ããè¯ãææã¯è±ã®å¥åº·ç¶æ
ã®3åã®1ããªãã«åãããããããå°ä¸ã«çªå
¥ãã¾ããæ»æï¼ã¢ã¯ãã£ã
-04:49=ããªãã®å人ã復活ãããï¼ããããããã¯ã¾ãããªãã®æµã復活ããããã¨æ³¨æãã¦ãã ãããæ»æï¼ãã£ããã¨å¾©æ´»ãããããã«æ¼ãããæ»æã«æ³¨æãã¦ãã ããã復活ãå é
-04:50=誰ããå°ä¸ã«é ãã¦ããï¼ããªã«ã®ã¹ãã©ã¤ãã§ããããæãï¼ã¿ã¤ãã¼ã¯ããããæãæ¹æ³ãã¯ããã«å¶å¾¡ãã¾ãã
-04:51=æ³¥ã®ãã¼ã«ãæãã¤ãããã¨ã«ãã£ã¦èªç±ãªã·ã§ããã§åå¾ãã¾ããåºããã¯ãããããè±ãããã¯ããã¯ããã
+04:14=é«æææçï¼åªãããã©ã·ã¥ã¼ããã¤ããã|ããã¯ããªããé ããããè½ã¡ãå±éã¨ç§ã®ãã¡ã¼ã¸ãåãã¦ããè±ãä¿åãã¾ãã|æ»æï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ãã©ã·ã¥ã¼ããã³ã°ã¸ã£ã³ãã伸ã°ã
+04:15=çæã®å®è¡ã使ç¨ãã¦æµãæ»æããé£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ãã|å·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
+04:16=ã¿ã¼ã²ããã¨ãªã¢ã«ããã¤ãã®é±å±±ãããããããã«ã¯é£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ãã|å·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
+04:17=é¿é£ãå¿
è¦ã§ããï¼ããªããã«ãã¼ä»ä¸åºä½å°é¢ã«ãã³ãã«ãæãããã«ããã¼ãã¼ãã使ç¨ãã¦ãã¾ãã|æ»æã®éå§ã¾ãã¯åæ¢æã
+04:18=追å ã®ä¿è·ãå¿
è¦ãªå ´åãã¾ãã¯å°é¢ãééãããã§ããï¼å¥½ããªããã«ãããã¤ãã®æ¡ã«ç½®ãã¾ãã|æå¹ãªä½ç½®ã«é
ç½®æ¡ï¼å·¦å³ï¼ã«ã¼ã½ã«ãé
ç½®ããé¸ææ¡
+04:19=ããã¯ããªããæ°ç§ä»¥å
ã«å±éºãªç¶æ³ããè±ãä¿åãããã¨ãã§ãã¾ãããã«ãå³ç¬éãã¬ãã¼ãã¼ã·ã§ã³ã§ä½¿ç¨ããã»ã¼ãã¹ã¦ã®æ¦å¨ãããå¼·åã«ãããã¨ãã§ãã¾ãã|ã«ã¼ã½ã«ï¼é¸æãã¦ã¿ã¼ã²ããé å
+04:20=å¥ã®è±ã¨ãç¾å¨ã®ã¿ã¼ã³ãåçãããã¨ãã§ãã¾ãã|æ»æï¼ã¹ã¤ããã³ã°è±ãæå¹ã«ãã
+04:21=ã¤ã³ãã¯ãæã«è¤æ°ã®çå¼¾ã解æ¾ãã¾ãæ榴弾ã®ãããªå¼¾ä¸¸ãæã¤ã|æ»æï¼ãã«ãã¯ã¼ã§æã¤
+04:22=ã ãã§ãªããã¤ã³ãã£ã¸ã§ã¼ã³ãºã®ããã«ï¼|éã¯å¤ãã®ç¶æ³ã§æç¨ãªæ¦å¨ã§ããã|ããªããå´ãã誰ããçªãåºããããå ´åã¯ç¹ã«ã|æ»æï¼ããªãã®åã«ã¹ãã©ã¤ã¯ã®ãã¹ã¦
+04:23=ããªãã失ããã®ã¯ä½ããªãå ´åãããã¯ããªã便å©ããããã¾ããã|å½¼ã®æ¹æ³ä¸ã®ãã¹ã¦ãå·ã¤ããã¨çµäºæã«ççºããç¹å®ã®æ¹åã«å½¼ãèµ·åãããã¨ã§ãè±ãçãè´ã«æ§ããã|æ»æï¼å£æ»
çãªãè´å½çãªæ»æãéå§
+04:24=èªçæ¥ããã§ã¨ãï¼|ãã®ã±ã¼ããèµ·åãããããå³ã®æµã®é£ã«æ©ãã¦ãå½¼ããççºçãã¼ãã£ãæããã¦ã¿ã¾ãããã|ã±ã¼ãã¯ãã»ã¼ãã¹ã¦ã®å°å½¢ãééãããã¨ãã§ãã¾ãããå½¼ã¯ä»¥åããã®æ¹æ³ãççºãããããããã¾ããã|æ»æï¼ã±ã¼ããèµ·åããããåæ¢ãããã¨ççºãã
+04:25=ï¼ããã¦ãããã¤ãã®ã®ã£ãããç©´ï¼ãè±ã«åãã£ã¦ã¸ã£ã³ããããã¨ãããªãã®æµãåå¾ããã«ã¯ããã®å¤è£
ãããã使ç¨ãã¦ãã¾ãã|æ»æï¼ãããã使ç¨ãã¦ãå¥ã®è±ãèªæããã
+04:26=ããªãã®æµã§ããã®ã¸ã¥ã¼ã·ã¼ãªã¹ã¤ã«ãã¹ãã¼ãã¾ãã|ã¿ã¤ãã¼ã®æéãåããã¨ãããã¯ããã¤ãã®ççºçãªæçã«åå²ããã¾ãã|1-5ï¼ã»ããã¹ã¤ã«ã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:27=ãã®æªéã®ããççºã使ç¨ãã¦ãããªãã®å¯¾æ¦ç¸æã«æ¥ç«ã®é¨ãã¦ã¿ã¾ãããã|è¿ãããå°ããªç«ç½ãé·ãç¶ããããããªãã¨ççºã«å¾ããã¨ã¯ããã¾ããã|æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:28=ãã®ãã±ãããæã¡ä¸ããå¾ã®çãæéãããã¯åºä½å°é¢ãæåãéå§ãããã®ãã¥ã¼ãºãããªã¬ãããã¨ççºããããåã³åæµ®ä¸ãã¾ãã|æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:29=ããã¯å°ããªåä¾ã®ããã®ãã®ã§ã¯ããã¾ããï¼|ãã¼ã«éã¯çè¬ãå
å¡«ããå°ããªè²ã®ãã¼ã«ã®ãã³ãçºçããã¾ãã|æ»æï¼ã¢ãããã¦ã³ããã«ãã¯ã¼ã§ã·ã¥ã¼ããç®æãã¦é²ã¿ã¾ã
+04:30=å¼·åãªããã¼ã ã¹ãã©ã¤ããèµ·åããã«ã¯é£è¡æ©ã®ä¸ã§å¼ã³åºãã¾ãã|é©åã«ãã®æ»æãç®æãã¦ããã«åº§ã£ã¦ä¸éãªè±ãå«ã風æ¯ã®å·¨å¤§ãªé¨åãæ ¹çµ¶ãããã¨ãã§ãã¾ãã|å·¦å³ï¼é¸æãã¦ã¿ã¼ã²ããé åï¼æ»ææ¹åã®ã«ã¼ã½ã«ã決å®
+04:31=RCãã¬ã¼ã³ã¯ç®±ãåéããããé ãé¢ããè±ãæ»æããã®ã«çæ³çãªæ¦å¨ã§ãã|ã©ã¡ãã®æµã«ãããæ縦ããããæåã®ããã¤ãã®çå¼¾ããããããã¾ãã|æ»æï¼ã¯ã«ãã¥ã¼ã¬ãæ¦éã«ä¹ãã¾ãããå·¦å³ï¼å¹³é¢ã¹ãã¢ã¸ã£ã³ãå¹³é¢ã¾ãã¯ãããããã³ã°çå¼¾ãèµ·åãã¾ãã
+04:32=ä½éåã¯ã©ããªãã¤ã¨ãããããå¹æçã§ãï¼|é«ããé·ãè·é¢ãé£ã³è¶ããããæµãããã«é£ã¶ãã¾ãããã|æ»æï¼ã¢ã¯ãã£ã
+04:33=æã«ã¯ãããã¤ãã®ããå¤ãã®ãã¡ã¼ã¸ãä¸ããããã«ãã®å°ãä½åãªãã¼ã¹ããã¡ããã©å¿
è¦ãããã¾ãã|æ»æï¼ã¢ã¯ãã£ã
+04:34=ç§ã«è§¦ãããã¨ãã§ããªãï¼|æ»æï¼ã¢ã¯ãã£ã
+04:35=æã«ã¯æéãæ©ãããå®è¡ãã¦ããã|ããªãã®æ»æãå®äºããããã«ãããã¤ãã®ä½åãªç§ãã¤ããã|æ»æï¼ã¢ã¯ãã£ã
+04:36=ãã¦ãæã«ã¯ããªããç®æãã®ã¯ãã¾ãã«ãæªãã§ãã|ç¾ä»£ã®æè¡ã使ç¨ãã¦ããã¤ãã®æ¯æ´ãå¾ãã|æ»æï¼ã¢ã¯ãã£ã
+04:37=æ¥å
ãæãã¦ã¯ããã¾ããã|ããã¯ã¡ããã©1ã¿ã¼ã³æç¶ãã¾ãããããªããä»ã®è±ã«ä½ã®ãã¡ã¼ã¸ãå¸åãããã¨ãã§ããããã«ãªãã¾ãã|æ»æï¼ã¢ã¯ãã£ã
+04:38=ã¹ãã¤ãã¼ã©ã¤ãã«ã¯ãããªãã®å
¨ä½ã®å
µå¨åº«ã®ä¸ã§æãå£æ»
çãªæ¦å¨ã«ãªãã¾ããããããããã¯æ¥è¿æ¦ã§é常ã«å¹æçã§ãã|ãã¡ã¼ã¸ã¯ããã®ã¿ã¼ã²ããã¾ã§ã®è·é¢ã¨ã¨ãã«å¢å ãä¸ããã|æ»æï¼ã·ã¥ã¼ãï¼åï¼
+04:39=空é£ã¶åç¤ã使ç¨ãã¦ãããã®ä»ã®é¨åã«é£ã¶ã|ããã¯ããã¹ã¿ã¼ã¦ã¼ãã£ãªãã£ã®ãã¼ãæ¦å ´ã®ã»ã¼ä»»æã®ä½ç½®ã«è¡ããã¨ãã§ããããã«ãªãã¾ããã|æ»æï¼æ大ã¢ã¯ãã£ãå·¦å³ï¼ããããæ榴弾ã¾ãã¯é¡ä¼¼ã®æ¦å¨ï¼ä¸æ¹åã«ãã³ã°ã¸ã£ã³ãåãé©ç¨ãã¾ãã
+04:40=ï¼ããã«ãªãï¼ãçç¼æ¶²ã§æºãããããã®ããã«ã使ç¨ãã¦ãç«ç½ã®ããã¤ãã®å°ãè¨å®ãã¾ãã|æ»æï¼ããå¤ãã®é»åã使ã£ã¦æ®å½±ãããã¼ã«ã
+04:41=証æ ã®æ§è³ªãã空é£ã¶åç¤ãä¸åãããããã¾ããã|ãã¼ãã£ã¯ãè±ãæã¡æ©ãã¨ããªãã®æµã«åµããããããããã¨ãã§ãã¾ãï¼|ãã¼ãã£ã¼ã使ç¨ããã¨ãããªãã®ã¿ã¼ã³ã®æéã«é£ã¹ãããã«ãè¿
éã§ããï¼|æ»æï¼ããã³ããããåµã¢ããå·¦å³ï¼ä¸æ¹åã«ãã©ãã
+04:42=ãã®æºå¸¯ãã¼ã¿ã«è£
ç½®ã¯ãç¬æã«ãããªãã®æµãã¾ãã¯å°å½¢ä¸ã®2ç¹éã®ããªãã®æ¦å¨ããªãã輸éãããã¨ãå¯è½ã§ãã|è³¢æã«ããã使ç¨ãã¦ããã£ã³ãã¼ã³ãããã¾ã...大æåï¼|æ»æï¼ãµã¤ã¯ã«ãã¼ã¿ã«ã®è²ï¼ãã¼ã¿ã«ã¹ã¤ãããæã¤
+04:43=ããªãã®é³æ¥½ããã¥ã¼ççºãæåãããï¼|天ãããã¢ãããããããã¾ããã注æãã¦ãã ãã...誰ãããããåçããå¿
è¦ããããããã¯ããªãã®äººçãè¦ãããããããªãï¼|ã«ã¼ã½ã«ï¼é¸æãã¦ã¿ã¼ã²ããé åF1-F9ãã¼ãæ¼ãã¦ï¼ãã¢ããå¼¾ã
+04:44=ããã¯ãã ã®ãã¼ãºã§ã¯ãªããçç©å
µå¨ã ï¼|ã¿ã¤ãã¼ãã¼ãã«éããã¨ãããã¯ééããªãèããã¿ãããã誰ããä¸å¹¸ã«æ¯ãããããããã¯è¢«å®³ã®è¨å¤§ãªéãçºçãããã¨ã¯ããã¾ããï¼|1-5ï¼ã»ããã°ã¬ãã¼ãã®ã¿ã¤ãã¼æ»æï¼ããå¤ãã®é»åãã¹ãã¼ããããã«ãã¼ã«ã
+04:45=ãã¹ã¦ã®ãããã®ç©çå¦ã®ã¯ã©ã¹ã¯æçµçã«å ±ããã¦ãããããªãã®æµã«å£æ»
çãªæ£å¼¦æ³¢ãèµ·åãã¾ãã|æ°ãä»ããããã®æ¦å¨ã¯é常ã«ããã¯ãããã¯ãã¾ãã|ï¼ãã®æ¦å¨ã¯ä¸å®å
¨ã§ãï¼æ»æåï¼ã·ã¥ã¼ã
+04:46=液ä½çãé常ã«æãã¨ããªãã®æµãã«ãã¼ãã¦ãã¾ãã|ã»ã®ã¼ã®ï¼|ã¢ã¿ãã¯ãä¸ä¸ã«ã¢ã¯ãã£ãã«ãã¾ãã|å·¦å³ãç®æãã¦é²ã¿ã¾ãï¼å¾ã®é»æºãå¤æ´ãã¾ãã
+04:47=2å
端ã®ã¨ãã£ããåå£ãªãç²çå°é·ã®æ¥½ãã¿ãåå¢ã|é£éåå¿ãè¨å®ãããï¼ãããã¯ä¸¡æ¹ï¼|ï¼æ»æãå®ãï¼ããå¤ãã®é»åï¼åï¼ã§æ®å½±ãããã¼ã«ã
+04:48=ãªãã¢ã«ãã¹ã¦ã®èå¾
ãåå¾ããå¿
è¦ãããã¾ãï¼è±ãã¯ãåã«æ¥½ãã¿ã¨ãã¦ãããã¨ãã§ãã¾ãï¼|ãã®ãã³ãã¼ããè¯ãææã¯è±ã®å¥åº·ç¶æ
ã®3åã®1ããªãã«åãããããããå°ä¸ã«çªå
¥ãã¾ãã|æ»æï¼ã¢ã¯ãã£ã
+04:49=ããªãã®å人ã復活ãããï¼|ããããããã¯ã¾ãããªãã®æµã復活ããããã¨æ³¨æãã¦ãã ããã|æ»æï¼ãã£ããã¨å¾©æ´»ãããããã«æ¼ãããæ»æã«æ³¨æãã¦ãã ããã|復活ãå é
+04:50=誰ããå°ä¸ã«é ãã¦ããï¼ããªã«ã®ã¹ãã©ã¤ãã§ããããæãï¼|ã¿ã¤ãã¼ã¯ããããæãæ¹æ³ãã¯ããã«å¶å¾¡ãã¾ãã
+04:51=æ³¥ã®ãã¼ã«ãæãã¤ãããã¨ã«ãã£ã¦èªç±ãªã·ã§ããã§åå¾ãã¾ãã|åºããã¯ãããããè±ãããã¯ããã¯ããã
04:52=UNUSED
-04:53=ããªãã®ä»²éãåç¬ã§æ¦ãããã«æ®ããªãããæéã¨ç©ºéãä»ãã¦åéºã«åºãããã¤ã§ãè¿ãããã«æºåãããã¾ãã¯çªç¶æ»ã®å ´åãã¾ãã¯ããããã¯ãã¹ã¦æåãã¦ãã¾ããå
責äºé
ãããªãã¯ä¸äººã§ããå ´åã¯ãçªç¶æ»ã§æ©è½ãããããã³ã°ã§ããå ´åã§ã¯ããã¾ããã
-04:54=INCOMPLETE
-04:55=ã¹ãã£ããã¼ãã¬ã¼ã¯ã®ã¹ããªã¼ã ãã¹ãã¬ã¼ããã³ãã«ãå°éãæµãåãããããªãã¸ãæ§ç¯ãã¾ããããªããä¸ã®ä»»æã®ãåå¾ããªãããã«æ³¨æãã¦ãã ããï¼
+04:53=ããªãã®ä»²éãåç¬ã§æ¦ãããã«æ®ããªãããæéã¨ç©ºéãä»ãã¦åéºã«åºãã|ãã¤ã§ãè¿ãããã«æºåãããã¾ãã¯çªç¶æ»ã®å ´åãã¾ãã¯ããããã¯ãã¹ã¦æåãã¦ãã¾ãã|å
責äºé
ã|ããªãã¯ä¸äººã§ããå ´åã¯ãçªç¶æ»ã§æ©è½ãããããã³ã°ã§ããå ´åã§ã¯ããã¾ããã
+;04:54=INCOMPLETE
+04:54=ã¹ãã£ããã¼ãã¬ã¼ã¯ã®ã¹ããªã¼ã ãã¹ãã¬ã¼ã|ãã³ãã«ãå°éãæµãåãããããªãã¸ãæ§ç¯ãã¾ãã|ããªããä¸ã®ä»»æã®ãåå¾ããªãããã«æ³¨æãã¦ãã ããï¼
; Game goal strings
05:00=ã²ã¼ã ã¢ã¼ã
diff --git a/share/hedgewars/Data/Locale/ko.lua b/share/hedgewars/Data/Locale/ko.lua
index 6e243f6..5dd0fb0 100644
--- a/share/hedgewars/Data/Locale/ko.lua
+++ b/share/hedgewars/Data/Locale/ko.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
-- ["Fastest lap: "] = "",
-- ["Feeble Resistance"] = "",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
-- ["Hooray!"] = "",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/ko.txt b/share/hedgewars/Data/Locale/ko.txt
index 2687f91..f394f0a 100644
--- a/share/hedgewars/Data/Locale/ko.txt
+++ b/share/hedgewars/Data/Locale/ko.txt
@@ -13,7 +13,7 @@
00:10=ë¤ì´ëë§ì´í¸
00:11=ì¼êµ¬ ë°©ë§ì´
00:12=Shoryuken
-00:13=ì´
+00:13=ì´
00:14=ëíì°
00:15=íí ê³µìµ
00:16=ì§ë¢° ê³µìµ
diff --git a/share/hedgewars/Data/Locale/lt.lua b/share/hedgewars/Data/Locale/lt.lua
index 46fca6c..4a0e39c 100644
--- a/share/hedgewars/Data/Locale/lt.lua
+++ b/share/hedgewars/Data/Locale/lt.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Greièiausias Ratas: ",
["Feeble Resistance"] = "Silpnaus Atsparumo Tvirtovë",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = " Nelaimingu Eþiu Liko!",
["Hapless Hogs"] = "Nelaimingi Eþiai",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurah!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Kulkos Per-Eþy",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Padëk Daugiau Kelio Taðku Su [ENTER"],
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Vartotojo Iðukis",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/lt.txt b/share/hedgewars/Data/Locale/lt.txt
index ff8f2f9..055739d 100644
--- a/share/hedgewars/Data/Locale/lt.txt
+++ b/share/hedgewars/Data/Locale/lt.txt
@@ -54,8 +54,8 @@
00:51=Purvo Kamuolys
00:52=Joks Ginklas Nepasirinktas
00:53=TARDIS
-00:54=Struktūra
-00:55=ŽemÄs PurÅ¡kimas
+; 00:54=Struktūra
+00:54=ŽemÄs PurÅ¡kimas
01:00=KaukimÄs!
01:01=Lygiosios
@@ -175,7 +175,6 @@
02:01=%1 nori žaisti delfinus
02:01=%1 nuejo i Aquaria
02:01=%1 rado prarasta atlantijos miesta
-02:01=%1 bando pajimti pagrindini vaidmeni Bioshock 3
02:01=Tavo Å¡uniuko stylius galÄtu panaudoti Å¡iek tiek daugiau praktikos, %1
02:01=%1 galÄjo atsineÅ¡ti laiva
02:01=%1 nepatinka vandens sportas
@@ -298,7 +297,7 @@
02:07=Tai Gali Praversti...
02:07=Naudingi Irankiai!
02:07=IÅ¡naudok Å ia DÄže
-02:07=Atsargiai Žemiau
+02:07=Atsargiai Žemiau
02:07=Dar Daugiau Naudingu Irankiu!
02:07=Irankiai tau!
02:07=Tai TurÄtu Buti Gera!
@@ -364,7 +363,7 @@
02:09=%1 artÄja prie savizudybÄs
02:09=%1 padeda priešui
02:09=Tai buvo kvaila %1
-02:09=%1 Palauk KA??
+02:09=%1 Palauk KA??
02:09=%1 susimaiÅ¡Ä
02:09=%1 sužaloja save
02:09=%1 myli žeminti save
@@ -406,7 +405,7 @@
03:11=Bonk!
03:12=Kovos Menai
03:13=UNUSED
-03:14=Transporto PriemonÄ
+03:14=Transporto PriemonÄ
03:15=AviacinÄ Ataka
03:16=AviacinÄ Ataka
03:17=Kasimosi Irankis
@@ -447,7 +446,7 @@
03:51=Rastas Ant ŽemÄs
03:52=UNUSED
03:53=Tipas 40
-03:54=Pastatyk Ka Nors
+;03:54=Pastatyk Ka Nors
; Weapon Descriptions (use | as line breaks)
04:00=Atakuok savo priešus su paprasta granata.|Ji sprogs kaip jos laikmatis pasieks nuli.|1-5: Nustatyk granatos laikmati|Ataka: Laikyk kad mestum stipriau
@@ -455,7 +454,7 @@
04:02=Atakuok savo prieÅ¡us paleisdamas balistini objekta|kuris gali buti valdomas vÄjo.|Ataka: Laikyk kad Å¡autum stipriau
04:03=Paleisk sprogstanÄia bite kuri seks prieÅ¡a|arba pasirinkta taikini. NeÅ¡auk su pilna jÄga|nes tai gadina taikluma.|PelÄ: Pasirink taikini|Ataka: Laikyk kad Å¡autum stipriau
04:04=Atakuok savo prieÅ¡us naudodamas Å¡ratini Å¡autuva.|AÄiu jo pasiskirstimui tau nereikia nusitaikity tiesiai i prieÅ¡a|kad padarytum žalos.|Ataka: Å auna (Keleta Kartu)
-04:05=JudÄk po žeme naudok kasimo iranga|kad galÄtum nusileisti i tuneli arba i kita vietove.|Ataka: PradÄti ir nustoti kasima
+04:05=JudÄk po žeme naudok kasimo iranga|kad galÄtum nusileisti i tuneli arba i kita vietove.|Ataka: PradÄti ir nustoti kasima
04:06=Nusibodo? NÄra Kaip Pulti? Taupai Kulkas?|Jokiu Problemu! Tiesiog praleisk savo eile, baily!|Ataka: Praleidžia tavo eile be veiksmo
04:07=Nuvaryk toli ir greitai|su virve. Numesk ežius i vandeni|arba numesk ant ju granata arba panašius ginklus.|Ataka: Šauk arba atleisk virve|Ilgas Šuolis: Meta granatas arba panašius ginklus
04:08=Laikyk savo prieÅ¡us kuo toliau numesdamas|mina siauruose praÄjimuose arba prie ju kojiu. Tik|buk tikras kad pabÄgsi kad pats jos neaktyvuotum!|Ataka: Meta mina tau prie kojiu
diff --git a/share/hedgewars/Data/Locale/missions_de.txt b/share/hedgewars/Data/Locale/missions_de.txt
index cc59440..81ee730 100644
--- a/share/hedgewars/Data/Locale/missions_de.txt
+++ b/share/hedgewars/Data/Locale/missions_de.txt
@@ -1,4 +1,4 @@
-Basic_Training_-_Bazooka.name=Training: Bazooka - Grundlagen
+Basic_Training_-_Bazooka.name=Training: Bazooka - Grundlagen
Basic_Training_-_Bazooka.desc="Nutze den Wind zu deinem Vorteil aus!"
Basic_Training_-_Grenade.name=Training: Granate - Grundlagen
diff --git a/share/hedgewars/Data/Locale/missions_en.txt b/share/hedgewars/Data/Locale/missions_en.txt
index 64898bc..478ef59 100644
--- a/share/hedgewars/Data/Locale/missions_en.txt
+++ b/share/hedgewars/Data/Locale/missions_en.txt
@@ -43,6 +43,9 @@ User_Mission_-_The_Great_Escape.desc="You think you can cage me!?"
User_Mission_-_Rope_Knock_Challenge.name=Challenge: Rope Knocking
User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!"
+User_Mission_-_Nobody_Laugh.name=Mission: Nobody Laugh
+User_Mission_-_Nobody_Laugh.desc="This ain't no joke."
+
User_Mission_-_RCPlane_Challenge.name=Challenge: RC Plane
User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?"
diff --git a/share/hedgewars/Data/Locale/missions_fr.txt b/share/hedgewars/Data/Locale/missions_fr.txt
index 244c653..9b5a92d 100644
--- a/share/hedgewars/Data/Locale/missions_fr.txt
+++ b/share/hedgewars/Data/Locale/missions_fr.txt
@@ -1,5 +1,5 @@
Basic_Training_-_Bazooka.name=Initiation au Bazooka
-Basic_Training_-_Bazooka.desc="Pour gagner, utiliser le vent à votre avantage !"
+Basic_Training_-_Bazooka.desc="Pour gagner, utiliser le vent à votre avantage !"
Basic_Training_-_Grenade.name=Entrainement au lancer de Grenade
Basic_Training_-_Grenade.desc="Souvenez vous, retirez la goupille et lancez !"
@@ -13,14 +13,14 @@ Basic_Training_-_Shotgun.desc="On tire d'abord, on pose les questions après !"
Basic_Training_-_Sniper_Rifle.name=Initiation au Sniper
Basic_Training_-_Sniper_Rifle.desc="Pan ! En pleine tête !"
-Basic_Training_-_Rope.name=Initiation à la Corde Ninja
+Basic_Training_-_Rope.name=Initiation au Grappin
Basic_Training_-_Rope.desc="Bouge de là et Balance toi !"
-User_Mission_-_Dangerous_Ducklings.name=Mission: Canards dangereux
-User_Mission_-_Dangerous_Ducklings.desc="Très bien le bleu, il est temps de mettre en pratique ce que tu as appris aux entraînements !"
+User_Mission_-_Dangerous_Ducklings.name=Mission: Canards dangereux
+User_Mission_-_Dangerous_Ducklings.desc="Très bien le bleu, il est temps de mettre en pratique ce que tu as appris aux entraînements !"
User_Mission_-_Diver.name=Mission: Diver
-User_Mission_-_Diver.desc="Cet assault 'sous-marin' est plus dur que cela n'y paraît...."
+User_Mission_-_Diver.desc="Cet assault 'sous-marin' est plus dur que cela n'y paraît...."
User_Mission_-_Teamwork.name=Mission: Travail en équipe
User_Mission_-_Teamwork.desc="Parfois, l'amour blesse."
@@ -28,7 +28,7 @@ User_Mission_-_Teamwork.desc="Parfois, l'amour blesse."
User_Mission_-_Spooky_Tree.name=Mission: L'arbre qui parle
User_Mission_-_Spooky_Tree.desc="Beaucoup de caisses par ici. J'espère vraiment que cet oiseau n'a pas faim."
-User_Mission_-_Bamboo_Thicket.name=Mission: Forêt de Bamboo
+User_Mission_-_Bamboo_Thicket.name=Mission: Forêt de Bamboo
User_Mission_-_Bamboo_Thicket.desc="La mort vient d'en haut."
User_Mission_-_That_Sinking_Feeling.name=Mission: Cette impression de naufrage
@@ -40,8 +40,8 @@ User_Mission_-_Newton_and_the_Hammock.desc="Souvenez vous petits hérissons : La
User_Mission_-_The_Great_Escape.name=Mission: La grande évasion
User_Mission_-_The_Great_Escape.desc="Tu pense que tu peux me capturer ?!"
-User_Mission_-_Rope_Knock_Challenge.name=Challenge: A coup de Corde Ninja
+User_Mission_-_Rope_Knock_Challenge.name=Challenge: A coup de Grappin
User_Mission_-_Rope_Knock_Challenge.desc="Regarde derrière toi !"
User_Mission_-_RCPlane_Challenge.name=Challenge: Avion télécommandé
-User_Mission_-_RCPlane_Challenge.desc="Plutôt confiant, hein, aviateur ?"
\ No newline at end of file
+User_Mission_-_RCPlane_Challenge.desc="Plutôt confiant, hein, aviateur ?"
diff --git a/share/hedgewars/Data/Locale/missions_it.txt b/share/hedgewars/Data/Locale/missions_it.txt
index 20c1e50..88e7b22 100644
--- a/share/hedgewars/Data/Locale/missions_it.txt
+++ b/share/hedgewars/Data/Locale/missions_it.txt
@@ -4,7 +4,7 @@ Basic_Training_-_Bazooka.desc="Utilizzare il vento a proprio vantaggio costituis
Basic_Training_-_Grenade.name=Addestramento base sull'utilizzo delle Granate
Basic_Training_-_Grenade.desc="Ricorda, toglierai PRIMA la sicura e POI lancerai la granata!"
-Basic_Training_-_Cluster_Bomb.name=ddestramento base sull'utilizzo delle Granate a Grappolo
+Basic_Training_-_Cluster_Bomb.name=Addestramento base sull'utilizzo delle Granate a Grappolo
Basic_Training_-_Cluster_Bomb.desc="Qualcuno ha bisogno di una doccia (molto) calda!"
Basic_Training_-_Shotgun.name=Addestramento base sull'utilizzo del Fucile a Pompa
diff --git a/share/hedgewars/Data/Locale/missions_pt.txt b/share/hedgewars/Data/Locale/missions_pt.txt
new file mode 100755
index 0000000..678e379
--- /dev/null
+++ b/share/hedgewars/Data/Locale/missions_pt.txt
@@ -0,0 +1,50 @@
+Basic_Training_-_Bazooka.name=Treino Básico com Bazuca
+Basic_Training_-_Bazooka.desc="Saber utilizar o vento para tua vantagem é a chave!"
+
+Basic_Training_-_Grenade.name=Treino Básico com Granada
+Basic_Training_-_Grenade.desc="Lembra-te, tens de retirar a cavilha E ATIRAR!"
+
+Basic_Training_-_Cluster_Bomb.name=Treino Básico com Bomba de Fragmentos
+Basic_Training_-_Cluster_Bomb.desc="Alguem está a precisar de um duche bem quente!"
+
+Basic_Training_-_Shotgun.name=Treino Básico com Caçadeira
+Basic_Training_-_Shotgun.desc="Dispara primeiro, questiona depois!"
+
+Basic_Training_-_Sniper_Rifle.name=Treino Básico com Sniper
+Basic_Training_-_Sniper_Rifle.desc="Boom, headshot!"
+
+Basic_Training_-_Rope.name=Treino Básico com Corda
+Basic_Training_-_Rope.desc="Get out there and swing!"
+
+User_Mission_-_Dangerous_Ducklings.name=Missão: Dangerous Ducklings
+User_Mission_-_Dangerous_Ducklings.desc="Alright, rookie! Time to put what we learned in Basic Training into practice!"
+
+User_Mission_-_Diver.name=Missão: Diver
+User_Mission_-_Diver.desc="Esta coisa do 'assalto anfÃbio' é mais difÃcil do que parece..."
+
+User_Mission_-_Teamwork.name=Missão: Teamwork
+User_Mission_-_Teamwork.desc="Por vezes, o amor doi."
+
+User_Mission_-_Spooky_Tree.name=Missão: Spooky Tree
+User_Mission_-_Spooky_Tree.desc="Imensas caixas por todo o lado. Só espero que este pássaro não se esteja a sentir com fome."
+
+User_Mission_-_Bamboo_Thicket.name=Missão: Bamboo Thicket
+User_Mission_-_Bamboo_Thicket.desc="Death comes from above."
+
+User_Mission_-_That_Sinking_Feeling.name=Missão: That Sinking Feeling
+User_Mission_-_That_Sinking_Feeling.desc="A água está a subir rapidamente e o tempo é limitado. Muitos tentaram e falharam. Consegues salvá-los todos?"
+
+User_Mission_-_Newton_and_the_Hammock.name=Missão: Newton and the Hammock
+User_Mission_-_Newton_and_the_Hammock.desc="Remember hoglets: The velocity of a body remains constant unless the body is acted upon by an external force!"
+
+User_Mission_-_The_Great_Escape.name=Missão: The Great Escape
+User_Mission_-_The_Great_Escape.desc="Pensas que me consegues enjaular!?"
+
+User_Mission_-_Rope_Knock_Challenge.name=Desafio: Rope Knocking
+User_Mission_-_Rope_Knock_Challenge.desc="Look behind you!"
+
+User_Mission_-_RCPlane_Challenge.name=Desafio: Avião Telecomandado
+User_Mission_-_RCPlane_Challenge.desc="Feeling pretty confident, eh, flyboy?"
+
+portal.name=Missão: Treino com Portais
+portal.desc="Use the portal to move fast and far, use it to kill, use it with caution!"
diff --git a/share/hedgewars/Data/Locale/missions_tr.txt b/share/hedgewars/Data/Locale/missions_tr.txt
new file mode 100755
index 0000000..c1ff2c0
--- /dev/null
+++ b/share/hedgewars/Data/Locale/missions_tr.txt
@@ -0,0 +1,50 @@
+Basic_Training_-_Bazooka.name=Temel Roketatar EÄitimi
+Basic_Training_-_Bazooka.desc="Rüzgarı yararına kullanmak bir anahtar!"
+
+Basic_Training_-_Grenade.name=Temel Bomba EÄitimi
+Basic_Training_-_Grenade.desc="Unutma, pimi çek VE at!"
+
+Basic_Training_-_Cluster_Bomb.name=Temel Parça Tesirli Bomba EÄitimi
+Basic_Training_-_Cluster_Bomb.desc="Birinin sıcak duÅa ihtiyacı var!"
+
+Basic_Training_-_Shotgun.name=Temel Tüfek EÄitimi
+Basic_Training_-_Shotgun.desc="Ãnce atıŠyap, soruları sonra sor!"
+
+Basic_Training_-_Sniper_Rifle.name=Temel Keskin NiÅancı TüfeÄi EÄitimi
+Basic_Training_-_Sniper_Rifle.desc="Bum, kafadan!"
+
+Basic_Training_-_Rope.name=Temel Halat EÄitimi
+Basic_Training_-_Rope.desc="Ordan çık ve sallan!"
+
+User_Mission_-_Dangerous_Ducklings.name=Görev: Tehlikeli Ãrdek Yavruları
+User_Mission_-_Dangerous_Ducklings.desc="Peki acemi! Åimdi Temel EÄitimde öÄrendiklerini uygulamanın zamanı!"
+
+User_Mission_-_Diver.name=Görev: Dalıcı
+User_Mission_-_Diver.desc="Bu 'iki yönlü saldırı' göründüÄünden daha zor..."
+
+User_Mission_-_Teamwork.name=Görev: Takım ÃalıÅması
+User_Mission_-_Teamwork.desc="Bazen, aÅk acıtır."
+
+User_Mission_-_Spooky_Tree.name=Görev: Korkak AÄaç
+User_Mission_-_Spooky_Tree.desc="Burada çok fazla kasa var. Eminim bu kuÅ aç deÄildir."
+
+User_Mission_-_Bamboo_Thicket.name=Görev: Bambu Ormanı
+User_Mission_-_Bamboo_Thicket.desc="Ãlüm yukardan gelir."
+
+User_Mission_-_That_Sinking_Feeling.name=Görev: BatıyormuŠHissi
+User_Mission_-_That_Sinking_Feeling.desc="Su hızlıca yükseliyor ve zaman kısıtlı. ÃoÄu denedi ve kaybetti. Hepsini kurtarabilecek misin?"
+
+User_Mission_-_Newton_and_the_Hammock.name=Görev: Newton ve Hamak
+User_Mission_-_Newton_and_the_Hammock.desc="KirpiÅleri unutma: Bir vücudun hızı harici bir kuvvetle itilmedikçe sabit kalır!"
+
+User_Mission_-_The_Great_Escape.name=Görev: Büyük KaçıÅ
+User_Mission_-_The_Great_Escape.desc="Beni hapsedebileceÄini mi sanıyorsun!?"
+
+User_Mission_-_Rope_Knock_Challenge.name=Mücadele: Halat VuruÅu
+User_Mission_-_Rope_Knock_Challenge.desc="Arkana bak!"
+
+User_Mission_-_RCPlane_Challenge.name=Mücadele: RC UçaÄı
+User_Mission_-_RCPlane_Challenge.desc="Ãok emin görünüyorsun deÄil mi, uçan çocuk?"
+
+portal.name= Görev: Portal eÄitim görevi
+portal.desc="Hızlı ve uzak yerlere hareket için portalı kullan, öldürmek için kullan, dikkatli kullan!"
diff --git a/share/hedgewars/Data/Locale/nl.txt b/share/hedgewars/Data/Locale/nl.txt
index 592dab8..cbd327a 100644
--- a/share/hedgewars/Data/Locale/nl.txt
+++ b/share/hedgewars/Data/Locale/nl.txt
@@ -164,7 +164,6 @@
02:01=%1 wants to play Ecco the dolphin
02:01=%1 has gone to visit Aquaria
02:01=%1 has found the lost city of Atlantis
-02:01=%1 aims for the lead role in Bioshock 3
02:01=Your doggy paddle could use a little work, %1
02:01=%1 should have brought a jet ski
02:01=%1 doesn't like watersports
diff --git a/share/hedgewars/Data/Locale/pl.lua b/share/hedgewars/Data/Locale/pl.lua
index 92aadce..d86329f 100644
--- a/share/hedgewars/Data/Locale/pl.lua
+++ b/share/hedgewars/Data/Locale/pl.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Najszybsze okrÄ
żenie: ",
["Feeble Resistance"] = "Ruch Oporu",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = " NieszczÄsne Jeże pozostaÅy",
["Hapless Hogs"] = "NieszczÄsne Jeże",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurraaa!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Oddzielna amunicja dla jeży",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Postaw wiÄcej punktów orientacyjnych za pomocÄ
[Enteru]",
+
["Place more waypoints using the 'Air Attack' weapon."] = "Postaw wiÄcej punktów orientacyjnych używajÄ
c [Nalotu]",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/pl.txt b/share/hedgewars/Data/Locale/pl.txt
index 3cee9d7..88e80ca 100644
--- a/share/hedgewars/Data/Locale/pl.txt
+++ b/share/hedgewars/Data/Locale/pl.txt
@@ -54,10 +54,10 @@
00:51=Kula bÅotna
00:52=Nie wybrano broni
00:53=TARDIS
-00:54=Budynek
-00:55=Miotacz bÅota
-00:56=Zamrażarka
-00:57=Tasak
+; 00:54=Budynek
+00:54=Miotacz bÅota
+00:55=Zamrażarka
+00:56=Tasak
01:00=Walczmy!
01:01=Remis
@@ -174,7 +174,7 @@
02:01=%1 Åpi z rybami
02:01=%1 uważa, że fizyka pÅynów w tej grze jest do bani!
02:01=%1 wyglÄ
da na spragnionego
-02:01=Morze Ciebie wzywa, %1
+02:01=Morze CiÄ wzywa, %1
02:01=%1 zaginÄ
Å na morzu
02:01=%1 powinien przynieÅÄ zestaw do nurkowania
02:01=%1 ma pogrzeb na morzu
@@ -193,7 +193,6 @@
02:01=%1 bÄdzie graÅ w "UwolniÄ OrkÄ"
02:01=%1 szuka rybek do akwarium!
02:01=%1 odnalazÅ AtlantydÄ!
-02:01=%1 chce byÄ gÅównÄ
postaciÄ
w Bioshock 3
02:01=Trzeba byÅo siÄ uczyÄ pÅywaÄ...
02:01=%1 powinien ze sobÄ
zabraÄ narty wodne
02:01=%1 nie lubi sportów wodnych
@@ -247,14 +246,14 @@
02:02=Możesz uważaÄ siÄ za szczÄÅliwca jeżeli nie grasz przeciwko Jessorowi
02:02=Dajcie z siebie wszystko!
02:02=Przegrany sprzÄ
ta teren.
-02:02=Niech rozpocznie siÄ walka millenium
-02:02=Niech rozpocznie siÄ walka wieku
-02:02=Niech rozpocznie siÄ walka dekady
+02:02=Niech rozpocznie siÄ walka millenium
+02:02=Niech rozpocznie siÄ walka wieku
+02:02=Niech rozpocznie siÄ walka dekady
02:02=Niech rozpocznie siÄ walka roku
02:02=Niech rozpocznie siÄ walka miesiÄ
ca
02:02=Niech rozpocznie siÄ walka tygodnia
02:02=Niech rozpocznie siÄ walka dnia
-02:02=Niech rozpocznie siÄ walka godziny
+02:02=Niech rozpocznie siÄ walka godziny
02:02=Graj jak najlepiej!
02:02=Zniszcz przeciwnika!
02:02=Powodzenia
@@ -287,7 +286,7 @@
02:05=Dobre życie... w formie skrzyneczki!
02:05=KtoÅ dzwoniÅ po doktora?
02:05=Åwieże bandaże!
-02:05=To pomoże poczuÄ siÄ Tobie lepiej
+02:05=Po tym poczujesz sie lepiej!
02:05=Pomniejszy Eliksir Å»ywotnoÅci! Eeee... To chyba nie ta nazwa.
02:05=Zbierz mnie!
02:05=Zbierz to!
@@ -310,6 +309,7 @@
02:05=W Hedgewars opieka zdrowotna naprawdÄ wymiata!
02:05=Na zdrowie!
02:05=Szczepionka!
+02:05=Ostatnio coÅ niewyraźnie wyglÄ
dasz. Weź tÄ apteczkÄ!
; New ammo crate
02:06=WiÄcej broni!
@@ -540,8 +540,10 @@
03:51=Znalezione na ziemi
03:52=UNUSED
03:53=Typ 40
-03:54=Zbuduj coÅ przydatnego
-03:55=NarzÄdzie
+;03:54=Zbuduj coÅ przydatnego
+03:54=NarzÄdzie
+03:55=PrzeÅammy lody!
+03:56=Nie przytnij sobie igieÅ!
; Weapon Descriptions (use | as line breaks)
04:00=Atakuj przeciwników zwykÅym granatem.|Wybuchnie kiedy zapalnik skoÅczy odliczanie.|1-5: Ustawia zapalnik|Atak: Przytrzymaj by rzuciÄ z wiÄkszÄ
siÅÄ
@@ -549,9 +551,9 @@
04:02=Atakuj przeciwników pociskiem balistycznym,|który jest podatny na wiatr.|Atak: Przytrzymaj by strzeliÄ z wiÄkszÄ
siÅÄ
04:03=WypuÅÄ zdenerwowanÄ
PszczoÅÄ, która "użÄ
dli"|zaznaczony cel. By zwiÄkszyÄ precyzjÄ nie|strzelaj peÅnÄ
mocÄ
|Kursor: Wybierz cel|Atak: Przytrzymaj by strzeliÄ z wiÄkszÄ
siÅÄ
04:04=Atakuj przeciwników strzelbÄ
z dwoma strzaÅami.|DziaÅa obszarowo, wiÄc nie musisz dokÅadnie|celowaÄ by zraniÄ przeciwników.|Atak: Strzel (kilka razy)
-04:05=Schowaj siÄ pod ziemiÄ! Użyj mÅota pneumatycznego|do wywiercenia dziury w podÅożu i dostania siÄ do|innych miejsc.|Atak: Zacznij/ZakoÅcz kopaÄ
+04:05=Schowaj siÄ pod ziemiÄ! Użyj mÅota pneumatycznego|do wywiercenia dziury w podÅożu i dostania siÄ do|innych miejsc.|Atak: Zacznij/ZakoÅcz kopaÄ
04:06=Znudzony? Brak motywacji do ataku? OszczÄdzasz broÅ?|No problemo! Po prostu pomiÅ turÄ, tchórzu!|Atak: PomiÅ turÄ bez walki
-04:07=SkrÃ³Ä wielkie odlegÅoÅci używajÄ
c liny. RozpÄdź siÄ|by wÅlizgnÄ
Ä siÄ w inne jeże lub upuÅciÄ na nich|granat albo innÄ
broÅ.|Atak: RozwiÅ albo odÅÄ
cz linÄ|DÅugi skok: UpuÅÄ granat lub podobnÄ
broÅ
+04:07=SkrÃ³Ä wielkie odlegÅoÅci używajÄ
c liny. RozpÄdź siÄ|by wÅlizgnÄ
Ä siÄ w inne jeże lub upuÅciÄ na nich|granat albo innÄ
broÅ.|Atak: RozwiÅ albo odÅÄ
cz linÄ|DÅugi skok: UpuÅÄ granat lub podobnÄ
broÅ
04:08=Trzymaj przeciwników na dystans przez upuszczenie|miny w wÄ
skim przejÅciu lub zaraz obok ich stóp. I nie|zapomnij uciec zanim siÄ wÅÄ
czy!|Atak: UpuÅÄ minÄ obok siebie
04:09=Niepewny co do umiejÄtnoÅci w celowaniu?|Weź pistolet i powystrzelaj ich jak kaczki.|Atak: Strzel (kilka razy)
04:10=Brutalna siÅa zawsze jest rozwiÄ
zaniem. UpuÅÄ ten|wybuchowÄ
laskÄ dynamitu obok przeciwnika i|uciekaj gdzie pieprz roÅnie.|Atak: UpuÅÄ dynamit obok siebie
@@ -565,15 +567,15 @@
04:18=Potrzebujesz dodatkowej ochrony albo chcesz|przejÅÄ przez teren nie do przejÅcia? UmieÅÄ|konstrukcje gdzie chcesz.|Lewo/Prawo: Wybierz konstrukcjÄ do umieszczenia|Kursor: UmieÅÄ konstrukcjÄ w odpowiednim miejscu
04:19=Teleport użyty w odpowiednim momencie, staje|siÄ potÄżniejszy niż każda inna broÅ,|ponieważ potrafi wyzwoliÄ jeża z tarapatów|w przeciÄ
gu sekund.|Kursor: Wybierz region
04:20=Pozwala w tej turze zagraÄ innym jeżem.|Atak: Uaktywnij wybieranie jeża
-04:21=Odpal moździerz, który po uderzeniu|wypuÅci kilka bomb.|Atak: Strzel z caÅÄ
mocÄ
+04:21=Odpal moździerz, który po uderzeniu|wypuÅci kilka bomb.|Atak: Strzel z caÅÄ
mocÄ
04:22=Nie tylko dla Indiana Jones! Ten bicz może|byÄ użyteczny w wielu wypadkach. Szczególnie|kiedy chcesz kogoÅ zrzuciÄ z urwiska.|Atak: Ubiczuj wszystko co jest przed tobÄ
04:23=JeÅli nie masz nic do stracenia, ten atak może byÄ|caÅkiem użyteczny. PoÅwiÄÄ swojego jeża i poÅlij|go w odpowiednim kierunku, raniÄ
c wszystkich po|drodze i eksplodujÄ
c na koÅcu.|Atak: Odpal tÄ niszczycielskÄ
i zabójczÄ
technikÄ
04:24=Sto lat! Uruchom ciasto i pozwól mu pójÅÄ w stronÄ|twoich przeciwników urzÄ
dzajÄ
c im wybuchowe przyjÄcie.|Może chodziÄ prawie po wszystkim, ale wtedy|wczeÅniej eksploduje.|Atak: Odpal ciasto albo zatrzymaj je, by wybuchÅo
04:25=Użyj kostiumu by sprawiÄ, żeby twój wróg zakochaÅ siÄ|w Tobie (i spadÅ w przepaÅÄ lub dziurÄ).|Atak: Użyj kostiumu i uwiedź jeża
04:26=RzuÄ tego smacznego arbuza w przeciwników. Kiedy jego|zapalnik wskaże zero, podzieli siÄ na mniejsze kawaÅki.|1-5: Ustawia zapalnik arbuza|Atak: Przytrzymaj by rzuciÄ z wiÄkszÄ
siÅÄ
04:27=Niech ognie piekielne ogarnÄ
twoich przeciwników!|Nie podchodź zbyt blisko po wybuchu, gdyż ogieÅ|pali siÄ przez dÅuższy czas|Atak: Przytrzymaj by rzuciÄ z wiÄkszÄ
siÅÄ
-04:28=Krótko po wystrzeleniu, rakieta zacznie wierciÄ tunel w ziemi|i eksploduje gdy zapalnik zostanie uruchomiony lub|jeÅli pojawi siÄ po drugiej stronie terenu.|Atak: Przytrzymaj by strzeliÄ z wiÄkszÄ
siÅÄ
-04:29=Tego nie powinny używaÄ dzieci!|Pistolet na kulki wystrzeliwuje tony maÅych|kolorowych kulek wypeÅnionych materiaÅem wybuchowym.|Atak: Strzel kulkami|Góra/DóÅ: Kontynuuj celowanie
+04:28=Krótko po wystrzeleniu, rakieta zacznie wierciÄ tunel w ziemi|i eksploduje gdy zapalnik zostanie uruchomiony lub|jeÅli pojawi siÄ po drugiej stronie terenu.|Atak: Przytrzymaj by strzeliÄ z wiÄkszÄ
siÅÄ
+04:29=Tego nie powinny używaÄ dzieci!|Pistolet na kulki wystrzeliwuje tony maÅych|kolorowych kulek wypeÅnionych materiaÅem wybuchowym.|Atak: Strzel kulkami|Góra/DóÅ: Kontynuuj celowanie
04:30=Wezwij samolot, żeby zrzuciÄ dużÄ
iloÅÄ|napalmu. DziÄki dobremu celowi ten atak|może zlikwidowaÄ dużÄ
czÄÅÄ mapy, w tym|znajdujÄ
ce siÄ tam nieszczÄsne jeże.|Lewo/Prawo: OkreÅl kierunek ataku|Kursor: Wybierz region
04:31=Zaatakuj odlegÅych przeciwników, bÄ
dź zbierz|skrzynki! Nie zapomnij o zrzuceniu bomb!|Góra/DóÅ: Steruj samolotem|Atak: ZrzuÄ bombÄ (3x) |DÅugi skok: Niech walkirie wkroczÄ
na pole bitwy!
04:32=Niska grawitacja jest lepsza od diety! Skacz|wyżej i dalej albo pozwól przeciwnikom fruwaÄ.|Atak: Aktywuj
@@ -598,8 +600,10 @@
04:51=ObrzuÄ kogoÅ bÅotem! BroÅ ta nie zadaje dużych|obrażeÅ ale może Gogol zepchnÄ
Ä z krawÄdzi!|Atak: Przytrzymaj by strzeliÄ z wiÄkszÄ
siÅÄ
04:52=UNUSED
04:53=Wybierz siÄ na podróż w czasie i przestrzeni|zostawiajÄ
c inne jeże na polu walki.|BÄ
dź przygotowany na powrót w dowolnym momencie.|Gdy rozpocznie siÄ|NagÅa ÅmierÄ lub wiÄkszoÅÄ jeży zostanie wybita.|Uwaga. Nie zadziaÅa podczas NagÅej Åmierci,|gdy jesteÅ sam lub jeÅli jesteÅ Królem.
-04:54=INCOMPLETE
-04:55=Wystrzel strumieÅ kleistej mazi.|Buduj mosty, zasypuj wrogów, zatykaj tunele.|Uważaj by nie zasypaÄ samego siebie!
+;04:54=INCOMPLETE
+04:54=Wystrzel strumieÅ kleistej mazi.|Buduj mosty, zasypuj wrogów, zatykaj tunele.|Uważaj by nie zasypaÄ samego siebie!
+04:55=Epoka lodowcowa powraca!!|Zamroź jeże, uczyÅ podÅoże Åliskim lub zapobiegnij|utoniÄciu zamrażajÄ
c wodÄ.|Atak: StrzaÅ
+04:56=RzuÄ w przeciwnika dwoma tasakami i zablokuj mu |drogÄ lub użyj ich do wspinaczki! Jednak uważaj! |Te tasaki sÄ
naprawdÄ ostre!|Atak: Przytrzymaj by rzuciÄ z wiÄkszÄ
siÅÄ
(dwukrotnie)
; Game goal strings
05:00=Ustawienia gry
diff --git a/share/hedgewars/Data/Locale/pt_BR.lua b/share/hedgewars/Data/Locale/pt_BR.lua
index 42f06ba..3444285 100644
--- a/share/hedgewars/Data/Locale/pt_BR.lua
+++ b/share/hedgewars/Data/Locale/pt_BR.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Volta mais rápida: ",
-- ["Feeble Resistance"] = "",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
-- ["Hooray!"] = "",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/pt_BR.txt b/share/hedgewars/Data/Locale/pt_BR.txt
index ba4a93d..1e0245d 100644
--- a/share/hedgewars/Data/Locale/pt_BR.txt
+++ b/share/hedgewars/Data/Locale/pt_BR.txt
@@ -52,6 +52,13 @@
00:49=Ressucitador
00:50=Ataque Perfurador
00:51=Bola de Lama
+00:52=Arma não selecionada
+00:53=Máquina do tempo
+; 00:54=Estrutura
+00:54=Spray de terra
+00:55=Freezer
+00:56=Machadinha
+
01:00=Hora de lutar!
01:01=Partida empatou
@@ -63,11 +70,18 @@
01:07=%1 Remanescente
01:08=CombustÃvel
01:09=Sincronizando...
-01:10=Usar esta ultilidade não encerrará o turno
+01:10=Usar esta utilidade não encerrará o turno
01:11=Esta arma ou utilidade ainda não está disponÃvel
01:12=Ãltimo round antes da Morte Súbita!
01:13=%1 rounds até a Morte Súbita
01:14=Se prepare, %1!
+01:15=MÃnimo
+01:16=Baixo
+01:17=Normal
+01:18=Alto
+01:19=Extremo
+01:20=%1 Quique
+01:21=Ãudio mudo
; Event messages
; Hog (%1) died
@@ -122,7 +136,7 @@
02:02=Armado e preparado!
02:02=3..2..1...!
02:02=Cúpula do Trovão!Cúpula do Trovão!Cúpula do Trovão!
-02:02=Abrem-se as curtinas e começa o espetáculo
+02:02=Abrem-se as cortinas e começa o espetáculo
02:02=A bola está em jogo!
02:02=Bobeou....dançou!
02:02=Só os melhores sobrevivem!
@@ -134,6 +148,11 @@
02:02=Começa a partida
02:02=Vamos a luta companheiros
02:02=Pela Pátria!
+02:02=Vitória ou morte!
+02:02=Esmague seu inimigo!
+02:02=Solte os cães de batalha!
+02:02=Apiiiita o árbitro!
+02:02=Ao vencedor as batatas!
; Round ends (win; unused atm)
02:03=...
@@ -148,10 +167,13 @@
02:05=Mais um suspiro!
02:05=Chamando doutor Hans Chucrutes
02:05=ColÃrio para os olhos!
-02:05=O Motoboy da farmácia chegou!
+02:05=O motoboy da farmácia chegou!
02:05=Curativos!
02:05=Energia extra!
02:05=Energéticos!
+02:05=Um Hi-Potion! Uuups, jogo errado
+02:05=Posologia: Tantos quanto possas conseguir!
+
; New ammo crate
02:06=Mais armas!
@@ -168,6 +190,10 @@
02:06=Suprimentos
02:06=O que faltava para você vencer!
02:06=Qual será a surpresa?
+02:06=Uma caixinha de surpresas!
+02:06=Não sabes o pesadelo que foi atravessar a fronteira com isso!
+02:06=Cuidado! Volátil!
+02:06=Brinquedinhos destrutivos do Céu!
; New utility crate
02:07=Hora das compras
@@ -193,7 +219,7 @@
02:08=%1 está se balançando na rede
02:08=%1 prefere só ficar olhando
02:08=%1 desaponta a todos
-02:08=%1 ficou filosofando
+02:08=%1 ficou filosofando
02:08=%1 amarelou
02:08=%1 tá de boa
02:08=%1 pegou no sono
@@ -201,11 +227,17 @@
02:08=%1 prefere Gandhi a Mandela
02:08=%1 foi ler um livro
02:08=%1 está procurando algo melhor para fazer
+02:08=%1 é um franguinho!
+02:08=%1 decidiu que o melhor a fazer é ... nada!
+02:08=%1 está fora de forma!
+02:08=%1 é um pacifista
+02:08=%1 está paralizado de terror
+02:08=%1 está pedindo para sair
; Hog (%1) hurts himself only
02:09=%1 se machucou
02:09=%1 fez dodói
-02:09=%1 é uma anta
+02:09=%1 é uma anta
02:09=%1 não sabe quem é o inimigo
02:09=%1 não gosta de si mesmo
02:09=%1 não tem amor próprio
@@ -220,6 +252,12 @@
02:09=%1 mudou de equipe
02:09=%1 acha que ninguém viu
02:09=%1 devia procurar outro jogo
+02:09=%1 deveria mudar de profissão
+02:09=%1 não tem instinto de sobrevivência
+02:09=%1 deveria praticar pontaria
+02:09=%1 acaba de demonstrar ao inimigo do que é capaz
+02:09=As armas de %1 estão obviamente defeituosas!
+02:09=Não, não, não, %1, deves atirar no INIMIGO!
; Hog shot an home run (using the bat and another hog)
02:10=Humilhooooouuu!
@@ -227,12 +265,12 @@
02:10=Esse aà está fora!
02:10=Home Run!
02:10=Ouriço perdido!
+02:10=Bolinha perdida!
; Hog (%1) has to leave (team is gone)
02:11=%1 foi nanar
02:11=%1 abandonou o jogo
02:11=%1 estava borrando as calças
-02:11=Beam him up, Scotty!
02:11=%1 teve que sair
; Weapon Categories
@@ -259,7 +297,7 @@
03:20=Ação
03:21=Arma BalÃstica
03:22=Me chame Indiana!
-03:23=Artes Marciais (Realmente)
+03:23=Artes Marciais (Realmente)
03:24=O Bolo não é de brinquedo!
03:25=Disfarce
03:26=Granada Suculenta
@@ -276,18 +314,23 @@
03:37=Efeito Temporário
03:38=Arma de Fogo (múltiplos tiros)
03:39=Utilidade de Transporte
-03:40=Granada Inceneradora
+03:40=Granada Incendiária
03:41=Grande fan de Squawks
-03:42=Ãltima tecnologia
+03:42=Eu irei fazer uma nota aqui ...
03:43=Musical
-03:44=Velho e fedorento
+03:44=Data de validade: 1923
03:45=Trigonometria pura
-03:46=Incendiário
+03:46=Quente! Quente! Quente!
03:47=Grudenta
03:48=Tanto bate até que fura!
03:49=Faz o que você imagina
03:50=Contra covardes
-03:51=Devagar, e sempre....
+03:51=Encontrei no chão
+03:52=Sem uso
+03:53=Tipo 40
+;03:54=Constrói algo
+03:54=Utilidade
+
; Weapon Descriptions (use | as line breaks)
04:00=Ataque seus inimigos usando uma granada simples|Ela explodirá assim que o tempo passar|1-5: Escolha o tempo da granada|Ataque: Quanto mais tempo, mais forte o lançamento.
@@ -310,7 +353,7 @@
04:15=Chame um avião para bombadear seus inimigos.|Esquerda/Direita: Determina a direção do ataque|Cursor: Seleciona a região do ataque
04:16=Chame um avião para lançar diversas minas|na área alvo.|Esquerda/Direita: Determina a direção do ataque|Cursor: Seleciona a região do ataque
04:17=Precisa de abrigo? Use o maçarico para|cavar um túnel que te de cobertura.|Ataque:Liga/Desliga o maçarico
-04:18=Precisa de proteção adicional ou quer atravessar|um lugar difÃcil? Coloque algumas vigas.|Esquerda/Direita: Seleciona a viga a colocar|Cursor: Coloca a viga em uma posição válida.
+04:18=Precisa de proteção adicional ou quer atravessar|um lugar difÃcil? Coloque algumas vigas.|Esquerda/Direita: Seleciona a viga a colocar|Cursor: Coloca a viga em uma posição válida.
04:19=Usada no momento certo, teleportar-se pode ser mais|poderosa que todas as outras armas, permitindo|salvar alguns ouriços em situação perigosa|Cursor: Seleciona o destino do teletransporte.
04:20=Permite você jogar este turno com um ouriço diferente.|Ataque: Ativa|Tab: Alterna o ouriço
@@ -345,6 +388,12 @@
04:47=Uma simples mina não basta? A mina aderente pode|ser arremessada e ficará aderida ao tocar no solo,|em um objeto, e até em um ouriço!|Ataque:Quanto mais tempo, mais forte o lançamento (duas vezes).
04:48=Vamos a obra? Use esta arma para martelar|o inimigo no solo, ou através dele e tirando um terço da vida dele!|Ataque: Ativa
04:49=Ressucite seus amigos, mas preste atenção|para não ressucitar seus inimigos!|Ataque: Mantenha pressionado para transferir|sua vida|Acima:Acelera a transferência de vida
+04:50=Alguém está se escondendo embaixo da terra?|Desenterre-os com um Ataque Perfurador!|O timer controla a profundidade alcançada.
+04:51=Ganhe um tiro de graça, atirando uma bola de barro.|Fará com que o inimigo saia voando|e arde a vista.
+04:52=Sem Uso
+04:53=Viage através do tempo e espaço,|deixando seus camaradas na mão.|Esteja preparado para retornar a qualquer momento,|ou para a Morte Súbita se todos os aliados foram mortos.|Aviso. Não funciona na Morte Súbita,|se você estiversozinho, ou se você for o Rei.
+;04:54=INCOMPLETO
+04:54=Atira um jorro de barro pegajoso.|Constrói pontes, enterra inimigos, sela túneis.|Cuidado para que não pegue em você!
; Game goal strings
05:00=Modos de Jogo
@@ -355,16 +404,17 @@
05:05=Vampirismo: Ouriços serão curados pelos danos causados
05:06=Carma: Ouriços serão machucados pelos danos causados
05:07=Proteja o rei: Não deixe o seu Rei morrer!|Colocar o Rei: Escolha um lugar protegido para posicionar o seu Rei
-05:08=Colocar Ouriços: Permite posicionar os ouriços antes dapartida começar
+05:08=Colocar Ouriços: Permite posicionar os ouriços antes da partida começar
05:09=Artilharia: Ouriços não podem andar para mudar de lugar
05:10=Terreno IndestrutÃvel: Maioria das armas não destrói o terreno
-05:11=Armas Compartilhadas: Todos as equipes de mesma cor compratilham a munição
+05:11=Munição Compartilhada: Todos as equipes de mesma cor compartilham a munição
05:12=Temporizador de mina: Minas detonarão após %1 segundo(s)
05:13=Temporizador de mina: Minas detonarão imediatamente
-05:14=Temporizador de mina: Minas detonarão em 0 - 3 segundos
+05:14=Temporizador de mina: Minas detonarão em 0 - 5 segundos
05:15=Modificador de Dano: Todas as armas farão %1% danos
05:16=A vida dos ouriços é reiniciada ao fim de cada turno
05:17=Ouriços da IA renascem após morrerem
05:18=Ataque ilimitado
05:19=Armas são reiniciadas ao fim do turno
05:20=Armas não são compartilhadas entre os ouriços
+05:21=Tag Team: Equipes do mesmo clan se revezam entre si.|Turno compartilhado: Equipes do mesmo clan compartilham a duração do turno.
diff --git a/share/hedgewars/Data/Locale/pt_PT.lua b/share/hedgewars/Data/Locale/pt_PT.lua
index 332f276..125f8c4 100644
--- a/share/hedgewars/Data/Locale/pt_PT.lua
+++ b/share/hedgewars/Data/Locale/pt_PT.lua
@@ -5,57 +5,57 @@ locale = {
["011101000"] = "011101000", -- A_Classic_Fairytale:dragon
["011101001"] = "011101001", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
["30 minutes later..."] = "30 minutos depois...", -- A_Classic_Fairytale:shadow
--- ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "ácerca de um mês atrás, um cyborg veio e disse-nos que voces é que eram os cabinais!", -- A_Classic_Fairytale:enemy
- ["Accuracy Bonus!"] = "Bónus de precisão!",
+ ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "à volta de um mês atrás, apareceu um cyborg e disse-nos que voces é que eram os cabinais!", -- A_Classic_Fairytale:enemy
+ ["Accuracy Bonus!"] = "Bónus de Precisão!",
["Ace"] = "Ãs", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
["Achievement Unlocked"] = "Proeza Desbloqueada", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_That_Sinking_Feeling, Tumbler
["???"] = "???", -- A_Classic_Fairytale:backstab
--- ["A Classic Fairytale"] = "Um Classico Conto de Fadas", -- A_Classic_Fairytale:first_blood
--- ["Actually, you aren't worthy of life! Take this..."] = "", -- A_Classic_Fairytale:shadow
--- ["A cy-what?"] = "", -- A_Classic_Fairytale:enemy
--- ["Adventurous"] = "", -- A_Classic_Fairytale:journey
--- ["Africa"] = "", -- Continental_supplies
--- ["After Leaks A Lot betrayed his tribe, he joined the cannibals..."] = "", -- A_Classic_Fairytale:first_blood
--- ["After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."] = "", -- A_Classic_Fairytale:shadow
--- ["Again with the 'cannibals' thing!"] = "", -- A_Classic_Fairytale:enemy
--- ["a Hedgewars challenge"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
+ ["A Classic Fairytale"] = "Um Clássico Conto de Fadas", -- A_Classic_Fairytale:first_blood
+ ["Actually, you aren't worthy of life! Take this..."] = "Pensando melhor, não mereçes viver! Toma isto...", -- A_Classic_Fairytale:shadow
+ ["A cy-what?"] = "Um cy-quê?", -- A_Classic_Fairytale:enemy
+ ["Adventurous"] = "Aventureiro", -- A_Classic_Fairytale:journey
+ ["Africa"] = "Ãfrica", -- Continental_supplies
+ ["After Leaks A Lot betrayed his tribe, he joined the cannibals..."] = "Depois do Leaks A Lot ter traÃdo a sua tribo, ele juntou-se aos canibais...", -- A_Classic_Fairytale:first_blood
+ ["After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."] = "Depois do choque causado pelo espião inimigo, Leaks A Lot e Nuvem Densa foram caçar para relaxar.", -- A_Classic_Fairytale:shadow
+ ["Again with the 'cannibals' thing!"] = "Outra vez com a cena dos 'canibais'!", -- A_Classic_Fairytale:enemy
+ ["a Hedgewars challenge"] = "um desafio Hedgewars", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
["a Hedgewars mini-game"] = "um mini-jogo Hedgewars", -- Space_Invasion, The_Specialists
["Aiming Practice"] = "Pratica a tua pontaria", --Bazooka, Shotgun, SniperRifle
--- ["A leap in a leap"] = "", -- A_Classic_Fairytale:first_blood
--- ["A little gift from the cyborgs"] = "", -- A_Classic_Fairytale:shadow
--- ["All gone...everything!"] = "", -- A_Classic_Fairytale:enemy
--- ["All right, we just need to get to the other side of the island!"] = "", -- A_Classic_Fairytale:journey
--- ["All walls touched!"] = "", -- WxW
--- ["Ammo Depleted!"] = "",
--- ["ammo extended!"] = "",
--- ["Ammo is reset at the end of your turn."] = "",
+-- ["A leap in a leap"] = "Um salto num salto", -- A_Classic_Fairytale:first_blood
+ ["A little gift from the cyborgs"] = "Um pequeno presente dos cyborgs", -- A_Classic_Fairytale:shadow
+ ["All gone...everything!"] = "Foi-se...tudo!", -- A_Classic_Fairytale:enemy
+ ["All right, we just need to get to the other side of the island!"] = "Ok, so precisamos de chegar ao outro lado da ilha!", -- A_Classic_Fairytale:journey
+ ["All walls touched!"] = "Todas as paredes alcançadas!", -- WxW
+-- ["Ammo Depleted!"] = "Munições Esgotadas!",
+-- ["ammo extended!"] = "munições adicionadas!",
+ ["Ammo is reset at the end of your turn."] = "O armamento é reposto no fim do teu turno.",
-- ["Ammo Maniac!"] = "",
["Ammo"] = "Munições",
--- ["And how am I alive?!"] = "", -- A_Classic_Fairytale:enemy
+ ["And how am I alive?!"] = "E como raio estou eu vivo ainda?!", -- A_Classic_Fairytale:enemy
-- ["And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."] = "", -- A_Classic_Fairytale:first_blood
--- ["And so it began..."] = "", -- A_Classic_Fairytale:first_blood
--- ["...and so the cyborgs took over the world..."] = "", -- A_Classic_Fairytale:shadow
--- ["And so they discovered that cyborgs weren't invulnerable..."] = "", -- A_Classic_Fairytale:journey
--- ["And where's all the weed?"] = "", -- A_Classic_Fairytale:dragon
--- ["And you believed me? Oh, god, that's cute!"] = "", -- A_Classic_Fairytale:journey
+ ["And so it began..."] = "E assim começou...", -- A_Classic_Fairytale:first_blood
+ ["...and so the cyborgs took over the world..."] = "...e então os cyborgs apoderaram-se do mundo...", -- A_Classic_Fairytale:shadow
+ ["And so they discovered that cyborgs weren't invulnerable..."] = "E então descobriram que os cyborgs não eram invulneráveis...", -- A_Classic_Fairytale:journey
+ ["And where's all the weed?"] = "E onde está a erva toda?", -- A_Classic_Fairytale:dragon
+ ["And you believed me? Oh, god, that's cute!"] = "E tu acreditaste em mim? Ai meu deus, tão fofo!", -- A_Classic_Fairytale:journey
-- ["Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"] = "", -- Continental_supplies
--- ["Antarctica"] = "", -- Continental_supplies
--- ["Are we there yet?"] = "", -- A_Classic_Fairytale:shadow
--- ["Are you accusing me of something?"] = "", -- A_Classic_Fairytale:backstab
--- ["Are you saying that many of us have died for your entertainment?"] = "", -- A_Classic_Fairytale:enemy
+ ["Antarctica"] = "Antártica", -- Continental_supplies
+ ["Are we there yet?"] = "Já chegámos?", -- A_Classic_Fairytale:shadow
+-- ["Are you accusing me of something?"] = "Estás a acusar-me de alguma coisa?", -- A_Classic_Fairytale:backstab
+-- ["Are you saying that many of us have died for your entertainment?"] = "Estás a tentar dizer-me que estas quantidade de nós morreu para o teu entertenimento?", -- A_Classic_Fairytale:enemy
-- ["Artur Detour"] = "", -- A_Classic_Fairytale:queen
--- ["As a reward for your performance, here's some new technology!"] = "", -- A_Classic_Fairytale:dragon
--- ["a shoppa minigame"] = "", -- WxW
--- ["Asia"] = "", -- Continental_supplies
+ ["As a reward for your performance, here's some new technology!"] = "De forma a recompensar o teu desempenho, aqui tens alguma nova tecnologia!", -- A_Classic_Fairytale:dragon
+ ["a shoppa minigame"] = "um minijogo shoppa", -- WxW
+ ["Asia"] = "Ãsia", -- Continental_supplies
-- ["Assault Team"] = "", -- A_Classic_Fairytale:backstab
--- ["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "", -- A_Classic_Fairytale:dragon
+ ["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "Como o armamento está muito disperso, podes querer reutilizar a corda enquanto no ar.|", -- A_Classic_Fairytale:dragon
-- ["As the challenge was completed, Leaks A Lot set foot on the ground..."] = "", -- A_Classic_Fairytale:first_blood
--- ["As you can see, there is no way to get on the other side!"] = "", -- A_Classic_Fairytale:dragon
--- ["Attack From Rope"] = "", -- WxW
--- ["Australia"] = "", -- Continental_supplies
--- ["Available points remaining: "] = "",
--- ["Back Breaker"] = "", -- A_Classic_Fairytale:backstab
--- ["Back in the village, after telling the villagers about the threat..."] = "", -- A_Classic_Fairytale:united
+ ["As you can see, there is no way to get on the other side!"] = "Como podes ver, não existe forma de passarmos para o outro lado!", -- A_Classic_Fairytale:dragon
+ ["Attack From Rope"] = "Ataca Da Corda", -- WxW
+ ["Australia"] = "Austrália", -- Continental_supplies
+-- ["Available points remaining: "] = "Pontos activos restantes: ",
+-- ["Back Breaker"] = "Parte Costas", -- A_Classic_Fairytale:backstab
+-- ["Back in the village, after telling the villagers about the threat..."] = "De volta à \Mais tarde na aldeia, depois de ter avisado os aldeões sobre a ameaça...", -- A_Classic_Fairytale:united
["[Backspace]"] = "[Retrocesso (backspace)]",
-- ["Backstab"] = "", -- A_Classic_Fairytale:backstab
-- ["Bad Team"] = "", -- User_Mission_-_The_Great_Escape
@@ -89,32 +89,32 @@ locale = {
-- ["Brain Teaser"] = "", -- A_Classic_Fairytale:backstab
-- ["Brutal Lily"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil
-- ["Brutus"] = "", -- A_Classic_Fairytale:backstab
--- ["Build a track and race."] = "",
--- ["Bullseye"] = "", -- A_Classic_Fairytale:dragon
+-- ["Build a track and race."] = "Constroi uma pista e compete numa corrida.",
+-- ["Bullseye"] = "Em cheio", -- A_Classic_Fairytale:dragon
-- ["But it proved to be no easy task!"] = "", -- A_Classic_Fairytale:dragon
--- ["But that's impossible!"] = "", -- A_Classic_Fairytale:backstab
--- ["But the ones alive are stronger in their heart!"] = "", -- A_Classic_Fairytale:enemy
--- ["But...we died!"] = "", -- A_Classic_Fairytale:backstab
--- ["But where can we go?"] = "", -- A_Classic_Fairytale:united
--- ["But why would they help us?"] = "", -- A_Classic_Fairytale:backstab
--- ["But you're cannibals. It's what you do."] = "", -- A_Classic_Fairytale:enemy
--- ["But you said you'd let her go!"] = "", -- A_Classic_Fairytale:journey
--- ["Call me Beep! Well, 'cause I'm such a nice...person!"] = "", -- A_Classic_Fairytale:family
--- ["Cannibals"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood
+ ["But that's impossible!"] = "Mas isso é impossÃvel!", -- A_Classic_Fairytale:backstab
+-- ["But the ones alive are stronger in their heart!"] = "Mas os sobreviventes têm um coração mais forte! (não faz sentido assim...)", -- A_Classic_Fairytale:enemy
+-- ["But...we died!"] = "Mas...nós morremos!", -- A_Classic_Fairytale:backstab
+-- ["But where can we go?"] = "Mas para onde podemos ir?", -- A_Classic_Fairytale:united
+-- ["But why would they help us?"] = "Mas porque nos ajudariam eles?", -- A_Classic_Fairytale:backstab
+-- ["But you're cannibals. It's what you do."] = "Mas voçês são canibais. à o que (voçês)fazem.", -- A_Classic_Fairytale:enemy
+-- ["But you said you'd let her go!"] = "Mas disseste que a deixarias ir!", -- A_Classic_Fairytale:journey
+-- ["Call me Beep! Well, 'cause I'm such a nice...person!"] = "Trata-me por Beep! Bem, porque eu sou um---a pessoa tão simpática!", -- A_Classic_Fairytale:family
+ ["Cannibals"] = "Canibais", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood
-- ["Cannibal Sentry"] = "", -- A_Classic_Fairytale:journey
--- ["Cannibals?! You're the cannibals!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Cannibals?! You're the cannibals!"] = "Canibais?! Vocês são os canibais!", -- A_Classic_Fairytale:enemy
["CAPTURE THE FLAG"] = "CAPTURAR A BANDEIRA",
["Careless"] = "Descuidado",
--- ["Carol"] = "", -- A_Classic_Fairytale:family
--- ["CHALLENGE COMPLETE"] = "DESAFIO COMPLETO", -- User_Mission_-_RCPlane_Challenge
+ ["Carol"] = "Carol", -- A_Classic_Fairytale:family
+ ["CHALLENGE COMPLETE"] = "DESAFIO COMPLETO", -- User_Mission_-_RCPlane_Challenge
["Change Weapon"] = "Trocar Arma",
--- ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "", -- A_Classic_Fairytale:shadow
--- ["Clumsy"] = "",
--- ["Cluster Bomb MASTER!"] = "", -- Basic_Training_-_Cluster_Bomb
--- ["Cluster Bomb Training"] = "", -- Basic_Training_-_Cluster_Bomb
--- ["Codename: Teamwork"] = "",
--- ["Collateral Damage"] = "", -- A_Classic_Fairytale:journey
--- ["Collateral Damage II"] = "", -- A_Classic_Fairytale:journey
+ ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "Escolhe o teu lado! Se quiseres juntar-te ao homem estranho, aproxima-te dele! Caso contrario, afastate dele. Se decidires atac...esquece...", -- A_Classic_Fairytale:shadow
+ ["Clumsy"] = "Desastrado",
+ ["Cluster Bomb MASTER!"] = "MESTRE da Bomba de Fragmentos!", -- Basic_Training_-_Cluster_Bomb
+ ["Cluster Bomb Training"] = "Treino com Bomba de Fragmentos!", -- Basic_Training_-_Cluster_Bomb
+-- ["Codename: Teamwork"] = "Nome de código: Trabalho em Equipa",
+ ["Collateral Damage"] = "Dano Colateral", -- A_Classic_Fairytale:journey
+ ["Collateral Damage II"] = "Dano Colateral II", -- A_Classic_Fairytale:journey
-- ["Collect all the crates, but remember, our time in this life is limited!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Collect or destroy all the health crates."] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"] = "", -- A_Classic_Fairytale:first_blood
@@ -136,7 +136,7 @@ locale = {
-- ["Corpse Thrower"] = "", -- A_Classic_Fairytale:epil
-- ["Crates Left:"] = "", -- User_Mission_-_RCPlane_Challenge
["Cybernetic Empire"] = "Império Cibernético",
--- ["Cyborg. It's what the aliens call themselves."] = "Cyborg. Ã o que os extra terrestres se chamam a eles mesmos(errrr)", -- A_Classic_Fairytale:enemy
+-- ["Cyborg. It's what the aliens call themselves."] = "Cyborg. Ã o que os extra terrestres se chamam a eles mesmos(errrr)\autointitulam", -- A_Classic_Fairytale:enemy
-- ["Dahmer"] = "", -- A_Classic_Fairytale:backstab
-- ["DAMMIT, ROOKIE!"] = "",
-- ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "",
@@ -147,18 +147,18 @@ locale = {
-- ["Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow
-- ["Defeat the cyborgs!"] = "", -- A_Classic_Fairytale:enemy
-- ["Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"] = "", -- A_Classic_Fairytale:shadow
--- ["Demolition is fun!"] = "",
--- ["Dense Cloud"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
--- ["Dense Cloud must have already told them everything..."] = "", -- A_Classic_Fairytale:shadow
+ ["Demolition is fun!"] = "Demolir é divertido!",
+ ["Dense Cloud"] = "Nuvem Densa", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+ ["Dense Cloud must have already told them everything..."] = "O Nuvem Densa já lhes deve ter dito tudo...", -- A_Classic_Fairytale:shadow
-- ["Depleted Kamikaze!"] = "",
-- ["Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Destroy invaders to score points."] = "",
-- ["Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."] = "", -- A_Classic_Fairytale:first_blood
-- ["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "", -- A_Classic_Fairytale:first_blood
--- ["Did anyone follow you?"] = "", -- A_Classic_Fairytale:united
+ ["Did anyone follow you?"] = "Foste seguido por alguém?", -- A_Classic_Fairytale:united
-- ["Did you see him coming?"] = "", -- A_Classic_Fairytale:shadow
--- ["Did you warn the village?"] = "", -- A_Classic_Fairytale:shadow
--- ["Die, die, die!"] = "", -- A_Classic_Fairytale:dragon
+ ["Did you warn the village?"] = "Avisaste a aldeia?", -- A_Classic_Fairytale:shadow
+ ["Die, die, die!"] = "Morre, morre, morre!", -- A_Classic_Fairytale:dragon
-- ["Disguise as a Rockhopper Penguin: [Swap place with a random enemy hog in the circle]"] = "", -- Continental_supplies
-- ["Dist: "] = "", -- Space_Invasion
-- ["Do not laugh, inexperienced one, for he speaks the truth!"] = "", -- A_Classic_Fairytale:backstab
@@ -166,32 +166,32 @@ locale = {
-- ["Do the deed"] = "", -- A_Classic_Fairytale:first_blood
-- ["Double Kill!"] = "",
-- ["DOUBLE KILL"] = "", -- Mutant
--- ["Do you have any idea how valuable grass is?"] = "", -- A_Classic_Fairytale:enemy
--- ["Do you think you're some kind of god?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Do you have any idea how valuable grass is?"] = "Tnes alguma ideia do quão aliosa esta erva é?", -- A_Classic_Fairytale:enemy
+-- ["Do you think you're some kind of god?"] = "Pensas que és\Axas-te algum tipo de deus?", -- A_Classic_Fairytale:enemy
-- ["Dragon's Lair"] = "", -- A_Classic_Fairytale:dragon
-- ["Drills"] = "", -- A_Classic_Fairytale:backstab
-- ["Drone Hunter!"] = "",
--- ["Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"] = "", -- Continental_supplies
+-- ["Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"] = "Larga uma bomba: [lança algum horoico vento que se ]", -- Continental_supplies
-- ["Drowner"] = "",
--- ["Dude, all the plants are gone!"] = "", -- A_Classic_Fairytale:family
--- ["Dude, can you see Ramon and Spiky?"] = "", -- A_Classic_Fairytale:journey
--- ["Dude, that's so cool!"] = "", -- A_Classic_Fairytale:backstab
--- ["Dude, we really need a new shaman..."] = "", -- A_Classic_Fairytale:shadow
--- ["Dude, what's this place?!"] = "", -- A_Classic_Fairytale:dragon
--- ["Dude, where are we?"] = "", -- A_Classic_Fairytale:backstab
--- ["Dude, wow! I just had the weirdest high!"] = "", -- A_Classic_Fairytale:backstab
--- ["Duration"] = "", -- Continental_supplies
--- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "", -- Continental_supplies
--- ["Each turn you get 1-3 random weapons"] = "",
--- ["Each turn you get one random weapon"] = "",
+-- ["Dude, all the plants are gone!"] = "Bacano, os planetas desapareceram todos!", -- A_Classic_Fairytale:family
+-- ["Dude, can you see Ramon and Spiky?"] = "Bacano, consegues ver o Ramon e o Spiky?", -- A_Classic_Fairytale:journey
+-- ["Dude, that's so cool!"] = "Bacano, isso\isto é tão fixe!", -- A_Classic_Fairytale:backstab
+-- ["Dude, we really need a new shaman..."] = "Bacano, precisamos mesmo de um xamã...", -- A_Classic_Fairytale:shadow
+-- ["Dude, what's this place?!"] = "Bacano, que sitio é este?!", -- A_Classic_Fairytale:dragon
+-- ["Dude, where are we?"] = "Bacano, onde estamos?", -- A_Classic_Fairytale:backstab
+-- ["Dude, wow! I just had the weirdest high!"] = "Bacano, wow! Acabei de ter o 'high' mais esquesito de sempre.", -- A_Classic_Fairytale:backstab
+ ["Duration"] = "Duração", -- Continental_supplies
+-- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "Tempestade de areia: [Causa 20 pontos de dano a toros os inimigos dentro no circulo]", -- Continental_supplies
+-- ["Each turn you get 1-3 random weapons"] = "Todos os turnos recebes 1-3 armas aleatórias",
+-- ["Each turn you get one random weapon"] = "Todos os turnos recebes uma arma aleatória",
-- ["Eagle Eye"] = "", -- A_Classic_Fairytale:backstab
-- ["Eagle Eye: [Blink to the impact ~ one shot]"] = "", -- Continental_supplies
--- ["Ear Sniffer"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:epil
+-- ["Ear Sniffer"] = "Snifa ouvidos\orelhas", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:epil
-- ["Elderbot"] = "", -- A_Classic_Fairytale:family
--- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape
+-- ["Elimate your captor."] = "Elimina o teu raptor.", -- User_Mission_-_The_Great_Escape
["Eliminate all enemies"] = "Elimina todos os inimigos",
["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Destrói todos os alvos antes do tempo terminar.|Tens munições infinitas para esta missão.", --Bazooka, Shotgun, SniperRifle
--- ["Eliminate enemy hogs and take their weapons."] = "", -- Highlander
+-- ["Eliminate enemy hogs and take their weapons."] = "Elimina os ouriços enimigos e fica-lhes com as armas\apodera-te das armas deles.", -- Highlander
["Eliminate Poison before the time runs out"] = "Elimina o Poison antes do tempo terminar.",
["Eliminate the Blue Team"] = "Elimina a equipa azul",
-- ["Eliminate the enemy before the time runs out"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
@@ -201,15 +201,15 @@ locale = {
-- ["Elmo"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["Energetic Engineer"] = "",
["Enjoy the swim..."] = "Aproveita o mergulho",
- ["[Enter]"] = "[Enter]",
--- ["Europe"] = "", -- Continental_supplies
--- [" ever done to you?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Everyone knows this."] = "", -- A_Classic_Fairytale:enemy
+ ["[Enter]"] = "[Enter]",
+ ["Europe"] = "Europa", -- Continental_supplies
+-- [" ever done to you?!"] = " alguma vez te aconteceu?!", -- A_Classic_Fairytale:backstab
+-- ["Everyone knows this."] = "Toda a gente sabe isso.", -- A_Classic_Fairytale:enemy
-- ["Every single time!"] = "", -- A_Classic_Fairytale:dragon
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
--- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
+-- ["Exactly, man! That was my dream."] = "Exactamente, homem! Esse era o meu sonho.", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Volta mais rápida: ",
-- ["Feeble Resistance"] = "",
@@ -218,273 +218,272 @@ locale = {
-- ["Fell From Heaven is the best! Fell From Heaven is the greatest!"] = "", -- A_Classic_Fairytale:family
-- ["Femur Lover"] = "", -- A_Classic_Fairytale:shadow
-- ["Fierce Competition!"] = "", -- Space_Invasion
--- ["Fiery Water"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
--- ["Find your tribe!|Cross the lake!"] = "", -- A_Classic_Fairytale:dragon
--- ["Finish your training|Hint: Animations can be skipped with the [Precise] key."] = "", -- A_Classic_Fairytale:first_blood
--- ["Fire"] = "",
+ ["Fiery Water"] = "Ãgua Flamejante", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+ ["Find your tribe!|Cross the lake!"] = "Encontra a tua tribo|Atravessa o lago!", -- A_Classic_Fairytale:dragon
+-- ["Finish your training|Hint: Animations can be skipped with the [Precise] key."] = "Acaba o teu treino|Ajuda: As animações podem ser saltadas com a tecla [Precisão].", -- A_Classic_Fairytale:first_blood
+ ["Fire"] = "Fogo",
-- ["Fire a mine: [Does what it says ~ Cant be dropped close to an enemy ~ 1 sec]"] = "", -- Continental_supplies
--- ["First aid kits?!"] = "", -- A_Classic_Fairytale:united
+ ["First aid kits?!"] = "Kits de primeiros socorros?!", -- A_Classic_Fairytale:united
-- ["First Blood"] = "", -- A_Classic_Fairytale:first_blood
-- ["FIRST BLOOD MUTATES"] = "", -- Mutant
--- ["First Steps"] = "", -- A_Classic_Fairytale:first_blood
+-- ["First Steps"] = "Primeiros Passos", -- A_Classic_Fairytale:first_blood
["Flag captured!"] = "Bandeira capturada!",
["Flag respawned!"] = "Bandeira reiniciada!",
["Flag returned!"] = "Bandeira devolvida!",
-- ["Flags, and their home base will be placed where each team ends their first turn."] = "",
--- ["Flamer"] = "",
--- ["Flaming Worm"] = "", -- A_Classic_Fairytale:backstab
+-- ["Flamer"] = "Azeiteiro",
+-- ["Flaming Worm"] = "Minhoca Flamejante", -- A_Classic_Fairytale:backstab
-- ["Flare: [fire up some bombs depending on hogs depending on hogs in the circle"] = "", -- Continental_supplies
-- ["Flesh for Brainz"] = "", -- A_Classic_Fairytale:journey
--- ["For improved features/stability, play 0.9.18+"] = "", -- WxW
--- ["Free Dense Cloud and continue the mission!"] = "", -- A_Classic_Fairytale:journey
--- ["Friendly Fire!"] = "",
--- ["fuel extended!"] = "",
--- ["GAME BEGUN!!!"] = "",
+ ["For improved features/stability, play 0.9.18+"] = "Para mais funcionalidades e maior estabilidade, joga 0.9.18+", -- WxW
+ ["Free Dense Cloud and continue the mission!"] = "Liberta o Nuvem Densa e continua a tua missão!", -- A_Classic_Fairytale:journey
+-- ["Friendly Fire!"] = "Fogo amigável!",
+-- ["fuel extended!"] = "combustivel aumentado!",
+-- ["GAME BEGUN!!!"] = "O JOGO COMEÃOU!!!",
["Game Modifiers: "] = "Modificadores de Jogo: ",
["GAME OVER!"] = "GAME OVER!",
-- ["Game Started!"] = "",
--- ["Game? Was this a game to you?!"] = "", -- A_Classic_Fairytale:enemy
+ ["Game? Was this a game to you?!"] = "Jogo? Isto foi um jogo para ti?!", -- A_Classic_Fairytale:enemy
-- ["GasBomb"] = "", -- Continental_supplies
-- ["Gas Gargler"] = "", -- A_Classic_Fairytale:queen
--- ["Get Dense Cloud out of the pit!"] = "", -- A_Classic_Fairytale:journey
+-- ["Get Dense Cloud out of the pit!"] = "Tira o Nuvem Densa do precipicio(?)", -- A_Classic_Fairytale:journey
["Get on over there and take him out!"] = "Chega-te aqui e acaba com ele!",
-- ["Get on the head of the mole"] = "", -- A_Classic_Fairytale:first_blood
-- ["Get out of there!"] = "", -- User_Mission_-_The_Great_Escape
--- ["Get that crate!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Get the crate on the other side of the island!|"] = "", -- A_Classic_Fairytale:journey
+-- ["Get that crate!"] = "Vai buscar aquela caixa!", -- A_Classic_Fairytale:first_blood
+-- ["Get the crate on the other side of the island!|"] = "Vai buscar a caixa no outro lado da ilha!|", -- A_Classic_Fairytale:journey
-- ["Get to the target using your rope! |Controls: Left & Right to swing the rope - Up & Down to Contract and Expand!"] = "", -- Basic_Training_-_Rope
-- ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"] = "", -- A_Classic_Fairytale:family
--- ["GG!"] = "", -- User_Mission_-_Rope_Knock_Challenge
+ ["GG!"] = "GG! (Excelente jogo!)", -- User_Mission_-_Rope_Knock_Challenge
-- ["Gimme Bones"] = "", -- A_Classic_Fairytale:backstab
-- ["Glark"] = "", -- A_Classic_Fairytale:shadow
--- ["Goal"] = "",
+-- ["Goal"] = "Objectivo\Fim",
["GO! GO! GO!"] = "GO! GO! GO!",
--- ["Good birdy......"] = "Lindo\Bom passarito......" (needs ingame confirmation),
--- ["Good Dude"] = "", -- User_Mission_-_The_Great_Escape
--- ["Good idea, they'll never find us there!"] = "", -- A_Classic_Fairytale:united
--- ["Good luck...or else!"] = "", -- A_Classic_Fairytale:journey
+ ["Good birdy......"] = "Lindo passarito......",
+ ["Good Dude"] = "Boa Bacano", -- User_Mission_-_The_Great_Escape
+ ["Good idea, they'll never find us there!"] = "Boa ideia, eles nunca nos vão encontrar aqui!", -- A_Classic_Fairytale:united
+ ["Good luck...or else!"] = "Boa sorte...caso contrário!", -- A_Classic_Fairytale:journey
["Good luck out there!"] = "Boa sorte aà fora!",
--- ["Good so far!"] = "",
--- ["Good to go!"] = "",
--- ["Go on top of the flower"] = "", -- A_Classic_Fairytale:first_blood
--- ["Go, quick!"] = "", -- A_Classic_Fairytale:backstab
+ ["Good so far!"] = "Até agora tudo bem!",
+-- ["Good to go!"] = "Pronto para seguir!",
+ ["Go on top of the flower"] = "Vai para cima da flor", -- A_Classic_Fairytale:first_blood
+ ["Go, quick!"] = "Vai, rápido!", -- A_Classic_Fairytale:backstab
-- ["Gorkij"] = "", -- A_Classic_Fairytale:journey
--- ["Go surf!"] = "", -- WxW
--- ["GOTCHA!"] = "",
--- ["Grab Mines/Explosives"] = "",
--- ["Great choice, Steve! Mind if I call you that?"] = "", -- A_Classic_Fairytale:shadow
--- ["Great work! Now hit it with your Baseball Bat! |Tip: You can change weapon with 'Right Click'!"] = "", -- Basic_Training_-_Rope
+-- ["Go surf!"] = "Vai 'surfar'!", -- WxW
+-- ["GOTCHA!"] = "APANHEI-TE!",
+-- ["Grab Mines/Explosives"] = "Agarra Minas/Explosivos",
+-- ["Great choice, Steve! Mind if I call you that?"] = "Excelente escolha, Steve! Importas-te que te chame\trate assim?", -- A_Classic_Fairytale:shadow
+-- ["Great work! Now hit it with your Baseball Bat! |Tip: You can change weapon with 'Right Click'!"] = Bom trabalho! Agora dá-lhe com o teu bastão de basebal! [Ajuada: Podes trocar de arma com o 'Click Direito'!]"", -- Basic_Training_-_Rope
-- ["Great! You will be contacted soon for assistance."] = "", -- A_Classic_Fairytale:shadow
--- ["Green lipstick bullet: [Is poisonous]"] = "", -- Continental_supplies
+-- ["Green lipstick bullet: [Is poisonous]"] = "Batom bala verde: [Ã venenoso]", -- Continental_supplies
-- ["Greetings, "] = "", -- A_Classic_Fairytale:dragon
-- ["Greetings, cloudy one!"] = "", -- A_Classic_Fairytale:shadow
--- ["Grenade Training"] = "", -- Basic_Training_-_Grenade
+-- ["Grenade Training"] = "Treino com Granadas", -- Basic_Training_-_Grenade
-- ["Grenadiers"] = "", -- Basic_Training_-_Grenade
--- ["Guys, do you think there's more of them?"] = "", -- A_Classic_Fairytale:backstab
+-- ["Guys, do you think there's more of them?"] = "Pessoal, axam que ainda há mais?\ha mais deles?", -- A_Classic_Fairytale:backstab
["HAHA!"] = "HAHA!", -- A_Classic_Fairytale:enemy
["Haha!"] = "Haha!", -- A_Classic_Fairytale:united
["Hahahaha!"] = "Hahahaha!",
--- ["Haha, now THAT would be something!"] = "",
--- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
--- ["Hapless Hogs"] = "",
--- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+-- ["Haha, now THAT would be something!"] = "Haha, agora ISSO seria espetacular!\é que era!",
+-- ["Hannibal"] = "Hannibal", -- A_Classic_Fairytale:epil
+-- ["Hapless Hogs"] = "Ouriços Desafortunados",
+-- [" Hapless Hogs left!"] = " Ouriços Desafortunados restantes!",
+-- [" HAS MUTATED"] = " MUTOU", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
--- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
--- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
--- ["Health crates extend your time."] = "",
+-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "Não tenhas ilusoes, a tua tribo está morta, indiferentes à tua escolha.", -- A_Classic_Fairytale:shadow
+-- ["Have we ever attacked you first?"] = "Alguma vez te atacamos primeiro?", -- A_Classic_Fairytale:enemy
+ ["Health crates extend your time."] = "As caixas de vida prolongam o teu tempo.",
-- ["Heavy"] = "",
-- ["Heavy Cannfantry"] = "", -- A_Classic_Fairytale:united
--- ["Hedge-cogs"] = "", -- A_Classic_Fairytale:enemy
+-- ["Hedge-cogs"] = "Engrenagens-ouriço", -- A_Classic_Fairytale:enemy
-- ["Hedgehog projectile: [fire your hog like a Sticky Bomb]"] = "", -- Continental_supplies
- ["Hedgewars-Basketball"] = "Hedgewars-Basketball",
+ ["Hedgewars-Basketball"] = "Hedgewars-Basquetebol",
["Hedgewars-Knockball"] = "Hedgewars-Knockball",
--- ["Hedgibal Lecter"] = "", -- A_Classic_Fairytale:backstab
--- ["Heh, it's not that bad."] = "",
--- ["Hello again, "] = "Olá novamente\outra vez, ", -- A_Classic_Fairytale:family
--- ["Help me, Leaks!"] = "", -- A_Classic_Fairytale:journey
--- ["Help me, please!!!"] = "", -- A_Classic_Fairytale:journey
--- ["Help me, please!"] = "", -- A_Classic_Fairytale:journey
--- ["He moves like an eagle in the sky."] = "", -- A_Classic_Fairytale:first_blood
--- ["He must be in the village already."] = "", -- A_Classic_Fairytale:journey
--- ["Here, let me help you!"] = "", -- A_Classic_Fairytale:backstab
--- ["Here, let me help you save her!"] = "", -- A_Classic_Fairytale:family
--- ["Here...pick your weapon!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Hero Team"] = "", -- User_Mission_-_The_Great_Escape
--- ["He's so brave..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hedgibal Lecter"] = "Hedgibal Lecter", -- A_Classic_Fairytale:backstab
+-- ["Heh, it's not that bad."] = "Heh, não é assim tão mau.\Podia ser pior.",
+ ["Hello again, "] = "Olá novamente, ", -- A_Classic_Fairytale:family
+ ["Help me, Leaks!"] = "Ajuda-me, Leaks!", -- A_Classic_Fairytale:journey
+ ["Help me, please!!!"] = "Ajuda-me, por favor!!!", -- A_Classic_Fairytale:journey
+ ["Help me, please!"] = "Ajuda-me, por favor!", -- A_Classic_Fairytale:journey
+-- ["He moves like an eagle in the sky."] = "Ele move-se tal\como uma águia no ceu.", -- A_Classic_Fairytale:first_blood
+-- ["He must be in the village already."] = "Ele já deve estar\ter chegado à na aldeia.", -- A_Classic_Fairytale:journey
+-- ["Here, let me help you!"] = "Aqui, deixa-me ajudar-te!", -- A_Classic_Fairytale:backstab
+-- ["Here, let me help you save her!"] = "Aqui, deixa-me ajudar-te a salva-la!", -- A_Classic_Fairytale:family
+-- ["Here...pick your weapon!"] = "Aqui\Pega...agarra a tua arma!", -- A_Classic_Fairytale:first_blood
+-- ["Hero Team"] = "Equipa Heroi", -- User_Mission_-_The_Great_Escape
+ ["He's so brave..."] = "Ele é tão corajoso...", -- A_Classic_Fairytale:first_blood
-- ["He won't be selling us out anymore!"] = "", -- A_Classic_Fairytale:backstab
--- ["Hey, guys!"] = ",pessoal!", -- A_Classic_Fairytale:backstab
--- ["Hey guys!"] = "pessoal!", -- A_Classic_Fairytale:united
--- ["Hey! This is cheating!"] = "", -- A_Classic_Fairytale:journey
+ ["Hey, guys!"] = "Hey, pessoal!", -- A_Classic_Fairytale:backstab
+ ["Hey guys!"] = "Hey pessoal!", -- A_Classic_Fairytale:united
+-- ["Hey! This is cheating!"] = "Hey! Isto\Isso é batota!", -- A_Classic_Fairytale:journey
-- ["HIGHLANDER"] = "", -- Highlander
-- ["Hightime"] = "", -- A_Classic_Fairytale:first_blood
--- ["Hint: Double Jump - Press [Backspace] twice"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hint: Double Jump - Press [Backspace] twice"] = "Dica: Duplo Salto - Carrega [Retroceder] duas vezes", -- A_Classic_Fairytale:first_blood
-- ["Hint: Select the BlowTorch, aim and press [Fire]. Press [Fire] again to stop.|Don't blow up the crate."] = "", -- A_Classic_Fairytale:journey
-- ["Hint: Select the LowGravity and press [Fire]."] = "", -- A_Classic_Fairytale:journey
-- ["Hint: you might want to stay out of sight and take all the crates...|"] = "", -- A_Classic_Fairytale:journey
--- ["His arms are so strong!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["His arms are so strong!"] = "Os braços dele são tão fortes!", -- A_Classic_Fairytale:first_blood
-- ["Hit Combo!"] = "",
--- ["Hmmm...actually...I didn't either."] = "", -- A_Classic_Fairytale:enemy
+ ["Hmmm...actually...I didn't either."] = "Hmmm...na verdade...uu também não fazia ideia.", -- A_Classic_Fairytale:enemy
["Hmmm..."] = "Hmmm...",
-- ["Hmmm, I'll have to find some way of moving him off this anti-portal surface..."] = "", -- portal
--- ["Hmmm...it's a draw. How unfortunate!"] = "", -- A_Classic_Fairytale:enemy
--- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
+ ["Hmmm...it's a draw. How unfortunate!"] = "Hmmm...é um empate. Que azar!", -- A_Classic_Fairytale:enemy
+ ["Hmmm...perhaps a little more time will help."] = "Hmmm...talvez um pouco mais de tempo ajude.", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurra!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
--- ["How can I ever repay you for saving my life?"] = "", -- A_Classic_Fairytale:journey
+-- ["How can I ever repay you for saving my life?"] = "Como posso eu (possivelmente) recompensar-te por teres salvo a minha vida?", -- A_Classic_Fairytale:journey
-- ["How come in a village full of warriors, it's up to me to save it?"] = "", -- A_Classic_Fairytale:dragon
--- ["How difficult would you like it to be?"] = "", -- A_Classic_Fairytale:first_blood
+ ["How difficult would you like it to be?"] = "Quão difÃcil gostarias que fosse?", -- A_Classic_Fairytale:first_blood
-- ["HOW DO THEY KNOW WHERE WE ARE???"] = "", -- A_Classic_Fairytale:united
-- ["However, if you fail to do so, she dies a most violent death, just like your friend! Muahahaha!"] = "", -- A_Classic_Fairytale:journey
-- ["However, if you fail to do so, she dies a most violent death! Muahahaha!"] = "", -- A_Classic_Fairytale:journey
--- ["However, my mates don't agree with me on letting you go..."] = "", -- A_Classic_Fairytale:dragon
--- [" HP"] = "", -- Mutant
+-- ["However, my mates don't agree with me on letting you go..."] = "No entanto, os meus colegas não concordam com eu deixar-vos ir...", -- A_Classic_Fairytale:dragon
+ [" HP"] = " HP", -- Mutant
["Hunter"] = "Comando", --Bazooka, Shotgun, SniperRifle
--- ["I believe there's more of them."] = "", -- A_Classic_Fairytale:backstab
--- ["I can see you have been training diligently."] = "", -- A_Classic_Fairytale:first_blood
--- ["I can't believe it worked!"] = "", -- A_Classic_Fairytale:shadow
--- ["I can't believe this!"] = "", -- A_Classic_Fairytale:enemy
--- ["I can't believe what I'm hearing!"] = "", -- A_Classic_Fairytale:backstab
--- ["I can't wait any more, I have to save myself!"] = "", -- A_Classic_Fairytale:shadow
--- ["I could just teleport myself there..."] = "", -- A_Classic_Fairytale:family
--- ["I'd better get going myself."] = "", -- A_Classic_Fairytale:journey
--- ["I didn't until about a month ago."] = "", -- A_Classic_Fairytale:enemy
+-- ["I believe there's more of them."] = "Acredito que existem mais deles.", -- A_Classic_Fairytale:backstab
+-- ["I can see you have been training diligently."] = "Consigo ver que tens treinado diligentemente.", -- A_Classic_Fairytale:first_blood
+ ["I can't believe it worked!"] = "Mal posso acreditar que funcionou!", -- A_Classic_Fairytale:shadow
+ ["I can't believe this!"] = "Não posso acreditar nisto!", -- A_Classic_Fairytale:enemy
+ ["I can't believe what I'm hearing!"] = "Não posso acreditar no que estou a ouvir!", -- A_Classic_Fairytale:backstab
+ ["I can't wait any more, I have to save myself!"] = "Não tenho paciencia para esperar mais, tenho de me salvar a mim mesmo!", -- A_Classic_Fairytale:shadow
+-- ["I could just teleport myself there..."] = "Podia simplesmente teletransportar-me para la...", -- A_Classic_Fairytale:family
+-- ["I'd better get going myself."] = "Seria melhor se fosse sozinho.", -- A_Classic_Fairytale:journey
+-- ["I didn't until about a month ago."] = "Nem pensei nisso até ao mês passado.", -- A_Classic_Fairytale:enemy
-- ["I don't know how you did that.. But good work! |The next one should be easy as cake for you!"] = "", -- Basic_Training_-_Rope
--- ["I feel something...a place! They will arrive near the circles!"] = "", -- A_Classic_Fairytale:backstab
--- ["If only I had a way..."] = "", -- A_Classic_Fairytale:backstab
+-- ["I feel something...a place! They will arrive near the circles!"] = "Eu sinti algo...um lugar! Eles vão chegar perto dos circulos!", -- A_Classic_Fairytale:backstab
+-- ["If only I had a way..."] = "Ao menos se eu tivesse uma maneira...", -- A_Classic_Fairytale:backstab
-- ["If only I were given a chance to explain my being here..."] = "", -- A_Classic_Fairytale:first_blood
--- ["I forgot that she's the daughter of the chief, too..."] = "", -- A_Classic_Fairytale:backstab
+-- ["I forgot that she's the daughter of the chief, too..."] = "Esqueci-me\Tinha-me esquecido que ela também é filha do chefe...", -- A_Classic_Fairytale:backstab
-- ["If they try coming here, they can have a taste of my delicious knuckles!"] = "", -- A_Classic_Fairytale:united
--- ["If you agree to provide the information we need, you will be spared!"] = "", -- A_Classic_Fairytale:shadow
+-- ["If you agree to provide the information we need, you will be spared!"] = "Se concordares em fornecer a informação que precisamos, serás poupado!", -- A_Classic_Fairytale:shadow
-- ["If you can get that crate fast enough, your beloved \"princess\" may go free."] = "", -- A_Classic_Fairytale:journey
-- ["If you decide to help us, though, we will no longer need to find a new governor for the island."] = "", -- A_Classic_Fairytale:shadow
--- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
--- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
--- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
--- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
--- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
--- ["I have to follow that alien."] = "", -- A_Classic_Fairytale:backstab
--- ["I have to get back to the village!"] = "", -- A_Classic_Fairytale:shadow
--- ["I hope you are prepared for a small challenge, young one."] = "", -- A_Classic_Fairytale:first_blood
--- ["I just don't want to sink to your level."] = "", -- A_Classic_Fairytale:backstab
--- ["I just found out that they have captured your princess!"] = "", -- A_Classic_Fairytale:family
--- ["I just wonder where Ramon and Spiky disappeared..."] = "", -- A_Classic_Fairytale:journey
--- ["I'll hold them off while you return to the village!"] = "", -- A_Classic_Fairytale:shadow
--- ["Imagine those targets are the wolves that killed your parents! Take your anger out on them!"] = "", -- A_Classic_Fairytale:first_blood
--- ["I'm...alive? How? Why?"] = "", -- A_Classic_Fairytale:backstab
--- ["I'm a ninja."] = "", -- A_Classic_Fairytale:dragon
--- ["I marked the place of their arrival. You're welcome!"] = "", -- A_Classic_Fairytale:backstab
--- ["I'm certain that this is a misunderstanding, fellow hedgehogs!"] = "", -- A_Classic_Fairytale:first_blood
--- ["I mean, none of you ceased to live."] = "", -- A_Classic_Fairytale:enemy
--- ["I'm getting old for this!"] = "", -- A_Classic_Fairytale:family
--- ["I'm getting thirsty..."] = "", -- A_Classic_Fairytale:family
--- ["I'm here to help you rescue her."] = "", -- A_Classic_Fairytale:family
--- ["I'm not sure about that!"] = "", -- A_Classic_Fairytale:united
--- ["Impressive...you are still dry as the corpse of a hawk after a week in the desert..."] = "", -- A_Classic_Fairytale:first_blood
--- ["I'm so scared!"] = "", -- A_Classic_Fairytale:united
--- ["Incredible..."] = "", -- A_Classic_Fairytale:shadow
--- ["I need to find the others!"] = "", -- A_Classic_Fairytale:backstab
--- ["I need to get to the other side of this island, fast!"] = "", -- A_Classic_Fairytale:journey
--- ["I need to move the tribe!"] = "", -- A_Classic_Fairytale:united
--- ["I need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
--- ["I need to warn the others."] = "", -- A_Classic_Fairytale:backstab
--- ["In fact, you are the only one that's been acting strangely."] = "", -- A_Classic_Fairytale:backstab
--- ["In order to get to the other side, you need to collect the crates first.|"] = "", -- A_Classic_Fairytale:dragon
+-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "Se ficares preso, usa o teu Desert Eagle ou recomeça a missão!|", -- A_Classic_Fairytale:journey
+-- ["If you know what I mean..."] = "Se percebes o que quero dizer...", -- A_Classic_Fairytale:shadow
+ ["If you say so..."] = "Se tu o dizes...", -- A_Classic_Fairytale:shadow
+ ["I guess you'll have to kill them."] = "Parece que vais ter de os matar.", -- A_Classic_Fairytale:dragon
+ ["I have come to make you an offering..."] = "Eu estou aqui para te fazer uma proposta...", -- A_Classic_Fairytale:shadow
+ ["I have no idea where that mole disappeared...Can you see it?"] = "Não faço ideia para onde se meteu aquela toupeira...Consegues vê-la?", -- A_Classic_Fairytale:shadow
+ ["I have to follow that alien."] = "Tenho de seguir aquele alienÃgena.", -- A_Classic_Fairytale:backstab
+ ["I have to get back to the village!"] = "Tenho de voltar para a aldeia!", -- A_Classic_Fairytale:shadow
+ ["I hope you are prepared for a small challenge, young one."] = "Espero que estejas preparado para um pequeno desafio jovem.", -- A_Classic_Fairytale:first_blood
+ ["I just don't want to sink to your level."] = "So não quero descer ao teu nÃvel.", -- A_Classic_Fairytale:backstab
+ ["I just found out that they have captured your princess!"] = "Acabei de descobrir que eles capturaram a princesa!", -- A_Classic_Fairytale:family
+ ["I just wonder where Ramon and Spiky disappeared..."] = "Só gostava de saber para onde o Ramom e o Spiky desapareceram...", -- A_Classic_Fairytale:journey
+ ["I'll hold them off while you return to the village!"] = "Eu mantenho-os ocupados enquanto regressas à aldeia!", -- A_Classic_Fairytale:shadow
+ ["Imagine those targets are the wolves that killed your parents! Take your anger out on them!"] = "Imagina que aqueles alvos são os lobos que mataram os teus pais! Descarrega toda a tua raiva neles!", -- A_Classic_Fairytale:first_blood
+ ["I'm...alive? How? Why?"] = "Eu estou...vivo? Como? Por quê?", -- A_Classic_Fairytale:backstab
+ ["I'm a ninja."] = "Sou um ninja.", -- A_Classic_Fairytale:dragon
+ ["I marked the place of their arrival. You're welcome!"] = "Eu marquei o local onde vão chegar. Não é preciso agradecer!", -- A_Classic_Fairytale:backstab
+ ["I'm certain that this is a misunderstanding, fellow hedgehogs!"] = "Tenho a certeza que isto é um mal entendido, camaradas ouriços!", -- A_Classic_Fairytale:first_blood
+ ["I mean, none of you ceased to live."] = "Quer dizer, nenhum de vocês cesou de viver.", -- A_Classic_Fairytale:enemy
+ ["I'm getting old for this!"] = "Estou a ficar velho para isto.", -- A_Classic_Fairytale:family
+ ["I'm getting thirsty..."] = "Estou a ficar com sede...", -- A_Classic_Fairytale:family
+ ["I'm here to help you rescue her."] = "Estou aqui para te ajudar a salva-la.", -- A_Classic_Fairytale:family
+ ["I'm not sure about that!"] = "Não tenho a certeza quanto a isso!", -- A_Classic_Fairytale:united
+ ["Impressive...you are still dry as the corpse of a hawk after a week in the desert..."] = "Impressionante...ainda estás seco tal e qual um cadáver de um falcão depois de uma semana no deserto...", -- A_Classic_Fairytale:first_blood
+ ["I'm so scared!"] = "Tenho tanto medo!", -- A_Classic_Fairytale:united
+ ["Incredible..."] = "IncrÃvel...", -- A_Classic_Fairytale:shadow
+ ["I need to find the others!"] = "Preciso de encontrar os outros!", -- A_Classic_Fairytale:backstab
+ ["I need to get to the other side of this island, fast!"] = "Preciso de chegar ao outro lado da ilha, rápido!", -- A_Classic_Fairytale:journey
+ ["I need to move the tribe!"] = "Preciso de mover a tribo!", -- A_Classic_Fairytale:united
+-- ["I need to prevent their arrival!"] = "Não posso deixar\permitir\Preciso de prevenir que cheguem!", -- A_Classic_Fairytale:backstab
+ ["I need to warn the others."] = "Preciso de avisar os outros.", -- A_Classic_Fairytale:backstab
+ ["In fact, you are the only one that's been acting strangely."] = "Na realidade, és o único que se tem comportado de forma estranha.", -- A_Classic_Fairytale:backstab
+ ["In order to get to the other side, you need to collect the crates first.|"] = "De forma a conseguir chegar ao outro lado, tens primeiro de obter todas as caixas.", -- A_Classic_Fairytale:dragon
["Instructor"] = "Instrutor", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings
--- ["Interesting idea, haha!"] = "", -- A_Classic_Fairytale:enemy
--- ["Interesting! Last time you said you killed a cannibal!"] = "", -- A_Classic_Fairytale:backstab
--- ["In the meantime, take these and return to your \"friend\"!"] = "", -- A_Classic_Fairytale:shadow
+ ["Interesting idea, haha!"] = "Interessante ideia, haha!", -- A_Classic_Fairytale:enemy
+ ["Interesting! Last time you said you killed a cannibal!"] = "Interessante! Da ultima vez disseste que tinhas morto um canibal!", -- A_Classic_Fairytale:backstab
+-- ["In the meantime, take these and return to your \"friend\"!"] = "Entretanto, pega\toma isto e volta para o teu \"amigo\"!", -- A_Classic_Fairytale:shadow
["invaders destroyed"] = "invasores destruidos",
--- ["Invasion"] = "", -- A_Classic_Fairytale:united
--- ["I saw it with my own eyes!"] = "", -- A_Classic_Fairytale:shadow
--- ["I see..."] = "", -- A_Classic_Fairytale:shadow
--- ["I see you have already taken the leap of faith."] = "", -- A_Classic_Fairytale:first_blood
--- ["I see you would like his punishment to be more...personal..."] = "", -- A_Classic_Fairytale:first_blood
--- ["I sense another wave of cannibals heading my way!"] = "", -- A_Classic_Fairytale:backstab
--- ["I sense another wave of cannibals heading our way!"] = "", -- A_Classic_Fairytale:backstab
--- ["I shouldn't have drunk that last pint."] = "", -- A_Classic_Fairytale:dragon
--- ["Is this place in my head?"] = "", -- A_Classic_Fairytale:dragon
--- ["It doesn't matter. I won't let that alien hurt my daughter!"] = "", -- A_Classic_Fairytale:dragon
--- ["I think we are safe here."] = "", -- A_Classic_Fairytale:backstab
--- ["I thought their shaman died when he tried our medicine!"] = "", -- A_Classic_Fairytale:shadow
--- ["It is called 'Hogs of Steel'."] = "", -- A_Classic_Fairytale:enemy
--- ["It is time to practice your fighting skills."] = "", -- A_Classic_Fairytale:first_blood
--- ["It must be a childhood trauma..."] = "", -- A_Classic_Fairytale:family
--- ["It must be the aliens!"] = "", -- A_Classic_Fairytale:backstab
--- ["It must be the aliens' deed."] = "", -- A_Classic_Fairytale:backstab
--- ["It must be the cyborgs again!"] = "", -- A_Classic_Fairytale:enemy
--- ["I told you, I just found them."] = "", -- A_Classic_Fairytale:backstab
--- ["It's a good thing SUDDEN DEATH is 99 turns away..."] = "",
--- ["It's always up to women to clear up the mess men created!"] = "", -- A_Classic_Fairytale:dragon
--- ["It's a shame, I forgot how to do that!"] = "", -- A_Classic_Fairytale:family
--- ["It's impossible to communicate with the spirits without a shaman."] = "", -- A_Classic_Fairytale:shadow
--- ["It's over..."] = "", -- A_Classic_Fairytale:shadow
--- ["It's time you learned that your actions have consequences!"] = "", -- A_Classic_Fairytale:journey
--- ["It's worth more than wood!"] = "", -- A_Classic_Fairytale:enemy
--- ["It wants our brains!"] = "", -- A_Classic_Fairytale:shadow
--- ["It was not a dream, unwise one!"] = "", -- A_Classic_Fairytale:backstab
--- ["I've seen this before. They just appear out of thin air."] = "", -- A_Classic_Fairytale:united
--- ["I want to play a game..."] = "", -- A_Classic_Fairytale:journey
--- ["I want to see how it handles this!"] = "", -- A_Classic_Fairytale:backstab
--- ["I wish to help you, "] = "", -- A_Classic_Fairytale:dragon
--- ["I wonder where Dense Cloud is..."] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
--- ["I wonder why I'm so angry all the time..."] = "", -- A_Classic_Fairytale:family
--- ["I won't let you kill her!"] = "", -- A_Classic_Fairytale:journey
--- ["Jack"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
--- ["Jeremiah"] = "", -- A_Classic_Fairytale:dragon
--- ["John"] = "", -- A_Classic_Fairytale:journey
--- ["Judas"] = "", -- A_Classic_Fairytale:backstab
--- ["Jumping is disabled"] = "",
--- ["Just kidding, none of you have died!"] = "", -- A_Classic_Fairytale:enemy
--- ["Just on a walk."] = "", -- A_Classic_Fairytale:united
--- ["Just wait till I get my hands on that trauma! ARGH!"] = "", -- A_Classic_Fairytale:family
+ ["Invasion"] = "Invasão", -- A_Classic_Fairytale:united
+ ["I saw it with my own eyes!"] = "Eu vi-o com os meus próprios olhos!", -- A_Classic_Fairytale:shadow
+ ["I see..."] = "Estou a ver...", -- A_Classic_Fairytale:shadow
+-- ["I see you have already taken the leap of faith."] = "Vejo que ja deste um salto de fé", -- A_Classic_Fairytale:first_blood
+-- ["I see you would like his punishment to be more...personal..."] = "Estou a ver que gostarias que o seu fosse mais... pessoal...", -- A_Classic_Fairytale:first_blood
+-- ["I sense another wave of cannibals heading my way!"] = "Sinto que outro ataque de canibais vem na minha direcção!", -- A_Classic_Fairytale:backstab
+-- ["I sense another wave of cannibals heading our way!"] = "Sinto que outro ataque de canibais vem\se move na nossa direcção!", -- A_Classic_Fairytale:backstab
+ ["I shouldn't have drunk that last pint."] = "Não devia ter bebido aquele ultimo caneco.", -- A_Classic_Fairytale:dragon
+-- ["Is this place in my head?"] = "Este lugar é na minha cabeça?", -- A_Classic_Fairytale:dragon
+ ["It doesn't matter. I won't let that alien hurt my daughter!"] = "Não quero saber. Não vou deixar aquele alienÃgena magoar a minha filha!", -- A_Classic_Fairytale:dragon
+ ["I think we are safe here."] = "Penso que estamos seguros aqui.", -- A_Classic_Fairytale:backstab
+ ["I thought their shaman died when he tried our medicine!"] = "Pensava que o xamã deles tinha morrido quando experimentou o nosso remédio!", -- A_Classic_Fairytale:shadow
+-- ["It is called 'Hogs of Steel'."] = "Ã chamado 'Hogs of Steel'.", -- A_Classic_Fairytale:enemy
+ ["It is time to practice your fighting skills."] = "Está na hora de praticar os habilidades em combate.", -- A_Classic_Fairytale:first_blood
+ ["It must be a childhood trauma..."] = "Deve ser um trauma de criança...", -- A_Classic_Fairytale:family
+ ["It must be the aliens!"] = "Devem ser os alienÃgenas!", -- A_Classic_Fairytale:backstab
+ ["It must be the aliens' deed."] = "Devem ser obra dos alienÃgenas!", -- A_Classic_Fairytale:backstab
+ ["It must be the cyborgs again!"] = "Devem ser os cyborgs novamente!", -- A_Classic_Fairytale:enemy
+-- ["I told you, I just found them."] = "Eu disse-te que os tinha acabado de encontrar.\que simplesmente os encontrei.", -- A_Classic_Fairytale:backstab
+ ["It's a good thing SUDDEN DEATH is 99 turns away..."] = "Ainda bem que ainda faltam 99 turnos para MORTE SÃBITA...",
+ ["It's always up to women to clear up the mess men created!"] = "Está sempre a cargo das mulheres, limpar a confusão que os homens criaram!", -- A_Classic_Fairytale:dragon
+-- ["It's a shame, I forgot how to do that!"] = "Ã uma pena, esqueci-me de como fazer isso\tal coisa!", -- A_Classic_Fairytale:family
+ ["It's impossible to communicate with the spirits without a shaman."] = "à impossÃvel comunicar com os espiritos sem um xamã.", -- A_Classic_Fairytale:shadow
+-- ["It's over..."] = "Acabou...\Finalmente acabou...", -- A_Classic_Fairytale:shadow
+-- ["It's time you learned that your actions have consequences!"] = "Está na hora de aprenderes que as tua ações teem consequencias!", -- A_Classic_Fairytale:journey
+-- ["It's worth more than wood!"] = "Ã mais valioso\Vale mais que madeira!", -- A_Classic_Fairytale:enemy
+-- ["It wants our brains!"] = "Quer os nosso cérebros!", -- A_Classic_Fairytale:shadow
+ ["It was not a dream, unwise one!"] = "Não foi um sonho, ó insensato!", -- A_Classic_Fairytale:backstab
+ ["I've seen this before. They just appear out of thin air."] = "Eu já vi isto antes. Eles aparecem do nada.", -- A_Classic_Fairytale:united
+ ["I want to play a game..."] = "Eu quero jogar um jogo...", -- A_Classic_Fairytale:journey
+-- ["I want to see how it handles this!"] = "Quero ver como ele<se desembaraça nesta..> trata da situação!", -- A_Classic_Fairytale:backstab
+ ["I wish to help you, "] = "Desejo ajudar-te, ", -- A_Classic_Fairytale:dragon
+ ["I wonder where Dense Cloud is..."] = "Pergunto-me onde estará o Nuvem Densa...", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
+ ["I wonder why I'm so angry all the time..."] = "Pergunto-me porque estou sempre tão zangado...", -- A_Classic_Fairytale:family
+ ["I won't let you kill her!"] = "Não te vou permitir que a mates!", -- A_Classic_Fairytale:journey
+ ["Jack"] = "Jack", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["Jeremiah"] = "Jeremiah", -- A_Classic_Fairytale:dragon
+ ["John"] = "John", -- A_Classic_Fairytale:journey
+ ["Judas"] = "Judas", -- A_Classic_Fairytale:backstab
+ ["Jumping is disabled"] = "Saltar está desactivado",
+ ["Just kidding, none of you have died!"] = "Estou só a brincar, nenhum de vocês morreu!", -- A_Classic_Fairytale:enemy
+-- ["Just on a walk."] = "Só a passear\dar um passeio.", -- A_Classic_Fairytale:united
+ ["Just wait till I get my hands on that trauma! ARGH!"] = "Espera até eu pôr as mãos naquele trauma! ARGH!", -- A_Classic_Fairytale:family
["Kamikaze Expert!"] = "Kamikaze profissional!",
--- ["Keep it up!"] = "Continua assim!",
--- ["Kerguelen"] = "", -- Continental_supplies
+ ["Keep it up!"] = "Continua assim!",
+ ["Kerguelen"] = "", -- Continental_supplies
-- ["Killing spree!"] = "",
--- ["KILL IT!"] = "", -- A_Classic_Fairytale:first_blood
--- ["KILLS"] = "",
--- ["Kill the aliens!"] = "", -- A_Classic_Fairytale:dragon
--- ["Kill the cannibal!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Kill the traitor...or spare his life!|Kill him or press [Precise]!"] = "", -- A_Classic_Fairytale:backstab
--- ["Last Target!"] = "",
--- ["Leader"] = "", -- A_Classic_Fairytale:enemy
+-- ["KILL IT!"] = "MATA-O!", -- A_Classic_Fairytale:first_blood
+-- ["KILLS"] = "VITIMAS",
+ ["Kill the aliens!"] = "Mata os alienÃgenas!", -- A_Classic_Fairytale:dragon
+ ["Kill the cannibal!"] = "Destrói o canibal!", -- A_Classic_Fairytale:first_blood
+-- ["Kill the traitor...or spare his life!|Kill him or press [Precise]!"] = "Acaba com o traÃdor...ou poupa a sua vida!|Mata-o ou pressiona [Precisão]!", -- A_Classic_Fairytale:backstab
+-- ["Last Target!"] = "Ultimo Alvo!",
+-- ["Leader"] = "Lider", -- A_Classic_Fairytale:enemy
-- ["Leaderbot"] = "", -- A_Classic_Fairytale:queen
--- ["Leaks A Lot"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
--- ["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "", -- A_Classic_Fairytale:journey
--- ["Leaks A Lot gave his life for his tribe! He should have survived!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Leaks A Lot must survive!"] = "", -- A_Classic_Fairytale:journey
+ ["Leaks A Lot"] = "Leaks A Lot", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+-- ["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "O Leaks A Lot, deprimido por ter morto a sua amada, não conseguiu salvar a aldeia...", -- A_Classic_Fairytale:journey
+ ["Leaks A Lot gave his life for his tribe! He should have survived!"] = "Leaks A Lot deu a sua vida pela tribo! Ele devia ter sobrevivido!", -- A_Classic_Fairytale:first_blood
+ ["Leaks A Lot must survive!"] = "Leaks A Lot tem de sobreviver!", -- A_Classic_Fairytale:journey
-- ["Led Heart"] = "", -- A_Classic_Fairytale:queen
--- ["Lee"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["Lee"] = "Lee", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
["[Left Shift]"] = "[Shift Esquerdo]",
--- ["Let a Continent provide your weapons!"] = "", -- Continental_supplies
--- ["Let me test your skills a little, will you?"] = "", -- A_Classic_Fairytale:journey
--- ["Let's go home!"] = "", -- A_Classic_Fairytale:journey
--- ["Let's head back to the village!"] = "", -- A_Classic_Fairytale:shadow
--- ["Let's see what your comrade does now!"] = "", -- A_Classic_Fairytale:journey
--- ["Let's show those cannibals what we're made of!"] = "", -- A_Classic_Fairytale:backstab
--- ["Let them have a taste of my fury!"] = "", -- A_Classic_Fairytale:backstab
--- ["Let us help, too!"] = "", -- A_Classic_Fairytale:backstab
+ ["Let a Continent provide your weapons!"] = "Deixa um Continente fornecer-vos armamento!", -- Continental_supplies
+-- ["Let me test your skills a little, will you?"] = "Pemite-me testar as tuas habilidades um pouco\por um bocadinho.<, ok?>", -- A_Classic_Fairytale:journey
+ ["Let's go home!"] = "Vamos para casa!", -- A_Classic_Fairytale:journey
+ ["Let's head back to the village!"] = "Vamos voltar para a aldeia!", -- A_Classic_Fairytale:shadow
+ ["Let's see what your comrade does now!"] = "Vamos ver o que o teu camarada faz agora.", -- A_Classic_Fairytale:journey
+ ["Let's show those cannibals what we're made of!"] = "Vamos mostrar àqueles canibais do que somos feitos!", -- A_Classic_Fairytale:backstab
+-- ["Let them have a taste of my fury!"] = "Deixa-os provar a minha fúria!", -- A_Classic_Fairytale:backstab
+ ["Let us help, too!"] = "Deixa-nos ajudar também!", -- A_Classic_Fairytale:backstab
-- ["Light Cannfantry"] = "", -- A_Classic_Fairytale:united
- ["Listen up, maggot!!"] = "Oiçam bem suas larvas!!",
--- ["Little did they know that this hunt will mark them forever..."] = "", -- A_Classic_Fairytale:shadow
+ ["Listen up, maggot!!"] = "Ouvem bem, verme!!",
+-- ["Little did they know that this hunt will mark them forever..."] = "Nunca eles imaginariam que esta caça os marcaria para sempre...", -- A_Classic_Fairytale:shadow
-- ["Lively Lifeguard"] = "",
--- ["Lonely Cries: [Rise the water if no hog is in the circle and deal 1 damage to all hogs]"] = "", -- Continental_supplies
--- ["Look, I had no choice!"] = "", -- A_Classic_Fairytale:backstab
--- ["Look out! There's more of them!"] = "", -- A_Classic_Fairytale:backstab
--- ["Look out! We're surrounded by cannibals!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Lonely Cries: [Rise the water if no hog is in the circle and deal 1 damage to all hogs]"] = "Choros Solitarios: [Aumente o nÃvel da água]", -- Continental_supplies
+ ["Look, I had no choice!"] = "Olha, eu não tive escolha!", -- A_Classic_Fairytale:backstab
+-- ["Look out! There's more of them!"] = "Cuidado! Existem mais!", -- A_Classic_Fairytale:backstab
+-- ["Look out! We're surrounded by cannibals!"] = "Cuidado! Estamos rodeados de cabinais!", -- A_Classic_Fairytale:enemy
-- ["Looks like the whole world is falling apart!"] = "", -- A_Classic_Fairytale:enemy
--- ["Luckily, I've managed to snatch some of them."] = "", -- A_Classic_Fairytale:united
--- ["LUDICROUS KILL"] = "", -- Mutant
+-- ["Luckily, I've managed to snatch some of them."] = "Por sorte, consegui <roubar> alguns deles.", -- A_Classic_Fairytale:united
+ ["LUDICROUS KILL"] = "LUDICROUS KILL", -- Mutant
-- ["May the spirits aid you in all your quests!"] = "", -- A_Classic_Fairytale:backstab
-- ["Medicine: [Fire some exploding medicine that will heal all hogs effected by the explosion]"] = "", -- Continental_supplies
--- ["MEGA KILL"] = "", -- Mutant
+ ["MEGA KILL"] = "MEGA KILL", -- Mutant
-- ["Meiwes"] = "", -- A_Classic_Fairytale:backstab
-- ["Mindy"] = "", -- A_Classic_Fairytale:united
-- ["Mine Deployer"] = "",
@@ -493,16 +492,16 @@ locale = {
["MISSION FAILED"] = "MISSÃO FALHADA", -- User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
["MISSION SUCCESSFUL"] = "MISSÃO COMPLETA", -- User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
["MISSION SUCCESS"] = "MISSÃO COMPLETA", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
--- ["Molotov"] = "", -- Continental_supplies
--- ["MONSTER KILL"] = "", -- Mutant
--- ["More Natives"] = "", -- A_Classic_Fairytale:epil
+ ["Molotov"] = "", -- Continental_supplies
+ ["MONSTER KILL"] = "MONSTER KILL", -- Mutant
+ ["More Natives"] = "Mais Nativos", -- A_Classic_Fairytale:epil
["Movement: [Up], [Down], [Left], [Right]"] = "Movimento: [Cima], [Baixo], [Esquerda], [Direita]",
--- ["Multi-shot!"] = "",
+-- ["Multi-shot!"] = "Multiplo-tiro!",
-- ["Muriel"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["Muscle Dissolver"] = "", -- A_Classic_Fairytale:shadow
--- ["-------"] = "", -- Mutant
+ ["-------"] = "-------", -- Mutant
-- ["Nade Boy"] = "", -- Basic_Training_-_Grenade
--- ["Name"] = "", -- A_Classic_Fairytale:queen
+ ["Name"] = "Nome", -- A_Classic_Fairytale:queen
-- ["Nameless Heroes"] = "",
-- ["Nancy Screw"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:queen
-- ["Napalm rocket: [Fire a bomb with napalm!]"] = "", -- Continental_supplies
@@ -511,64 +510,63 @@ locale = {
-- ["NEW CLAN RECORD: "] = "",
["NEW fastest lap: "] = "NOVA volta recorde: ",
-- ["New Mines Per Turn"] = "",
--- ["NEW RACE RECORD: "] = "",
+-- ["NEW RACE RECORD: "] = "NOVO RECORDE PARA ESTA PISTA: ",
-- ["Newton's Hammock"] = "",
--- ["Nicely done, meatbags!"] = "", -- A_Classic_Fairytale:enemy
--- ["Nice work, "] = "", -- A_Classic_Fairytale:dragon
--- ["Nice work!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Nicely done, meatbags!"] = "Muito bom trabalho\Muito bem, (seus )sacos de carne!", -- A_Classic_Fairytale:enemy
+ ["Nice work, "] = "Bom trabalho, ", -- A_Classic_Fairytale:dragon
+ ["Nice work!"] = "Bom trabalho!", -- A_Classic_Fairytale:enemy
-- ["Nilarian"] = "", -- A_Classic_Fairytale:queen
--- ["No, I came back to help you out..."] = "", -- A_Classic_Fairytale:shadow
--- ["No...I wonder where they disappeared?!"] = "", -- A_Classic_Fairytale:journey
+ ["No, I came back to help you out..."] = "Não, voltei para te ajudar...", -- A_Classic_Fairytale:shadow
+-- ["No...I wonder where they disappeared?!"] = "Não... Pegunto-me para onde desapareceram?!", -- A_Classic_Fairytale:journey
-- ["Nom-Nom"] = "", -- A_Classic_Fairytale:journey
-- ["NomNom"] = "", -- A_Classic_Fairytale:united
--- ["Nope. It was one fast mole, that's for sure."] = "", -- A_Classic_Fairytale:shadow
--- ["No! Please, help me!"] = "", -- A_Classic_Fairytale:journey
--- ["NORMAL"] = "", -- Continental_supplies
--- ["North America"] = "", -- Continental_supplies
--- ["Not all hogs are born equal."] = "", -- Highlander
+-- ["Nope. It was one fast mole, that's for sure."] = "Não. Mas foi uma toupeira muito rápida de certeza.", -- A_Classic_Fairytale:shadow
+ ["No! Please, help me!"] = "Não! Por favor, ajuda-me!", -- A_Classic_Fairytale:journey
+ ["NORMAL"] = "NORMAL", -- Continental_supplies
+ ["North America"] = "América do Norte", -- Continental_supplies
+-- ["Not all hogs are born equal."] = "Nem todos os ouriços nascem iguais\da mesma maneira.", -- Highlander
-- ["NOT ENOUGH WAYPOINTS"] = "",
--- ["Not now, Fiery Water!"] = "", -- A_Classic_Fairytale:backstab
+ ["Not now, Fiery Water!"] = "Agora não Ãgua Flamejante!", -- A_Classic_Fairytale:backstab
["Not So Friendly Match"] = "Partida não muito amigável", -- Basketball, Knockball
--- ["Not you again! My head still hurts from last time!"] = "", -- A_Classic_Fairytale:shadow
--- ["No, we made sure of that!"] = "", -- A_Classic_Fairytale:united
+-- ["Not you again! My head still hurts from last time!"] = "Tu outra vez?! A minha cabeça ainda doi da ultima vez!", -- A_Classic_Fairytale:shadow
+ ["No, we made sure of that!"] = "Não, certificamo-nos disso!", -- A_Classic_Fairytale:united
-- ["Now find the next target! |Tip: Normally you lose health by falling down, so be careful!"] = "", -- Basic_Training_-_Rope
--- ["No! What have I done?! What have YOU done?!"] = "", -- A_Classic_Fairytale:journey
--- ["No. Where did he come from?"] = "", -- A_Classic_Fairytale:shadow
--- ["Now how do I get on the other side?!"] = "", -- A_Classic_Fairytale:dragon
+ ["No! What have I done?! What have YOU done?!"] = "Não! O que fiz eu?! O que fizeste TU?!", -- A_Classic_Fairytale:journey
+ ["No. Where did he come from?"] = "Não. De onde raio é que ele apareceu?", -- A_Classic_Fairytale:shadow
+ ["Now how do I get on the other side?!"] = "Agora, como chego ao outro lado?!", -- A_Classic_Fairytale:dragon
-- ["No. You and the rest of the tribe are safer there!"] = "", -- A_Classic_Fairytale:backstab
-- ["Obliterate them!|Hint: You might want to take cover..."] = "", -- A_Classic_Fairytale:shadow
--- ["Obstacle course"] = "", -- A_Classic_Fairytale:dragon
--- ["Of course I have to save her. What did I expect?!"] = "", -- A_Classic_Fairytale:family
--- ["OH, COME ON!"] = "", -- A_Classic_Fairytale:journey
--- ["Oh, my!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Oh, my! This is even more entertaining than I've expected!"] = "", -- A_Classic_Fairytale:backstab
+ ["Obstacle course"] = "Pista de obstáculos", -- A_Classic_Fairytale:dragon
+ ["Of course I have to save her. What did I expect?!"] = "Claro que tenho de a salvar. Estavas à espera do quê?!", -- A_Classic_Fairytale:family
+-- ["OH, COME ON!"] = "OH, VÃ LÃ!", -- A_Classic_Fairytale:journey
+ ["Oh, my!"] = "Uau!", -- A_Classic_Fairytale:first_blood
+ ["Oh, my! This is even more entertaining than I've expected!"] = "Uau! Isto é mais interessante do que eu esperava!", -- A_Classic_Fairytale:backstab
["Oh no! Just try again!"] = "Oh não! Tenta novamente!", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
-- ["Oh no, not "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
["Oh no! Time's up! Just try again."] = "Oh não! Terminou o tempo! Tenta novamente.", --Bazooka, Shotgun, SniperRifle
-- ["Oh no! You failed! Just try again."] = "", -- Basic_Training_-_Cluster_Bomb
-- ["Oh, silly me! I forgot that I'm the shaman."] = "", -- A_Classic_Fairytale:backstab
--- ["Olive"] = "", -- A_Classic_Fairytale:united
--- ["Omnivore"] = "", -- A_Classic_Fairytale:first_blood
--- ["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "", -- A_Classic_Fairytale:first_blood
--- ["ONE HOG PER TEAM! KILLING EXCESS HEDGES"] = "", -- Mutant
+ ["Olive"] = "Azeitona", -- A_Classic_Fairytale:united
+ ["Omnivore"] = "OmnÃvoro", -- A_Classic_Fairytale:first_blood
+-- ["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "Era uma vez, numa ilha de grandes recursos naturais, viviam duas tribos com um profundo conflituo...", -- A_Classic_Fairytale:first_blood
+ ["ONE HOG PER TEAM! KILLING EXCESS HEDGES"] = "UM OURIÃO POR EQUIPA! A REMOVER OS OURIÃOS EM EXCESSO", -- Mutant
-- ["One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."] = "", -- A_Classic_Fairytale:first_blood
--- ["Oops...I dropped them."] = "", -- A_Classic_Fairytale:united
--- ["Open that crate and we will continue!"] = "", -- A_Classic_Fairytale:first_blood
+ ["Oops...I dropped them."] = "Oops...deixei-os cair.", -- A_Classic_Fairytale:united
+ ["Open that crate and we will continue!"] = "Abre a caixa e podemos prosseguir!", -- A_Classic_Fairytale:first_blood
["Operation Diver"] = "Operação Mergulho",
["Opposing Team: "] = "Equipa adversária",
-- ["Orlando Boom!"] = "", -- A_Classic_Fairytale:queen
--- ["Ouch!"] = "", -- User_Mission_-_Rope_Knock_Challenge
--- ["Our tribe, our beautiful island!"] = "", -- A_Classic_Fairytale:enemy
--- ["Parachute"] = "", -- Continental_supplies
+ ["Ouch!"] = "Ouch!", -- User_Mission_-_Rope_Knock_Challenge
+ ["Our tribe, our beautiful island!"] = "A nossa tribo, a nossa bela ilha!", -- A_Classic_Fairytale:enemy
+ ["Parachute"] = "Pára-quedas", -- Continental_supplies
["Pathetic Hog #%d"] = "Ouriço patético #%d",
--- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
--- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
--- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
--- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
+-- ["Pathetic Resistance"] = "Pátetica Resistencia", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
+ ["Perfect! Now try to get the next crate without hurting yourself!"] = "Perfeito! Agora tenta obter a proxima caixa sem te aleijares!", -- A_Classic_Fairytale:first_blood
+-- ["Per-Hog Ammo"] = "Armamento por-Ouriço",
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+ ["Pfew! That was close!"] = "Ufa! Foi por um triz.", -- A_Classic_Fairytale:shadow
+-- ["Piñata bullet: [Contains some sweet candy!]"] = "Bala pinhata: [Contem goluzeimas\doces!]", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -583,19 +581,19 @@ locale = {
-- ["Portal mission"] = "", -- portal
["Power Remaining"] = "Energia Restante",
["Prepare yourself"] = "Prepara-te!",
--- ["Press [Enter] to accept this configuration."] = "", -- WxW
--- ["Press [Left] or [Right] to move around, [Enter] to jump"] = "", -- A_Classic_Fairytale:first_blood
--- ["Press [Precise] to skip intro"] = "",
+ ["Press [Enter] to accept this configuration."] = "Pressiona [Enter] para aceitar esta configuração.", -- WxW
+ ["Press [Left] or [Right] to move around, [Enter] to jump"] = "Pressiona [Esquerda] ou [Direita] para te moveres, [Enter] para saltar", -- A_Classic_Fairytale:first_blood
+-- ["Press [Precise] to skip intro"] = "Pressiona [] para saltar a introdução",
-- ["Private Novak"] = "", -- Basic_Training_-_Cluster_Bomb
-- ["Protect yourselves!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow
-- ["Race complexity limit reached."] = "",
-- ["RACER"] = "",
--- ["Rachel"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["Rachel"] = "Rachel", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["Radar Ping"] = "", -- Space_Invasion
-- ["Raging Buffalo"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
-- ["Ramon"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
-- ["RC PLANE TRAINING"] = "", -- User_Mission_-_RCPlane_Challenge
--- ["Really?! You thought you could harm me with your little toys?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Really?! You thought you could harm me with your little toys?"] = "A SÃRIO?! Pensavas que me podias fazer mal com os teus pequenos brinquedos?", -- A_Classic_Fairytale:shadow
-- ["Regurgitator"] = "", -- A_Classic_Fairytale:backstab
-- ["Reinforcements"] = "", -- A_Classic_Fairytale:backstab
-- ["Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!"] = "", -- Basic_Training_-_Rope
@@ -608,36 +606,36 @@ locale = {
-- ["Rot Molester"] = "", -- A_Classic_Fairytale:shadow
-- ["Round Limit:"] = "",
-- ["Round Limit"] = "",
--- ["Rounds Complete: "] = "",
--- ["Rounds Complete"] = "",
+-- ["Rounds Complete: "] = "Rondas Completas: ",
+-- ["Rounds Complete"] = "Rondas Completas",
["RULES OF THE GAME [Press ESC to view]"] = "REGRAS DE JOGO [Pressiona ESC para as visualizar]",
--- ["Rusty Joe"] = "", -- A_Classic_Fairytale:queen
+-- ["Rusty Joe"] = "Joe Emferrujado", -- A_Classic_Fairytale:queen
-- ["s|"] = "",
-- ["Sabotage: [Sabotage all hogs in the circle and deal ~10 dmg]"] = "", -- Continental_supplies
-- ["Salivaslurper"] = "", -- A_Classic_Fairytale:united
--- ["Salvation"] = "", -- A_Classic_Fairytale:family
+-- ["Salvation"] = "Salvação", -- A_Classic_Fairytale:family
-- ["Salvation was one step closer now..."] = "", -- A_Classic_Fairytale:dragon
--- ["Save as many hapless hogs as possible!"] = "",
+ ["Save as many hapless hogs as possible!"] = "Salva o máximo de ouriços desafortunados possÃvel!",
-- ["Save Fell From Heaven!"] = "", -- A_Classic_Fairytale:journey
--- ["Save Leaks A Lot!|Hint: The Switch utility might be of help to you."] = "", -- A_Classic_Fairytale:shadow
+-- ["Save Leaks A Lot!|Hint: The Switch utility might be of help to you."] = "Salva o Leaks A Lot! Ajuda: A abilidade\ferramente Switch(?) pode ser-te util.", -- A_Classic_Fairytale:shadow
-- ["Save the princess! All your hogs must survive!|Hint: Kill the cyborgs first! Use the ammo very carefully!|Hint: You might want to spare a girder for cover!"] = "", -- A_Classic_Fairytale:family
-- ["Save the princess by collecting the crate in under 12 turns!"] = "", -- A_Classic_Fairytale:journey
-- ["Scalp Muncher"] = "", -- A_Classic_Fairytale:backstab
--- ["Score"] = "", -- Mutant
- ["SCORE"] = "RESULTADOS",
+ ["Score"] = "Resultado", -- Mutant
+ ["SCORE"] = "RESULTADO",
-- ["Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"] = "", -- Continental_supplies
["sec"] = "seg", -- CTF_Blizzard, TrophyRace, Basic_Training_-_Bazooka, Basic_Training_-_Shotgun, Basic_Training_-_Sniper_Rifle, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork, Capture_the_Flag
--- ["Seduction"] = "", -- Continental_supplies
+ ["Seduction"] = "Sedução", -- Continental_supplies
-- ["Seems like every time you take a \"walk\", the enemy find us!"] = "", -- A_Classic_Fairytale:backstab
-- ["See that crate farther on the right?"] = "", -- A_Classic_Fairytale:first_blood
["See ya!"] = "Chau!",
-- ["Segmentation Paul"] = "", -- A_Classic_Fairytale:dragon
--- ["Select continent!"] = "", -- Continental_supplies
--- ["Select difficulty: [Left] - easier or [Right] - harder"] = "", -- A_Classic_Fairytale:first_blood
+ ["Select continent!"] = "Seleciona o continente!", -- Continental_supplies
+-- ["Select difficulty: [Left] - easier or [Right] - harder"] = "Seleciona a dificuldade: [Esquerda] - facil ou [Direita] - dificil", -- A_Classic_Fairytale:first_blood
["selected!"] = "seleccionado!",
--- ["... share your beauty with the world every morning, my princess!"] = "", -- A_Classic_Fairytale:journey
--- ["She's behind that tall thingy."] = "", -- A_Classic_Fairytale:family
--- ["Shield boosted! +30 power"] = "Escudo melhorado! +30 energia (-unconfirmed)",
+ ["... share your beauty with the world every morning, my princess!"] = "... partilha a tua beleza com o mundo todas as manhãs, minha princesa!", -- A_Classic_Fairytale:journey
+ ["She's behind that tall thingy."] = "Ela está atráz daquela coisa alta.", -- A_Classic_Fairytale:family
+-- ["Shield boosted! +30 power"] = "Escudo reparado\aumentado! +30 energia (-unconfirmed)",
["Shield Depleted"] = "Escudo Esgotado",
["Shield is fully recharged!"] = "Escudo completamente recarregado!",
-- ["Shield Master!"] = "",
@@ -645,7 +643,7 @@ locale = {
["Shield OFF:"] = "Escudo DESLIGADO:",
["Shield ON:"] = "Escudo LIGADO:",
-- ["Shield Seeker!"] = "",
--- ["Shotgun"] = "", -- Continental_supplies
+ ["Shotgun"] = "Caçadeira", -- Continental_supplies
["Shotgun Team"] = "Caçadores",
["Shotgun Training"] = "Treino com Caçadeira",
-- ["shots remaining."] = "tiros restantes.",
@@ -654,7 +652,7 @@ locale = {
-- ["Sirius Lee"] = "", -- A_Classic_Fairytale:enemy
["%s is out and Team %d|scored a penalty!| |Score:"] = "%s está fora e a equipa %d|perde um ponto!| |Pontuação:", -- Basketball, Knockball
["%s is out and Team %d|scored a point!| |Score:"] = "%s está fora e a equipa %d|soma um ponto!| |Pontuação:", -- Basketball, Knockball
--- ["Slippery"] = "", -- A_Classic_Fairytale:journey
+-- ["Slippery"] = "Escorregadio", -- A_Classic_Fairytale:journey
-- ["Smith 0.97"] = "", -- A_Classic_Fairytale:enemy
-- ["Smith 0.98"] = "", -- A_Classic_Fairytale:enemy
-- ["Smith 0.99a"] = "", -- A_Classic_Fairytale:enemy
@@ -665,23 +663,23 @@ locale = {
-- ["Sniper!"] = "", -- Space_Invasion
["Sniper Training"] = "Treino com Sniper",
["Sniperz"] = "Sniperz",
--- ["So humiliating..."] = "", -- A_Classic_Fairytale:first_blood
--- ["South America"] = "", -- Continental_supplies
--- ["So? What will it be?"] = "", -- A_Classic_Fairytale:shadow
--- ["Spawn the crate, and attack!"] = "", -- WxW
--- ["Special Weapons:"] = "", -- Continental_supplies
--- ["Spiky Cheese"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
+ ["So humiliating..."] = "Tão humilhante...", -- A_Classic_Fairytale:first_blood
+ ["South America"] = "América do Sul", -- Continental_supplies
+ ["So? What will it be?"] = "Então? O que vai ser?", -- A_Classic_Fairytale:shadow
+-- ["Spawn the crate, and attack!"] = "Faz aparecer a caixa, e ataca!", -- WxW
+-- ["Special Weapons:"] = "Armas Especiais:", -- Continental_supplies
+-- ["Spiky Cheese"] = "Queijo \"Picante\"", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
-- ["Spleenlover"] = "", -- A_Classic_Fairytale:united
--- ["Sponge"] = "",
+-- ["Sponge"] = "Esponja",
-- ["Spooky Tree"] = "",
["s"] = "s", -- GaudyRacer, Space_Invasion
-- ["STATUS UPDATE"] = "", -- GaudyRacer, Space_Invasion
--- ["Steel Eye"] = "", -- A_Classic_Fairytale:queen
--- ["Step By Step"] = "", -- A_Classic_Fairytale:first_blood
--- ["Steve"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Steel Eye"] = "Olho de Ferro", -- A_Classic_Fairytale:queen
+-- ["Step By Step"] = "Passo a Passo", -- A_Classic_Fairytale:first_blood
+ ["Steve"] = "Steve", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["Sticky Mine"] = "", -- Continental_supplies
-- ["Stronglings"] = "", -- A_Classic_Fairytale:shadow
--- ["Structure"] = "", -- Continental_supplies
+ ["Structure"] = "Estrutura", -- Continental_supplies
-- ["Super Weapons"] = "", -- WxW
-- ["Surf Before Crate"] = "", -- WxW
-- ["Surfer! +15 points!"] = "", -- Space_Invasion
@@ -692,28 +690,28 @@ locale = {
-- ["Syntax Errol"] = "", -- A_Classic_Fairytale:dragon
-- ["Talk about mixed signals..."] = "", -- A_Classic_Fairytale:dragon
["Team %d: "] = "Equipa %d: ",
--- ["Team Scores"] = "", -- Control, Space_Invasion
--- ["Teleport hint: just use the mouse to select the destination!"] = "", -- A_Classic_Fairytale:dragon
--- ["Thanks!"] = "", -- A_Classic_Fairytale:family
--- ["Thank you, my hero!"] = "", -- A_Classic_Fairytale:family
--- ["Thank you, oh, thank you, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
--- ["Thank you, oh, thank you, my heroes!"] = "", -- A_Classic_Fairytale:journey
--- ["That is, indeed, very weird..."] = "", -- A_Classic_Fairytale:united
+-- ["Team Scores"] = "Pontuações Equipa", -- Control, Space_Invasion
+-- ["Teleport hint: just use the mouse to select the destination!"] = "Ajuda com o Teleporte: usa o rato para selecionar o teu destino!", -- A_Classic_Fairytale:dragon
+ ["Thanks!"] = "Obrigada!", -- A_Classic_Fairytale:family
+ ["Thank you, my hero!"] = "Obrigada, meu herói!", -- A_Classic_Fairytale:family
+ ["Thank you, oh, thank you, Leaks A Lot!"] = "Obrigada, oh, obrigada, Leaks A Lot!", -- A_Classic_Fairytale:journey
+ ["Thank you, oh, thank you, my heroes!"] = "Obrigada, oh, obrigada, meus heróis!", -- A_Classic_Fairytale:journey
+ ["That is, indeed, very weird..."] = "Isto é, de facto, muito estranho...", -- A_Classic_Fairytale:united
-- ["That makes it almost invaluable!"] = "", -- A_Classic_Fairytale:enemy
-- ["That ought to show them!"] = "", -- A_Classic_Fairytale:backstab
-- ["That's for my father!"] = "", -- A_Classic_Fairytale:backstab
--- ["That shaman sure knows what he's doing!"] = "", -- A_Classic_Fairytale:shadow
+-- ["That shaman sure knows what he's doing!"] = "Aquele xamã sabe mesmo o que está a fazer!", -- A_Classic_Fairytale:shadow
-- ["That Sinking Feeling"] = "",
--- ["That's not our problem!"] = "", -- A_Classic_Fairytale:enemy
--- ["That's typical of you!"] = "", -- A_Classic_Fairytale:family
--- ["That was just mean!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["That's not our problem!"] = "Não temos nada a ver com o teu problema.\Esse problema não tem nada a ver comnosco!", -- A_Classic_Fairytale:enemy
+ ["That's typical of you!"] = "TÃpico vindo de ti!", -- A_Classic_Fairytale:family
+-- ["That was just mean!"] = "Isso foi desnecessariamente mau! -errr má tradução", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
["That was pointless."] = "Isso foi completamente desnecessario.",
--- ["The answer is...entertaintment. You'll see what I mean."] = "", -- A_Classic_Fairytale:backstab
+-- ["The answer is...entertaintment. You'll see what I mean."] = "A resposta é...entertenimento. Já vais perceber ao que me refiro\quero dizer.", -- A_Classic_Fairytale:backstab
-- ["The anti-portal zone is all over the floor, and I have nothing to kill him...Droping something could hurt him enough to kill him..."] = "", -- portal
-- ["The Bull's Eye"] = "", -- A_Classic_Fairytale:first_blood
-- ["The caves are well hidden, they won't find us there!"] = "", -- A_Classic_Fairytale:united
-- ["The Crate Frenzy"] = "", -- A_Classic_Fairytale:first_blood
--- ["The Dilemma"] = "", -- A_Classic_Fairytale:shadow
+-- ["The Dilemma"] = "O Dilema", -- A_Classic_Fairytale:shadow
-- ["The enemy can't move but it might be a good idea to stay out of sight!|"] = "", -- A_Classic_Fairytale:dragon
["The enemy is hiding out on yonder ducky!"] = "O inimigo está escondido ali a diante ao pé do patinho!",
-- ["The Enemy Of My Enemy"] = "", -- A_Classic_Fairytale:enemy
@@ -721,10 +719,10 @@ locale = {
-- ["The First Encounter"] = "", -- A_Classic_Fairytale:shadow
["The flag will respawn next round."] = "A bandeira ira reaparecer no próximo turno.",
-- ["The food bites back"] = "", -- A_Classic_Fairytale:backstab
--- ["The giant umbrella from the last crate should help break the fall."] = "", -- A_Classic_Fairytale:first_blood
+-- ["The giant umbrella from the last crate should help break the fall."] = "O guarda-chuva gigante que estava na ultima caixa deve ajudar a amparar a tua queda.", -- A_Classic_Fairytale:first_blood
-- ["The Great Escape"] = "", -- User_Mission_-_The_Great_Escape
--- ["The guardian"] = "", -- A_Classic_Fairytale:shadow
--- ["The Individualist"] = "", -- A_Classic_Fairytale:shadow
+-- ["The guardian"] = "O guardião", -- A_Classic_Fairytale:shadow
+-- ["The Individualist"] = "O Individualista", -- A_Classic_Fairytale:shadow
-- ["Their buildings were very primitive back then, even for an uncivilised island."] = "", -- A_Classic_Fairytale:united
-- ["The Journey Back"] = "", -- A_Classic_Fairytale:journey
-- ["The Leap of Faith"] = "", -- A_Classic_Fairytale:first_blood
@@ -740,7 +738,7 @@ locale = {
-- ["There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"] = "", -- A_Classic_Fairytale:journey
-- ["The Rising"] = "", -- A_Classic_Fairytale:first_blood
-- ["The Savior"] = "", -- A_Classic_Fairytale:journey
--- ["These primitive people are so funny!"] = "", -- A_Classic_Fairytale:backstab
+-- ["These primitive people are so funny!"] = "Esta gente primitiva é tão divertida!", -- A_Classic_Fairytale:backstab
-- ["The Shadow Falls"] = "", -- A_Classic_Fairytale:shadow
-- ["The Showdown"] = "", -- A_Classic_Fairytale:shadow
-- ["The Slaughter"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:first_blood
@@ -752,32 +750,32 @@ locale = {
-- ["The Union"] = "", -- A_Classic_Fairytale:enemy
-- ["The village, unprepared, was destroyed by the cyborgs..."] = "", -- A_Classic_Fairytale:journey
-- ["The walk of Fame"] = "", -- A_Classic_Fairytale:shadow
--- ["The wasted youth"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The wasted youth"] = "A juventude desperdiçada", -- A_Classic_Fairytale:first_blood
-- ["The weapon in that last crate was bestowed upon us by the ancients!"] = "", -- A_Classic_Fairytale:first_blood
--- ["The what?!"] = "", -- A_Classic_Fairytale:dragon
--- ["The wind whispers that you are ready to become familiar with tools, now..."] = "", -- A_Classic_Fairytale:first_blood
+ ["The what?!"] = "Os quê?!", -- A_Classic_Fairytale:dragon
+-- ["The wind whispers that you are ready to become familiar with tools, now..."] = "O vento sussura que tu estás pronto para te familiarizares com as ferramentas agora...", -- A_Classic_Fairytale:first_blood
-- ["They are all waiting back in the village, haha."] = "", -- A_Classic_Fairytale:enemy
-- ["They Call Me Bullseye!"] = "", -- Space_Invasion
--- ["They have weapons we've never seen before!"] = "", -- A_Classic_Fairytale:united
+ ["They have weapons we've never seen before!"] = "Eles têm armas que nunca vimos antes!", -- A_Classic_Fairytale:united
-- ["They keep appearing like this. It's weird!"] = "", -- A_Classic_Fairytale:united
--- ["They killed "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["They killed "] = "Eles mataram ", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
-- ["They must be trying to weaken us!"] = "", -- A_Classic_Fairytale:enemy
--- ["They never learn"] = "", -- A_Classic_Fairytale:journey
--- ["They told us to wear these clothes. They said that this is the newest trend."] = "", -- A_Classic_Fairytale:enemy
+ ["They never learn"] = "Eles nunca aprendem", -- A_Classic_Fairytale:journey
+ ["They told us to wear these clothes. They said that this is the newest trend."] = "Eles disseram-nos para usar estas roupas. Eles disseram que isto era a última moda.", -- A_Classic_Fairytale:enemy
-- ["They've been manipulating us all this time!"] = "", -- A_Classic_Fairytale:enemy
-- ["Thighlicker"] = "", -- A_Classic_Fairytale:united
-- ["This is it! It's time to make Fell From Heaven fall for me..."] = "", -- A_Classic_Fairytale:first_blood
--- ["This island is the only place left on Earth with grass on it!"] = "", -- A_Classic_Fairytale:enemy
--- ["This is typical!"] = "", -- A_Classic_Fairytale:dragon
--- ["This must be some kind of sorcery!"] = "", -- A_Classic_Fairytale:shadow
--- ["This must be the caves!"] = "", -- A_Classic_Fairytale:backstab
--- ["This one's tricky."] = "",
--- ["This rain is really something..."] = "",
--- ["This will be fun!"] = "", -- A_Classic_Fairytale:enemy
--- ["Those aliens are destroying the island!"] = "", -- A_Classic_Fairytale:family
+-- ["This island is the only place left on Earth with grass on it!"] = "Esta ilha é o último lugar que resta na Terra com erva nele!", -- A_Classic_Fairytale:enemy
+ ["This is typical!"] = "TÃpico", -- A_Classic_Fairytale:dragon
+-- ["This must be some kind of sorcery!"] = "Isto deve ser algum tipo de feitiçaria!", -- A_Classic_Fairytale:shadow
+-- ["This must be the caves!"] = "Isto devem ser as cavernas!", -- A_Classic_Fairytale:backstab
+-- ["This one's tricky."] = "Este é complicado(?)",
+ ["This rain is really something..."] = "Esta chuva é mesmo qualquer coisa...",
+ ["This will be fun!"] = "Isto vai ser divertido!", -- A_Classic_Fairytale:enemy
+ ["Those aliens are destroying the island!"] = "Aqueles alienÃgenas estão a destruir a ilha!", -- A_Classic_Fairytale:family
-- ["Timed Kamikaze!"] = "",
--- ["Time Extended!"] = "",
--- ["Time Extension"] = "",
+ ["Time Extended!"] = "Tempo Prolongado!",
+ ["Time Extension"] = "Extensão de tempo",
["TIME: "] = "TEMPO: ",
-- ["Tip: The rope physics are different than in the real world, |use it to your advantage!"] = "", -- Basic_Training_-_Rope
["Toggle Shield"] = "Ligar\Desligar Escudo",
@@ -789,11 +787,11 @@ locale = {
-- ["Toxic Team"] = "", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
-- ["TRACK COMPLETED"] = "PISTA COMPLETA",
-- ["TRACK FAILED!"] = "PISTA",
--- ["training"] = "", -- portal
--- ["Traitors"] = "", -- A_Classic_Fairytale:epil
--- ["Tribe"] = "", -- A_Classic_Fairytale:backstab
+ ["training"] = "treino", -- portal
+ ["Traitores"] = "Traidores", -- A_Classic_Fairytale:epil
+ ["Tribe"] = "Tribo", -- A_Classic_Fairytale:backstab
["TrophyRace"] = "TrophyRace",
--- ["Try to protect the chief! You won't lose if he dies, but it is advised that he survives."] = "", -- A_Classic_Fairytale:united
+ ["Try to protect the chief! You won't lose if he dies, but it is advised that he survives."] = "Tenta protejer o chefe! Não perdes se ele morrer, mas é recomendado que ele sobreviva.", -- A_Classic_Fairytale:united
["T_T"] = "T_T",
-- ["Tumbling Time Extended!"] = "",
-- ["Turns until Sudden Death: "] = "", -- A_Classic_Fairytale:dragon
@@ -801,12 +799,12 @@ locale = {
-- ["Turn Time"] = "",
-- ["Two little hogs cooperating, getting past obstacles..."] = "", -- A_Classic_Fairytale:journey
-- ["Uhm...I met one of them and took his weapons."] = "", -- A_Classic_Fairytale:shadow
--- ["Uhmm...ok no."] = "", -- A_Classic_Fairytale:enemy
--- ["ULTRA KILL"] = "", -- Mutant
--- ["Under Construction"] = "", -- A_Classic_Fairytale:shadow
+-- ["Uhmm...ok no."] = "Uhm...ok não.", -- A_Classic_Fairytale:enemy
+ ["ULTRA KILL"] = "ULTRA KILL", -- Mutant
+ ["Under Construction"] = "Em Construção", -- A_Classic_Fairytale:shadow
-- ["Unexpected Igor"] = "", -- A_Classic_Fairytale:dragon
--- ["Unit 0x0007"] = "", -- A_Classic_Fairytale:family
--- ["Unit 334a$7%;.*"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+ ["Unit 0x0007"] = "Unidade 0x0007", -- A_Classic_Fairytale:family
+ ["Unit 334a$7%;.*"] = "Unidade 334a$7%;.*", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
["Unit 3378"] = "Unidade 3378",
["Unit 835"] = "Unidade 835",
-- ["United We Stand"] = "", -- A_Classic_Fairytale:united
@@ -815,170 +813,168 @@ locale = {
-- ["Unlucky Sods"] = "", -- User_Mission_-_Rope_Knock_Challenge
["Unstoppable!"] = "Imparável!",
-- ["Unsuspecting Louts"] = "", -- User_Mission_-_Rope_Knock_Challenge
--- ["[Up], [Down] to aim, [Space] to shoot!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
--- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
+ ["[Up], [Down] to aim, [Space] to shoot!"] = "[Cima], [Baixo] para apontar, [Espaço] para disparar!", -- A_Classic_Fairytale:first_blood
+-- ["Use it wisely!"] = "Usa com moderação\sábiamente", -- A_Classic_Fairytale:dragon
+-- ["Use it with precaution!"] = "Usa com cuidado!", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
--- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Use the rope to get on the head of the mole, young one!"] = "Usa a corda para chegar à cabeça da toupeira, jovem!", -- A_Classic_Fairytale:first_blood
+ ["Use the rope to knock your enemies to their doom."] = "Usa a corda para empurrar os teus inimigos para o seu fim.", -- User_Mission_-_Rope_Knock_Challenge
["Use your rope to get from start to finish as fast as you can!"] = "Utilizando a corda, percorre o percurso do inicio ao fim o mais rápido que conseguires!",
--- ["Vedgies"] = "", -- A_Classic_Fairytale:journey
--- ["Vegan Jack"] = "", -- A_Classic_Fairytale:enemy
--- ["Victory!"] = "", -- Basic_Training_-_Rope
--- ["Victory for the "] = "", -- CTF_Blizzard, Capture_the_Flag
- ["Victory for the"] = "Vitória para a",
--- ["Violence is not the answer to your problems!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Walls Left"] = "", -- WxW
--- ["Walls Required"] = "", -- WxW
--- ["WALL TO WALL"] = "", -- WxW
+ ["Vedgies"] = "Vegetais", -- A_Classic_Fairytale:journey
+ ["Vegan Jack"] = "Jack Vegetariano", -- A_Classic_Fairytale:enemy
+ ["Victory!"] = "Vitória!", -- Basic_Training_-_Rope
+ ["Victory for the "] = "Vitória para a", -- CTF_Blizzard, Capture_the_Flag
+ ["Violence is not the answer to your problems!"] = "Violência não é a resposta para os teus problemas!", -- A_Classic_Fairytale:first_blood
+-- ["Walls Left"] = "Faltam $1 paredes", -- WxW
+ ["Walls Required"] = "Paredes Necessárias", -- WxW
+ ["WALL TO WALL"] = "WALL TO WALL", -- WxW
-- ["Wannabe Flyboys"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Wannabe Shoppsta"] = "", -- User_Mission_-_Rope_Knock_Challenge
--- ["Watch your steps, young one!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Waypoint placed."] = "",
+-- ["Watch your steps, young one!"] = "Cuidado onde pões os pés, jovem!", -- A_Classic_Fairytale:first_blood
+-- ["Waypoint placed."] = "Waypoint colocado.",
-- ["Way-Points Remaining"] = "",
--- ["Weaklings"] = "", -- A_Classic_Fairytale:shadow
--- ["We all know what happens when you get frightened..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Weaklings"] = "Fracotes", -- A_Classic_Fairytale:shadow
+-- ["We all know what happens when you get frightened..."] = "Todos sabemos o que acontece quando te sentes assustado...", -- A_Classic_Fairytale:first_blood
-- ["Weapons Reset"] = "",
-- ["Weapons reset."] = "", -- Highlander
--- ["We are indeed."] = "", -- A_Classic_Fairytale:backstab
--- ["We can't defeat them!"] = "", -- A_Classic_Fairytale:shadow
--- ["We can't hold them up much longer!"] = "", -- A_Classic_Fairytale:united
--- ["We can't let them take over our little island!"] = "", -- A_Classic_Fairytale:enemy
--- ["We have no time to waste..."] = "", -- A_Classic_Fairytale:journey
--- ["We have nowhere else to live!"] = "", -- A_Classic_Fairytale:enemy
--- ["We have to protect the village!"] = "", -- A_Classic_Fairytale:united
--- ["We have to unite and defeat those cylergs!"] = "", -- A_Classic_Fairytale:enemy
--- ["Welcome, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
+ ["We are indeed."] = "Somos mesmo.", -- A_Classic_Fairytale:backstab
+-- ["We can't defeat them!"] = "Não podemos\conseguimos derrotalos!", -- A_Classic_Fairytale:shadow
+-- ["We can't hold them up much longer!"] = "Não conseguimos aguentalos por muito mais.", -- A_Classic_Fairytale:united
+-- ["We can't let them take over our little island!"] = "Não os podemos deixar apoderarem-se\que se apoderem da nossa pequena ilha!", -- A_Classic_Fairytale:enemy
+ ["We have no time to waste..."] = "Não temos tempo a perder...", -- A_Classic_Fairytale:journey
+-- ["We have nowhere else to live!"] = "Não temos mais onde viver!", -- A_Classic_Fairytale:enemy
+ ["We have to protect the village!"] = "Temos de protejer a aldeia!", -- A_Classic_Fairytale:united
+-- ["We have to unite and defeat those cylergs!"] = "Temos de nos unir e derrotar estes ciber-pernudos!", -- A_Classic_Fairytale:enemy
+ ["Welcome, Leaks A Lot!"] = "Bem vindo, Leaks a Lot!", -- A_Classic_Fairytale:journey
["Well done."] = "Bom trabalho.",
-- ["We'll give you a problem then!"] = "", -- A_Classic_Fairytale:enemy
--- ["We'll spare your life for now!"] = "", -- A_Classic_Fairytale:backstab
--- ["Well, that was a waste of time."] = "", -- A_Classic_Fairytale:dragon
+-- ["We'll spare your life for now!"] = "Vamos poupar a tua vida para ja!", -- A_Classic_Fairytale:backstab
+-- ["Well, that was a waste of time."] = "Bem, isto foi um desperdicio de tempo.", -- A_Classic_Fairytale:dragon
-- ["Well, well! Isn't that the cutest thing you've ever seen?"] = "", -- A_Classic_Fairytale:journey
--- ["Well, yes. This was a cyborg television show."] = "", -- A_Classic_Fairytale:enemy
--- ["We made sure noone followed us!"] = "", -- A_Classic_Fairytale:backstab
--- ["We need to move!"] = "", -- A_Classic_Fairytale:united
--- ["We need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
--- ["We need to warn the village."] = "", -- A_Classic_Fairytale:shadow
+-- ["Well, yes. This was a cyborg television show."] = "Bem, claro. Isto era um programa de televisão para cyborgs.", -- A_Classic_Fairytale:enemy
+-- ["We made sure noone followed us!"] = "Certificamo-nos que ninguem nos seguiu!", -- A_Classic_Fairytale:backstab
+-- ["We need to move!"] = "Temos de nos mover!", -- A_Classic_Fairytale:united
+-- ["We need to prevent their arrival!"] = "Temos de prevenir que cheguem!", -- A_Classic_Fairytale:backstab
+ ["We need to warn the village."] = "Temos de avisar a aldeia.", -- A_Classic_Fairytale:shadow
-- ["We should head back to the village now."] = "", -- A_Classic_Fairytale:shadow
--- ["We were trying to save her and we got lost."] = "", -- A_Classic_Fairytale:family
--- ["We won't let you hurt her!"] = "", -- A_Classic_Fairytale:journey
--- ["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "", -- A_Classic_Fairytale:first_blood
--- ["What a douche!"] = "", -- A_Classic_Fairytale:enemy
+-- ["We were trying to save her and we got lost."] = "Estavamos a tentar salva-la e acabamos por nos perder.", -- A_Classic_Fairytale:family
+-- ["We won't let you hurt her!"] = "Não vamos deixar que a magoes!", -- A_Classic_Fairytale:journey
+-- ["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "O quê? Um canibal? Aqui? Não ha tempo a perder! Vem, estás preparado.", -- A_Classic_Fairytale:first_blood
+ ["What a douche!"] = "Que otário!", -- A_Classic_Fairytale:enemy
-- ["What am I gonna...eat, yo?"] = "", -- A_Classic_Fairytale:family
--- ["What are you doing at a distance so great, young one?"] = "", -- A_Classic_Fairytale:first_blood
--- ["What are you doing? Let her go!"] = "", -- A_Classic_Fairytale:journey
--- ["What a ride!"] = "", -- A_Classic_Fairytale:shadow
--- ["What a strange cave!"] = "", -- A_Classic_Fairytale:dragon
+-- ["What are you doing at a distance so great, young one?"] = "O que estás a tão grande distancia, jovem?", -- A_Classic_Fairytale:first_blood
+-- ["What are you doing? Let her go!"] = "Que estás a fazer? Larga-a!", -- A_Classic_Fairytale:journey
+ ["What a ride!"] = "Que viagem!", -- A_Classic_Fairytale:shadow
+ ["What a strange cave!"] = "Que caverna estranha!", -- A_Classic_Fairytale:dragon
-- ["What a strange feeling!"] = "", -- A_Classic_Fairytale:backstab
--- ["What do my faulty eyes observe? A spy!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Whatever floats your boat..."] = "", -- A_Classic_Fairytale:shadow
--- [" What !! For all of this struggle i just win some ... TIME o0"] = "", -- portal
--- ["What has "] = "", -- A_Classic_Fairytale:backstab
--- ["What? Here? How did they find us?!"] = "", -- A_Classic_Fairytale:backstab
--- ["What is this place?"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy
--- ["What shall we do with the traitor?"] = "", -- A_Classic_Fairytale:backstab
--- ["WHAT?! You're the ones attacking us!"] = "", -- A_Classic_Fairytale:enemy
--- ["When?"] = "", -- A_Classic_Fairytale:enemy
--- ["When I find it..."] = "", -- A_Classic_Fairytale:dragon
--- ["Where are all these crates coming from?!"] = "", -- A_Classic_Fairytale:shadow
--- ["Where are they?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Where did that alien run?"] = "", -- A_Classic_Fairytale:dragon
--- ["Where did you get the exploding apples?"] = "", -- A_Classic_Fairytale:shadow
--- ["Where did you get the exploding apples and the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
--- ["Where did you get the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
--- ["Where did you get the weapons in the forest, Dense Cloud?"] = "", -- A_Classic_Fairytale:backstab
--- ["Where do you get that?!"] = "", -- A_Classic_Fairytale:enemy
--- ["Where have you been?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Where have you been?"] = "", -- A_Classic_Fairytale:united
--- ["? Why?"] = "", -- A_Classic_Fairytale:backstab
--- ["Why "] = "", -- A_Classic_Fairytale:backstab
--- ["! Why?!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
--- ["Why are you doing this?"] = "", -- A_Classic_Fairytale:journey
--- ["Why are you helping us, uhm...?"] = "", -- A_Classic_Fairytale:family
--- ["Why can't he just let her go?!"] = "", -- A_Classic_Fairytale:family
--- ["Why do men keep hurting me?"] = "", -- A_Classic_Fairytale:first_blood
--- ["Why do you not like me?"] = "", -- A_Classic_Fairytale:shadow
--- ["Why do you want to take over our island?"] = "", -- A_Classic_Fairytale:enemy
--- ["Why me?!"] = "", -- A_Classic_Fairytale:backstab
--- ["Why would they do this?"] = "", -- A_Classic_Fairytale:backstab
+ ["What do my faulty eyes observe? A spy!"] = "O que vêm observam os meus defeituoso olhos? Um espião!", -- A_Classic_Fairytale:first_blood
+-- ["Whatever floats your boat..."] = "O que quer que seja que faz o teu barco flutuar... (preciso melhor expressão verdadeiramente portuguesa)", -- A_Classic_Fairytale:shadow
+ [" What !! For all of this struggle i just win some ... TIME o0"] = " O quê !! Por todo este esforço tudo o que ganho é ... TEMPO o0", -- portal
+-- ["What has "] = "Foi aquilo ", -- A_Classic_Fairytale:backstab
+ ["What? Here? How did they find us?!"] = "O quê? Aqui? Como raio nos encontraram?!", -- A_Classic_Fairytale:backstab
+-- ["What is this place?"] = "O que é este sitio?\Que (raio de) sitio é este?", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy
+-- ["What shall we do with the traitor?"] = "O que fazemos com o traidor?", -- A_Classic_Fairytale:backstab
+-- ["WHAT?! You're the ones attacking us!"] = "O QU�! Voces é que nos atacaram\estão a atacar!", -- A_Classic_Fairytale:enemy
+ ["When?"] = "Quando?", -- A_Classic_Fairytale:enemy
+ ["When I find it..."] = "Quando o encontrar...", -- A_Classic_Fairytale:dragon
+ ["Where are all these crates coming from?!"] = "De onde vêm todas estas caixas?!", -- A_Classic_Fairytale:shadow
+ ["Where are they?!"] = "Onde estão eles?!", -- A_Classic_Fairytale:backstab
+ ["Where did that alien run?"] = "Para onde fugiu aquele alienÃgena?", -- A_Classic_Fairytale:dragon
+ ["Where did you get the exploding apples?"] = "Onde arranjaste as maçãs explosivas?", -- A_Classic_Fairytale:shadow
+ ["Where did you get the exploding apples and the magic bow that shoots many arrows?"] = "Onde arranjaste as maçãs explosivas e o arco mágico que dispara muitas flechas?", -- A_Classic_Fairytale:shadow
+ ["Where did you get the magic bow that shoots many arrows?"] = "Onde arranjaste o arco mágico que dispara muitas flechas?", -- A_Classic_Fairytale:shadow
+-- ["Where did you get the weapons in the forest, Dense Cloud?"] = "Onde arranjaste as armas na floresta, Nuvem Densa?", -- A_Classic_Fairytale:backstab
+ ["Where do you get that?!"] = "Onde arranjaste isso?!", -- A_Classic_Fairytale:enemy
+ ["Where have you been?!"] = "Onde estiveste?!", -- A_Classic_Fairytale:backstab
+ ["Where have you been?"] = "Onde estiveste?", -- A_Classic_Fairytale:united
+ ["? Why?"] = "? Por quê?", -- A_Classic_Fairytale:backstab
+ ["Why "] = "Por quê ", -- A_Classic_Fairytale:backstab
+ ["! Why?!"] = "! Por quê?!", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["Why are you doing this?"] = "Porque estás a fazer isto?", -- A_Classic_Fairytale:journey
+ ["Why are you helping us, uhm...?"] = "Porque nos estás a ajudar, uhm...?", -- A_Classic_Fairytale:family
+ ["Why can't he just let her go?!"] = "Porque não podemos simplesmente deixá-la ir?!", -- A_Classic_Fairytale:family
+ ["Why do men keep hurting me?"] = "Porque é que os homens continuam a magoar-me?", -- A_Classic_Fairytale:first_blood
+ ["Why do you not like me?"] = "Porque não gostas de mim?", -- A_Classic_Fairytale:shadow
+ ["Why do you want to take over our island?"] = "Porque querem apoderar-se da nossa ilha?", -- A_Classic_Fairytale:enemy
+ ["Why me?!"] = "Por quê eu?!", -- A_Classic_Fairytale:backstab
+ ["Why would they do this?"] = "Porque fariam eles isto?", -- A_Classic_Fairytale:backstab
-- ["- Will Get 1-3 random weapons"] = "", -- Continental_supplies
-- ["- Will refresh Parachute each turn."] = "", -- Continental_supplies
-- ["- Will refresh portalgun each turn."] = "", -- Continental_supplies
--- ["Will this ever end?"] = "",
--- ["WINNER IS "] = "", -- Mutant
+-- ["Will this ever end?"] = "Será que isto alguma vez vai acabar?",
+ ["WINNER IS "] = "O VENCEDOR Ã ", -- Mutant
["WINNING TIME: "] = "TEMPO VENCEDOR: ",
--- ["Wise Oak"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Wise Oak"] = "Carvalho Sábio", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
-- ["With Dense Cloud on the land of shadows, I'm the village's only hope..."] = "", -- A_Classic_Fairytale:journey
-- ["With the rest of the tribe gone, it was up to "] = "", -- A_Classic_Fairytale:dragon
--- ["Worry not, for it is a peaceful animal! There is no reason to be afraid..."] = "", -- A_Classic_Fairytale:first_blood
--- ["Wow, what a dream!"] = "", -- A_Classic_Fairytale:backstab
--- ["Y3K1337"] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
--- ["Yay, we won!"] = "", -- A_Classic_Fairytale:enemy
+ ["Worry not, for it is a peaceful animal! There is no reason to be afraid..."] = "Não te preocupes, pois este animal é perfeitamente pacÃfico! Não há qualquer fazão para receio...", -- A_Classic_Fairytale:first_blood
+ ["Wow, what a dream!"] = "Wow, mas que sonho!", -- A_Classic_Fairytale:backstab
+ ["Y3K1337"] = "Y3K1337", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
+-- ["Yay, we won!"] = "Boa, ganhamos!", -- A_Classic_Fairytale:enemy
-- ["Y Chwiliad"] = "", -- A_Classic_Fairytale:dragon
--- ["Yeah...I think it's a 'he', lol."] = "", -- A_Classic_Fairytale:shadow
--- ["Yeah, sure! I died. Hillarious!"] = "", -- A_Classic_Fairytale:backstab
--- ["Yeah, take that!"] = "", -- A_Classic_Fairytale:dragon
--- ["Yeah? Watcha gonna do? Cry?"] = "", -- A_Classic_Fairytale:journey
--- ["Yes!"] = "", -- A_Classic_Fairytale:enemy
--- ["Yes, yeees! You are now ready to enter the real world!"] = "", -- A_Classic_Fairytale:first_blood
--- ["Yo, dude, we're here, too!"] = "", -- A_Classic_Fairytale:family
--- ["You are given the chance to turn your life around..."] = "", -- A_Classic_Fairytale:shadow
--- ["You are playing with our lives here!"] = "", -- A_Classic_Fairytale:enemy
--- ["! You bastards!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
--- ["You bear impressive skills, "] = "", -- A_Classic_Fairytale:dragon
--- ["You can't fire a portal on the blue surface"] = "", -- portal
+-- ["Yeah...I think it's a 'he', lol."] = "Sim...penso que é um \"ele\", lol.", -- A_Classic_Fairytale:shadow
+ ["Yeah, sure! I died. Hillarious!"] = "Sim, claro! Morri. Que piada!", -- A_Classic_Fairytale:backstab
+-- ["Yeah, take that!"] = "Sim, toma isto!", -- A_Classic_Fairytale:dragon
+ ["Yeah? Watcha gonna do? Cry?"] = "Ai sim? E o que vais fazer? Chorar?", -- A_Classic_Fairytale:journey
+ ["Yes!"] = "Sim!", -- A_Classic_Fairytale:enemy
+-- ["Yes, yeees! You are now ready to enter the real world!"] = "Sim, SIM! Estás agora pronto para entrar no mundo real!", -- A_Classic_Fairytale:first_blood
+-- ["Yo, dude, we're here, too!"] = "Yo, bacano, também estamos aqui!\chagámos, também!", -- A_Classic_Fairytale:family
+ ["You are given the chance to turn your life around..."] = "Foi-te oferecida uma oportunidade para mudar a tua vida...", -- A_Classic_Fairytale:shadow
+-- ["You are playing with our lives here!"] = "Estas a bincar com as nossas vidas com isto!", -- A_Classic_Fairytale:enemy
+-- ["! You bastards!"] = "! Seus bastardos!<precisa uma expresão melhor>", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["You bear impressive skills, "] = "As tuas habilidades são impressionantes, ", -- A_Classic_Fairytale:dragon
+-- ["You can't fire a portal on the blue surface"] = "Não podes disparar um portal na superficie azul", -- portal
-- ["You couldn't possibly believe that after refusing my offer I'd just let you go!"] = "", -- A_Classic_Fairytale:journey
["You'd almost swear the water was rising!"] = "Quase eras capaz jurar que a água estava a subir!",
--- ["You'd better watch your steps..."] = "", -- A_Classic_Fairytale:journey
--- ["You did not make it in time, try again!"] = "", -- Basic_Training_-_Rope
+-- ["You'd better watch your steps..."] = "à melhor teres cuidado onde pôes os pés...", -- A_Classic_Fairytale:journey
+-- ["You did not make it in time, try again!"] = "Não chegaste a tempo, tenta novamente!", -- Basic_Training_-_Rope
-- ["You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."] = "", -- A_Classic_Fairytale:backstab
--- ["You have "] = "", -- A_Classic_Fairytale:dragon
+-- ["You have "] = "Tens ", -- A_Classic_Fairytale:dragon
-- ["You have been giving us out to the enemy, haven't you!"] = "", -- A_Classic_Fairytale:backstab
-- ["You have been respawned, at your last checkpoint!"] = "", -- Basic_Training_-_Rope
-- ["You have been respawned, be more carefull next time!"] = "", -- Basic_Training_-_Rope
--- ["You have chosen the perfect moment to leave."] = "", -- A_Classic_Fairytale:united
--- ["You have failed to complete your task, young one!"] = "", -- A_Classic_Fairytale:journey
--- ["You have failed to save the tribe!"] = "", -- A_Classic_Fairytale:backstab
--- ["You have finally figured it out!"] = "", -- A_Classic_Fairytale:enemy
--- ["You have kidnapped our whole tribe!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You have chosen the perfect moment to leave."] = "Escolheste o momento perfeito para ir embora\sair.", -- A_Classic_Fairytale:united
+-- ["You have failed to complete your task, young one!"] = "Não foste capaz de completar a tua tarefa, jovem!", -- A_Classic_Fairytale:journey
+-- ["You have failed to save the tribe!"] = "Não foste capaz de salvar a tribo!", -- A_Classic_Fairytale:backstab
+-- ["You have finally figured it out!"] = "Finalmente percebeste!", -- A_Classic_Fairytale:enemy
+-- ["You have kidnapped our whole tribe!"] = "Tu raptaste toda a nossa tribo!", -- A_Classic_Fairytale:enemy
-- ["You have killed an innocent hedgehog!"] = "", -- A_Classic_Fairytale:backstab
-- ["You have proven yourself worthy to see our most ancient secret!"] = "", -- A_Classic_Fairytale:first_blood
-- ["You have proven yourselves worthy!"] = "", -- A_Classic_Fairytale:enemy
["You have SCORED!!"] = "Marcaste!!",
--- ["You have to destroy 12 targets in 180 seconds"] = "", -- Basic_Training_-_Cluster_Bomb
--- ["You have won the game by proving true cooperative skills!"] = "", -- A_Classic_Fairytale:enemy
--- ["You just appeared out of thin air!"] = "", -- A_Classic_Fairytale:backstab
--- ["You just committed suicide..."] = "", -- A_Classic_Fairytale:shadow
--- ["You killed my father, you monster!"] = "", -- A_Classic_Fairytale:backstab
--- ["You know...taking a stroll."] = "", -- A_Classic_Fairytale:backstab
--- ["You know what? I don't even regret anything!"] = "", -- A_Classic_Fairytale:backstab
--- ["You'll see what I mean!"] = "", -- A_Classic_Fairytale:enemy
--- ["You may only attack from a rope!"] = "", -- WxW
--- ["You meatbags are pretty slow, you know!"] = "", -- A_Classic_Fairytale:enemy
+ ["You have to destroy 12 targets in 180 seconds"] = "Tens de destruir 12 alvos em 180 segundos", -- Basic_Training_-_Cluster_Bomb
+-- ["You have won the game by proving true cooperative skills!"] = "Ganhaste o jogo demonstrando a tua excelente habilidade em cooperar!", -- A_Classic_Fairytale:enemy
+ ["You just appeared out of thin air!"] = "Simplesmente apareceste do nada!", -- A_Classic_Fairytale:backstab
+ ["You just committed suicide..."] = "Acabaste de cometer suicÃdio...", -- A_Classic_Fairytale:shadow
+ ["You killed my father, you monster!"] = "Tu mataste o meu pai, seu monstro!", -- A_Classic_Fairytale:backstab
+-- ["You know...taking a stroll."] = "Tu sabes...a passear.", -- A_Classic_Fairytale:backstab
+-- ["You know what? I don't even regret anything!"] = "Sabes que mais? Nem me arrependo de nada disto!", -- A_Classic_Fairytale:backstab
+-- ["You'll see what I mean!"] = "Já vais perceber o que quero dizer!", -- A_Classic_Fairytale:enemy
+ ["You may only attack from a rope!"] = "Só podes atacar da corda!", -- WxW
+ ["You meatbags are pretty slow, you know!"] = "Voçês sacos de carne são muito lentos, sabiam?", -- A_Classic_Fairytale:enemy
-- ["You might want to find a way to instantly kill arriving cannibals!"] = "", -- A_Classic_Fairytale:backstab
-- ["Young one, you are telling us that they can instantly change location without a shaman?"] = "", -- A_Classic_Fairytale:united
-- ["You probably know what to do next..."] = "", -- A_Classic_Fairytale:first_blood
--- ["Your deaths will be avenged, cannibals!"] = "", -- A_Classic_Fairytale:enemy
--- ["Your death will not be in vain, Dense Cloud!"] = "", -- A_Classic_Fairytale:shadow
--- ["You're...alive!? But we saw you die!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Your deaths will be avenged, cannibals!"] = "As vossas mortes serão vingadas canibais!", -- A_Classic_Fairytale:enemy
+ ["Your death will not be in vain, Dense Cloud!"] = "A tua morte não será em vão, Nuvem Densa!", -- A_Classic_Fairytale:shadow
+ ["You're...alive!? But we saw you die!"] = "Estás...vivo!? Mas nós vimos-te morrer!", -- A_Classic_Fairytale:backstab
-- ["You're a pathetic liar!"] = "", -- A_Classic_Fairytale:backstab
--- ["You're funny!"] = "", -- A_Classic_Fairytale:journey
--- ["You're getting pretty good! |Tip: When you shorten you rope you move faster! |and when you lengthen it you move slower"] = "", -- Basic_Training_-_Rope
--- ["You're pathetic! You are not worthy of my attention..."] = "", -- A_Classic_Fairytale:shadow
--- ["You're probably wondering why I bought you back..."] = "", -- A_Classic_Fairytale:backstab
--- ["You're terrorizing the forest...We won't catch anything like this!"] = "", -- A_Classic_Fairytale:shadow
--- ["Your hogs must survive!"] = "", -- A_Classic_Fairytale:journey
--- ["Your movement skills will be evaluated now."] = "", -- A_Classic_Fairytale:first_blood
--- ["You saved"] = "",
--- ["You've been assaulting us, we have been just defending ourselves!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You're funny!"] = "Ãs engraçado!", -- A_Classic_Fairytale:journey
+-- ["You're getting pretty good! |Tip: When you shorten you rope you move faster! |and when you lengthen it you move slower"] = "Estás a ficar muito bom!", -- Basic_Training_-_Rope
+-- ["You're pathetic! You are not worthy of my attention..."] = "Ãs patetico! Não és digno da minha atenção...", -- A_Classic_Fairytale:shadow
+-- ["You're probably wondering why I bought you back..."] = "Deves-te estar(?) a perguntar-te porque te trouxe de volta...", -- A_Classic_Fairytale:backstab
+ ["You're terrorizing the forest...We won't catch anything like this!"] = "Estás a aterrorizar a floresta...Não vamos conseguir apanhar nada assim!", -- A_Classic_Fairytale:shadow
+ ["Your hogs must survive!"] = "Os teus ouriços têm de sobreviver!", -- A_Classic_Fairytale:journey
+-- ["Your movement skills will be evaluated now."] = "A tua habilidade para te movimentares serão agora avaliadas.", -- A_Classic_Fairytale:first_blood
+-- ["You saved"] = "Salvaste",
+-- ["You've been assaulting us, we have been just defending ourselves!"] = "Voces têm-nos atacado, apenas nos estamos a defender!", -- A_Classic_Fairytale:enemy
["You've failed. Try again."] = "Falhaste. Tenta novamente.",
["You've reached the goal!| |Time: "] = "Chegaste ao fim!| |Tempo: ",
--- ["You will be avenged!"] = "", -- A_Classic_Fairytale:shadow
--- ["You won't believe what happened to me!"] = "", -- A_Classic_Fairytale:backstab
--- ["Yuck! I bet they'll keep worshipping her even after I save the village!"] = "", -- A_Classic_Fairytale:family
+ ["You will be avenged!"] = "Serás vingado!", -- A_Classic_Fairytale:shadow
+ ["You won't believe what happened to me!"] = "Não vais acreditar no que se passou comigo!", -- A_Classic_Fairytale:backstab
+-- ["Yuck! I bet they'll keep worshipping her even after I save the village!"] = "Yuck! Aposto que eles vão continuar a venerala mesmo depois de eu ter salvo a aldeia deles~~~~~~", -- A_Classic_Fairytale:family
-- ["Zealandia"] = "", -- Continental_supplies
["'Zooka Team"] = "Bazuqueiros",
--- ["Zork"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ ["Zork"] = "Zork", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
}
diff --git a/share/hedgewars/Data/Locale/pt_PT.txt b/share/hedgewars/Data/Locale/pt_PT.txt
index 4090842..b3ff646 100644
--- a/share/hedgewars/Data/Locale/pt_PT.txt
+++ b/share/hedgewars/Data/Locale/pt_PT.txt
@@ -54,10 +54,10 @@
00:51=Bola de Lama
00:52=Nenhuma arma selecionada
00:53=Caixote do Tempo
-00:54=Estrutura
-00:55=Terreno-instantâneo
-00:56=Congelador
-00:57=Cutelo
+; 00:54=Estrutura
+00:54=Terreno-instantâneo
+00:55=Congelador
+00:56=Cutelo
01:00=Vamos lutar!
01:01=Ronda empatada
@@ -178,7 +178,6 @@
02:01=%1 foi brincar com os golfinhos
02:01=%1 foi visitar o Oceanário
02:01=%1 encontrou a Atlântida perdida
-02:01=%1 inscreve-se no papel principal do Bioshock 3
02:01=O teu pato insuflável ficou triste %1
02:01=%1 devia ter comprado uma mota de água
02:01=%1 não gosta de desportos náuticos
@@ -450,8 +449,8 @@
03:51=Encontrado no chão
03:52=UNUSED
03:53=Modelo 40
-03:54=Constroi qualquer coisa
-03:55=Utilitário
+;03:54=Constroi qualquer coisa
+03:54=Utilitário
; Weapon Descriptions (use | as line breaks)
04:00=Ataca os teus inimigos usando uma simples granada.|Explodirá quando o tempo chegar a zero.|1-5: Define o temporizador da granada|Ataque: Deixa premido para lançar com mais força
@@ -508,8 +507,8 @@
04:51=Empurra um ouriço sem perder o turno|criando uma bola de lama tu mesmo!
04:52=UNUSED
04:53=Parte numa aventura pelo tempo e espaço,|deixando os teus colegas para se defenderem sozinhos.|Está preparado para regressar a qualquer altura,|para Morte Súbita ou se todos forem derrotados.|Atenção: Não funciona em Morte Súbita,|se estiveres sozinho, ou se fores o Rei.
-04:54=INCOMPLETO
-04:55=Aplica estas particulas de terreno em spray onde quiseres.|Constroi pontes, enterra inimigos ou fecha túneis.|Tem apenas cuidado, não o uses em ti proprio!
+;04:54=INCOMPLETO
+04:54=Aplica estas particulas de terreno em spray onde quiseres.|Constroi pontes, enterra inimigos ou fecha túneis.|Tem apenas cuidado, não o uses em ti proprio!
; Game goal strings
05:00=Modos de Jogo
diff --git a/share/hedgewars/Data/Locale/ro.txt b/share/hedgewars/Data/Locale/ro.txt
index 741b3cd..e497465 100644
--- a/share/hedgewars/Data/Locale/ro.txt
+++ b/share/hedgewars/Data/Locale/ro.txt
@@ -1,4 +1,4 @@
-; English locale
+; Romanian locale
00:00=GrenadÄ
00:01=BombÄ cu dispersie
@@ -20,7 +20,7 @@
00:17=Lovitura de torÈÄ
00:18=Constructie
00:19=Teleportare
-00:20=SchimbÄ ariciuÈ
+00:20=SchimbÄ ariciuÈ
00:21=Mortar
00:22=Bici
00:23=Kamikaze
@@ -28,7 +28,7 @@
00:25=Seducere
00:26=Pepene bombÄ
00:27=GrenadÄ de mânÄ infernalÄ
-00:28=Racheta burghiu
+00:28=Racheta burghiu
00:29=Pistol cu bile
00:30=Napalm
00:31=Avion RC
@@ -54,8 +54,8 @@
00:51=Bila de noroi
00:52=Nici o armÄ selectatÄ
00:53=Cutia timpului
-00:54=StructurÄ
-00:55=Spray de teren
+; 00:54=StructurÄ
+00:54=Spray de teren
01:00=Hai sÄ ne batem!
01:01=RemizÄr
@@ -175,7 +175,6 @@
02:01=%1 wants to play Ecco the dolphin
02:01=%1 has gone to visit Aquaria
02:01=%1 has found the lost city of Atlantis
-02:01=%1 aims for the lead role in Bioshock 3
02:01=Your doggy paddle could use a little work, %1
02:01=%1 should have brought a jet ski
02:01=%1 doesn't like watersports
@@ -447,8 +446,8 @@
03:51=Found on the ground
03:52=UNUSED
03:53=Type 40
-03:54=Build something
-03:55=Utility
+;03:54=Build something
+03:54=Utility
; Weapon Descriptions (use | as line breaks)
04:00=Attack your enemies using a simple grenade.|It will explode once its timer reaches zero.|1-5: Set grenade's timer|Attack: Hold to throw with more power
@@ -505,8 +504,8 @@
04:51=Get in a free shot by hurling a ball of mud.|Stings a bit, and knocks hogs back.
04:52=UNUSED
04:53=Go on an adventure through time and space,|while leaving your comrades to fight on alone.|Be prepared to return at any time,|or for Sudden Death or if they are all defeated.|Disclaimer. Does not function in Sudden Death,|if you are alone, or if you are a King.
-04:54=INCOMPLETE
-04:55=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!
+;04:54=INCOMPLETE
+04:54=Spray a stream of sticky flakes.|Build bridges, bury enemies, seal off tunnels.|Be careful you don't get any on you!
; Game goal strings
05:00=Game Modes
diff --git a/share/hedgewars/Data/Locale/ru.lua b/share/hedgewars/Data/Locale/ru.lua
index 6c96cf2..ba1aa40 100644
--- a/share/hedgewars/Data/Locale/ru.lua
+++ b/share/hedgewars/Data/Locale/ru.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
-- ["Fastest lap: "] = "",
-- ["Feeble Resistance"] = "",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
["Hmmm..."] = "Хммм...",
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "УÑа!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/ru.txt b/share/hedgewars/Data/Locale/ru.txt
index 3618280..12ccd37 100644
--- a/share/hedgewars/Data/Locale/ru.txt
+++ b/share/hedgewars/Data/Locale/ru.txt
@@ -54,10 +54,10 @@
00:51=Ðомок гÑÑзи
00:52=ÐÑÑжие не вÑбÑано
00:53=ÐÑдка вÑемени
-00:54=СÑÑÑкÑÑÑа
-00:55=РаÑпÑлиÑÐµÐ»Ñ Ð·ÐµÐ¼Ð»Ð¸
-00:56=ÐамоÑаживаÑелÑ
-00:57=СекаÑ
+; 00:54=СÑÑÑкÑÑÑа
+00:54=РаÑпÑлиÑÐµÐ»Ñ Ð·ÐµÐ¼Ð»Ð¸
+00:55=ÐамоÑаживаÑелÑ
+00:56=СекаÑ
01:00=ÐпеÑÑд к победе!
01:01=ÐиÑÑÑ
@@ -177,7 +177,6 @@
02:01=%1 Ñ
оÑÐµÑ Ð¿Ð¾Ð¸Ð³ÑаÑÑ Ð² Ecco the Dolphin
02:01=%1 поÑел поÑмоÑÑеÑÑ Ð°ÐºÐ²Ð°ÑиÑм
02:01=%1 наÑÑл поÑеÑÑннÑй гоÑод ÐÑланÑидÑ
-02:01=%1 ÑÑÑемиÑÑÑ Ðº главной Ñоли в игÑе Bioshock 3
02:01=Твое плаванÑе по-ÑобаÑÑи пÑинеÑло мало полÑзÑ, %1
02:01=%1 забÑл взÑÑÑ Ð³Ð¸Ð´ÑоÑикл
02:01=%1 не лÑÐ±Ð¸Ñ Ð²Ð¾Ð´Ð½Ñй ÑпоÑÑ
@@ -450,8 +449,8 @@
03:51=ÐайденнÑй на земле
03:52=Ðе иÑполÑзÑеÑÑÑ
03:53=ÐÐ¾Ð´ÐµÐ»Ñ 40
-03:54=ÐоÑÑÑой ÑÑо нибÑдÑ
-03:55=ÐÐ¾Ð»ÐµÐ·Ð½Ð°Ñ Ð²ÐµÑÑ
+;03:54=ÐоÑÑÑой ÑÑо нибÑдÑ
+03:54=ÐÐ¾Ð»ÐµÐ·Ð½Ð°Ñ Ð²ÐµÑÑ
; Weapon Descriptions (use | as line breaks)
04:00=ÐÑакÑй ÑвоиÑ
вÑагов обÑÑной гÑанаÑой.|Ðна взоÑвеÑÑÑ ÑÑазÑ, как ÑолÑко ÑаймеÑ|доÑÑÐ¸Ð³Ð½ÐµÑ Ð½ÑлÑ.|1-5: УÑÑановиÑÑ ÑÐ°Ð¹Ð¼ÐµÑ Ð³ÑанаÑÑ|ÐÑака: УдеÑживай Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ далÑнего бÑоÑка
diff --git a/share/hedgewars/Data/Locale/sk.lua b/share/hedgewars/Data/Locale/sk.lua
index 46fb2c1..7a7d2d8 100644
--- a/share/hedgewars/Data/Locale/sk.lua
+++ b/share/hedgewars/Data/Locale/sk.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Najrýchlejšie kolo: ",
["Feeble Resistance"] = "Slabý odpor",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
["Hapless Hogs"] = "Bezmocnà ježkovia",
[" Hapless Hogs left!"] = " Bezmocných ježkov ostalo!",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurá!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "Samostatná munÃcia pre ježkov",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "Umiesnite viac bodov pomocou [ENTER]u",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "", -- Racer
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -822,7 +824,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "Výzva",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/sk.txt b/share/hedgewars/Data/Locale/sk.txt
index b242a72..62e8b2f 100644
--- a/share/hedgewars/Data/Locale/sk.txt
+++ b/share/hedgewars/Data/Locale/sk.txt
@@ -54,8 +54,10 @@
00:51=Blatová guľa
00:52=Žiadna zbraŠnie je vybraná
00:53=TARDIS
-00:54=Budova
-00:55=Postrek zeme
+; 00:54=Budova
+00:54=Postrek zeme
+00:55=ZmrazovaÄ
+00:56=SekáÄik
01:00=Do boja!
01:01=RemÃza
@@ -78,6 +80,7 @@
01:18=Vysoký
01:19=Extrémny
01:20=%1 odskok
+01:21=Vypnutý zvuk
; Správy o udalostiach
; Ježko (%1) zomrel
@@ -266,8 +269,8 @@
03:51=Nájdené na zemi
03:52=NEPOUŽÃVANÃ
03:53=Typ 40
-03:54=Postavte nieÄo
-03:55=Pomôcka
+;03:54=Postavte nieÄo
+03:54=Pomôcka
; Popis zbranà (ako oddeľovaÄ riadkov použite |)
04:00=ZaútoÄte na vaÅ¡ich nepriateľov obyÄajným granátom.|Vybuchne vtedy, keÄ vyprÅ¡Ã Äasomiera.|1â5: Nastavenie ÄasovaÄa granátu|Ãtok: Držanie tlaÄidla zvyÅ¡uje silu hodu|
@@ -324,8 +327,8 @@
04:51=NemÃÅajte munÃciu - hod blatom je zdarma.|TroÅ¡ku Å¡tÃpe a dokáže ježka zhodiÅ¥.
04:52=NEPOUŽITÃ
04:53=Vyberte sa na cestu Äasom a priestorom|a nechajte vaÅ¡ich priateľov bojovaÅ¥ bez vás.|BuÄte pripravený vrátiÅ¥ sa kedykoľvek,|buÄ pri Náhlej smrti alebo keÄ sú vÅ¡etci porazenÃ.|Poznámka: Nefunguje poÄas Náhlej smrti,|ak ste sám alebo ak ste kráľom.
-04:54=NEKOMPLETNÃ
-04:55=Rozprášte prúd lepkavej hliny.|Postavte mosty, pochovajte nepriateľov,|zapeÄaÅ¥te tunely. BuÄte|vÅ¡ak opatrný a nezaÅ¡pinte sa|od nej aj vy.
+;04:54=NEKOMPLETNÃ
+04:54=Rozprášte prúd lepkavej hliny.|Postavte mosty, pochovajte nepriateľov,|zapeÄaÅ¥te tunely. BuÄte|vÅ¡ak opatrný a nezaÅ¡pinte sa|od nej aj vy.
; Reťazce pre ciele hry
diff --git a/share/hedgewars/Data/Locale/stub.lua b/share/hedgewars/Data/Locale/stub.lua
index 6e243f6..5dd0fb0 100644
--- a/share/hedgewars/Data/Locale/stub.lua
+++ b/share/hedgewars/Data/Locale/stub.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
-- ["Fastest lap: "] = "",
-- ["Feeble Resistance"] = "",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
-- ["Hooray!"] = "",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/sv.lua b/share/hedgewars/Data/Locale/sv.lua
index a8ea9eb..130fd52 100644
--- a/share/hedgewars/Data/Locale/sv.lua
+++ b/share/hedgewars/Data/Locale/sv.lua
@@ -209,7 +209,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "Snabbast varv: ",
["Feeble Resistance"] = "Klent motstånd",
@@ -288,7 +288,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -331,7 +332,7 @@ locale = {
-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "Hurra!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -365,7 +366,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -564,11 +565,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -819,7 +821,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/sv.txt b/share/hedgewars/Data/Locale/sv.txt
index 6a0e103..18cf61f 100644
--- a/share/hedgewars/Data/Locale/sv.txt
+++ b/share/hedgewars/Data/Locale/sv.txt
@@ -54,8 +54,8 @@
00:51=Jordboll
00:52=Inget vapen valt
00:53=Tidslåda
-00:54=Struktur
-00:55=Markspruta
+; 00:54=Struktur
+00:54=Markspruta
01:00=Nu kör vi!
01:01=Oavgjort
@@ -180,7 +180,6 @@
02:01=%1 vill leka Ecco the dolphin
02:01=%1 har gått för att besöka Aquaria
02:01=%1 har funnit den förlorade staden Atlantis
-02:01=%1 siktar på huvudrollen i Bioshock 3
02:01=Du borde träna på ditt hundsim, %1
02:01=%1 skulle ha tagit med sig vattenskidor
02:01=%1 gillar inte vattensporter
@@ -477,8 +476,8 @@
03:51=Upphittad på marken
03:52=UNUSED
03:53=Typ 40
-03:54=Bygg något
-03:55=Verktyg
+;03:54=Bygg något
+03:54=Verktyg
; Weapon Descriptions (use | as line breaks)
04:00=Attackera fienden med en enkel granat.|Exploderar när tiden når noll.|1-5: Ställ in granatens tid|Attack: Håll ner för att kasta med mer kraft
@@ -535,8 +534,8 @@
04:51=Få till en gratisträff genom att kasta en boll med|jord. Känns lite gran, och knuffar tillbaka|igelkottar.
04:52=UNUSED
04:53=Ã
k på ett äventyr genom tid och rymd, medan dina|kamrater blir kvar själva att slåss. Var beredd|att komma tillbaka när som helst, eller till|Sudden Death eller om de andra blir besegrade.|Varning. Fungerar inte under Sudden Death, om du|är ensam, eller om du är en kung.
-04:54=INCOMPLETE
-04:55=Spruta en ström av fästande jord.|Bygg broar, gräv ner fienden, stäng igen tunnlar.|Var försiktig så att du inte får något på dig!
+;04:54=INCOMPLETE
+04:54=Spruta en ström av fästande jord.|Bygg broar, gräv ner fienden, stäng igen tunnlar.|Var försiktig så att du inte får något på dig!
; Game goal strings
05:00=Spellägen
diff --git a/share/hedgewars/Data/Locale/tr.lua b/share/hedgewars/Data/Locale/tr.lua
new file mode 100755
index 0000000..2044c90
--- /dev/null
+++ b/share/hedgewars/Data/Locale/tr.lua
@@ -0,0 +1,989 @@
+locale = {
+-- [":("] = "",
+-- ["!!!"] = "",
+-- ["..."] = "",
+-- ["011101000"] = "", -- A_Classic_Fairytale:dragon
+-- ["011101001"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+ ["30 minutes later..."] = "30 dakika sonra...", -- A_Classic_Fairytale:shadow
+-- ["About a month ago, a cyborg came and told us that you're the cannibals!"] = "", -- A_Classic_Fairytale:enemy
+ ["Accuracy Bonus!"] = "Güzel NiÅan Bonusu!",
+-- ["Ace"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
+-- ["Achievement Unlocked"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_That_Sinking_Feeling, Tumbler
+-- ["A Classic Fairytale"] = "", -- A_Classic_Fairytale:first_blood
+-- ["???"] = "", -- A_Classic_Fairytale:backstab
+-- ["Actually, you aren't worthy of life! Take this..."] = "", -- A_Classic_Fairytale:shadow
+-- ["A cy-what?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Adventurous"] = "", -- A_Classic_Fairytale:journey
+-- ["Africa"] = "", -- Continental_supplies
+-- ["After Leaks A Lot betrayed his tribe, he joined the cannibals..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["After the shock caused by the enemy spy, Leaks A Lot and Dense Cloud went hunting to relax."] = "", -- A_Classic_Fairytale:shadow
+-- ["Again with the 'cannibals' thing!"] = "", -- A_Classic_Fairytale:enemy
+-- ["a Hedgewars challenge"] = "", -- User_Mission_-_RCPlane_Challenge, User_Mission_-_Rope_Knock_Challenge
+ ["a Hedgewars mini-game"] = "Hedgewars mini oyunu", -- Space_Invasion, The_Specialists
+ ["Aiming Practice"] = "AtıŠEÄitimi", --Bazooka, Shotgun, SniperRifle
+-- ["A leap in a leap"] = "", -- A_Classic_Fairytale:first_blood
+-- ["A little gift from the cyborgs"] = "", -- A_Classic_Fairytale:shadow
+-- ["All gone...everything!"] = "", -- A_Classic_Fairytale:enemy
+-- ["All right, we just need to get to the other side of the island!"] = "", -- A_Classic_Fairytale:journey
+-- ["All walls touched!"] = "", -- WxW
+ ["Ammo Depleted!"] = "Munition erschöpft!",
+ ["ammo extended!"] = "Munition aufgestockt!",
+ ["Ammo is reset at the end of your turn."] = "Munition wird am Ende des Spielzuges zurückgesetzt.",
+ ["Ammo Maniac!"] = "Munitionsverrückter!",
+ ["Ammo"] = "Mermi",
+-- ["And how am I alive?!"] = "", -- A_Classic_Fairytale:enemy
+-- ["And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["And so it began..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["...and so the cyborgs took over the world..."] = "", -- A_Classic_Fairytale:shadow
+-- ["And so they discovered that cyborgs weren't invulnerable..."] = "", -- A_Classic_Fairytale:journey
+-- ["And where's all the weed?"] = "", -- A_Classic_Fairytale:dragon
+-- ["And you believed me? Oh, god, that's cute!"] = "", -- A_Classic_Fairytale:journey
+-- ["Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"] = "", -- Continental_supplies
+-- ["Antarctica"] = "", -- Continental_supplies
+-- ["Are we there yet?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Are you accusing me of something?"] = "", -- A_Classic_Fairytale:backstab
+-- ["Are you saying that many of us have died for your entertainment?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Artur Detour"] = "", -- A_Classic_Fairytale:queen
+-- ["As a reward for your performance, here's some new technology!"] = "", -- A_Classic_Fairytale:dragon
+-- ["a shoppa minigame"] = "", -- WxW
+-- ["Asia"] = "", -- Continental_supplies
+-- ["Assault Team"] = "", -- A_Classic_Fairytale:backstab
+-- ["As the ammo is sparse, you might want to reuse ropes while mid-air.|"] = "", -- A_Classic_Fairytale:dragon
+-- ["As the challenge was completed, Leaks A Lot set foot on the ground..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["As you can see, there is no way to get on the other side!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Attack From Rope"] = "", -- WxW
+-- ["Australia"] = "", -- Continental_supplies
+ ["Available points remaining: "] = "Verfügbare Punkte verbleibend:",
+-- ["Back Breaker"] = "", -- A_Classic_Fairytale:backstab
+-- ["Back in the village, after telling the villagers about the threat..."] = "", -- A_Classic_Fairytale:united
+-- ["[Backspace]"] = "",
+-- ["Backstab"] = "", -- A_Classic_Fairytale:backstab
+-- ["Bad Team"] = "", -- User_Mission_-_The_Great_Escape
+-- ["Bamboo Thicket"] = "",
+ ["Barrel Eater!"] = "Fassfresser!",
+ ["Barrel Launcher"] = "Fasswerfer",
+-- ["Baseballbat"] = "", -- Continental_supplies
+ ["Bat balls at your enemies and|push them into the sea!"] = "Schlage Bälle auf deine Widersacher|und lass sie ins Meer fallen!",
+ ["Bat your opponents through the|baskets and out of the map!"] = "Schlage deine Widersacher durch|die Körbe und aus der Karte hinaus!",
+ ["Bazooka Training"] = "Bazooka-Training",
+-- ["Beep Loopers"] = "", -- A_Classic_Fairytale:queen
+ ["Best laps per team: "] = "Beste Rundenzeiten pro Team: ",
+ ["Best Team Times: "] = "Beste Team-Zeiten: ",
+-- ["Beware, though! If you are slow, you die!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Biomechanic Team"] = "", -- A_Classic_Fairytale:family
+-- ["Blender"] = "", -- A_Classic_Fairytale:family
+-- ["Bloodpie"] = "", -- A_Classic_Fairytale:backstab
+-- ["Bloodrocutor"] = "", -- A_Classic_Fairytale:shadow
+-- ["Bloodsucker"] = "", -- A_Classic_Fairytale:shadow
+ ["Bloody Rookies"] = "Blutige Anfänger", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree
+-- ["Bone Jackson"] = "", -- A_Classic_Fairytale:backstab
+-- ["Bonely"] = "", -- A_Classic_Fairytale:shadow
+ ["Boom!"] = "Bumm!",
+ ["BOOM!"] = "KABUMM!",
+ ["Boss defeated!"] = "Boss wurde besiegt!",
+ ["Boss Slayer!"] = "Boss-Töter!",
+-- ["Brain Blower"] = "", -- A_Classic_Fairytale:journey
+-- ["Brainiac"] = "", -- A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:shadow
+-- ["Brainila"] = "", -- A_Classic_Fairytale:united
+-- ["Brain Stu"] = "", -- A_Classic_Fairytale:united
+-- ["Brain Teaser"] = "", -- A_Classic_Fairytale:backstab
+-- ["Brutal Lily"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil
+-- ["Brutus"] = "", -- A_Classic_Fairytale:backstab
+ ["Build a track and race."] = "Konstruiere eine Strecke und mach ein Wettrennen.",
+-- ["Bullseye"] = "", -- A_Classic_Fairytale:dragon
+-- ["But it proved to be no easy task!"] = "", -- A_Classic_Fairytale:dragon
+-- ["But that's impossible!"] = "", -- A_Classic_Fairytale:backstab
+-- ["But the ones alive are stronger in their heart!"] = "", -- A_Classic_Fairytale:enemy
+-- ["But...we died!"] = "", -- A_Classic_Fairytale:backstab
+-- ["But where can we go?"] = "", -- A_Classic_Fairytale:united
+-- ["But why would they help us?"] = "", -- A_Classic_Fairytale:backstab
+-- ["But you're cannibals. It's what you do."] = "", -- A_Classic_Fairytale:enemy
+-- ["But you said you'd let her go!"] = "", -- A_Classic_Fairytale:journey
+-- ["Call me Beep! Well, 'cause I'm such a nice...person!"] = "", -- A_Classic_Fairytale:family
+-- ["Cannibals"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:first_blood
+-- ["Cannibal Sentry"] = "", -- A_Classic_Fairytale:journey
+-- ["Cannibals?! You're the cannibals!"] = "", -- A_Classic_Fairytale:enemy
+ ["CAPTURE THE FLAG"] = "EROBERE DIE FAHNE",
+ ["Careless"] = "Achtlos",
+-- ["Carol"] = "", -- A_Classic_Fairytale:family
+-- ["CHALLENGE COMPLETE"] = "", -- User_Mission_-_RCPlane_Challenge
+ ["Change Weapon"] = "Waffenwechsel",
+-- ["Choose your side! If you want to join the strange man, walk up to him.|Otherwise, walk away from him. If you decide to att...nevermind..."] = "", -- A_Classic_Fairytale:shadow
+ ["Clumsy"] = "Hoppla",
+-- ["Cluster Bomb MASTER!"] = "", -- Basic_Training_-_Cluster_Bomb
+-- ["Cluster Bomb Training"] = "", -- Basic_Training_-_Cluster_Bomb
+ ["Codename: Teamwork"] = "Code-Name: Teamwork",
+-- ["Collateral Damage"] = "", -- A_Classic_Fairytale:journey
+-- ["Collateral Damage II"] = "", -- A_Classic_Fairytale:journey
+-- ["Collect all the crates, but remember, our time in this life is limited!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Collect or destroy all the health crates."] = "", -- User_Mission_-_RCPlane_Challenge
+-- ["Collect the crate on the right.|Hint: Select the rope, [Up] or [Down] to aim, [Space] to fire, directional keys to move.|Ropes can be fired again in the air!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Collect the crates within the time limit!|If you fail, you'll have to try again."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Come closer, so that your training may continue!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Compete to use as few planes as possible!"] = "", -- User_Mission_-_RCPlane_Challenge
+ ["Complete the track as fast as you can!"] = "Durchlaufe die Strecke so schnell du kannst!",
+-- ["COMPLETION TIME"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Configuration accepted."] = "", -- WxW
+-- ["Congratulations"] = "", -- Basic_Training_-_Rope
+ ["Congratulations!"] = "Gratulation!",
+-- ["Congratulations! You needed only half of time|to eliminate all targets."] = "", -- Basic_Training_-_Cluster_Bomb
+-- ["Congratulations! You've completed the Rope tutorial! |- Tutorial ends in 10 seconds!"] = "", -- Basic_Training_-_Rope
+ ["Congratulations! You've eliminated all targets|within the allowed time frame."] = "Gratulation! Du hast alle Ziele innerhalb der|verfügbaren Zeit ausgeschaltet.", --Bazooka, Shotgun, SniperRifle
+-- ["Continental supplies"] = "", -- Continental_supplies
+ ["Control pillars to score points."] = "Kontrolliere die Säulen um Punkte zu erhalten.",
+-- ["Corporationals"] = "", -- A_Classic_Fairytale:queen
+-- ["Corpsemonger"] = "", -- A_Classic_Fairytale:shadow
+-- ["Corpse Thrower"] = "", -- A_Classic_Fairytale:epil
+-- ["Crates Left:"] = "", -- User_Mission_-_RCPlane_Challenge
+ ["Cybernetic Empire"] = "Kybernetisches Imperium",
+-- ["Cyborg. It's what the aliens call themselves."] = "", -- A_Classic_Fairytale:enemy
+-- ["Dahmer"] = "", -- A_Classic_Fairytale:backstab
+ ["DAMMIT, ROOKIE! GET OFF MY HEAD!"] = "VERDAMMT, REKRUT! RUNTER VON MEINEM KOPF!",
+ ["DAMMIT, ROOKIE!"] = "VERDAMMT, REKRUT!",
+-- ["Dangerous Ducklings"] = "",
+ ["Deadweight"] = "Gravitus",
+-- ["Defeat the cannibals"] = "", -- A_Classic_Fairytale:backstab
+-- ["Defeat the cannibals!|"] = "", -- A_Classic_Fairytale:united
+-- ["Defeat the cannibals!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow
+-- ["Defeat the cyborgs!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Defend yourself!|Hint: You can get tips on using weapons by moving your mouse over them in the weapon selection menu"] = "", -- A_Classic_Fairytale:shadow
+ ["Demolition is fun!"] = "Zerstörung macht SpaÃ!",
+-- ["Dense Cloud"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+-- ["Dense Cloud must have already told them everything..."] = "", -- A_Classic_Fairytale:shadow
+ ["Depleted Kamikaze!"] = "Munitionsloses Kamikaze!",
+-- ["Destroy him, Leaks A Lot! He is responsible for the deaths of many of us!"] = "", -- A_Classic_Fairytale:first_blood
+ ["Destroy invaders to score points."] = "Zerstöre die Angreifer um Punkte zu erhalten.",
+-- ["Destroy the targets!|Hint: Select the Shoryuken and hit [Space]|P.S. You can use it mid-air."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Destroy the targets!|Hint: [Up], [Down] to aim, [Space] to shoot"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Did anyone follow you?"] = "", -- A_Classic_Fairytale:united
+-- ["Did you see him coming?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Did you warn the village?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Die, die, die!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Disguise as a Rockhopper Penguin: [Swap place with a random enemy hog in the circle]"] = "", -- Continental_supplies
+-- ["Dist: "] = "", -- Space_Invasion
+-- ["Do not laugh, inexperienced one, for he speaks the truth!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Do not let his words fool you, young one! He will stab you in the back as soon as you turn away!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Do the deed"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Double Kill!"] = "",
+-- ["DOUBLE KILL"] = "", -- Mutant
+-- ["Do you have any idea how valuable grass is?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Do you think you're some kind of god?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Dragon's Lair"] = "", -- A_Classic_Fairytale:dragon
+-- ["Drills"] = "", -- A_Classic_Fairytale:backstab
+-- ["Drone Hunter!"] = "",
+-- ["Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"] = "", -- Continental_supplies
+ ["Drowner"] = "Absäufer",
+-- ["Dude, all the plants are gone!"] = "", -- A_Classic_Fairytale:family
+-- ["Dude, can you see Ramon and Spiky?"] = "", -- A_Classic_Fairytale:journey
+-- ["Dude, that's so cool!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Dude, we really need a new shaman..."] = "", -- A_Classic_Fairytale:shadow
+-- ["Dude, what's this place?!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Dude, where are we?"] = "", -- A_Classic_Fairytale:backstab
+-- ["Dude, wow! I just had the weirdest high!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Duration"] = "", -- Continental_supplies
+-- ["Dust storm: [Deals 20 damage to all enemies in the circle]"] = "", -- Continental_supplies
+ ["Each turn you get 1-3 random weapons"] = "Du bekommst jede Runde 1-3 zufällig gewählte Waffen",
+ ["Each turn you get one random weapon"] = "Du bekommst jede Runde eine zufällig gewählte Waffe.",
+-- ["Eagle Eye"] = "", -- A_Classic_Fairytale:backstab
+-- ["Eagle Eye: [Blink to the impact ~ one shot]"] = "", -- Continental_supplies
+-- ["Ear Sniffer"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:epil
+-- ["Elderbot"] = "", -- A_Classic_Fairytale:family
+-- ["Elimate your captor."] = "", -- User_Mission_-_The_Great_Escape
+ ["Eliminate all enemies"] = "Vernichte alle Gegner",
+ ["Eliminate all targets before your time runs out.|You have unlimited ammo for this mission."] = "Eliminiere alle Ziele bevor die Zeit ausläuft.|Du hast in dieser Mission unbegrenzte Munition.", --Bazooka, Shotgun, SniperRifle
+-- ["Eliminate enemy hogs and take their weapons."] = "", -- Highlander
+ ["Eliminate Poison before the time runs out"] = "Neutralisiere das Gift bevor die Zeit abgelaufen ist",
+ ["Eliminate the Blue Team"] = "Lösche das Blaue Team aus",
+ ["Eliminate the enemy before the time runs out"] = "Vernichte den Feind bevor die Zeit abgelaufen ist", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
+ ["Eliminate the enemy hogs to win."] = "Vernichte alle gegnerischen Igel um zu gewinnen",
+ ["Eliminate the enemy specialists."] = "Vernichte die gegnerischen Spezialisten",
+ ["- Eliminate Unit 3378 |- Feeble Resistance must survive"] = "- Vernichte Einheit 3378 | Kraftloser Widerstand muss überleben",
+-- ["Elmo"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Energetic Engineer"] = "",
+ ["Enjoy the swim..."] = "Viel Spaà beim Schwimmen...",
+-- ["[Enter]"] = "",
+-- ["Europe"] = "", -- Continental_supplies
+-- [" ever done to you?!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Everyone knows this."] = "", -- A_Classic_Fairytale:enemy
+-- ["Every single time!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
+-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
+-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
+-- ["INSANITY"] = "", -- Mutant
+-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
+ ["Fastest lap: "] = "Schnellste Runde: ",
+ ["Feeble Resistance"] = "Kraftloser Widerstand",
+-- ["Fell From Grace"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Fell From Heaven"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen
+-- ["Fell From Heaven is the best! Fell From Heaven is the greatest!"] = "", -- A_Classic_Fairytale:family
+-- ["Femur Lover"] = "", -- A_Classic_Fairytale:shadow
+-- ["Fierce Competition!"] = "", -- Space_Invasion
+-- ["Fiery Water"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+-- ["Find your tribe!|Cross the lake!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Finish your training|Hint: Animations can be skipped with the [Precise] key."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Fire a mine: [Does what it says ~ Cant be dropped close to an enemy ~ 1 sec]"] = "", -- Continental_supplies
+ ["Fire"] = "Feuer",
+-- ["First aid kits?!"] = "", -- A_Classic_Fairytale:united
+-- ["First Blood"] = "", -- A_Classic_Fairytale:first_blood
+-- ["FIRST BLOOD MUTATES"] = "", -- Mutant
+-- ["First Steps"] = "", -- A_Classic_Fairytale:first_blood
+ ["Flag captured!"] = "Fahne erobert!",
+ ["Flag respawned!"] = "Fahne wieder erschienen!",
+ ["Flag returned!"] = "Fahne zurückgebracht!",
+ ["Flags, and their home base will be placed where each team ends their first turn."] = "Fahnen und deren Heimatstandort werden dort plaziert wo jedes Team deren ersten Zug beendet.",
+-- ["Flamer"] = "",
+-- ["Flaming Worm"] = "", -- A_Classic_Fairytale:backstab
+-- ["Flare: [fire up some bombs depending on hogs depending on hogs in the circle"] = "", -- Continental_supplies
+-- ["Flesh for Brainz"] = "", -- A_Classic_Fairytale:journey
+-- ["For improved features/stability, play 0.9.18+"] = "", -- WxW
+-- ["Free Dense Cloud and continue the mission!"] = "", -- A_Classic_Fairytale:journey
+-- ["Friendly Fire!"] = "",
+ ["fuel extended!"] = "Treibstoff aus!",
+ ["GAME BEGUN!!!"] = "SPIEL GESTARTET!!!",
+-- ["Game Modifiers: "] = "", -- The_Specialists
+ ["GAME OVER!"] = "SPIEL ZU ENDE!",
+ ["Game Started!"] = "Spiel Gestartet!]",
+-- ["Game? Was this a game to you?!"] = "", -- A_Classic_Fairytale:enemy
+-- ["GasBomb"] = "", -- Continental_supplies
+-- ["Gas Gargler"] = "", -- A_Classic_Fairytale:queen
+-- ["Get Dense Cloud out of the pit!"] = "", -- A_Classic_Fairytale:journey
+ ["Get on over there and take him out!"] = "Mach, dass du hinüber kommst und schalte ihn aus!",
+-- ["Get on the head of the mole"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Get out of there!"] = "", -- User_Mission_-_The_Great_Escape
+-- ["Get that crate!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Get the crate on the other side of the island!|"] = "", -- A_Classic_Fairytale:journey
+-- ["Get to the target using your rope! |Controls: Left & Right to swing the rope - Up & Down to Contract and Expand!"] = "", -- Basic_Training_-_Rope
+-- ["Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"] = "", -- A_Classic_Fairytale:family
+-- ["GG!"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Gimme Bones"] = "", -- A_Classic_Fairytale:backstab
+-- ["Glark"] = "", -- A_Classic_Fairytale:shadow
+ ["Goal"] = "Ziel",
+ ["GO! GO! GO!"] = "Bewegung, Bewegung, Bewegung!",
+ ["Good birdy......"] = "Braver Vogel......",
+-- ["Good Dude"] = "", -- User_Mission_-_The_Great_Escape
+-- ["Good idea, they'll never find us there!"] = "", -- A_Classic_Fairytale:united
+-- ["Good luck...or else!"] = "", -- A_Classic_Fairytale:journey
+ ["Good luck out there!"] = "Viel Glück da drauÃen!",
+ ["Good so far!"] = "Gut soweit!",
+ ["Good to go!"] = "Startklar!",
+-- ["Go on top of the flower"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Go, quick!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Gorkij"] = "", -- A_Classic_Fairytale:journey
+-- ["Go surf!"] = "", -- WxW
+ ["GOTCHA!"] = "ERWISCHT!",
+ ["Grab Mines/Explosives"] = "Sammle Minen/Fässer",
+-- ["Great choice, Steve! Mind if I call you that?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Great work! Now hit it with your Baseball Bat! |Tip: You can change weapon with 'Right Click'!"] = "", -- Basic_Training_-_Rope
+-- ["Great! You will be contacted soon for assistance."] = "", -- A_Classic_Fairytale:shadow
+-- ["Green lipstick bullet: [Is poisonous]"] = "", -- Continental_supplies
+-- ["Greetings, "] = "", -- A_Classic_Fairytale:dragon
+-- ["Greetings, cloudy one!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Grenade Training"] = "", -- Basic_Training_-_Grenade
+-- ["Grenadiers"] = "", -- Basic_Training_-_Grenade
+-- ["Guys, do you think there's more of them?"] = "", -- A_Classic_Fairytale:backstab
+-- ["HAHA!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Haha!"] = "", -- A_Classic_Fairytale:united
+-- ["Hahahaha!"] = "",
+ ["Haha, now THAT would be something!"] = "Haha, na DAS wär ja was!",
+-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
+ ["Hapless Hogs"] = "Glücklose Igel",
+ [" Hapless Hogs left!"] = " Glücklose Igel verbleibend!",
+
+-- [" HAS MUTATED"] = "", -- Mutant
+-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
+-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
+-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
+ ["Health crates extend your time."] = "Medipacks verlängern deine Zeit.",
+-- ["Heavy Cannfantry"] = "", -- A_Classic_Fairytale:united
+ ["Heavy"] = "Schwierig",
+-- ["Hedge-cogs"] = "", -- A_Classic_Fairytale:enemy
+-- ["Hedgehog projectile: [fire your hog like a Sticky Bomb]"] = "", -- Continental_supplies
+ ["Hedgewars-Basketball"] = "Hedgewars-Basketball",
+ ["Hedgewars-Knockball"] = "Hedgewars-Knockball",
+-- ["Hedgibal Lecter"] = "", -- A_Classic_Fairytale:backstab
+ ["Heh, it's not that bad."] = "Hehe, so schlimm ist es nicht.",
+-- ["Hello again, "] = "", -- A_Classic_Fairytale:family
+-- ["Help me, Leaks!"] = "", -- A_Classic_Fairytale:journey
+-- ["Help me, please!!!"] = "", -- A_Classic_Fairytale:journey
+-- ["Help me, please!"] = "", -- A_Classic_Fairytale:journey
+-- ["He moves like an eagle in the sky."] = "", -- A_Classic_Fairytale:first_blood
+-- ["He must be in the village already."] = "", -- A_Classic_Fairytale:journey
+-- ["Here, let me help you!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Here, let me help you save her!"] = "", -- A_Classic_Fairytale:family
+-- ["Here...pick your weapon!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hero Team"] = "", -- User_Mission_-_The_Great_Escape
+-- ["He's so brave..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["He won't be selling us out anymore!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Hey, guys!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Hey guys!"] = "", -- A_Classic_Fairytale:united
+-- ["Hey! This is cheating!"] = "", -- A_Classic_Fairytale:journey
+-- ["HIGHLANDER"] = "", -- Highlander
+-- ["Hightime"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hint: Double Jump - Press [Backspace] twice"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hint: Select the BlowTorch, aim and press [Fire]. Press [Fire] again to stop.|Don't blow up the crate."] = "", -- A_Classic_Fairytale:journey
+-- ["Hint: Select the LowGravity and press [Fire]."] = "", -- A_Classic_Fairytale:journey
+-- ["Hint: you might want to stay out of sight and take all the crates...|"] = "", -- A_Classic_Fairytale:journey
+-- ["His arms are so strong!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hit Combo!"] = "",
+-- ["Hmmm..."] = "",
+-- ["Hmmm...actually...I didn't either."] = "", -- A_Classic_Fairytale:enemy
+-- ["Hmmm, I'll have to find some way of moving him off this anti-portal surface..."] = "", -- portal
+-- ["Hmmm...it's a draw. How unfortunate!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Hmmm...perhaps a little more time will help."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
+-- ["Hogs in sight!"] = "", -- Continental_supplies
+-- ["HOLY SHYTE!"] = "", -- Mutant
+-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
+ ["Hooray!"] = "Hurra!",
+-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
+-- ["How can I ever repay you for saving my life?"] = "", -- A_Classic_Fairytale:journey
+-- ["How come in a village full of warriors, it's up to me to save it?"] = "", -- A_Classic_Fairytale:dragon
+-- ["How difficult would you like it to be?"] = "", -- A_Classic_Fairytale:first_blood
+-- ["HOW DO THEY KNOW WHERE WE ARE???"] = "", -- A_Classic_Fairytale:united
+-- ["However, if you fail to do so, she dies a most violent death, just like your friend! Muahahaha!"] = "", -- A_Classic_Fairytale:journey
+-- ["However, if you fail to do so, she dies a most violent death! Muahahaha!"] = "", -- A_Classic_Fairytale:journey
+-- ["However, my mates don't agree with me on letting you go..."] = "", -- A_Classic_Fairytale:dragon
+-- [" HP"] = "", -- Mutant
+ ["Hunter"] = "Jäger", --Bazooka, Shotgun, SniperRifle
+-- ["I believe there's more of them."] = "", -- A_Classic_Fairytale:backstab
+-- ["I can see you have been training diligently."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I can't believe it worked!"] = "", -- A_Classic_Fairytale:shadow
+-- ["I can't believe this!"] = "", -- A_Classic_Fairytale:enemy
+-- ["I can't believe what I'm hearing!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I can't wait any more, I have to save myself!"] = "", -- A_Classic_Fairytale:shadow
+-- ["I could just teleport myself there..."] = "", -- A_Classic_Fairytale:family
+-- ["I'd better get going myself."] = "", -- A_Classic_Fairytale:journey
+-- ["I didn't until about a month ago."] = "", -- A_Classic_Fairytale:enemy
+-- ["I don't know how you did that.. But good work! |The next one should be easy as cake for you!"] = "", -- Basic_Training_-_Rope
+-- ["I feel something...a place! They will arrive near the circles!"] = "", -- A_Classic_Fairytale:backstab
+-- ["If only I had a way..."] = "", -- A_Classic_Fairytale:backstab
+-- ["If only I were given a chance to explain my being here..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I forgot that she's the daughter of the chief, too..."] = "", -- A_Classic_Fairytale:backstab
+-- ["If they try coming here, they can have a taste of my delicious knuckles!"] = "", -- A_Classic_Fairytale:united
+-- ["If you agree to provide the information we need, you will be spared!"] = "", -- A_Classic_Fairytale:shadow
+-- ["If you can get that crate fast enough, your beloved \"princess\" may go free."] = "", -- A_Classic_Fairytale:journey
+-- ["If you decide to help us, though, we will no longer need to find a new governor for the island."] = "", -- A_Classic_Fairytale:shadow
+-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
+-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
+-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
+
+-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
+-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
+-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
+-- ["I have to follow that alien."] = "", -- A_Classic_Fairytale:backstab
+-- ["I have to get back to the village!"] = "", -- A_Classic_Fairytale:shadow
+-- ["I hope you are prepared for a small challenge, young one."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I just don't want to sink to your level."] = "", -- A_Classic_Fairytale:backstab
+-- ["I just found out that they have captured your princess!"] = "", -- A_Classic_Fairytale:family
+-- ["I just wonder where Ramon and Spiky disappeared..."] = "", -- A_Classic_Fairytale:journey
+-- ["I'll hold them off while you return to the village!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Imagine those targets are the wolves that killed your parents! Take your anger out on them!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["I'm...alive? How? Why?"] = "", -- A_Classic_Fairytale:backstab
+-- ["I'm a ninja."] = "", -- A_Classic_Fairytale:dragon
+-- ["I marked the place of their arrival. You're welcome!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I'm certain that this is a misunderstanding, fellow hedgehogs!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["I mean, none of you ceased to live."] = "", -- A_Classic_Fairytale:enemy
+-- ["I'm getting old for this!"] = "", -- A_Classic_Fairytale:family
+-- ["I'm getting thirsty..."] = "", -- A_Classic_Fairytale:family
+-- ["I'm here to help you rescue her."] = "", -- A_Classic_Fairytale:family
+-- ["I'm not sure about that!"] = "", -- A_Classic_Fairytale:united
+-- ["Impressive...you are still dry as the corpse of a hawk after a week in the desert..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I'm so scared!"] = "", -- A_Classic_Fairytale:united
+-- ["Incredible..."] = "", -- A_Classic_Fairytale:shadow
+-- ["I need to find the others!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I need to get to the other side of this island, fast!"] = "", -- A_Classic_Fairytale:journey
+-- ["I need to move the tribe!"] = "", -- A_Classic_Fairytale:united
+-- ["I need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I need to warn the others."] = "", -- A_Classic_Fairytale:backstab
+-- ["In fact, you are the only one that's been acting strangely."] = "", -- A_Classic_Fairytale:backstab
+-- ["In order to get to the other side, you need to collect the crates first.|"] = "", -- A_Classic_Fairytale:dragon
+ ["Instructor"] = "Ausbilder", -- 01#Boot_Camp, User_Mission_-_Dangerous_Ducklings
+-- ["Interesting idea, haha!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Interesting! Last time you said you killed a cannibal!"] = "", -- A_Classic_Fairytale:backstab
+-- ["In the meantime, take these and return to your \"friend\"!"] = "", -- A_Classic_Fairytale:shadow
+ ["invaders destroyed"] = "Angreifer zerstört",
+-- ["Invasion"] = "", -- A_Classic_Fairytale:united
+-- ["I saw it with my own eyes!"] = "", -- A_Classic_Fairytale:shadow
+-- ["I see..."] = "", -- A_Classic_Fairytale:shadow
+-- ["I see you have already taken the leap of faith."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I see you would like his punishment to be more...personal..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["I sense another wave of cannibals heading my way!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I sense another wave of cannibals heading our way!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I shouldn't have drunk that last pint."] = "", -- A_Classic_Fairytale:dragon
+-- ["Is this place in my head?"] = "", -- A_Classic_Fairytale:dragon
+-- ["It doesn't matter. I won't let that alien hurt my daughter!"] = "", -- A_Classic_Fairytale:dragon
+-- ["I think we are safe here."] = "", -- A_Classic_Fairytale:backstab
+-- ["I thought their shaman died when he tried our medicine!"] = "", -- A_Classic_Fairytale:shadow
+-- ["It is called 'Hogs of Steel'."] = "", -- A_Classic_Fairytale:enemy
+-- ["It is time to practice your fighting skills."] = "", -- A_Classic_Fairytale:first_blood
+-- ["It must be a childhood trauma..."] = "", -- A_Classic_Fairytale:family
+-- ["It must be the aliens!"] = "", -- A_Classic_Fairytale:backstab
+-- ["It must be the aliens' deed."] = "", -- A_Classic_Fairytale:backstab
+-- ["It must be the cyborgs again!"] = "", -- A_Classic_Fairytale:enemy
+-- ["I told you, I just found them."] = "", -- A_Classic_Fairytale:backstab
+ ["It's a good thing SUDDEN DEATH is 99 turns away..."] = "Gut, dass SUDDEN DEATH noch 99 Runden entfernt ist...",
+-- ["It's always up to women to clear up the mess men created!"] = "", -- A_Classic_Fairytale:dragon
+-- ["It's a shame, I forgot how to do that!"] = "", -- A_Classic_Fairytale:family
+-- ["It's impossible to communicate with the spirits without a shaman."] = "", -- A_Classic_Fairytale:shadow
+-- ["It's over..."] = "", -- A_Classic_Fairytale:shadow
+-- ["It's time you learned that your actions have consequences!"] = "", -- A_Classic_Fairytale:journey
+-- ["It's worth more than wood!"] = "", -- A_Classic_Fairytale:enemy
+-- ["It wants our brains!"] = "", -- A_Classic_Fairytale:shadow
+-- ["It was not a dream, unwise one!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I've seen this before. They just appear out of thin air."] = "", -- A_Classic_Fairytale:united
+-- ["I want to play a game..."] = "", -- A_Classic_Fairytale:journey
+-- ["I want to see how it handles this!"] = "", -- A_Classic_Fairytale:backstab
+-- ["I wish to help you, "] = "", -- A_Classic_Fairytale:dragon
+-- ["I wonder where Dense Cloud is..."] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
+-- ["I wonder why I'm so angry all the time..."] = "", -- A_Classic_Fairytale:family
+-- ["I won't let you kill her!"] = "", -- A_Classic_Fairytale:journey
+-- ["Jack"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Jeremiah"] = "", -- A_Classic_Fairytale:dragon
+-- ["John"] = "", -- A_Classic_Fairytale:journey
+-- ["Judas"] = "", -- A_Classic_Fairytale:backstab
+ ["Jumping is disabled"] = "Sprünge sind deaktiviert!",
+-- ["Just kidding, none of you have died!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Just on a walk."] = "", -- A_Classic_Fairytale:united
+-- ["Just wait till I get my hands on that trauma! ARGH!"] = "", -- A_Classic_Fairytale:family
+ ["Kamikaze Expert!"] = "Kamikazeexperte!",
+ ["Keep it up!"] = "Weiter so!",
+-- ["Kerguelen"] = "", -- Continental_supplies
+ ["Killing spree!"] = "Blutrausch!",
+-- ["KILL IT!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["KILLS"] = "",
+-- ["Kill the aliens!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Kill the cannibal!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Kill the traitor...or spare his life!|Kill him or press [Precise]!"] = "", -- A_Classic_Fairytale:backstab
+ ["Last Target!"] = "Letzte Zielscheibe!",
+-- ["Leader"] = "", -- A_Classic_Fairytale:enemy
+-- ["Leaderbot"] = "", -- A_Classic_Fairytale:queen
+-- ["Leaks A Lot"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+-- ["Leaks A Lot, depressed for killing his loved one, failed to save the village..."] = "", -- A_Classic_Fairytale:journey
+-- ["Leaks A Lot gave his life for his tribe! He should have survived!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Leaks A Lot must survive!"] = "", -- A_Classic_Fairytale:journey
+-- ["Led Heart"] = "", -- A_Classic_Fairytale:queen
+-- ["Lee"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["[Left Shift]"] = "",
+-- ["Let a Continent provide your weapons!"] = "", -- Continental_supplies
+-- ["Let me test your skills a little, will you?"] = "", -- A_Classic_Fairytale:journey
+-- ["Let's go home!"] = "", -- A_Classic_Fairytale:journey
+-- ["Let's head back to the village!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Let's see what your comrade does now!"] = "", -- A_Classic_Fairytale:journey
+-- ["Let's show those cannibals what we're made of!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Let them have a taste of my fury!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Let us help, too!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Light Cannfantry"] = "", -- A_Classic_Fairytale:united
+ ["Listen up, maggot!!"] = "Aufgepasst, du Made!!",
+-- ["Little did they know that this hunt will mark them forever..."] = "", -- A_Classic_Fairytale:shadow
+-- ["Lively Lifeguard"] = "",
+-- ["Lonely Cries: [Rise the water if no hog is in the circle and deal 1 damage to all hogs]"] = "", -- Continental_supplies
+-- ["Look, I had no choice!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Look out! There's more of them!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Look out! We're surrounded by cannibals!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Looks like the whole world is falling apart!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Luckily, I've managed to snatch some of them."] = "", -- A_Classic_Fairytale:united
+-- ["LUDICROUS KILL"] = "", -- Mutant
+-- ["May the spirits aid you in all your quests!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Medicine: [Fire some exploding medicine that will heal all hogs effected by the explosion]"] = "", -- Continental_supplies
+-- ["MEGA KILL"] = "", -- Mutant
+-- ["Meiwes"] = "", -- A_Classic_Fairytale:backstab
+-- ["Mindy"] = "", -- A_Classic_Fairytale:united
+ ["Mine Deployer"] = "Minenleger",
+ ["Mine Eater!"] = "Minenfresser!",
+ ["|- Mines Time:"] = "| - Minenzündzeit: ", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["MISSION FAILED"] = "MISSION GESCHEITERT", -- User_Mission_-_Dangerous_Ducklings, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["MISSION SUCCESSFUL"] = "MISSION ERFOLGREICH", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["MISSION SUCCESS"] = "MISSIONSERFOLG",
+-- ["Molotov"] = "", -- Continental_supplies
+-- ["MONSTER KILL"] = "", -- Mutant
+-- ["More Natives"] = "", -- A_Classic_Fairytale:epil
+ ["Movement: [Up], [Down], [Left], [Right]"] = "Bewegung: [Hoch], [Runter], [Links], [Rechts]",
+-- ["Multi-shot!"] = "",
+ ["Munition!"] = "Munition erschöpft!",
+-- ["Muriel"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Muscle Dissolver"] = "", -- A_Classic_Fairytale:shadow
+-- ["-------"] = "", -- Mutant
+-- ["Nade Boy"] = "", -- Basic_Training_-_Grenade
+-- ["Name"] = "", -- A_Classic_Fairytale:queen
+ ["Nameless Heroes"] = "Namenlose Helden",
+-- ["Nancy Screw"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:queen
+-- ["Napalm rocket: [Fire a bomb with napalm!]"] = "", -- Continental_supplies
+-- ["Natives"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:journey, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow, A_Classic_Fairytale:united
+ ["New Barrels Per Turn"] = "Neue Fässer jede Runde",
+ ["NEW CLAN RECORD: "] = "NEUER KLAN-REKORD",
+ ["NEW fastest lap: "] = "NEUE schnellste Runde: ",
+ ["New Mines Per Turn"] = "Neue Minen jede Runde",
+ ["NEW RACE RECORD: "] = "NEUER RENNREKORD: ",
+-- ["Newton's Hammock"] = "",
+-- ["Nicely done, meatbags!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Nice work, "] = "", -- A_Classic_Fairytale:dragon
+-- ["Nice work!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Nilarian"] = "", -- A_Classic_Fairytale:queen
+-- ["No, I came back to help you out..."] = "", -- A_Classic_Fairytale:shadow
+-- ["No...I wonder where they disappeared?!"] = "", -- A_Classic_Fairytale:journey
+-- ["Nom-Nom"] = "", -- A_Classic_Fairytale:journey
+-- ["NomNom"] = "", -- A_Classic_Fairytale:united
+-- ["Nope. It was one fast mole, that's for sure."] = "", -- A_Classic_Fairytale:shadow
+-- ["No! Please, help me!"] = "", -- A_Classic_Fairytale:journey
+-- ["NORMAL"] = "", -- Continental_supplies
+-- ["North America"] = "", -- Continental_supplies
+-- ["Not all hogs are born equal."] = "", -- Highlander
+ ["NOT ENOUGH WAYPOINTS"] = "NICHT GENUG WEGPUNKTE",
+-- ["Not now, Fiery Water!"] = "", -- A_Classic_Fairytale:backstab
+ ["Not So Friendly Match"] = "Kein-so-Freundschaftsspiel", -- Basketball, Knockball
+-- ["Not you again! My head still hurts from last time!"] = "", -- A_Classic_Fairytale:shadow
+-- ["No, we made sure of that!"] = "", -- A_Classic_Fairytale:united
+-- ["Now find the next target! |Tip: Normally you lose health by falling down, so be careful!"] = "", -- Basic_Training_-_Rope
+-- ["No! What have I done?! What have YOU done?!"] = "", -- A_Classic_Fairytale:journey
+-- ["No. Where did he come from?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Now how do I get on the other side?!"] = "", -- A_Classic_Fairytale:dragon
+-- ["No. You and the rest of the tribe are safer there!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Obliterate them!|Hint: You might want to take cover..."] = "", -- A_Classic_Fairytale:shadow
+-- ["Obstacle course"] = "", -- A_Classic_Fairytale:dragon
+-- ["Of course I have to save her. What did I expect?!"] = "", -- A_Classic_Fairytale:family
+-- ["OH, COME ON!"] = "", -- A_Classic_Fairytale:journey
+-- ["Oh, my!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Oh, my! This is even more entertaining than I've expected!"] = "", -- A_Classic_Fairytale:backstab
+ ["Oh no! Just try again!"] = "Oh nein! Versuch's nochmal!", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+-- ["Oh no, not "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["Oh no! Time's up! Just try again."] = "Oh nein! Die Zeit ist um! Versuche es nochmal.", --Bazooka, Shotgun, SniperRifle
+-- ["Oh no! You failed! Just try again."] = "", -- Basic_Training_-_Cluster_Bomb
+-- ["Oh, silly me! I forgot that I'm the shaman."] = "", -- A_Classic_Fairytale:backstab
+-- ["Olive"] = "", -- A_Classic_Fairytale:united
+-- ["Omnivore"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Once upon a time, on an island with great natural resources, lived two tribes in heated conflict..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["ONE HOG PER TEAM! KILLING EXCESS HEDGES"] = "", -- Mutant
+-- ["One tribe was peaceful, spending their time hunting and training, enjoying the small pleasures of life..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Oops...I dropped them."] = "", -- A_Classic_Fairytale:united
+-- ["Open that crate and we will continue!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Operation Diver"] = "",
+ ["Opposing Team: "] = "Gegnerisches Team: ",
+-- ["Orlando Boom!"] = "", -- A_Classic_Fairytale:queen
+-- ["Ouch!"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Our tribe, our beautiful island!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Parachute"] = "", -- Continental_supplies
+ ["Pathetic Hog #%d"] = "Erbärmlicher Igel #%d",
+ ["Pathetic Resistance"] = "Erbärmlicher Widerstand", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
+-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
+ ["Per-Hog Ammo"] = "Munition pro Igel",
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
+-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
+-- ["Pings left:"] = "", -- Space_Invasion
+
+ ["Place more waypoints using the 'Air Attack' weapon."] = "Platziere mehr Wegpunkte durch Verwenden der 'Luftangriff'-Waffe",
+-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
+-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
+-- ["Play with me!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Please place the way-point further from the waterline."] = "", -- Racer
+-- ["Please place the way-point in the open, within the map boundaries."] = "", -- Racer
+-- ["Please, stop releasing your \"smoke signals\"!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Point Blank Combo!"] = "", -- Space_Invasion
+ ["points"] = "Punkte", -- Control, CTF_Blizzard, Basic_Training_-_Bazooka, Basic_Training_-_Shotgun, Basic_Training_-_Sniper_Rifle
+ ["Poison"] = "Gift",
+-- ["Portal hint: one goes to the destination, and one is the entrance.|"] = "", -- A_Classic_Fairytale:dragon
+-- ["Portal mission"] = "", -- portal
+ ["Power Remaining"] = "Verbleibende Energie",
+ ["Prepare yourself"] = "Mach dich bereit",
+-- ["Press [Enter] to accept this configuration."] = "", -- WxW
+-- ["Press [Left] or [Right] to move around, [Enter] to jump"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Press [Precise] to skip intro"] = "",
+-- ["Private Novak"] = "", -- Basic_Training_-_Cluster_Bomb
+-- ["Protect yourselves!|Grenade hint: set the timer with [1-5], aim with [Up]/[Down] and hold [Space] to set power"] = "", -- A_Classic_Fairytale:shadow
+ ["PUNKTESTAND"] = "",
+ ["Race complexity limit reached."] = "Rennkomplexitätslimit erreicht.",
+-- ["RACER"] = "",
+-- ["Rachel"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Radar Ping"] = "", -- Space_Invasion
+-- ["Raging Buffalo"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+-- ["Ramon"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
+-- ["RC PLANE TRAINING"] = "", -- User_Mission_-_RCPlane_Challenge
+-- ["Really?! You thought you could harm me with your little toys?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Regurgitator"] = "", -- A_Classic_Fairytale:backstab
+-- ["Reinforcements"] = "", -- A_Classic_Fairytale:backstab
+-- ["Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!"] = "", -- Basic_Training_-_Rope
+-- ["Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"] = "", -- A_Classic_Fairytale:shadow
+ [" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = " - Bringe die gegnerische Flagge zu deiner Heimatbasis um zu punkten. | - Das Team das zuerst 3 Flaggen erobert gewinnt. | - Du kannst nur punkten wenn deine eigene Flagge in deiner Basis ist | - Igel lassen die Flagge fallen wenn sie sterben oder ertrinken | - Fallen gelassene Flaggen können zurückgebracht oder wieder gestohlen werden | - Igel tauchen nach ihrem Tod wieder auf",
+-- ["Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Righteous Beard"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+-- ["ROPE-KNOCKING"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Rope Training"] = "", -- Basic_Training_-_Rope
+-- ["Rot Molester"] = "", -- A_Classic_Fairytale:shadow
+-- ["Round Limit:"] = "",
+ ["Round Limit"] = "Rundenbegrenzung",
+-- ["Rounds Complete: "] = "",
+ ["Rounds Complete"] = "Runden Gespielt",
+ ["RULES OF THE GAME [Press ESC to view]"] = "SPIEL REGELN (Drücke ESC zum Anzeigen)",
+-- ["Rusty Joe"] = "", -- A_Classic_Fairytale:queen
+-- ["s|"] = "",
+-- ["Sabotage: [Sabotage all hogs in the circle and deal ~10 dmg]"] = "", -- Continental_supplies
+-- ["Salivaslurper"] = "", -- A_Classic_Fairytale:united
+-- ["Salvation"] = "", -- A_Classic_Fairytale:family
+-- ["Salvation was one step closer now..."] = "", -- A_Classic_Fairytale:dragon
+ ["Save as many hapless hogs as possible!"] = "Rette so viele glücklose Igel als möglich!",
+-- ["Save Fell From Heaven!"] = "", -- A_Classic_Fairytale:journey
+-- ["Save Leaks A Lot!|Hint: The Switch utility might be of help to you."] = "", -- A_Classic_Fairytale:shadow
+-- ["Save the princess! All your hogs must survive!|Hint: Kill the cyborgs first! Use the ammo very carefully!|Hint: You might want to spare a girder for cover!"] = "", -- A_Classic_Fairytale:family
+-- ["Save the princess by collecting the crate in under 12 turns!"] = "", -- A_Classic_Fairytale:journey
+-- ["Scalp Muncher"] = "", -- A_Classic_Fairytale:backstab
+-- ["Score"] = "", -- Mutant
+-- ["SCORE"] = "", -- Space_Invasion
+-- ["Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"] = "", -- Continental_supplies
+-- ["sec"] = "", -- CTF_Blizzard, TrophyRace, Basic_Training_-_Bazooka, Basic_Training_-_Shotgun, Basic_Training_-_Sniper_Rifle, User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork, Capture_the_Flag
+-- ["Seduction"] = "", -- Continental_supplies
+-- ["Seems like every time you take a \"walk\", the enemy find us!"] = "", -- A_Classic_Fairytale:backstab
+-- ["See that crate farther on the right?"] = "", -- A_Classic_Fairytale:first_blood
+ ["See ya!"] = "Mach's gut!",
+-- ["Segmentation Paul"] = "", -- A_Classic_Fairytale:dragon
+-- ["Select continent!"] = "", -- Continental_supplies
+-- ["Select difficulty: [Left] - easier or [Right] - harder"] = "", -- A_Classic_Fairytale:first_blood
+ ["selected!"] = "ausgewählt!",
+-- ["s"] = "", -- GaudyRacer, Space_Invasion
+-- ["... share your beauty with the world every morning, my princess!"] = "", -- A_Classic_Fairytale:journey
+-- ["She's behind that tall thingy."] = "", -- A_Classic_Fairytale:family
+ ["Shield boosted! +30 power"] = "Schild verstärkt! +30 Energie",
+ ["Shield Depleted"] = "Schild aufgebraucht!",
+ ["Shield is fully recharged!"] = "Schild vollständig aufgeladen!",
+ ["Shield Master!"] = "Schildmeister!",
+ ["Shield Miser!"] = "Schildgieriger",
+ ["Shield OFF:"] = "Schild AUS:",
+ ["Shield ON:"] = "Schild AN:",
+ ["Shield Seeker!"] = "Schildsucher!",
+-- ["Shotgun"] = "", -- Continental_supplies
+ ["Shotgun Team"] = "Schrotflinten-Team",
+ ["Shotgun Training"] = "Schrotflinten-Training",
+ ["shots remaining."] = "Schüsse übrig",
+ ["Silly"] = "Doofi",
+ ["Sinky"] = "Blubb",
+-- ["Sirius Lee"] = "", -- A_Classic_Fairytale:enemy
+ ["%s is out and Team %d|scored a penalty!| |Score:"] = "%s ist drauÃen und Team %d|erhält eine Strafe!| |Punktestand:", -- Basketball, Knockball
+ ["%s is out and Team %d|scored a point!| |Score:"] = "%s ist drauÃen und Team %d|erhält einen Punkt!| |Punktestand:", -- Basketball, Knockball
+-- ["Slippery"] = "", -- A_Classic_Fairytale:journey
+-- ["Smith 0.97"] = "", -- A_Classic_Fairytale:enemy
+-- ["Smith 0.98"] = "", -- A_Classic_Fairytale:enemy
+-- ["Smith 0.99a"] = "", -- A_Classic_Fairytale:enemy
+-- ["Smith 0.99b"] = "", -- A_Classic_Fairytale:enemy
+-- ["Smith 0.99f"] = "", -- A_Classic_Fairytale:enemy
+-- ["Smith 1.0"] = "", -- A_Classic_Fairytale:enemy
+-- ["Sniper Rifle"] = "", -- Continental_supplies
+-- ["Sniper!"] = "", -- Space_Invasion
+ ["Sniper Training"] = "Scharfschützen-Training",
+ ["Sniperz"] = "Heckenschützen",
+-- ["So humiliating..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["South America"] = "", -- Continental_supplies
+-- ["So? What will it be?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Spawn the crate, and attack!"] = "", -- WxW
+-- ["Special Weapons:"] = "", -- Continental_supplies
+ ["Spielmodifikatoren: "] = "",
+-- ["Spiky Cheese"] = "", -- A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:shadow
+-- ["Spleenlover"] = "", -- A_Classic_Fairytale:united
+ ["Sponge"] = "Schwamm",
+-- ["Spooky Tree"] = "",
+-- ["STATUS UPDATE"] = "", -- GaudyRacer, Space_Invasion
+-- ["Steel Eye"] = "", -- A_Classic_Fairytale:queen
+-- ["Step By Step"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Steve"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["Sticky Mine"] = "", -- Continental_supplies
+-- ["Stronglings"] = "", -- A_Classic_Fairytale:shadow
+-- ["Structure"] = "", -- Continental_supplies
+-- ["Super Weapons"] = "", -- WxW
+-- ["Surf Before Crate"] = "", -- WxW
+-- ["Surfer! +15 points!"] = "", -- Space_Invasion
+-- ["Surfer!"] = "", -- WxW
+-- ["Survive!|Hint: Cinematics can be skipped with the [Precise] key."] = "", -- A_Classic_Fairytale:shadow
+-- ["Swing, Leaks A Lot, on the wings of the wind!"] = "", -- A_Classic_Fairytale:first_blood
+ ["Switched to "] = "Gewechselt zu ",
+-- ["Syntax Errol"] = "", -- A_Classic_Fairytale:dragon
+-- ["Talk about mixed signals..."] = "", -- A_Classic_Fairytale:dragon
+-- ["Team %d: "] = "",
+ ["Team Scores"] = "Teampunktestand", -- Control, Space_Invasion
+-- ["Teleport hint: just use the mouse to select the destination!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Thanks!"] = "", -- A_Classic_Fairytale:family
+-- ["Thank you, my hero!"] = "", -- A_Classic_Fairytale:family
+-- ["Thank you, oh, thank you, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
+-- ["Thank you, oh, thank you, my heroes!"] = "", -- A_Classic_Fairytale:journey
+-- ["That is, indeed, very weird..."] = "", -- A_Classic_Fairytale:united
+-- ["That makes it almost invaluable!"] = "", -- A_Classic_Fairytale:enemy
+-- ["That ought to show them!"] = "", -- A_Classic_Fairytale:backstab
+-- ["That's for my father!"] = "", -- A_Classic_Fairytale:backstab
+-- ["That shaman sure knows what he's doing!"] = "", -- A_Classic_Fairytale:shadow
+-- ["That Sinking Feeling"] = "",
+-- ["That's not our problem!"] = "", -- A_Classic_Fairytale:enemy
+-- ["That's typical of you!"] = "", -- A_Classic_Fairytale:family
+-- ["That was just mean!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+ ["That was pointless."] = "Das war sinnlos.",
+-- ["The answer is...entertaintment. You'll see what I mean."] = "", -- A_Classic_Fairytale:backstab
+-- ["The anti-portal zone is all over the floor, and I have nothing to kill him...Droping something could hurt him enough to kill him..."] = "", -- portal
+-- ["The Bull's Eye"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The caves are well hidden, they won't find us there!"] = "", -- A_Classic_Fairytale:united
+-- ["The Crate Frenzy"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Dilemma"] = "", -- A_Classic_Fairytale:shadow
+-- ["The enemy can't move but it might be a good idea to stay out of sight!|"] = "", -- A_Classic_Fairytale:dragon
+ ["The enemy is hiding out on yonder ducky!"] = "Der Feind versteckt sich auf dem Entlein dort drüben!",
+-- ["The Enemy Of My Enemy"] = "", -- A_Classic_Fairytale:enemy
+-- ["The First Blood"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The First Encounter"] = "", -- A_Classic_Fairytale:shadow
+ ["The flag will respawn next round."] = "Die Fahne wird nächste Runde wieder auftauchen.",
+-- ["The food bites back"] = "", -- A_Classic_Fairytale:backstab
+-- ["The giant umbrella from the last crate should help break the fall."] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Great Escape"] = "", -- User_Mission_-_The_Great_Escape
+-- ["The guardian"] = "", -- A_Classic_Fairytale:shadow
+-- ["The Individualist"] = "", -- A_Classic_Fairytale:shadow
+-- ["Their buildings were very primitive back then, even for an uncivilised island."] = "", -- A_Classic_Fairytale:united
+-- ["The Journey Back"] = "", -- A_Classic_Fairytale:journey
+-- ["The Leap of Faith"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Moonwalk"] = "", -- A_Classic_Fairytale:journey
+ ["The Nameless One"] = "Der Namenlose",
+-- ["The next one is pretty hard! |Tip: You have to do multiple swings!"] = "", -- Basic_Training_-_Rope
+-- ["Then how do they keep appearing?"] = "", -- A_Classic_Fairytale:shadow
+-- ["The other one were all cannibals, spending their time eating the organs of fellow hedgehogs..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["There must be a spy among us!"] = "", -- A_Classic_Fairytale:backstab
+-- ["There's more of them? When did they become so hungry?"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["There's nothing more satisfying for me than seeing you share your beauty with the world every morning, my princess!"] = "", -- A_Classic_Fairytale:journey
+-- ["There's nothing more satisfying to us than seeing you share your beauty..."] = "", -- A_Classic_Fairytale:journey
+-- ["There's nothing more satisfying to us than seeing you share your beauty with the world every morning, my princess!"] = "", -- A_Classic_Fairytale:journey
+-- ["The Rising"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Savior"] = "", -- A_Classic_Fairytale:journey
+-- ["These primitive people are so funny!"] = "", -- A_Classic_Fairytale:backstab
+-- ["The Shadow Falls"] = "", -- A_Classic_Fairytale:shadow
+-- ["The Showdown"] = "", -- A_Classic_Fairytale:shadow
+-- ["The Slaughter"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:first_blood
+ ["THE SPECIALISTS"] = "DIE SPEZIALISTEN",
+-- ["The spirits of the ancerstors are surely pleased, Leaks A Lot."] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Torment"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Tunnel Maker"] = "", -- A_Classic_Fairytale:journey
+-- ["The Ultimate Weapon"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The Union"] = "", -- A_Classic_Fairytale:enemy
+-- ["The village, unprepared, was destroyed by the cyborgs..."] = "", -- A_Classic_Fairytale:journey
+-- ["The walk of Fame"] = "", -- A_Classic_Fairytale:shadow
+-- ["The wasted youth"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The weapon in that last crate was bestowed upon us by the ancients!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["The what?!"] = "", -- A_Classic_Fairytale:dragon
+-- ["The wind whispers that you are ready to become familiar with tools, now..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["They are all waiting back in the village, haha."] = "", -- A_Classic_Fairytale:enemy
+-- ["They Call Me Bullseye!"] = "", -- Space_Invasion
+-- ["They have weapons we've never seen before!"] = "", -- A_Classic_Fairytale:united
+-- ["They keep appearing like this. It's weird!"] = "", -- A_Classic_Fairytale:united
+-- ["They killed "] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["They must be trying to weaken us!"] = "", -- A_Classic_Fairytale:enemy
+-- ["They never learn"] = "", -- A_Classic_Fairytale:journey
+-- ["They told us to wear these clothes. They said that this is the newest trend."] = "", -- A_Classic_Fairytale:enemy
+-- ["They've been manipulating us all this time!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Thighlicker"] = "", -- A_Classic_Fairytale:united
+-- ["This is it! It's time to make Fell From Heaven fall for me..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["This island is the only place left on Earth with grass on it!"] = "", -- A_Classic_Fairytale:enemy
+-- ["This is typical!"] = "", -- A_Classic_Fairytale:dragon
+-- ["This must be some kind of sorcery!"] = "", -- A_Classic_Fairytale:shadow
+-- ["This must be the caves!"] = "", -- A_Classic_Fairytale:backstab
+ ["This one's tricky."] = "Der hier ist knifflig.",
+ ["This rain is really something..."] = "Das nenne ich mal einen Regenschauer...",
+-- ["This will be fun!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Those aliens are destroying the island!"] = "", -- A_Classic_Fairytale:family
+ ["Timed Kamikaze!"] = "Pünktliches Kamikaze!",
+ ["Time Extended!"] = "Zeit verlängert!",
+ ["Time Extension"] = "Zeitverlängerung",
+ ["Time Left: "] = "Verbleibende Zeit",
+ ["TIME: "] = "ZEIT: ",
+-- ["Tip: The rope physics are different than in the real world, |use it to your advantage!"] = "", -- Basic_Training_-_Rope
+ ["Toggle Shield"] = "Schild ein/aus",
+-- ["To help you, of course!"] = "", -- A_Classic_Fairytale:journey
+-- ["To place a girder, select it, use [Left] and [Right] to select angle and length, place with [Left Click]"] = "", -- A_Classic_Fairytale:shadow
+-- ["Torn Muscle"] = "", -- A_Classic_Fairytale:journey
+-- [" to save the village."] = "", -- A_Classic_Fairytale:dragon
+-- ["To the caves..."] = "", -- A_Classic_Fairytale:united
+ ["Toxic Team"] = "Giftige Gegner", -- User_Mission_-_Diver, User_Mission_-_Spooky_Tree, User_Mission_-_Teamwork
+ ["TRACK COMPLETED"] = "STRECKENLAUF BEENDET",
+ ["TRACK FAILED!"] = "STRECKENLAUF GESCHEITERT",
+-- ["training"] = "", -- portal
+-- ["Traitors"] = "", -- A_Classic_Fairytale:epil
+-- ["Tribe"] = "", -- A_Classic_Fairytale:backstab
+-- ["TrophyRace"] = "",
+-- ["Try to protect the chief! You won't lose if he dies, but it is advised that he survives."] = "", -- A_Classic_Fairytale:united
+-- ["T_T"] = "",
+ ["Tumbling Time Extended!"] = "Purzelzeit verlängert!",
+-- ["Turns until Sudden Death: "] = "", -- A_Classic_Fairytale:dragon
+-- [" turns until Sudden Death! Better hurry!"] = "", -- A_Classic_Fairytale:dragon
+ ["Turn Time"] = "Zeit pro Zug",
+-- ["Two little hogs cooperating, getting past obstacles..."] = "", -- A_Classic_Fairytale:journey
+-- ["Uhm...I met one of them and took his weapons."] = "", -- A_Classic_Fairytale:shadow
+-- ["Uhmm...ok no."] = "", -- A_Classic_Fairytale:enemy
+-- ["ULTRA KILL"] = "", -- Mutant
+-- ["Under Construction"] = "", -- A_Classic_Fairytale:shadow
+-- ["Unexpected Igor"] = "", -- A_Classic_Fairytale:dragon
+-- ["Unit 0x0007"] = "", -- A_Classic_Fairytale:family
+-- ["Unit 334a$7%;.*"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:family, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
+ ["Unit 3378"] = "Einheit 3378",
+ ["Unit 835"] = "Einheit 3378",
+-- ["United We Stand"] = "", -- A_Classic_Fairytale:united
+ ["Unit"] = "Einheit",
+ ["Unlimited Attacks"] = "Unbegrenzte Angriffe",
+-- ["Unlucky Sods"] = "", -- User_Mission_-_Rope_Knock_Challenge
+ ["Unstoppable!"] = "Unaufhaltbar!",
+-- ["Unsuspecting Louts"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["[Up], [Down] to aim, [Space] to shoot!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["User Challenge"] = "",
+
+-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
+-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
+ ["Use your rope to get from start to finish as fast as you can!"] = "Nutze das Seil um von Start zu Ziel zu gelangen - so schnell du kannst!",
+-- ["Vedgies"] = "", -- A_Classic_Fairytale:journey
+-- ["Vegan Jack"] = "", -- A_Classic_Fairytale:enemy
+-- ["Victory!"] = "", -- Basic_Training_-_Rope
+ ["Victory for the "] = "Sieg für ", -- CTF_Blizzard, Capture_the_Flag
+-- ["Violence is not the answer to your problems!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Walls Left"] = "", -- WxW
+-- ["Walls Required"] = "", -- WxW
+-- ["WALL TO WALL"] = "", -- WxW
+-- ["Wannabe Flyboys"] = "", -- User_Mission_-_RCPlane_Challenge
+-- ["Wannabe Shoppsta"] = "", -- User_Mission_-_Rope_Knock_Challenge
+-- ["Watch your steps, young one!"] = "", -- A_Classic_Fairytale:first_blood
+ ["Waypoint placed."] = "Wegpunkt gesetzt",
+ ["Way-Points Remaining"] = "Wegpunkte verbleibend",
+-- ["Weaklings"] = "", -- A_Classic_Fairytale:shadow
+-- ["We all know what happens when you get frightened..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Weapons reset."] = "", -- Highlander
+ ["Weapons Reset"] = "Waffenzurücksetzung",
+-- ["We are indeed."] = "", -- A_Classic_Fairytale:backstab
+-- ["We can't defeat them!"] = "", -- A_Classic_Fairytale:shadow
+-- ["We can't hold them up much longer!"] = "", -- A_Classic_Fairytale:united
+-- ["We can't let them take over our little island!"] = "", -- A_Classic_Fairytale:enemy
+-- ["We have no time to waste..."] = "", -- A_Classic_Fairytale:journey
+-- ["We have nowhere else to live!"] = "", -- A_Classic_Fairytale:enemy
+-- ["We have to protect the village!"] = "", -- A_Classic_Fairytale:united
+-- ["We have to unite and defeat those cylergs!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Welcome, Leaks A Lot!"] = "", -- A_Classic_Fairytale:journey
+ ["Well done."] = "Gut gemacht.",
+-- ["We'll give you a problem then!"] = "", -- A_Classic_Fairytale:enemy
+-- ["We'll spare your life for now!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Well, that was a waste of time."] = "", -- A_Classic_Fairytale:dragon
+-- ["Well, well! Isn't that the cutest thing you've ever seen?"] = "", -- A_Classic_Fairytale:journey
+-- ["Well, yes. This was a cyborg television show."] = "", -- A_Classic_Fairytale:enemy
+-- ["We made sure noone followed us!"] = "", -- A_Classic_Fairytale:backstab
+-- ["We need to move!"] = "", -- A_Classic_Fairytale:united
+-- ["We need to prevent their arrival!"] = "", -- A_Classic_Fairytale:backstab
+-- ["We need to warn the village."] = "", -- A_Classic_Fairytale:shadow
+-- ["We should head back to the village now."] = "", -- A_Classic_Fairytale:shadow
+-- ["We were trying to save her and we got lost."] = "", -- A_Classic_Fairytale:family
+-- ["We won't let you hurt her!"] = "", -- A_Classic_Fairytale:journey
+-- ["What?! A cannibal? Here? There is no time to waste! Come, you are prepared."] = "", -- A_Classic_Fairytale:first_blood
+-- ["What a douche!"] = "", -- A_Classic_Fairytale:enemy
+-- ["What am I gonna...eat, yo?"] = "", -- A_Classic_Fairytale:family
+-- ["What are you doing at a distance so great, young one?"] = "", -- A_Classic_Fairytale:first_blood
+-- ["What are you doing? Let her go!"] = "", -- A_Classic_Fairytale:journey
+-- ["What a ride!"] = "", -- A_Classic_Fairytale:shadow
+-- ["What a strange cave!"] = "", -- A_Classic_Fairytale:dragon
+-- ["What a strange feeling!"] = "", -- A_Classic_Fairytale:backstab
+-- ["What do my faulty eyes observe? A spy!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Whatever floats your boat..."] = "", -- A_Classic_Fairytale:shadow
+-- [" What !! For all of this struggle i just win some ... TIME o0"] = "", -- portal
+-- ["What has "] = "", -- A_Classic_Fairytale:backstab
+-- ["What? Here? How did they find us?!"] = "", -- A_Classic_Fairytale:backstab
+-- ["What is this place?"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy
+-- ["What shall we do with the traitor?"] = "", -- A_Classic_Fairytale:backstab
+-- ["WHAT?! You're the ones attacking us!"] = "", -- A_Classic_Fairytale:enemy
+-- ["When?"] = "", -- A_Classic_Fairytale:enemy
+-- ["When I find it..."] = "", -- A_Classic_Fairytale:dragon
+-- ["Where are all these crates coming from?!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Where are they?!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Where did that alien run?"] = "", -- A_Classic_Fairytale:dragon
+-- ["Where did you get the exploding apples?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Where did you get the exploding apples and the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Where did you get the magic bow that shoots many arrows?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Where did you get the weapons in the forest, Dense Cloud?"] = "", -- A_Classic_Fairytale:backstab
+-- ["Where do you get that?!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Where have you been?!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Where have you been?"] = "", -- A_Classic_Fairytale:united
+-- ["? Why?"] = "", -- A_Classic_Fairytale:backstab
+-- ["Why "] = "", -- A_Classic_Fairytale:backstab
+-- ["! Why?!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["Why are you doing this?"] = "", -- A_Classic_Fairytale:journey
+-- ["Why are you helping us, uhm...?"] = "", -- A_Classic_Fairytale:family
+-- ["Why can't he just let her go?!"] = "", -- A_Classic_Fairytale:family
+-- ["Why do men keep hurting me?"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Why do you not like me?"] = "", -- A_Classic_Fairytale:shadow
+-- ["Why do you want to take over our island?"] = "", -- A_Classic_Fairytale:enemy
+-- ["Why me?!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Why would they do this?"] = "", -- A_Classic_Fairytale:backstab
+-- ["- Will Get 1-3 random weapons"] = "", -- Continental_supplies
+-- ["- Will refresh Parachute each turn."] = "", -- Continental_supplies
+-- ["- Will refresh portalgun each turn."] = "", -- Continental_supplies
+ ["Will this ever end?"] = "Bu sona erecek mi?",
+-- ["WINNER IS "] = "", -- Mutant
+ ["WINNING TIME: "] = "KAZANMA SÃRESÄ°: ",
+-- ["Wise Oak"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+-- ["With Dense Cloud on the land of shadows, I'm the village's only hope..."] = "", -- A_Classic_Fairytale:journey
+-- ["With the rest of the tribe gone, it was up to "] = "", -- A_Classic_Fairytale:dragon
+-- ["Worry not, for it is a peaceful animal! There is no reason to be afraid..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Wow, what a dream!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Y3K1337"] = "", -- A_Classic_Fairytale:journey, A_Classic_Fairytale:shadow
+-- ["Yay, we won!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Y Chwiliad"] = "", -- A_Classic_Fairytale:dragon
+-- ["Yeah...I think it's a 'he', lol."] = "", -- A_Classic_Fairytale:shadow
+-- ["Yeah, sure! I died. Hillarious!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Yeah, take that!"] = "", -- A_Classic_Fairytale:dragon
+-- ["Yeah? Watcha gonna do? Cry?"] = "", -- A_Classic_Fairytale:journey
+-- ["Yes!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Yes, yeees! You are now ready to enter the real world!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["Yo, dude, we're here, too!"] = "", -- A_Classic_Fairytale:family
+-- ["You are given the chance to turn your life around..."] = "", -- A_Classic_Fairytale:shadow
+-- ["You are playing with our lives here!"] = "", -- A_Classic_Fairytale:enemy
+-- ["! You bastards!"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:united
+-- ["You bear impressive skills, "] = "", -- A_Classic_Fairytale:dragon
+-- ["You can't fire a portal on the blue surface"] = "", -- portal
+-- ["You couldn't possibly believe that after refusing my offer I'd just let you go!"] = "", -- A_Classic_Fairytale:journey
+ ["You'd almost swear the water was rising!"] = "Suyun yükseldiÄine yemin edebilirdin!",
+-- ["You'd better watch your steps..."] = "", -- A_Classic_Fairytale:journey
+-- ["You did not make it in time, try again!"] = "", -- Basic_Training_-_Rope
+-- ["You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."] = "", -- A_Classic_Fairytale:backstab
+-- ["You have "] = "", -- A_Classic_Fairytale:dragon
+-- ["You have been giving us out to the enemy, haven't you!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You have been respawned, at your last checkpoint!"] = "", -- Basic_Training_-_Rope
+-- ["You have been respawned, be more carefull next time!"] = "", -- Basic_Training_-_Rope
+-- ["You have chosen the perfect moment to leave."] = "", -- A_Classic_Fairytale:united
+-- ["You have failed to complete your task, young one!"] = "", -- A_Classic_Fairytale:journey
+-- ["You have failed to save the tribe!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You have finally figured it out!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You have kidnapped our whole tribe!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You have killed an innocent hedgehog!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You have proven yourself worthy to see our most ancient secret!"] = "", -- A_Classic_Fairytale:first_blood
+-- ["You have proven yourselves worthy!"] = "", -- A_Classic_Fairytale:enemy
+ ["You have SCORED!!"] = "VURDUN!",
+-- ["You have to destroy 12 targets in 180 seconds"] = "", -- Basic_Training_-_Cluster_Bomb
+-- ["You have won the game by proving true cooperative skills!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You just appeared out of thin air!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You just committed suicide..."] = "", -- A_Classic_Fairytale:shadow
+-- ["You killed my father, you monster!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You know...taking a stroll."] = "", -- A_Classic_Fairytale:backstab
+-- ["You know what? I don't even regret anything!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You'll see what I mean!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You may only attack from a rope!"] = "", -- WxW
+-- ["You meatbags are pretty slow, you know!"] = "", -- A_Classic_Fairytale:enemy
+-- ["You might want to find a way to instantly kill arriving cannibals!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Young one, you are telling us that they can instantly change location without a shaman?"] = "", -- A_Classic_Fairytale:united
+-- ["You probably know what to do next..."] = "", -- A_Classic_Fairytale:first_blood
+-- ["Your deaths will be avenged, cannibals!"] = "", -- A_Classic_Fairytale:enemy
+-- ["Your death will not be in vain, Dense Cloud!"] = "", -- A_Classic_Fairytale:shadow
+-- ["You're...alive!? But we saw you die!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You're a pathetic liar!"] = "", -- A_Classic_Fairytale:backstab
+-- ["You're funny!"] = "", -- A_Classic_Fairytale:journey
+-- ["You're getting pretty good! |Tip: When you shorten you rope you move faster! |and when you lengthen it you move slower"] = "", -- Basic_Training_-_Rope
+-- ["You're pathetic! You are not worthy of my attention..."] = "", -- A_Classic_Fairytale:shadow
+-- ["You're probably wondering why I bought you back..."] = "", -- A_Classic_Fairytale:backstab
+-- ["You're terrorizing the forest...We won't catch anything like this!"] = "", -- A_Classic_Fairytale:shadow
+-- ["Your hogs must survive!"] = "", -- A_Classic_Fairytale:journey
+-- ["Your movement skills will be evaluated now."] = "", -- A_Classic_Fairytale:first_blood
+ ["You saved"] = "Kurtarılan: ",
+-- ["You've been assaulting us, we have been just defending ourselves!"] = "", -- A_Classic_Fairytale:enemy
+ ["You've failed. Try again."] = "BaÅaramadın. Yeniden dene!",
+ ["You've reached the goal!| |Time: "] = "Hedefe ulaÅtın!| |Süre: ",
+-- ["You will be avenged!"] = "", -- A_Classic_Fairytale:shadow
+-- ["You won't believe what happened to me!"] = "", -- A_Classic_Fairytale:backstab
+-- ["Yuck! I bet they'll keep worshipping her even after I save the village!"] = "", -- A_Classic_Fairytale:family
+-- ["Zealandia"] = "", -- Continental_supplies
+ ["'Zooka Team"] = "Roketatar Takımı",
+-- ["Zork"] = "", -- A_Classic_Fairytale:dragon, A_Classic_Fairytale:family, A_Classic_Fairytale:queen
+ }
diff --git a/share/hedgewars/Data/Locale/tr.txt b/share/hedgewars/Data/Locale/tr.txt
old mode 100644
new mode 100755
index 60034fe..c68fc42
--- a/share/hedgewars/Data/Locale/tr.txt
+++ b/share/hedgewars/Data/Locale/tr.txt
@@ -2,7 +2,7 @@
00:00=El Bombası
00:01=Parça Tesirli Bomba
-00:02=Bazuka
+00:02=Roketatar
00:03=UFO
00:04=Pompalı Tüfek
00:05=Kompresör
@@ -12,7 +12,7 @@
00:09=Ãöl Kartalı
00:10=Dinamit
00:11=Beyzbol Sopası
-00:12=Shoryuken
+00:12=Yükselen Ejderha
00:13=san
00:14=ParaÅüt
00:15=Hava Saldırısı
@@ -37,34 +37,501 @@
00:34=Ãlümsüzlük
00:35=ArttırılmıŠZaman
00:36=Lazer GörüÅü
-00:37=Vampirism
-00:38=Sniper Rifle
-00:39=Flying Saucer
-00:40=Molotov Cocktail
+00:37=VampirleÅme
+00:38=Keskin NiÅansı TüfeÄi
+00:39=Uçan Daire
+00:40=Molotof Kokteyli
+00:41=KuÅçuk
+00:42=TaÅınabilir Portal Aygıtı
+00:43=Piano VuruÅu
+00:44=Eski Limburger
+00:45=Sinüs Tabancası (beta)
+00:46=Alev Püskürtücü
+00:47=YapıÅkan Mayın
+00:48=Ãekiç
+00:49=Yeniden DoÄuÅ
+00:50=Matkap VuruÅu
+00:51=Ãamur Topu
+00:52=Silah Seçilmedi
+00:53=Zaman Kutusu
+; 00:54=Yapı
+00:54=Zemin Spreyi
+00:55=Dondurucu
+00:56=Satır
01:00=SavaÅ baÅlasın!
01:01=Beraberlik
01:02=%1 kazandı!
-01:03=Bölüm %1%
+01:03=Bölüm %%1
01:04=Duraklatıldı
01:05=Ãıkılsın mı (Y/Esc)?
01:06=Ani ölüm!
-01:07=%1 Remaining
-01:08=Fuel
+01:07=%1 Kaldı
+01:08=Yakıt
+01:09=EÅzamanlanıyor...
+01:10=Bu yardımcıyı kullanmak sıranı bitirmeyecek!
+01:11=Bu silah veya yardımcı henüz kullanılamıyor!
+01:12=Ani Ãlüm için son tur!
+01:13=Ani Ãlüme %1 tur kaldı!
+01:14=Hazırlan, %1!
+01:15=Az
+01:16=DüÅük
+01:17=Normal
+01:18=Yüksek
+01:19=En Yüksek
+01:20=%1 Sekmesi
+01:21=Ses Kapalı
+
; Event messages
; Hog (%1) died
-02:00=%1 has kicked the bucket!
-02:00=%1 has seen the light!
-02:00=%1 never saw that comming!
+02:00=%1 sepeti boyladı!
+02:00=%1 ıÅıÄı gördü!
+02:00=%1 bunun geldiÄini farketmemiÅti!
+02:00=%1 baŠbaŠyapıyor!
+02:00=%1 daha iyi bir yere gitti!
+02:00=%1 yapan ile buluÅuyor!
+02:00=%1 daha fazla dayanamıyor!
+02:00=%1 görevini yaptı!
+02:00=%1 mükemmel fedakarlık yapıyor!
+02:00=%1 havan sarımını ateÅliyor!
+02:00=%1 aÄaç olup ayrılıyor!
+02:00=%1 zaman aÅımına uÄradı!
+02:00=%1 dünya barıÅı istiyor!
+02:00=%1 sevgiyle hatırlanacak!
+02:00=%1 damar geniÅlemesi baÅladı!
+02:00=%1 arkasında gözü yaÅlı eÅ ve çocuk bırakıyor
+02:00=%1 son roketatarını fırlattı
+02:00=%1 son el bombasını fırlattı
+02:00=%1 son pastasını piÅirdi
+02:00=%1 son halatında sallandı
+02:00=%1 son hava saldırısını çaÄırdı
+02:00=%1 son tüfeÄini ateÅledi
+02:00=%1 son karpuzunu attı
+02:00=%1 son çizimini yaptı
+02:00=%1 bir atıÅı çok kez aldı
+02:00=%1 gerçekten bir saÄlık sandıÄı kullanabilirdi
+02:00=%1 daha iyi bir oyun oynamak için gitti
+02:00=%1 hayata kaçtı
+02:00=%1 baÅarısız oldu
+02:00=Zavallı %1...
+02:00=%1 wormux'u tercih ediyor
+02:00=%1 yüzüyle vuruÅları engelliyordu
+02:00=%1 bana göre bir kahraman...hımmm...kirpi
+02:00=%1 kendi yerini Valhalla'da buldu
+02:00=%1 binayı terketti
+02:00=%1 dinazorların yanına gidiyor
+02:00=%1 kirpileri nesillerini tüketmeye bir adım daha yaklaÅtırdı
+02:00=%1 gözlerimi yaÅarttı
+02:00=%1 eskiden bir kirpiydi
+02:00=%1 papatya ekiyor
+02:00=%1 artık yok
+02:00=%1 için bir veda yapalım
+02:00=%1 ümidi kesildi
+02:00=%1 son perdeyi kapattı
+02:00=Varsa iç bir tane %1
+02:00=%1 Anlık YoÄun Varlık Sorunu çekiyor
+02:00=%1 hayata veda etti
+02:00=%1 kaya gibi öldü
+02:00=%1 artık yok
+02:00=%1 son kullanma tarihi doldu
+02:00=YaÅamdan yoksun, %1 huzur içinde yatsın
+02:00=%1 görünmezler korosuna katıldı
+02:00=HoÅça kal %1, seni iyi bilirdik!
+02:00=%1 vurulmaya çok az dayanabildi
+02:00=%1 ek bir can kullanabilirdi
+02:00=Evde bir doktor var mı?
+
; Hog (%1) drowned
-02:01=%1 plays submarine!
-02:01=%1 mimics the Titanic!
-02:01=%1 swims like a stone!
-; Match starts
-02:02=Let's fight!
-02:02=Armed and ready!
+02:01=%1 deniz altı oynuyor!
+02:01=%1 Titanik'i taklit ediyor!
+02:01=%1 kaya gibi yüzüyor!
+02:01=%1 tuÄla gibi havada kaldı!
+02:01=%1 derin dibi kontrol ediyor
+02:01=%1 bir Åey diyor: "gulu gulu gulu"
+02:01=%1 atlama yapıyor
+02:01=%1 kolluklarını unuttu
+02:01=%1 gerçekten yüzme dersi almalıydı
+02:01=%1 sörf tahtasını evde bırakmıÅ
+02:01=%1 yıkanıyor
+02:01=%1 ıslak bir kirpi
+02:01=%1 can yeleÄini getirmeyi unuttu
+02:01=%1 bıcı bıcıya gidiyor
+02:01=%1 balıklarla yüzüyor
+02:01=%1 oyundaki su fiziÄinin berbat olduÄunu düÅünüyor
+02:01=%1 susamıŠgörünüyor
+02:01=Deniz seni istiyor %1
+02:01=%1 denizde kayboldu
+02:01=%1 dalıŠtakımını getirmeliydi
+02:01=%1 denizde gömülüyor
+02:01=%1 batıyor gibi hissediyor
+02:01=%1 sırtüstü yüzme denemesi yapıyor
+02:01=%1 Titanik'i aramaya gidiyor
+02:01=%1 bu sefer güldürmedi
+02:01=%1 Nemo'yu arıyor
+02:01=%1 su alıyor
+02:01=AÅaÄıda kaç kirpi var bir bilsen
+02:01=%1 okyanus seviyesini yükseltiyor
+02:01=%1 orduya katılmamıÅtı
+02:01=%1 ölü balık taklidi yapıyor
+02:01=En azından tuvalette boÄulmadın, %1
+02:01=Sonic yüzemezdi %1 de öyle
+02:01=%1 Ecco the dolphin oyunu oynamak istiyor
+02:01=%1 Akvaryum ziyaretine gitti
+02:01=%1 kayıp Åehir Atlantis'i buldu
+02:01=%1 Bioshock 3'te baŠrolü oynamaya gidiyor
+02:01=Patilerin biraz çalıÅabilirdi, %1
+02:01=%1 bir jet ski getirmeliydi
+02:01=%1 su sporlarını sevmiyor
+02:01=%1 sonsuza kadar baloncuk çıkarıyor
+02:01=%1 bir sala ihtiyaç duyuyor
+02:01=%1 tuzlu suyun cilt için iyi geldiÄini düÅünüyor
+02:01=%1 yarasına tuz basıyor
+02:01=%1 tahtada yürüdü
+02:01=%1 bir banyoya sahip
+02:01=%1 artık ıslak ıslak ıslak
+02:01=%1 tüylerini ıslattı
+02:01=O, %1 için bir Davy Jones dolabı
+
+; Round starts
+02:02=SavaÅ baÅlasın!
+02:02=Hazır ve nazır!
+02:02=Haykırmaya hazır ol!
+02:02=Hadi baÅlayalım!
+02:02=Artık parti baÅlasın
+02:02=Son kalan kirpi kazansın
+02:02=Hadi gidelim!
+02:02=BaÅlayalım!
+02:02=Bastır!
+02:02=BaÅlıyor...
+02:02=Bu büyük Åeyin bir baÅlangıcı
+02:02=Hedgewars'a HoÅ Geldin
+02:02=Sınır hattına hoŠgeldin
+02:02=DüÅmanını ez!
+02:02=En iyi kirpi kazansın
+02:02=Zafer ya da ölüm
+02:02=Zafer ganimettir
+02:02=Kaybetmek bir seçenek deÄil
+02:02=AÄla tahribat! Kirpi savaÅı baÅlasın!
+02:02=Hedgewars, Hedgewars.org tarafından saÄlandı
+02:02=GL HF
+02:02=Åansın varmıŠTiyuri'ye karÅı oynamıyorsun
+02:02=Åansın varmıŠC0Rr'e karÅı oynamıyorsunun
+02:02=Åansın varmıŠNemo'ya karÅı oynamıyorsun
+02:02=Åansın varmıŠSmaxx'e karÅı oynamıyorsun
+02:02=Åansın varmıŠJessor'e karÅı oynamıyorsun
+02:02=Her Åeyi ortaya koy!
+02:02=Kaybeden bulaÅıkları yıkar!
+02:02=Binyıl dövüÅü baÅlasın
+02:02=Yüzyıl dövüÅü baÅlasın
+02:02=Onyıl dövüÅü baÅlasın
+02:02=Yılın dövüÅü baÅlasın
+02:02=Ayın dövüÅü baÅlasın
+02:02=Haftanın dövüÅü baÅlasın
+02:02=Günün dövüÅü baÅlasın
+02:02=Saatin dövüÅü baÅlasın
+02:02=Elinden geleni yap!
+02:02=DüÅmanı yok et!
+02:02=Ä°yi Åanslar
+02:02=Ä°yi eÄlenceler
+02:02=Ä°yi dövüÅ
+02:02=Pis dövüÅ
+02:02=Onura dövüÅ
+02:02=Pes etme
+02:02=Asla teslim olma
+02:02=Yen ve parçala!
+02:02=Parçalama festivali baÅlasın!
+02:02=Umarım mücadeleye hazırsın!
+02:02=Hadi Hadi Hadi!
+02:02=Hedgehogs devam!
+02:02=Göster onlara!
+02:02=Asla korkma!
+02:02=Cesur ol ve fethet
+
+; Round ends (win; unused atm)
+02:03=...
+
+; Round ends (draw; unused atm)
+02:04=...
+
+; New health crate
+02:05=Yardım geliyor!
+02:05=İlkyardım!
+02:05=Göklerden ilkyardım!
+02:05=Size bir saÄlık paketi
+02:05=Ä°yi saÄlık... kutu biçiminde!
+02:05=Doktor çaÄırıyor
+02:05=Taze yara bantları!
+02:05=Bu daha iyi hissetmeni saÄlayacak
+02:05=Büyük iksir! Aaa, yanlıŠoyun
+02:05=Bir beni-al!
+02:05=Yakala
+02:05=SaÄlıklı bir atıÅtırmalık
+02:05=Acıya tedavi
+02:05=Kullanım dozu: bulabildiÄin kadar çok!
+02:05=Acele posta
+02:05=Emanetler!
+
+; New ammo crate
+02:06=Daha çok silah!
+02:06=Destek geliyor!
+02:06=Kilitlen ve bırak!
+02:06=Acaba içinde hangi silah var?
+02:06=Tedarikler!
+02:06=İçinde ne olabilir?
+02:06=Hedgewars'ta yılbaÅı erken geliyor
+02:06=Bir hediye!
+02:06=Ãzel posta!
+02:06=Bunu gümrükten geçirmek bir kabustu
+02:06=Cennetten yok edici oyuncaklar
+02:06=Uyarı! Uçucu İçerik
+02:06=Kaldır veya havaya uçur, seçim senin
+02:06=EÅyalar!
+02:06=Hım hım Cephane
+02:06=Yok edici güç kutusu
+02:06=Uçak postası!
+02:06=Bu kutuda ne varsa pizza olmadıÄı kesin
+02:06=Al Åunu!
+02:06=Silah bırakılıyor
+02:06=DüÅmanın bunu almasın!
+02:06=Yeni parlak oyuncaklar!
+02:06=Gizemli bir kutu!
+
+; New utility crate
+02:07=Araç zamanı!
+02:07=Bu iÅe yarayabilir...
+02:07=Araçlar!
+02:07=Bu kutudan yararlan
+02:07=Dikkat et
+02:07=Daha fazla alet!
+02:07=Senin için alet!
+02:07=Bu güzel olmalı!
+02:07=Zekice kullan
+02:07=Off bu kutu da aÄırmıÅ
+02:07=Buna ihtiyacın olabilir
+
+; Hog (%1) skips his turn
+02:08=%1 çoook sıkıcı...
+02:08=%1 rahatsız olamazdı
+02:08=%1 tembel bir kirpi
+02:08=%1 düÅüncesiz
+02:08=%1 pes etti
+02:08=Ertelersen kaybedersin, %1
+02:08=%1 utanmaksızın geçiyor
+02:08=%1 gerçekten tembel
+02:08=%1 daha fazla motivasyona ihtiyacın var
+02:08=%1 bir barıÅcı
+02:08=%1 bir mola alıyor
+02:08=%1 dinleniyor
+02:08=%1 moral bozmuyor
+02:08=%1 yeteneklerine inanmıyor
+02:08=%1 hiçbir Åey yapmamaya karar veriyor
+02:08=%1 düÅmanın kendisini yok etmesine izin veriyor
+02:08=%1 partilerde berbat olur
+02:08=%1 saklanıyor
+02:08=%1 bu fırsatı deÄerlendirmek istemedi
+02:08=%1 yapabileceÄi en iyi Åeyin...hiçbir Åey olduÄuna karar verdi
+02:08=%1 koca bir korkak
+02:08=Gıt gıt gıdak, %1 bir tavuk
+02:08=%1 küçük bir sarı arıyor
+02:08=%1 bir ürkek!
+02:08=%1 ani ölümü bekliyor
+02:08=%1 dövüŠistemiyor
+02:08=%1 hayattaki amacını tekrar düÅünüyor
+02:08=%1 hiçbir zaman iyi bir atıŠyapamadı zaten
+02:08=%1 orduya da isteyerek katılmamıÅtı
+02:08=Zamanımızı boÅa harcamayı kes, %1
+02:08=Beni hayal kırıklıÄına uÄrattın, %1
+02:08=Hadi ama, bundan daha iyisini yapabilirsin %1
+02:08=%1 kalbi kırıldı
+02:08=Görünüyor ki %1 daha iyi yapacak Åeylere sahip
+02:08=%1 korkak bir ölü
+02:08=%1 uyuya kaldı
+
+; Hog (%1) hurts himself only
+02:09=%1 atıŠçalıÅmalı!
+02:09=%1 kendinden nefret ediyor gibi görünüyor
+02:09=%1 yanlıŠtarafta duruyor!
+02:09=%1 emo gibi yapıyor
+02:09=%1 silahını yanlıŠyönde tutuyordu
+02:09=%1 sanki biraz sadist
+02:09=%1 bir mazoÅist
+02:09=%1 kendini koruma iç güdüsüne sahip deÄil
+02:09=%1 batırdı
+02:09=%1 mahvetti
+02:09=Kötü bir atıÅtı, %1
+02:09=%1 tehlikeli silahlarla çok dikkatsiz
+02:09=%1 kariyerini deÄiÅtirmeyi düÅünmeli
+02:09=Dünyadaki. En berbat. AtıÅtı!
+02:09=Yo yo yo %1, DÃÅMANA ateÅ etmelisin!
+02:09=%1 sadece düÅmanı yok etmeli
+02:09=%1 intihara bir adım daha yaklaÅıyor
+02:09=%1 düÅmana yardım ediyor
+02:09=Bu aptalcaydı %1
+02:09=%1 "acı yok, kazanmak yok" deyimiyle yaÅıyor
+02:09=%1, sanki kafan karıÅık
+02:09=%1 yanlıÅlıkla kendine zarar veriyor
+02:09=%1, kendini utandırmakta üstüne yok
+02:09=%1 bir saloz!
+02:09=Sakarsın %1
+02:09=%1 düÅmana yeteneklerini gösteriyor
+02:09=%1 her zaman mükemmel olması beklenemez
+02:09=Sorun deÄil %1, hiç kimse mükemmel deÄildir
+02:09=%1 bunu kesinlikle bilerek yaptı
+02:09=Yapmazsan kimseye söylemem, %1
+02:09=Ne utanç verici ama!
+02:09=Eminim kimse bunu görmedi %1
+02:09=%1 kendi alan kılavuzunu gözden geçirmeli
+02:09=%1 silahında sorun vardı
+
; Hog shot an home run (using the bat and another hog)
-02:10=Home Run!
-02:10=A bird, a plane, ...
-02:10=That one is out!
+02:10=Tur VuruÅu!
+02:10=Bu bir kuÅ. Hayır uçak, ...
+02:10=Bu çıkar!
+
+; Hog (%1) has to leave (team is gone)
+02:11=%1 uyumaya gitmeli!
+02:11=%1 oynamak için çok meÅgul görünüyor
+02:11=AteÅle onu, Scotty!
+02:11=%1 gitmeli
+
+; Weapon Categories
+03:00=Zamanlı El Bombası
+03:01=Zamanlı El Bombası
+03:02=Balistik Silah
+03:03=Kılavuzlu Silah
+03:04=Tabanca (çok atıÅlı)
+03:05=Kazma Aracı
+03:06=Eylem
+03:07=TaÅıma Yardımcısı
+03:08=Yakınlık Bombası
+03:09=Tabanca (çok atıÅlı)
+03:10=BUM!
+03:11=Bum!
+03:12=DövüŠSanatları
+03:13=KULLANILMIYOR
+03:14=TaÅıma Yardımcısı
+03:15=Hava Saldırısı
+03:16=Hava Saldırısı
+03:17=Kazma Aracı
+03:18=Yardımcı
+03:19=TaÅıma Yardımcısı
+03:20=Eylem
+03:21=Balistik Silah
+03:22=Bana Indiana de!
+03:23=(Gerçekten) DövüŠSanatları
+03:24=Pasta yalan DEÄÄ°L!
+03:25=Kostüm Seti
+03:26=Meyveli El Bombası
+03:27=AteÅli El Bombası
+03:28=Balistik Silah
+03:29=Balistik Silah
+03:30=Hava Saldırısı
+03:31=Uzaktan Kumandalı Bomba
+03:32=Geçici Etki
+03:33=Geçici Etki
+03:34=Geçici Etki
+03:35=Geçici Etki
+03:36=Geçici Etki
+03:37=Geçici Etki
+03:38=Tabanca (çok atıÅlı)
+03:39=TaÅıma Yardımcısı
+03:40=Yakıcı El Bombası
+03:41=Cıvıldamaların büyük fanı
+03:42=Burada bir Åey demek istiyorum...
+; the misspelled "Beethoven" is intentional (-> to beat)
+03:43=Beathoven'ın ölümcül sonatasını gösteriyor
+03:44=Son kullanma tarihi: 1923
+03:45=Bilimin gücü
+03:46=Sıcak Sıcak Sıcak!
+03:47=Bunları kullanıÅlı bir yere yapıÅtır!
+03:48=Ãekiç zamanı!
+03:49=Tahmin ettiÄin Åeyi yapıyor
+03:50=Köstebek fanı
+03:51=Zeminde bulunan
+03:52=KULLANILMIYOR
+03:53=Tür 40
+03:54=Bir Åey inÅa et
+03:55=Yardımcı
+
+; Weapon Descriptions (use | as line breaks)
+04:00=DüÅmanlarına basit el bombası ile saldır.|Zamanlayıcı sıfır olduÄunda patlayacak.|1-5: Bomba süresini ayarla|Saldır: Daha fazla güçte atmak için basılı tut
+04:01=DüÄmanlarına parça tesirli bomba ile saldır.|Zamanlayıcı sıfır olduÄunda daha küçük|bombalara dönüÅür.|1-5: Bomba süresini ayarla|Saldır: Daha fazla güçte atmak için basılı tut
+04:02=DüÅmanlarına rüzgardan etkilenebilecek|balistik mermi kullanarak saldır.|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:03=Seçili hedefe kilitlenecek patlayıcı bir arı|fırlat. KesinliÄini arttırmak için tam güçle|fırlatma.|Ä°mleç: Hedef seç|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:04=DüÅmanına iki atıÅla tüfek kullanarak saldır.|Yayılması sayesinde rakibine zarar vermen için|keskin vuruÅ yapman gerekmiyor.|Saldır: AteÅ (çok kez)
+04:05=Yer altına hareket et! Ãekici kullanarak|zemine bir delik kaz ve diÄer yerlere ulaÅ.|Saldır: Kazmayı baÅlat ve durdur
+04:06=Sıkıldın mı? Saldıracak yer mi yok? Cephane mi |kurtarmak istiyorsun? Problem yok!|Pas geç korkak!|Saldır: DövüÅmeden turu atla
+04:07=Ä°p kullanarak zamanlı atıÅlarla uzun mesafelere|baÄlan. DiÄer kirpilere doÄru kaymak için|momentumunu kullan veya üzerlerine el bombası|ve diÄer silahları at.|Saldır: At ve ipi bırak|Uzun Atlama: El bombası veya benzer silahları|bırak
+04:08=Küçük geçiÅlere veya ayaklarının yanına mayın|bırakarak düÅmanı uzaklaÅtır. Kendin için|tetiklemediÄinden emin ol!|Saldır: AyaÄının yanına mayın bırak
+04:09=Hedefinden emin deÄil misin? Tabanca|kullanarak dört atıÅa kadar düÅmanı vur.|Saldır: AteÅ (çok kez)
+04:10=Zor kullanım her zaman bir seçenek. Bu klasik|patlayıcıyı düÅmanının yanına koy ve çekil.|Saldır: AyaÄının yanına dinamit bırak
+04:11=DüÅman kirpilerden üzerlerine sopa ile vurarak|uzaklara veya suya düÅür. Veya|arkadaÅlarına birkaç mayın fırlatmak nasıl olurdu?|Saldır: Ãnündeki herÅeye vurarak fırlat
+04:12=YakınlaÅ ve neredeyse bu ölümcül dövüŠsanatı|teknik gücünü ortaya çıkar.|Saldır: MuhteÅem Yükselen Ejderha yap.
+04:13=KULLANILMIYOR
+04:14=Yükseklikten mi korkuyorsun? O zaman bir paraÅüt|kullan.|UzaÄa düÅerken açılacak ve kirpinin düÅme zararı|almasını engelleyecek|Saldır: ParaÅütü aç|Uzun Atlama: El bombası veya benzeri silahlar bırak
+04:15=Bombalayıcı kulanarak uçakla düÅmanlarına saldır.|Sol/SaÄ: Saldırı yönünü belirle|Ä°mleç: Hedef bölgeyi seç
+04:16=Hedef alana çeÅitli mayın atacak bir uçak çaÄır.|Sol/SaÄ: Saldırı yönünü belirle|Ä°mleç: Hedef bölgeyi seç
+04:17=Korunak mı gerekiyor? Seni kaplayabilecek bir|tünel için kaynak makinesi kullan|Saldır: Kazmayı baÅlat/durdur
+04:18=Ek koruma mı gerekiyor? Yoksa geçilemez|zemini mi geçmek istiyorsun? Ä°stediÄin kadar|merdiven koy|Sol/SaÄ: YerleÅtilecek merdiveni seç|Ä°mleç: Geçerli yere merdiven yerleÅtir
+04:19=DoÄru yerde kullanıldıÄında ıÅınlanma tüm|silahlardan daha güçlü olabilir. Kirpileri|saniyeler içerisinde tehlikeli durumlardan|kurtarır.|Ä°mleç: Hedef bölgeyi seç
+04:20=Geçerli turu baÅka bir kirpiyle oynamanı|saÄlar.|Saldır: Kirpi deÄiÅtirmeyi etkinleÅtir
+04:21=El bombasına benzer bir füze fırlatır ve|çarpma sonrası çok sayıda bombaya dönüÅür.|Saldır: Tam güçte fırlat
+04:22=Sadece Indiana Jones için deÄil! Kamçı|çoÄu durumda çok kullanıÅlı bir silahtır.|Ãzellikle birini yamaçtan uçurmak için.|Saldır: Ãnündeki her Åeye vur
+04:23=EÄer kaybedecek hiçbir Åeyin yoksa, bu|kullanıÅlı olabilir. Kirpini özel bir yönde|baÅlatarak feda et ve önündeki her Åeye|zarar verip sonunda patlamasını saÄla.|Saldır: Åiddetli ve ölümcül bir saldırı baÅlat
+04:24=Mutlu Yıllar! Bu keki çalıÅtır, düÅmanının yanına|yürümesine izin ver ve patlayan bir parti yapmalarını|saÄla. Kek neredeyse tüm zeminlerden geçebilir|fakat yolun ortasında patlayabilir.|Saldır: Keki baÅlat ve durdurup patlat
+04:25=Bu kiti kullanarak düÅmanlarının kirpine doÄru zıplamasını|saÄla (ve bir boÅluk veya deliÄe).|Saldır: Kiti kullan ve diÄer kirpiyi etkile
+04:26=Bu sulu karpuzu düÅmanına at. Zaman dolduÄunda|çok sayıda patlayıcı parçaya ayrılacaktır.|1-5: Karpuz zaanlayıcısını ayarla.|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:27=Bu zalim patlayıcıyı kullanarak rakibini cehennem|ateÅ yaÄmuruna tut. Küçük ateÅler daha|uzun süreceÄinden yakın olmamaya dikkat et.|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:28=Bu roketi fırlattıktan kısa süre sonra katı zemini|kazmaya baÅlayacak ve tekrar yüzeye çıktıÄında|veya süresi dolduÄunda patlayacak.|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:29=Bu küçük çocuklar için deÄil! Top tabancası patlayıcı|dolu tonlarca küçük renkli top fırlatır.|Saldır: Tam güçte atıŠyap|Yukarı/AÅaÄı: NiÅan al
+04:30=MuhteÅem napalm atıÅı için bir uçak çaÄır.|DoÄru niÅan ile bu saldırı zeminin büyük bölümünü|yok edebilir ve tabii ki Åansız kirpileri de.|Sol/SaÄ: Saldırı yönünü belirle|Ä°mleç: Hedef bölgeyi seç
+04:31=RC uçaÄı sandıkları toplamak veya uzaktaki kirpilere|saldırmak için kullanıÅlı bir silahtır.|DoÄrudan düÅmanlara çarp veya ilk olarak bomba bırak.|Saldır: UçaÄı baÅlat veya bomba bırak|Uzun Zıplama: Valkrie'lerin savaÅa gelmelerini saÄla|Sol/SaÄ: UçaÄı kontrol et
+04:32=DüÅük yer çekimi diÄer tüm diyetlerden daha etkilidir!|Daha yukarı ve büyük uzaklıklara zıpla|veya düÅmanının daha uzaÄa uçmasını saÄla|Saldır: EtkinleÅtir
+04:33=Bazen daha fazla zarar vermek için bu küçük ek güce|ihtiyacın olabilir.|Saldır: EtkinleÅtir
+04:34=Bana dokunamazsın!|Saldır: EtkinleÅtir
+04:35=Bazen zaman su gibi akıp geçiyor. Saldırını bitirmek|için ek saniye al.|Saldır: EtkinleÅtir
+04:36=Aslında bazen hedef tutturmada çok kötüsün. Modern|teknoloji kullanarak biraz yardım al.|Saldır: EtkinleÅtir
+04:37=Gün ıÅıÄından korkma. Sadece bir tur sürecek fakat|DiÄer kirpilere verdiÄin zararı emmeni saÄlayacak.|Saldır: EtkinleÅtir
+04:38=Keskin niÅancı tüfeÄi birliÄindeki en zarar verici silah|olabilir ancak yakın mesafede etkisi azdır.|Hasar, hedef uzak oldukça daha çok artar.|Saldır: AteÅ et (iki kez)
+04:39=Haritanın diÄer yerlerine uçan daire ile uç.|Bu uzmanlaÅmak için zaman gerektirir ve|alıÅana kadar savaÅ alanında her yere|götürebilir.|Saldır: EtkinleÅtir|Yukarı/Sol/SaÄ: Bir yöne güç uygula|Uzun Atlama: El bombası veya|benzer silahlar bırak
+04:40=Set some ground on fire using this bottle filled|with (soon to be) burning liquid.|Saldır: Daha fazla güçle atıŠiçin basılı tut
+04:41=DoÄa uçan dairenin üzerinde de olabilir|KuÅçuk kirpini taÅıyabilir ve|düÅmanlarına yumurta bırakabilir!|Hızlı ol, çünkü KuÅçuÄu kullanmak |zamanını tüketir!|Saldır: EtkinleÅtir ve yumurta bırak|Yukarı/Sol/SaÄ: Bir yöne kanat çırp
+04:42=Bu taÅınabilir portal aygıtı seni, düÅmanlarını|veya bir silahını zemindeki iki nokta arasında|hemen taÅıma yeteneÄine|sahip.|Zekice kullan ve maceran bir... BAÅARIYA|DÃNÃÅSÃN!|Saldır: Bir portal ateÅ et|DeÄiÅtir: Portal renkleri arasında geçiÅ yap
+04:43=Müzikal kariyerine baÅarılı bir patlamayla baÅla!|Cennetten bir piyano düÅür, fakat dikkat et...|birinin çalması gerekiyor ve|bu senin hayatın olmasın.|Ä°mleç: Hedef bölgeyi seç|F1-F9: Piyanoyu çal
+04:44=Bu sadece bir peynir deÄil, bir biyolojik silah!|Zamanlayıcı sıfır olduÄunda koca bir hasar|vermenin yanında, kokuya dokunan Åanssız|herkesi de zehirleyecek!|1-5: Bombanın zamanını ayarla|Saldır: Daha fazla güç ile fırlatmak için tut
+04:45=Sonunda fizik dersleri iÅe yaradı.|DüÅmanlarına kocaman bir sinüs dalgası at.|Dikkatli ol, bu silah oldukça büyük bir vuruÅa sahip|(Bu silah bitmedi)|Saldır: AteÅ et
+04:46=DüÅmanlarını sızan akıÅkan alevle kapla|Kalp ısıtıcı!|Saldır: EtkinleÅtir|Yukarı/AÅaÄı: Hedef almaya devam et|Sol/SaÄ: FıÅkırtma gücünü deÄiÅtir
+04:47=Dikenli, sinsi, yapıÅkan mayınlarla çifte zevk!|Zincirleme reaksiyon ayarla veya kendini koru (veya ikisi de!)|Saldır: Daha fazla güçle atıŠiçin basılı tut (iki kez)
+04:48=Niçin köstebeklere kötü davranılsın?|Bir kirpi de zevk için dövülebilir! Bu|çekicin iyi bir yanı kirpinin canının |üçte birini alması ve yer altına sokması.|Saldır: EtkinleÅtir
+04:49=ArkadaÅlarını yeniden canlandır!|Fakat dikkatli ol, bu ayrıca düÅmanlarını da|canlandırır.|Saldır: YavaÅça canlandırmak için saldırma|düÄmesini basılı tut|Yukarı: Canlandırmayı hızlandır
+04:50=Biri altta mı saklanıyor?|Matkap saldırısı ile kaz!|Zamanlayıcı ne kadar kazılacaÄını denetler.
+04:51=Bir çamur topu fırlatarak ücretsiz bir atıŠkap.|Biraz kokar ancak kirpileri geri sektirir.
+04:52=KULLANILMIYOR
+04:53=ArkadaÅlarını savaÅta yalnız bırakarak|zaman ve uzaya seyahat et.|Herhangi bir an, Ani Ãlüm veya tümü|ölmüÅse geri gelmeye hazır ol.|Yadsıma: Ani Ãlüm kipinde, tek isen veya|Kralsan çalıÅmaz.
+04:54=TAM DEÄÄ°L
+04:55=YapıÅkan tanecikler püskürt.|Köprü yap, düÅmanı göm, tünelleri kapat.|Dikkatli ol sana gelmesin!
+
+; Game goal strings
+05:00=Oyun Kipleri
+05:01=AÅaÄıdaki kurallar uygulanır
+05:02=Kaleler: Kaleni savun; düÅmanlarını alt et!
+05:03=DüÅük Yer Ãekimi: Adımına dikkat et
+05:04=Dayanıklılık: Kirpiler (neredeyse) zarar görmezler
+05:05=VampirleÅme: Verilen hasar kirpileri iyileÅtirir
+05:06=Karma: Verilen hasar kirpilere zarar verir
+05:07=Kralı Koru: Kralın ölmesine izin verme!|Kralı YerleÅtir: Kralın için korunaklı bir baÅlangıç noktası seç
+05:08=Kirpileri YerleÅtir: Kirpilerini oyun baÅlamadan önce yerleÅtir
+05:09=AÄır Sınıf: Kirpiler hareket etmek için yer deÄiÅtiremezler
+05:10=Yıkılmaz Zemin: ÃoÄu silah zemine zarar veremez
+05:11=PaylaÅılan Cephane: Aynı renkteki tüm takımlar cephaneyi paylaÅır
+05:12=Mayın Zamanlayıcı: Mayınlar %1 saniye sonra patlayacak
+05:13=Mayın Zamanlayıcı: Mayınlar hemen patlayacak
+05:14=Mayın Zamanlayıcı: Mayınlar 0 - 5 saniye içinde patlayacak
+05:15=Hasar DeÄiÅtirici: Tüm silahlar %%1 hasar verecek
+05:16=Tur sonunda tüm kirpilerin saÄlıÄı sıfırlanacak
+05:17=Yapay zeka kirpileri öldükten sonra yeniden doÄar
+05:18=Sınırsız Saldırı
+05:19=Silahlar her tur sonunda sıfırlanır
+05:20=Silahlar kirpiler arasında paylaÅılmaz
+05:21=Takımları Etiketle: Klandaki takımlar baÅarılı turlar alır|PaylaÅılan Zaman: Klandaki takımlar tur zamanını paylaÅırlar
diff --git a/share/hedgewars/Data/Locale/uk.lua b/share/hedgewars/Data/Locale/uk.lua
index 2cff31b..844cb12 100644
--- a/share/hedgewars/Data/Locale/uk.lua
+++ b/share/hedgewars/Data/Locale/uk.lua
@@ -208,7 +208,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "ÐайÑвидÑа паÑÑÑÑ: ",
["Feeble Resistance"] = "ÐалÑгÑÐ´Ð½Ñ ÐовÑÑанÑÑ",
@@ -287,7 +287,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
[" Hapless Hogs left!"] = " ÐеÑаÑниÑ
ÐжакÑв лиÑилоÑÑ!",
["Hapless Hogs"] = "ÐеÑаÑÐ½Ñ Ðжаки",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -330,7 +331,7 @@ locale = {
["Hmmm..."] = "Хмм...",
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "УÑааа!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -364,7 +365,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -563,11 +564,12 @@ locale = {
["Pathetic Resistance"] = "ÐалÑгÑдний ÐпÑÑ", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
["Per-Hog Ammo"] = "ÐоÑпÑипаÑи на Ñжака",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
- ["Place more waypoints using [ENTER]"] = "РозмÑÑÑÑÑÑ Ð±ÑлÑÑе ÑоÑок ÑлÑÑ
Ñ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ [Enter]",
+
["Place more waypoints using the 'Air Attack' weapon."] = "РозмÑÑÑÑÑÑ Ð±ÑлÑÑе ÑоÑок ÑлÑÑ
Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑавÑи збÑÐ¾Ñ 'ÐовÑÑÑÑна ÐÑака'.",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -818,7 +820,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
["User Challenge"] = "ÐÑÐµÐ»Ñ Ð¼Ñж коÑиÑÑÑваÑами",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/uk.txt b/share/hedgewars/Data/Locale/uk.txt
index a0be440..5948eac 100644
--- a/share/hedgewars/Data/Locale/uk.txt
+++ b/share/hedgewars/Data/Locale/uk.txt
@@ -54,8 +54,8 @@
00:51=ÐÑÑдка багна
00:52=ÐбÑÐ¾Ñ Ð½Ðµ вибÑана
00:53=ÐÑдка ЧаÑÑ
-00:54=СÑÑÑкÑÑÑа
-00:55=ÐемлÑний СпÑей
+; 00:54=СÑÑÑкÑÑÑа
+00:54=ÐемлÑний СпÑей
01:00=ÐпеÑед до пеÑемоги!
01:01=ÐÑÑиÑ
@@ -110,7 +110,7 @@
02:01=%1 забÑв надÑÑи ÑÑÑÑвалÑний жилеÑ
02:01=%1 ÑпиÑÑ ÑеÑед Ñиб
02:01=%1 Ñ
оÑе пиÑи
-02:01=%1 загÑбивÑÑ Ð² моÑÑ
+02:01=%1 загÑбивÑÑ Ð² моÑÑ
02:01=%1 забÑв надÑÑи акваланг
02:01=%1 поÑ
ований Ñ Ð¼Ð¾ÑÑ
02:01=%1 пÑобÑÑ Ð¿Ð»Ð°Ð²Ð°Ñи на ÑпинÑ
@@ -286,8 +286,8 @@
03:51=Ðнайдено на землÑ
03:52=UNUSED
03:53=Тип 40
-03:54=ÐбÑдÑй ÑоÑÑ
-03:55=УÑилÑÑа
+;03:54=ÐбÑдÑй ÑоÑÑ
+03:54=УÑилÑÑа
; Weapon Descriptions (use | as line breaks)
04:00=ÐÑакÑй воÑогÑв викоÑиÑÑовÑÑÑи пÑоÑÑÑ Ð³ÑанаÑÑ.|Ðона вибÑÑ
не Ñк ÑÑлÑки ÑÑ ÑÐ°Ð¹Ð¼ÐµÑ Ð´Ð¾Ñ
одиÑÑ Ð´Ð¾ нÑлÑ.|1-5: ÐиÑÑав ÑÐ°Ð¹Ð¼ÐµÑ Ð³ÑанаÑи|ÐÑака: УÑÑимÑй Ñоб меÑнÑÑи ÑилÑнÑÑе
@@ -344,8 +344,8 @@
04:51=ÐдÑйÑни Ñ
алÑвний ÑдаÑ, ÑпÑÑни гÑÑÐ´ÐºÑ Ð±Ð°Ð³Ð½Ð°.|ТÑоÑ
и пеÑе Ñ Ð²ÑÐ´ÐºÐ¸Ð´Ð°Ñ Ñжака назад.
04:52=UNUSED
04:53=ÐдÑйÑни подоÑож кÑÑÐ·Ñ ÑÐ°Ñ Ñа пÑоÑÑÑÑ,|залиÑивÑи ÑоваÑиÑÑв биÑиÑÑ Ð´Ð°Ð»Ñ Ñамим.|ÐÑÐ´Ñ Ð³Ð¾Ñовий повеÑнÑÑиÑÑ Ð² ÐºÐ¾Ð¶Ð½Ñ Ð¼Ð¸ÑÑ,|або до РапÑÐ¾Ð²Ð¾Ñ ÑмеÑÑÑ Ð°Ð±Ð¾ до ÑÑ
поÑазки.|ÐÑдмова. Ðе пÑаÑÑÑ Ð² РапÑовÑй СмеÑÑÑ,|ÑкÑо Ñи один, або ÑкÑо Ñи ÐоÑолÑ.
-04:54=ÐÐÐÐÐÐРШÐÐÐ
-04:55=Розпили поÑÑк лепкиÑ
плаÑÑÑвÑÑв.|бÑдÑй моÑÑи, Ñ
оÑони воÑогÑв, пеÑекÑивай ÑÑнелÑ.|СÑеж Ñоб на Ñебе не впала жодна з ниÑ
!
+;04:54=ÐÐÐÐÐÐРШÐÐÐ
+04:54=Розпили поÑÑк лепкиÑ
плаÑÑÑвÑÑв.|бÑдÑй моÑÑи, Ñ
оÑони воÑогÑв, пеÑекÑивай ÑÑнелÑ.|СÑеж Ñоб на Ñебе не впала жодна з ниÑ
!
; Game goal strings
05:00=Режими ÐÑи
diff --git a/share/hedgewars/Data/Locale/zh_CN.lua b/share/hedgewars/Data/Locale/zh_CN.lua
index 467107e..fe8b99a 100644
--- a/share/hedgewars/Data/Locale/zh_CN.lua
+++ b/share/hedgewars/Data/Locale/zh_CN.lua
@@ -208,7 +208,7 @@ locale = {
-- ["Everything looks OK..."] = "", -- A_Classic_Fairytale:enemy
-- ["Exactly, man! That was my dream."] = "", -- A_Classic_Fairytale:backstab
-- ["Eye Chewer"] = "", -- A_Classic_Fairytale:journey
--- ["FAG"] = "", -- Mutant
+-- ["INSANITY"] = "", -- Mutant
-- ["Family Reunion"] = "", -- A_Classic_Fairytale:family
["Fastest lap: "] = "æå¿«è®°å½:",
["Feeble Resistance"] = "åæè
",
@@ -287,7 +287,8 @@ locale = {
-- ["Hannibal"] = "", -- A_Classic_Fairytale:epil
-- ["Hapless Hogs"] = "",
-- [" Hapless Hogs left!"] = "",
--- [" HAS MUTATED\" )"] = "", --
+
+-- [" HAS MUTATED"] = "", -- Mutant
-- ["Hatless Jerry"] = "", -- A_Classic_Fairytale:queen
-- ["Have no illusions, your tribe is dead, indifferent of your choice."] = "", -- A_Classic_Fairytale:shadow
-- ["Have we ever attacked you first?"] = "", -- A_Classic_Fairytale:enemy
@@ -330,7 +331,7 @@ locale = {
["Hmmm..."] = "å...",
-- ["Hogminator"] = "", -- A_Classic_Fairytale:family
-- ["Hogs in sight!"] = "", -- Continental_supplies
--- ["HOLY SHIT!"] = "", -- Mutant
+-- ["HOLY SHYTE!"] = "", -- Mutant
-- ["Honest Lee"] = "", -- A_Classic_Fairytale:enemy
["Hooray!"] = "å¼!",
-- ["Hostage Situation"] = "", -- A_Classic_Fairytale:family
@@ -364,7 +365,7 @@ locale = {
-- ["If you get stuck, use your Desert Eagle or restart the mission!|"] = "", -- A_Classic_Fairytale:journey
-- ["If you know what I mean..."] = "", -- A_Classic_Fairytale:shadow
-- ["If you say so..."] = "", -- A_Classic_Fairytale:shadow
--- ["If you wish to restart the course, hold [Precise] while your turn ends (e.g with Skip)"] = "", --
+
-- ["I guess you'll have to kill them."] = "", -- A_Classic_Fairytale:dragon
-- ["I have come to make you an offering..."] = "", -- A_Classic_Fairytale:shadow
-- ["I have no idea where that mole disappeared...Can you see it?"] = "", -- A_Classic_Fairytale:shadow
@@ -554,8 +555,7 @@ locale = {
-- ["Oops...I dropped them."] = "", -- A_Classic_Fairytale:united
-- ["Open that crate and we will continue!"] = "", -- A_Classic_Fairytale:first_blood
["Operation Diver"] = "æ°´ä¸è¡å¨",
--- ["Opposing Team: "] =
- ["Opposing Team:"] = "对æ¹éä¼",
+ ["Opposing Team: "] = "对æ¹éä¼",
-- ["Orlando Boom!"] = "", -- A_Classic_Fairytale:queen
-- ["Ouch!"] = "", -- User_Mission_-_Rope_Knock_Challenge
-- ["Our tribe, our beautiful island!"] = "", -- A_Classic_Fairytale:enemy
@@ -566,11 +566,12 @@ locale = {
-- ["Pathetic Resistance"] = "", -- User_Mission_-_Bamboo_Thicket, User_Mission_-_Newton_and_the_Hammock
-- ["Perfect! Now try to get the next crate without hurting yourself!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Per-Hog Ammo"] = "",
--- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease)"] = "", --
+-- ["- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[precise/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"] = "", -- Continental_supplies
+
-- ["Pfew! That was close!"] = "", -- A_Classic_Fairytale:shadow
-- ["Piñata bullet: [Contains some sweet candy!]"] = "", -- Continental_supplies
-- ["Pings left:"] = "", -- Space_Invasion
--- ["Place more waypoints using [ENTER]"] = "",
+
-- ["Place more waypoints using the 'Air Attack' weapon."] = "",
-- ["Planes Used:"] = "", -- User_Mission_-_RCPlane_Challenge
-- ["Planes Used"] = "", -- User_Mission_-_RCPlane_Challenge
@@ -602,8 +603,7 @@ locale = {
-- ["Reinforcements"] = "", -- A_Classic_Fairytale:backstab
-- ["Remember: The rope only bend around objects, |if it doesn't hit anything it's always stright!"] = "", -- Basic_Training_-_Rope
-- ["Remember this, pathetic animal: when the day comes, you will regret your blind loyalty!"] = "", -- A_Classic_Fairytale:shadow
--- [" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] =
- ["- Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = "-带åæ人æå¸å¾å| -第ä¸æ¯3次夺æéä¼è·è| - åªææå¸å¨å·±æ¹åºå°æç®| -带æåºç¬æ¶éåæå¸è½ä¸| -è½ä¸çæå¸ä½¿ç¨æ¹å¼ä¸å| -æ失çåºç¬ç¬é´è¿å",
+ [" - Return the enemy flag to your base to score | - First team to 3 captures wins | - You may only score when your flag is in your base | - Hogs will drop the flag if killed, or drowned | - Dropped flags may be returned or recaptured | - Hogs respawn when killed"] = "-带åæ人æå¸å¾å| -第ä¸æ¯3次夺æéä¼è·è| - åªææå¸å¨å·±æ¹åºå°æç®| -带æåºç¬æ¶éåæå¸è½ä¸| -è½ä¸çæå¸ä½¿ç¨æ¹å¼ä¸å| -æ失çåºç¬ç¬é´è¿å",
-- ["Return to Leaks A Lot! If you get stuck, press [Precise] to try again!"] = "", -- A_Classic_Fairytale:shadow
-- ["Righteous Beard"] = "", -- A_Classic_Fairytale:backstab, A_Classic_Fairytale:dragon, A_Classic_Fairytale:enemy, A_Classic_Fairytale:epil, A_Classic_Fairytale:family, A_Classic_Fairytale:first_blood, A_Classic_Fairytale:queen, A_Classic_Fairytale:united
-- ["ROPE-KNOCKING"] = "", -- User_Mission_-_Rope_Knock_Challenge
@@ -822,7 +822,7 @@ locale = {
-- ["Use it wisely!"] = "", -- A_Classic_Fairytale:dragon
-- ["Use it with precaution!"] = "", -- A_Classic_Fairytale:first_blood
-- ["User Challenge"] = "",
--- ["Use the parachute ([Space] while in air)"] = "", --
+
-- ["Use the portal gun to get to the next crate, then use the new gun to get to the final destination!|"] = "", -- A_Classic_Fairytale:dragon
-- ["Use the rope to get on the head of the mole, young one!"] = "", -- A_Classic_Fairytale:first_blood
-- ["Use the rope to knock your enemies to their doom."] = "", -- User_Mission_-_Rope_Knock_Challenge
diff --git a/share/hedgewars/Data/Locale/zh_TW.txt b/share/hedgewars/Data/Locale/zh_TW.txt
index 291936f..1618f3c 100644
--- a/share/hedgewars/Data/Locale/zh_TW.txt
+++ b/share/hedgewars/Data/Locale/zh_TW.txt
@@ -237,8 +237,6 @@
02:01=%1 å»æ°´æé¤¨å ±å°äº
;02:01=%1 has found the lost city of Atlantis
02:01=%1 æ¾å°äºå³èªªä¸çäºç¹èèæ¯å
-;02:01=%1 aims for the lead role in Bioshock 3
-02:01=%1 çç®çæ¯çºäºå¨çåå±æ©3ä¸èµ·å¸¶é ä½ç¨
;02:01=Your doggy paddle could use a little work, %1
02:01=çç¬å¼ææç¨ç, %1
;02:01=%1 should have brought a jet ski
diff --git a/share/hedgewars/Data/Maps/Bamboo/CMakeLists.txt b/share/hedgewars/Data/Maps/Bamboo/CMakeLists.txt
index 13acdbe..7c1e86c 100644
--- a/share/hedgewars/Data/Maps/Bamboo/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Bamboo/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Bamboo)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Bamboo)
diff --git a/share/hedgewars/Data/Maps/BambooPlinko/CMakeLists.txt b/share/hedgewars/Data/Maps/BambooPlinko/CMakeLists.txt
index 2e24bd3..77c9013 100644
--- a/share/hedgewars/Data/Maps/BambooPlinko/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/BambooPlinko/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/BambooPlinko)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/BambooPlinko)
diff --git a/share/hedgewars/Data/Maps/Basketball/CMakeLists.txt b/share/hedgewars/Data/Maps/Basketball/CMakeLists.txt
index f1126c3..5d90814 100644
--- a/share/hedgewars/Data/Maps/Basketball/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Basketball/CMakeLists.txt
@@ -1,7 +1,8 @@
install(FILES
- map.png
- map.cfg
- map.lua
- mask.png
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Basketball)
+ map.png
+ map.cfg
+ map.lua
+ mask.png
+ preview.png
+ desc.txt
+ DESTINATION ${SHAREPATH}Data/Maps/Basketball)
diff --git a/share/hedgewars/Data/Maps/Basketball/desc.txt b/share/hedgewars/Data/Maps/Basketball/desc.txt
new file mode 100644
index 0000000..034a1dc
--- /dev/null
+++ b/share/hedgewars/Data/Maps/Basketball/desc.txt
@@ -0,0 +1 @@
+en_US=Who said hedgehogs can't play basketball?
diff --git a/share/hedgewars/Data/Maps/Basketball/map.cfg b/share/hedgewars/Data/Maps/Basketball/map.cfg
index 00a322d..e146d2e 100644
--- a/share/hedgewars/Data/Maps/Basketball/map.cfg
+++ b/share/hedgewars/Data/Maps/Basketball/map.cfg
@@ -1,2 +1,2 @@
Nature
-12
+12
\ No newline at end of file
diff --git a/share/hedgewars/Data/Maps/Basketball/map.lua b/share/hedgewars/Data/Maps/Basketball/map.lua
index 4add4a4..34d8930 100644
--- a/share/hedgewars/Data/Maps/Basketball/map.lua
+++ b/share/hedgewars/Data/Maps/Basketball/map.lua
@@ -1,6 +1,6 @@
-- Hedgewars - Basketball for 2+ Players
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("Scripts/Locale.lua")()
local score = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0}
diff --git a/share/hedgewars/Data/Maps/Bath/CMakeLists.txt b/share/hedgewars/Data/Maps/Bath/CMakeLists.txt
index 1491a5b..409dd9d 100644
--- a/share/hedgewars/Data/Maps/Bath/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Bath/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Bath)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Bath)
diff --git a/share/hedgewars/Data/Maps/Battlefield/CMakeLists.txt b/share/hedgewars/Data/Maps/Battlefield/CMakeLists.txt
index 65a2675..c9835f1 100644
--- a/share/hedgewars/Data/Maps/Battlefield/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Battlefield/CMakeLists.txt
@@ -1,7 +1,7 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Battlefield)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Battlefield)
diff --git a/share/hedgewars/Data/Maps/Blizzard/CMakeLists.txt b/share/hedgewars/Data/Maps/Blizzard/CMakeLists.txt
index e63bd5b..a5b10e9 100644
--- a/share/hedgewars/Data/Maps/Blizzard/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Blizzard/CMakeLists.txt
@@ -1,7 +1,7 @@
install(FILES
- map.png
- map.cfg
- mask.png
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Blizzard)
+ map.png
+ map.cfg
+ mask.png
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Blizzard)
diff --git a/share/hedgewars/Data/Maps/Blox/CMakeLists.txt b/share/hedgewars/Data/Maps/Blox/CMakeLists.txt
index e8115c9..e21337c 100644
--- a/share/hedgewars/Data/Maps/Blox/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Blox/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Blox)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Blox)
diff --git a/share/hedgewars/Data/Maps/Bubbleflow/CMakeLists.txt b/share/hedgewars/Data/Maps/Bubbleflow/CMakeLists.txt
index 216612c..644445e 100644
--- a/share/hedgewars/Data/Maps/Bubbleflow/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Bubbleflow/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Bubbleflow)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Bubbleflow)
diff --git a/share/hedgewars/Data/Maps/CMakeLists.txt b/share/hedgewars/Data/Maps/CMakeLists.txt
index 1967ca7..4cda211 100644
--- a/share/hedgewars/Data/Maps/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/CMakeLists.txt
@@ -1,45 +1,53 @@
foreach(dir
- Bamboo
- BambooPlinko
- Basketball
- Bath
- Battlefield
- Blizzard
- Blox
- Bubbleflow
- Cake
- Castle
- Cave
- Cheese
- Cogs
- Control
- CrazyMission
- CTF_Blizzard
- EarthRise
- Eyes
- Hammock
- HedgeFortress
- Hedgelove
- Hedgewars
- Hogville
- Hydrant
- Islands
- Knockball
- Lonely_Island
- Mushrooms
- Octorama
- PirateFlag
- Plane
- portal
- Ropes
- Ruler
- Sheep
- ShoppaKing
- Sticks
- Trash
- Tree
- TrophyRace
- )
+ Bamboo
+ BambooPlinko
+ Basketball
+ Bath
+ Battlefield
+ Blizzard
+ Blox
+ Bubbleflow
+ Cake
+ Castle
+ Cave
+ Cheese
+ Cogs
+ Control
+ CrazyMission
+ CTF_Blizzard
+ EarthRise
+ Eyes
+ Hammock
+ HedgeFortress
+ Hedgelove
+ Hedgewars
+ Hogville
+ Hydrant
+ Islands
+ Knockball
+ Lonely_Island
+ Mushrooms
+ Octorama
+ PirateFlag
+ Plane
+ portal
+ Ropes
+ Ruler
+ SB_Bones
+ SB_Crystal
+ SB_Grassy
+ SB_Grove
+ SB_Haunty
+ SB_Oaks
+ SB_Shrooms
+ SB_Tentacles
+ Sheep
+ ShoppaKing
+ Sticks
+ Trash
+ Tree
+ TrophyRace
+ )
add_subdirectory(${dir})
endforeach(dir)
diff --git a/share/hedgewars/Data/Maps/CTF_Blizzard/CMakeLists.txt b/share/hedgewars/Data/Maps/CTF_Blizzard/CMakeLists.txt
index e82bb0d..bf130e5 100644
--- a/share/hedgewars/Data/Maps/CTF_Blizzard/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/CTF_Blizzard/CMakeLists.txt
@@ -1,5 +1,6 @@
install(FILES
- map.cfg
- map.lua
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/CTF_Blizzard)
+ map.cfg
+ map.lua
+ preview.png
+ desc.txt
+ DESTINATION ${SHAREPATH}Data/Maps/CTF_Blizzard)
diff --git a/share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt b/share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt
new file mode 100644
index 0000000..3de5ca5
--- /dev/null
+++ b/share/hedgewars/Data/Maps/CTF_Blizzard/desc.txt
@@ -0,0 +1 @@
+en_US=Capture the Flag\, blizzard style!
diff --git a/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua b/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
index 7193d29..3a2063d 100644
--- a/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
+++ b/share/hedgewars/Data/Maps/CTF_Blizzard/map.lua
@@ -91,7 +91,7 @@
-- add support for more players
-- re-enable sudden death, but set water rise to 0
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("Scripts/Locale.lua")()
---------------------------------------------------------------
----------lots of bad variables and things
diff --git a/share/hedgewars/Data/Maps/Cake/CMakeLists.txt b/share/hedgewars/Data/Maps/Cake/CMakeLists.txt
index 613be2a..e90cb07 100644
--- a/share/hedgewars/Data/Maps/Cake/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Cake/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Cake)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Cake)
diff --git a/share/hedgewars/Data/Maps/Castle/CMakeLists.txt b/share/hedgewars/Data/Maps/Castle/CMakeLists.txt
index 938887a..8c190f1 100644
--- a/share/hedgewars/Data/Maps/Castle/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Castle/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Castle)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Castle)
diff --git a/share/hedgewars/Data/Maps/Cave/CMakeLists.txt b/share/hedgewars/Data/Maps/Cave/CMakeLists.txt
index d968133..a70de1f 100644
--- a/share/hedgewars/Data/Maps/Cave/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Cave/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Cave)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Cave)
diff --git a/share/hedgewars/Data/Maps/Cheese/CMakeLists.txt b/share/hedgewars/Data/Maps/Cheese/CMakeLists.txt
index a2bfc90..1a92557 100644
--- a/share/hedgewars/Data/Maps/Cheese/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Cheese/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Cheese)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Cheese)
diff --git a/share/hedgewars/Data/Maps/Cogs/CMakeLists.txt b/share/hedgewars/Data/Maps/Cogs/CMakeLists.txt
index 029ea1d..a92c2ca 100644
--- a/share/hedgewars/Data/Maps/Cogs/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Cogs/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Cogs)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Cogs)
diff --git a/share/hedgewars/Data/Maps/Control/CMakeLists.txt b/share/hedgewars/Data/Maps/Control/CMakeLists.txt
index 415a00c..3d2a864 100644
--- a/share/hedgewars/Data/Maps/Control/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Control/CMakeLists.txt
@@ -1,6 +1,7 @@
install(FILES
- map.cfg
- map.lua
- map.png
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Control)
+ map.cfg
+ map.lua
+ map.png
+ preview.png
+ desc.txt
+ DESTINATION ${SHAREPATH}Data/Maps/Control)
diff --git a/share/hedgewars/Data/Maps/Control/desc.txt b/share/hedgewars/Data/Maps/Control/desc.txt
new file mode 100644
index 0000000..2c0dd7e
--- /dev/null
+++ b/share/hedgewars/Data/Maps/Control/desc.txt
@@ -0,0 +1 @@
+en_US=Islands scattered everywhere\, full set of weapons.
diff --git a/share/hedgewars/Data/Maps/Control/map.cfg b/share/hedgewars/Data/Maps/Control/map.cfg
index fbc5ec7..63ca187 100644
--- a/share/hedgewars/Data/Maps/Control/map.cfg
+++ b/share/hedgewars/Data/Maps/Control/map.cfg
@@ -1,4 +1,4 @@
Deepspace
48
Default
-Crazy
+Crazy
\ No newline at end of file
diff --git a/share/hedgewars/Data/Maps/Control/map.lua b/share/hedgewars/Data/Maps/Control/map.lua
index 61e091e..b10b078 100644
--- a/share/hedgewars/Data/Maps/Control/map.lua
+++ b/share/hedgewars/Data/Maps/Control/map.lua
@@ -49,7 +49,7 @@
--script begins
-----------------
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("Scripts/Locale.lua")()
---------------------------------------------------------------
----------lots of bad variables and things
diff --git a/share/hedgewars/Data/Maps/CrazyMission/CMakeLists.txt b/share/hedgewars/Data/Maps/CrazyMission/CMakeLists.txt
index 87143d5..85dcbaf 100644
--- a/share/hedgewars/Data/Maps/CrazyMission/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/CrazyMission/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/CrazyMission)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/CrazyMission)
diff --git a/share/hedgewars/Data/Maps/EarthRise/CMakeLists.txt b/share/hedgewars/Data/Maps/EarthRise/CMakeLists.txt
index 5aca87f..fa892c9 100644
--- a/share/hedgewars/Data/Maps/EarthRise/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/EarthRise/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/EarthRise)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/EarthRise)
diff --git a/share/hedgewars/Data/Maps/Eyes/CMakeLists.txt b/share/hedgewars/Data/Maps/Eyes/CMakeLists.txt
index 60f95cf..578aaab 100644
--- a/share/hedgewars/Data/Maps/Eyes/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Eyes/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Eyes)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Eyes)
diff --git a/share/hedgewars/Data/Maps/Eyes/preview.png b/share/hedgewars/Data/Maps/Eyes/preview.png
index 2c0539a..99ccb9d 100644
Binary files a/share/hedgewars/Data/Maps/Eyes/preview.png and b/share/hedgewars/Data/Maps/Eyes/preview.png differ
diff --git a/share/hedgewars/Data/Maps/Hammock/CMakeLists.txt b/share/hedgewars/Data/Maps/Hammock/CMakeLists.txt
index 7ef9bac..6724886 100644
--- a/share/hedgewars/Data/Maps/Hammock/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Hammock/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Hammock)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Hammock)
diff --git a/share/hedgewars/Data/Maps/HedgeFortress/CMakeLists.txt b/share/hedgewars/Data/Maps/HedgeFortress/CMakeLists.txt
index 8ac7d25..2e4fad0 100644
--- a/share/hedgewars/Data/Maps/HedgeFortress/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/HedgeFortress/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/HedgeFortress)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/HedgeFortress)
diff --git a/share/hedgewars/Data/Maps/Hedgelove/CMakeLists.txt b/share/hedgewars/Data/Maps/Hedgelove/CMakeLists.txt
index f375147..d5cac46 100644
--- a/share/hedgewars/Data/Maps/Hedgelove/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Hedgelove/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Hedgelove)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Hedgelove)
diff --git a/share/hedgewars/Data/Maps/Hedgewars/CMakeLists.txt b/share/hedgewars/Data/Maps/Hedgewars/CMakeLists.txt
index 2f4cca7..8e88319 100644
--- a/share/hedgewars/Data/Maps/Hedgewars/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Hedgewars/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Hedgewars)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Hedgewars)
diff --git a/share/hedgewars/Data/Maps/Hogville/CMakeLists.txt b/share/hedgewars/Data/Maps/Hogville/CMakeLists.txt
index 3cea0ef..1b00934 100644
--- a/share/hedgewars/Data/Maps/Hogville/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Hogville/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Hogville)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Hogville)
diff --git a/share/hedgewars/Data/Maps/Hydrant/CMakeLists.txt b/share/hedgewars/Data/Maps/Hydrant/CMakeLists.txt
index 4c654d0..f7c3ee1 100644
--- a/share/hedgewars/Data/Maps/Hydrant/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Hydrant/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Hydrant)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Hydrant)
diff --git a/share/hedgewars/Data/Maps/Islands/CMakeLists.txt b/share/hedgewars/Data/Maps/Islands/CMakeLists.txt
index f5f4c32..368240d 100644
--- a/share/hedgewars/Data/Maps/Islands/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Islands/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Islands)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Islands)
diff --git a/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt b/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt
index 71a4bf5..510caea 100644
--- a/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt
@@ -1,6 +1,7 @@
install(FILES
- map.png
- map.cfg
- map.lua
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Knockball)
+ map.png
+ map.cfg
+ map.lua
+ preview.png
+ desc.txt
+ DESTINATION ${SHAREPATH}Data/Maps/Knockball)
diff --git a/share/hedgewars/Data/Maps/Knockball/desc.txt b/share/hedgewars/Data/Maps/Knockball/desc.txt
new file mode 100644
index 0000000..d763b47
--- /dev/null
+++ b/share/hedgewars/Data/Maps/Knockball/desc.txt
@@ -0,0 +1 @@
+en_US=Knock your opponents off the platforms using only a bat!
diff --git a/share/hedgewars/Data/Maps/Knockball/map.lua b/share/hedgewars/Data/Maps/Knockball/map.lua
index 4b586a2..5cdba09 100644
--- a/share/hedgewars/Data/Maps/Knockball/map.lua
+++ b/share/hedgewars/Data/Maps/Knockball/map.lua
@@ -1,6 +1,6 @@
-- Hedgewars - Knockball for 2+ Players
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("Scripts/Locale.lua")()
local score = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0}
diff --git a/share/hedgewars/Data/Maps/Lonely_Island/CMakeLists.txt b/share/hedgewars/Data/Maps/Lonely_Island/CMakeLists.txt
index d6269b0..88e466f 100644
--- a/share/hedgewars/Data/Maps/Lonely_Island/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Lonely_Island/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Lonely_Island)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Lonely_Island)
diff --git a/share/hedgewars/Data/Maps/Mushrooms/CMakeLists.txt b/share/hedgewars/Data/Maps/Mushrooms/CMakeLists.txt
index 34fbd65..0505535 100644
--- a/share/hedgewars/Data/Maps/Mushrooms/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Mushrooms/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Mushrooms)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Mushrooms)
diff --git a/share/hedgewars/Data/Maps/Octorama/CMakeLists.txt b/share/hedgewars/Data/Maps/Octorama/CMakeLists.txt
index c08f239..5abee8e 100644
--- a/share/hedgewars/Data/Maps/Octorama/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Octorama/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- info.txt
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Octorama)
+ info.txt
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Octorama)
diff --git a/share/hedgewars/Data/Maps/Octorama/info.txt b/share/hedgewars/Data/Maps/Octorama/info.txt
index c1c2f6a..b795d59 100644
--- a/share/hedgewars/Data/Maps/Octorama/info.txt
+++ b/share/hedgewars/Data/Maps/Octorama/info.txt
@@ -2,9 +2,9 @@
octorama
:: TYPE
- custom hedgewars map
-
-:: VERSION
+ custom hedgewars map
+
+:: VERSION
RC3
:: CHANGELOG
@@ -27,13 +27,13 @@
- shades on upper left bubbles are now correct
- removed the theme for now since the theme didn't
bring anything new but the music (tiyuri)
-
-:: DESCRIPTION
- just a fun map similar to bubbleflow
-
-:: CREATOR
+
+:: DESCRIPTION
+ just a fun map similar to bubbleflow
+
+:: CREATOR
jesse/jessor - http://geekosphere.org
-
+
:: RIGHTZ
Octopod Vector Art: http://iconicon.net/ (CC)
diff --git a/share/hedgewars/Data/Maps/Octorama/preview.png b/share/hedgewars/Data/Maps/Octorama/preview.png
index ee35486..68e2f78 100644
Binary files a/share/hedgewars/Data/Maps/Octorama/preview.png and b/share/hedgewars/Data/Maps/Octorama/preview.png differ
diff --git a/share/hedgewars/Data/Maps/PirateFlag/CMakeLists.txt b/share/hedgewars/Data/Maps/PirateFlag/CMakeLists.txt
index d77d800..8408fbd 100644
--- a/share/hedgewars/Data/Maps/PirateFlag/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/PirateFlag/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/PirateFlag)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/PirateFlag)
diff --git a/share/hedgewars/Data/Maps/Plane/CMakeLists.txt b/share/hedgewars/Data/Maps/Plane/CMakeLists.txt
index 05757d7..b2ba971 100644
--- a/share/hedgewars/Data/Maps/Plane/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Plane/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Plane)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Plane)
diff --git a/share/hedgewars/Data/Maps/Ropes/CMakeLists.txt b/share/hedgewars/Data/Maps/Ropes/CMakeLists.txt
index 7bf8a06..efddc92 100644
--- a/share/hedgewars/Data/Maps/Ropes/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Ropes/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Ropes)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Ropes)
diff --git a/share/hedgewars/Data/Maps/Ruler/CMakeLists.txt b/share/hedgewars/Data/Maps/Ruler/CMakeLists.txt
index 3549c17..6b9bd32 100644
--- a/share/hedgewars/Data/Maps/Ruler/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Ruler/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Ruler)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Ruler)
diff --git a/share/hedgewars/Data/Maps/SB_Bones/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Bones/CMakeLists.txt
new file mode 100644
index 0000000..d077868
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Bones/CMakeLists.txt
@@ -0,0 +1,5 @@
+install(FILES
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Bones)
diff --git a/share/hedgewars/Data/Maps/SB_Bones/map.cfg b/share/hedgewars/Data/Maps/SB_Bones/map.cfg
new file mode 100644
index 0000000..73a6ce7
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Bones/map.cfg
@@ -0,0 +1,2 @@
+Desert
+48
diff --git a/share/hedgewars/Data/Maps/SB_Bones/map.png b/share/hedgewars/Data/Maps/SB_Bones/map.png
new file mode 100644
index 0000000..fa3f4fd
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Bones/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Bones/preview.png b/share/hedgewars/Data/Maps/SB_Bones/preview.png
new file mode 100644
index 0000000..3e46681
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Bones/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Crystal/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Crystal/CMakeLists.txt
new file mode 100644
index 0000000..f44507a
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Crystal/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Crystal)
diff --git a/share/hedgewars/Data/Maps/SB_Crystal/map.cfg b/share/hedgewars/Data/Maps/SB_Crystal/map.cfg
new file mode 100644
index 0000000..a19eb6c
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Crystal/map.cfg
@@ -0,0 +1,2 @@
+Cave
+32
diff --git a/share/hedgewars/Data/Maps/SB_Crystal/map.png b/share/hedgewars/Data/Maps/SB_Crystal/map.png
new file mode 100644
index 0000000..5116f65
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Crystal/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Crystal/mask.png b/share/hedgewars/Data/Maps/SB_Crystal/mask.png
new file mode 100644
index 0000000..8a5fe35
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Crystal/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Crystal/preview.png b/share/hedgewars/Data/Maps/SB_Crystal/preview.png
new file mode 100644
index 0000000..a822bb3
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Crystal/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grassy/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Grassy/CMakeLists.txt
new file mode 100644
index 0000000..90b632c
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Grassy/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Grassy)
diff --git a/share/hedgewars/Data/Maps/SB_Grassy/map.cfg b/share/hedgewars/Data/Maps/SB_Grassy/map.cfg
new file mode 100644
index 0000000..a3b1a1f
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Grassy/map.cfg
@@ -0,0 +1,2 @@
+Castle
+40
diff --git a/share/hedgewars/Data/Maps/SB_Grassy/map.png b/share/hedgewars/Data/Maps/SB_Grassy/map.png
new file mode 100644
index 0000000..eb98d48
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grassy/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grassy/mask.png b/share/hedgewars/Data/Maps/SB_Grassy/mask.png
new file mode 100644
index 0000000..c20701b
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grassy/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grassy/preview.png b/share/hedgewars/Data/Maps/SB_Grassy/preview.png
new file mode 100644
index 0000000..fc37b64
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grassy/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grove/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Grove/CMakeLists.txt
new file mode 100644
index 0000000..1c0c496
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Grove/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Grove)
diff --git a/share/hedgewars/Data/Maps/SB_Grove/map.cfg b/share/hedgewars/Data/Maps/SB_Grove/map.cfg
new file mode 100644
index 0000000..1e6115a
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Grove/map.cfg
@@ -0,0 +1,2 @@
+Nature
+48
diff --git a/share/hedgewars/Data/Maps/SB_Grove/map.png b/share/hedgewars/Data/Maps/SB_Grove/map.png
new file mode 100644
index 0000000..3b41d30
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grove/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grove/mask.png b/share/hedgewars/Data/Maps/SB_Grove/mask.png
new file mode 100644
index 0000000..f79bbe7
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grove/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Grove/preview.png b/share/hedgewars/Data/Maps/SB_Grove/preview.png
new file mode 100644
index 0000000..bf87802
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Grove/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Haunty/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Haunty/CMakeLists.txt
new file mode 100644
index 0000000..34455fa
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Haunty/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Haunty)
diff --git a/share/hedgewars/Data/Maps/SB_Haunty/map.cfg b/share/hedgewars/Data/Maps/SB_Haunty/map.cfg
new file mode 100644
index 0000000..737afcc
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Haunty/map.cfg
@@ -0,0 +1,2 @@
+Halloween
+24
diff --git a/share/hedgewars/Data/Maps/SB_Haunty/map.png b/share/hedgewars/Data/Maps/SB_Haunty/map.png
new file mode 100644
index 0000000..bbdf3a2
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Haunty/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Haunty/mask.png b/share/hedgewars/Data/Maps/SB_Haunty/mask.png
new file mode 100644
index 0000000..cc01ef6
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Haunty/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Haunty/preview.png b/share/hedgewars/Data/Maps/SB_Haunty/preview.png
new file mode 100644
index 0000000..724dd19
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Haunty/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Oaks/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Oaks/CMakeLists.txt
new file mode 100644
index 0000000..1c2c746
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Oaks/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Oaks)
diff --git a/share/hedgewars/Data/Maps/SB_Oaks/map.cfg b/share/hedgewars/Data/Maps/SB_Oaks/map.cfg
new file mode 100644
index 0000000..1e6115a
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Oaks/map.cfg
@@ -0,0 +1,2 @@
+Nature
+48
diff --git a/share/hedgewars/Data/Maps/SB_Oaks/map.png b/share/hedgewars/Data/Maps/SB_Oaks/map.png
new file mode 100644
index 0000000..bda14dc
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Oaks/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Oaks/mask.png b/share/hedgewars/Data/Maps/SB_Oaks/mask.png
new file mode 100644
index 0000000..f98aa52
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Oaks/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Oaks/preview.png b/share/hedgewars/Data/Maps/SB_Oaks/preview.png
new file mode 100644
index 0000000..21af0f5
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Oaks/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Shrooms/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Shrooms/CMakeLists.txt
new file mode 100644
index 0000000..3642b06
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Shrooms/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Shrooms)
diff --git a/share/hedgewars/Data/Maps/SB_Shrooms/map.cfg b/share/hedgewars/Data/Maps/SB_Shrooms/map.cfg
new file mode 100644
index 0000000..1e6115a
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Shrooms/map.cfg
@@ -0,0 +1,2 @@
+Nature
+48
diff --git a/share/hedgewars/Data/Maps/SB_Shrooms/map.png b/share/hedgewars/Data/Maps/SB_Shrooms/map.png
new file mode 100644
index 0000000..e618f19
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Shrooms/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Shrooms/mask.png b/share/hedgewars/Data/Maps/SB_Shrooms/mask.png
new file mode 100644
index 0000000..a7f89e5
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Shrooms/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Shrooms/preview.png b/share/hedgewars/Data/Maps/SB_Shrooms/preview.png
new file mode 100644
index 0000000..51099c4
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Shrooms/preview.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Tentacles/CMakeLists.txt b/share/hedgewars/Data/Maps/SB_Tentacles/CMakeLists.txt
new file mode 100644
index 0000000..2bfce2f
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Tentacles/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(FILES
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/SB_Tentacles)
diff --git a/share/hedgewars/Data/Maps/SB_Tentacles/map.cfg b/share/hedgewars/Data/Maps/SB_Tentacles/map.cfg
new file mode 100644
index 0000000..40cb51c
--- /dev/null
+++ b/share/hedgewars/Data/Maps/SB_Tentacles/map.cfg
@@ -0,0 +1,2 @@
+Hell
+40
diff --git a/share/hedgewars/Data/Maps/SB_Tentacles/map.png b/share/hedgewars/Data/Maps/SB_Tentacles/map.png
new file mode 100644
index 0000000..11e7f5a
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Tentacles/map.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Tentacles/mask.png b/share/hedgewars/Data/Maps/SB_Tentacles/mask.png
new file mode 100644
index 0000000..e20e036
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Tentacles/mask.png differ
diff --git a/share/hedgewars/Data/Maps/SB_Tentacles/preview.png b/share/hedgewars/Data/Maps/SB_Tentacles/preview.png
new file mode 100644
index 0000000..e4024e5
Binary files /dev/null and b/share/hedgewars/Data/Maps/SB_Tentacles/preview.png differ
diff --git a/share/hedgewars/Data/Maps/Sheep/CMakeLists.txt b/share/hedgewars/Data/Maps/Sheep/CMakeLists.txt
index 692c0e8..b595ce4 100644
--- a/share/hedgewars/Data/Maps/Sheep/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Sheep/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Sheep)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Sheep)
diff --git a/share/hedgewars/Data/Maps/ShoppaKing/CMakeLists.txt b/share/hedgewars/Data/Maps/ShoppaKing/CMakeLists.txt
index ba701c1..b4bed4f 100644
--- a/share/hedgewars/Data/Maps/ShoppaKing/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/ShoppaKing/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/ShoppaKing)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/ShoppaKing)
diff --git a/share/hedgewars/Data/Maps/ShoppaKing/map.png b/share/hedgewars/Data/Maps/ShoppaKing/map.png
index 543f01b..298f760 100644
Binary files a/share/hedgewars/Data/Maps/ShoppaKing/map.png and b/share/hedgewars/Data/Maps/ShoppaKing/map.png differ
diff --git a/share/hedgewars/Data/Maps/Sticks/CMakeLists.txt b/share/hedgewars/Data/Maps/Sticks/CMakeLists.txt
index b92cc15..c676856 100644
--- a/share/hedgewars/Data/Maps/Sticks/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Sticks/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Sticks)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Sticks)
diff --git a/share/hedgewars/Data/Maps/Trash/CMakeLists.txt b/share/hedgewars/Data/Maps/Trash/CMakeLists.txt
index b667274..79e1cae 100644
--- a/share/hedgewars/Data/Maps/Trash/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Trash/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Trash)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Trash)
diff --git a/share/hedgewars/Data/Maps/Tree/CMakeLists.txt b/share/hedgewars/Data/Maps/Tree/CMakeLists.txt
index 62536ca..57c3af6 100644
--- a/share/hedgewars/Data/Maps/Tree/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/Tree/CMakeLists.txt
@@ -1,5 +1,5 @@
install(FILES
- map.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/Tree)
+ map.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/Tree)
diff --git a/share/hedgewars/Data/Maps/TrophyRace/CMakeLists.txt b/share/hedgewars/Data/Maps/TrophyRace/CMakeLists.txt
index 6205c37..c557a7c 100644
--- a/share/hedgewars/Data/Maps/TrophyRace/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/TrophyRace/CMakeLists.txt
@@ -1,7 +1,8 @@
install(FILES
- map.cfg
- map.lua
- map.png
- mask.png
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/TrophyRace)
+ map.cfg
+ map.lua
+ map.png
+ mask.png
+ preview.png
+ desc.txt
+ DESTINATION ${SHAREPATH}Data/Maps/TrophyRace)
diff --git a/share/hedgewars/Data/Maps/TrophyRace/desc.txt b/share/hedgewars/Data/Maps/TrophyRace/desc.txt
new file mode 100644
index 0000000..22ddcf0
--- /dev/null
+++ b/share/hedgewars/Data/Maps/TrophyRace/desc.txt
@@ -0,0 +1 @@
+en_US=Ready\, set\, go! Who is going to be the first in this crazy race?
\ No newline at end of file
diff --git a/share/hedgewars/Data/Maps/TrophyRace/map.lua b/share/hedgewars/Data/Maps/TrophyRace/map.lua
index 26f1b1f..798b2e5 100644
--- a/share/hedgewars/Data/Maps/TrophyRace/map.lua
+++ b/share/hedgewars/Data/Maps/TrophyRace/map.lua
@@ -1,6 +1,6 @@
-- Hedgewars - Roperace for 2+ Players
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("Scripts/Locale.lua")()
-- store number of hedgehogs
local numhhs = 0
diff --git a/share/hedgewars/Data/Maps/TrophyRace/map.png b/share/hedgewars/Data/Maps/TrophyRace/map.png
index 858826a..239ca9e 100644
Binary files a/share/hedgewars/Data/Maps/TrophyRace/map.png and b/share/hedgewars/Data/Maps/TrophyRace/map.png differ
diff --git a/share/hedgewars/Data/Maps/portal/CMakeLists.txt b/share/hedgewars/Data/Maps/portal/CMakeLists.txt
index 08a3313..d83ca5f 100644
--- a/share/hedgewars/Data/Maps/portal/CMakeLists.txt
+++ b/share/hedgewars/Data/Maps/portal/CMakeLists.txt
@@ -1,6 +1,6 @@
install(FILES
- map.png
- mask.png
- map.cfg
- preview.png
- DESTINATION ${SHAREPATH}Data/Maps/portal)
+ map.png
+ mask.png
+ map.cfg
+ preview.png
+ DESTINATION ${SHAREPATH}Data/Maps/portal)
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt
index e65af6a..a7fb4cd 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/CMakeLists.txt
@@ -1,7 +1,9 @@
file(GLOB Config *.ini)
file(GLOB Missions *.lua)
+file(GLOB Packs *.hwp)
install(FILES
- ${Config}
- ${Missions}
- DESTINATION "${SHAREPATH}Data/Missions/Campaign/A Classic Fairytale")
+ ${Config}
+ ${Missions}
+ ${Packs}
+ DESTINATION "${SHAREPATH}Data/Missions/Campaign/A Classic Fairytale")
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua
index 89f9d48..48368aa 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/backstab.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Constants---------------------------------
choiceAccepted = 1
@@ -760,7 +760,9 @@ function AfterWave3DeadAnim()
SaveCampaignVar("M5ChiefDead", "0")
end
SaveCampaignVar("M5Choice", "" .. choice)
- SaveCampaignVar("Progress", "5")
+ if progress and progress<5 then
+ SaveCampaignVar("Progress", "5")
+ end
for i = 1, 7 do
if natives[i] == deployedHog then
@@ -814,6 +816,7 @@ function RestoreWave(index)
end
function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
m2Choice = tonumber(GetCampaignVar("M2Choice"))
m4DenseDead = tonumber(GetCampaignVar("M4DenseDead"))
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua
index f4944d0..0590319 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/dragon.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Map--------------------------------------
local map =
@@ -399,7 +399,9 @@ end
function DoMissionFinished()
AddCaption(loc("Salvation was one step closer now..."))
- SaveCampaignVar("Progress", "6")
+ if progress and progress<6 then
+ SaveCampaignVar("Progress", "6")
+ end
ParseCommand("teamgone " .. loc("011101001"))
TurnTimeLeft = 0
end
@@ -451,6 +453,7 @@ function RestoreHedge(hedge)
end
function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
end
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua
index 18e3dd2..eefc56b 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/enemy.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
--------------------------------------------Constants------------------------------------
@@ -400,7 +400,9 @@ function WonMission()
end
function WinMission()
- SaveCampaignVar("Progress", "9")
+ if progress and progress<9 then
+ SaveCampaignVar("Progress", "9")
+ end
ParseCommand("teamgone " .. loc("011101001"))
TurnTimeLeft = 0
end
@@ -420,6 +422,7 @@ function RestoreHedge(hedge)
end
function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
m2Choice = tonumber(GetCampaignVar("M2Choice"))
m5Choice = tonumber(GetCampaignVar("M5Choice"))
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua
index ec0e144..bdf022a 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/epil.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Constants---------------------------------
leaksNum = 1
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua
index c3e6265..a7df301 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/family.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Map--------------------------------------
local map =
@@ -284,7 +284,9 @@ end
function DoPrincessFreed()
AnimSay(princess, loc("Thank you, my hero!"), SAY_SAY, 0)
- SaveCampaignVar("Progress", "7")
+ if progress and progress<7 then
+ SaveCampaignVar("Progress", "7")
+ end
ParseCommand("teamgone " .. loc("011101001"))
TurnTimeLeft = 0
end
@@ -390,6 +392,7 @@ function RestoreHedge(hedge)
end
function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
m2Choice = tonumber(GetCampaignVar("M2Choice"))
m5Choice = tonumber(GetCampaignVar("M5Choice"))
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.hwp b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.hwp
new file mode 100644
index 0000000..6cda913
Binary files /dev/null and b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.hwp differ
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua
index af3737e..9bbdbca 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/first_blood.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Variables---------------------------------
startDialogue = {}
@@ -56,6 +56,7 @@ punchTaken = false
canKilled = false
desertTaken = false
challengeFailed = false
+deleteCrate = false
difficultyChoice = false
princessFace = "Left"
elderFace = "Left"
@@ -220,6 +221,9 @@ function AnimationSetup()
end
-----------------------------Events------------------------------------
function CheckNeedToTurn(gear)
+ if youngKilled then
+ return false
+ end
if gear == princess then
if princessKilled ~= true then
if (GetX(princess) > GetX(youngh) and princessFace == "Right")
@@ -466,6 +470,7 @@ end
function DoTimesUp()
challengeFailed = true
+ deleteCrate = true
DeleteGear(crates[1])
TurnTimeLeft = -1
AddCaption(loc("And so happenned that Leaks A Lot failed to complete the challenge! He landed, pressured by shame..."))
@@ -538,7 +543,9 @@ end
function DoCannibalKilled()
AddAnim(cannKilledAnim)
- SaveCampaignVar("Progress", "1")
+ if not progress then
+ SaveCampaignVar("Progress", "1")
+ end
end
function DoCannibalKilledEarly()
@@ -603,9 +610,7 @@ function onGameInit()
MinesTime = 3000
Explosives = 0
Delay = 10
- MapGen = 0
- TemplateFilter = 6
- TemplateNumber = 33
+ Map = "A_Classic_Fairytale_first_blood"
Theme = "Nature"
@@ -630,6 +635,7 @@ function onGameInit()
end
function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
TurnTimeLeft = -1
FollowGear(youngh)
ShowMission(loc("A Classic Fairytale"), loc("First Blood"), loc("Finish your training|Hint: Animations can be skipped with the [Precise] key."), -amSkip, 0)
@@ -664,6 +670,8 @@ function onGearDelete(gear)
rope2Taken = true
elseif gear == ropeCrate3 then
rope3Taken = true
+ elseif gear == crates[1] and deleteCrate == true then
+ deleteCrate = false
elseif gear == crates[1] and challengeFailed == false then
crates[1] = nil
cratesCollected = cratesCollected + 1
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.hwp b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.hwp
new file mode 100644
index 0000000..8f46467
Binary files /dev/null and b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.hwp differ
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua
index 6104ff6..2b6d333 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/journey.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
--///////////////////////////////CONSTANTS///////////////////////////
@@ -903,7 +903,9 @@ function CheckWon()
end
function DoWon()
- SaveCampaignVar("Progress", "3")
+ if progress and progress<3 then
+ SaveCampaignVar("Progress", "3")
+ end
AddAnim(winAnim)
AddFunction({func = FinishWon, args = {}})
end
@@ -939,11 +941,10 @@ function onGameInit()
MinesTime = 3000
Explosives = 0
Delay = 5
- MapGen = 0
- TemplateFilter = 6
- TemplateNumber = 27
- Theme = "Nature"
- SuddenDeathTurns = 3000
+ Map = "A_Classic_Fairytale_journey"
+ Theme = "Nature"
+
+ SuddenDeathTurns = 3000
AddTeam(loc("Natives"), 29439, "Bone", "Island", "HillBilly", "cm_birdy")
leaks = AddHog(loc("Leaks A Lot"), 0, 100, "Rambo")
@@ -974,6 +975,7 @@ function onGameInit()
end
function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
m2Choice = tonumber(GetCampaignVar("M2Choice"))
m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
m2RamonDead = tonumber(GetCampaignVar("M2RamonDead"))
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua
index 901b67a..5c8ff30 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/queen.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Map--------------------------------------
@@ -575,6 +575,7 @@ function RestoreHedge(hedge)
end
function GetVariables()
+ progress = tonumber(GetCampaignVar("Progress"))
m5DeployedNum = tonumber(GetCampaignVar("M5DeployedNum"))
m2Choice = tonumber(GetCampaignVar("M2Choice"))
m5Choice = tonumber(GetCampaignVar("M5Choice"))
@@ -606,7 +607,9 @@ function SaveCampaignVariables()
SaveCampaignVar("M8PrincessLeader", princessLeader)
SaveCampaignVar("M8EnemyFled", enemyFled)
SaveCampaignVar("M8Scene", "" .. scene)
- SaveCampaignVar("Progress", "8")
+ if progress and progress<8 then
+ SaveCampaignVar("Progress", "8")
+ end
end
function SetupPlace()
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.hwp b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.hwp
new file mode 100644
index 0000000..7584a1c
Binary files /dev/null and b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.hwp differ
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua
index b618727..95f8ec3 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/shadow.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Constants---------------------------------
startStage = 0
@@ -761,7 +761,9 @@ function DoStronglingsDead()
SaveCampaignVar("M2RamonDead", "0")
SaveCampaignVar("M2SpikyDead", "0")
AddFunction({func = KillCyborg, args = {}})
- SaveCampaignVar("Progress", "2")
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
SaveCampaignVar("M2Choice", "" .. choice)
end
@@ -783,7 +785,9 @@ function DoStronglingsDeadRefused()
end
AddAnim(refusedFinalAnim)
AddFunction({func = KillCyborg, args = {}})
- SaveCampaignVar("Progress", "2")
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
SaveCampaignVar("M2Choice", "" .. choice)
end
@@ -791,7 +795,9 @@ function DoStronglingsDeadAttacked()
SaveCampaignVar("M2DenseDead", "1")
SaveCampaignVar("M2RamonDead", "0")
SaveCampaignVar("M2SpikyDead", "0")
- SaveCampaignVar("Progress", "2")
+ if progress and progress<2 then
+ SaveCampaignVar("Progress", "2")
+ end
SaveCampaignVar("M2Choice", "" .. choice)
AddAnim(attackedFinalAnim)
AddFunction({func = KillCyborg, args = {}})
@@ -839,11 +845,9 @@ function onGameInit()
MinesTime = 3000
Explosives = 0
Delay = 10
- MapGen = 0
- TemplateFilter = 6
- TemplateNumber = 22
+ Map = "A_Classic_Fairytale_shadow"
Theme = "Nature"
- SuddenDeathTurns = 3000
+ SuddenDeathTurns = 3000
AddHogs()
PlaceHogs()
@@ -854,6 +858,7 @@ function onGameInit()
end
function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
HideHogs()
AddAmmo(leaks, amSwitch, 100)
AddAmmo(dense, amSwitch, 100)
diff --git a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua
index 37355dc..e891c84 100644
--- a/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua
+++ b/share/hedgewars/Data/Missions/Campaign/A Classic Fairytale/united.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Animate.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Animate.lua")
-----------------------------Constants---------------------------------
choiceAccept = 1
@@ -109,7 +109,9 @@ function AfterFinalAnim()
else
SaveCampaignVar("M4DenseDead", "0")
end
- SaveCampaignVar("Progress", "4")
+ if progress and progress<4 then
+ SaveCampaignVar("Progress", "4")
+ end
ParseCommand("teamgone " .. loc("011101001"))
TurnTimeLeft = 0
end
@@ -416,6 +418,7 @@ function onGameInit()
end
function onGameStart()
+ progress = tonumber(GetCampaignVar("Progress"))
GetVariables()
SetupAmmo()
SetupPlace()
diff --git a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt
index 921f5f7..27d85f8 100644
--- a/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt
+++ b/share/hedgewars/Data/Missions/Campaign/CMakeLists.txt
@@ -3,5 +3,5 @@ add_subdirectory("A Classic Fairytale")
file(GLOB Scripts *.lua)
install(FILES
- ${Scripts}
- DESTINATION ${SHAREPATH}Data/Missions/Campaign)
+ ${Scripts}
+ DESTINATION ${SHAREPATH}Data/Missions/Campaign)
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua
index eaef38b..c4498a8 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua
@@ -13,7 +13,7 @@
-- about translations.
-- We can use the function loc(text) to localize a string.
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
-- This variable will hold the number of destroyed targets.
local score = 0
@@ -22,7 +22,7 @@ local score_goal = 5
-- This variable controls how many milliseconds/ticks we'd
-- like to wait before we end the round once all targets
-- have been destroyed.
-local end_timer = 5000 -- 5000 ms = 5 s
+local end_timer = 1000 -- 1000 ms = 1 s
-- This variable is set to true if the game is lost (i.e.
-- time runs out).
local game_lost = false
@@ -64,7 +64,15 @@ function onGameInit()
-- The base number for the random number generator
Seed = 1
-- Game settings and rules
- GameFlags = gfMultiWeapon + gfOneClanMode + gfSolidLand
+ EnableGameFlags(gfMultiWeapon, gfOneClanMode, gfSolidLand)
+ -- Uncommenting this wouldn't do anything
+ --EnableGameFlags(gfMultiWeapon, gfOneClanMode, gfSolidLand)
+ -- Neither this
+ --DisableGameFlags(gfArtillery)
+ -- Uncommenting this would make the terrain damageable
+ --DisableGameFlags(gfSolidLand)
+ -- Uncommenting this would remove all flags set previously
+ --ClearGameFlags()
-- The time the player has to move each round (in ms)
TurnTime = 60000
-- The frequency of crate drops
@@ -132,11 +140,11 @@ function onGameTick20()
-- ... end the game ...
EndGame()
else
- -- ... or just lower the timer by 1.
- end_timer = end_timer - 20
+ -- ... or just lower the timer by 20ms.
-- Reset the time left to stop the timer
TurnTimeLeft = time_goal
end
+ end_timer = end_timer - 20
end
end
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Cluster_Bomb.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Cluster_Bomb.lua
index d3e2651..bc21d0f 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Cluster_Bomb.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Cluster_Bomb.lua
@@ -1,8 +1,8 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil
local scored = 0
-local end_timer = 5000
+local end_timer = 1000
local game_lost = false
local time_goal = 0
@@ -76,9 +76,9 @@ function onGameTick20()
if end_timer == 0 then
EndGame()
else
- end_timer = end_timer - 20
TurnTimeLeft = time_goal
end
+ end_timer = end_timer - 20
end
end
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Grenade.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Grenade.lua
index 2e4728e..e0798c4 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Grenade.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Grenade.lua
@@ -13,7 +13,7 @@
-- about translations.
-- We can use the function loc(text) to localize a string.
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
-- This variable will hold the number of destroyed targets.
local score = 0
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua
index 0de69b4..c1f8912 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua
@@ -7,8 +7,8 @@
--I know there need to be more "tutorial" specefic messages, but I had a hard timer figuring out what to type / what would be the best technical description.
-loadfile( GetDataPath() .. "Scripts/Locale.lua" )()
-loadfile( GetDataPath() .. "Scripts/Utils.lua" )() -- For the gearIsInBox function, wrote my own, but decided it was a waste to include it
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Utils.lua") -- For the gearIsInBox function, wrote my own, but decided it was a waste to include it
local Player = nil -- Pointer to hog created in: onGameInit
local Target = nil -- Pointer to target hog
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Shotgun.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Shotgun.lua
index 656b73f..220243c 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Shotgun.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Shotgun.lua
@@ -13,7 +13,7 @@
-- about translations.
-- We can use the function loc(text) to localize a string.
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
-- This variable will hold the number of destroyed targets.
local score = 0
@@ -22,7 +22,7 @@ local score_goal = 5
-- This variable controls how many milliseconds/ticks we'd
-- like to wait before we end the round once all targets
-- have been destroyed.
-local end_timer = 5000 -- 5000 ms = 5 s
+local end_timer = 1000 -- 1000 ms = 1 s
-- This variable is set to true if the game is lost (i.e.
-- time runs out).
local game_lost = false
@@ -133,10 +133,10 @@ function onGameTick20()
EndGame()
else
-- ... or just lower the timer by 1.
- end_timer = end_timer - 20
-- Reset the time left to stop the timer
TurnTimeLeft = time_goal
end
+ end_timer = end_timer - 20
end
end
diff --git a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Sniper_Rifle.lua b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Sniper_Rifle.lua
index d9207a5..3547051 100644
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Sniper_Rifle.lua
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Sniper_Rifle.lua
@@ -13,7 +13,7 @@
-- about translations.
-- We can use the function loc(text) to localize a string.
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
-- This variable will hold the number of destroyed targets.
local score = 0
@@ -22,7 +22,7 @@ local score_goal = 31
-- This variable controls how many milliseconds/ticks we'd
-- like to wait before we end the round once all targets
-- have been destroyed.
-local end_timer = 5000 -- 5000 ms = 5 s
+local end_timer = 1000 -- 1000 ms = 1 s
-- This variable is set to true if the game is lost (i.e.
-- time runs out).
local game_lost = false
@@ -145,10 +145,10 @@ function onGameTick20()
EndGame()
else
-- ... or just lower the timer by 1.
- end_timer = end_timer - 20
-- Reset the time left to stop the timer
TurnTimeLeft = time_goal
end
+ end_timer = end_timer - 20
end
end
diff --git a/share/hedgewars/Data/Missions/Training/CMakeLists.txt b/share/hedgewars/Data/Missions/Training/CMakeLists.txt
index 47f01af..b6a6358 100644
--- a/share/hedgewars/Data/Missions/Training/CMakeLists.txt
+++ b/share/hedgewars/Data/Missions/Training/CMakeLists.txt
@@ -1,5 +1,5 @@
file(GLOB Scripts *.lua)
install(FILES
- ${Scripts}
- DESTINATION ${SHAREPATH}Data/Missions/Training)
+ ${Scripts}
+ DESTINATION ${SHAREPATH}Data/Missions/Training)
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Bamboo_Thicket.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Bamboo_Thicket.lua
index fc806dd..ab8b02c 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Bamboo_Thicket.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Bamboo_Thicket.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil
local enemy = nil
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Dangerous_Ducklings.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Dangerous_Ducklings.lua
index a470212..44af356 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Dangerous_Ducklings.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Dangerous_Ducklings.lua
@@ -1,11 +1,9 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil -- This variable will point to the hog's gear
local instructor = nil
local enemy = nil
---local givenSpeech = false
local speechStage = 0
@@ -33,22 +31,18 @@ function onGameInit()
AddTeam(loc("Bloody Rookies"), 14483456, "Simple", "Island", "Default")
player = AddHog(loc("Hunter"), 0, 1, "NoHat")
+ instructor = AddHog(loc("Instructor"), 0, 100, "sf_vega")
- --AddTeam("Instructors", 14483456, "Simple", "Island", "Default")
- instructor = AddHog(loc("Instructor"), 1, 1, "sf_vega")
-
- AddTeam("Blue Team", 29439, "Simple", "Island", "Default")
- enemy = AddHog("Filthy Blue", 1, 100, "Skull")
+ AddTeam(loc("Blue Team"), 29439, "Simple", "Island", "Default")
+ enemy = AddHog(loc("Filthy Blue"), 1, 100, "Skull")
SetGearPosition(player,146,902)
SetGearPosition(instructor,317,902)
SetGearPosition(enemy,1918,837)
-
HogSay(player, ".............................", SAY_THINK)
HogTurnLeft(instructor, true)
-
end
@@ -59,15 +53,7 @@ function onGameStart()
FollowGear(player)
- --spawnTarget()
-
- -- Show some nice mission goals.
- -- Parameters are: caption, sub caption, description,
- -- extra text, icon and time to show.
- -- A negative icon parameter (-n) represents the n-th weapon icon
- -- A positive icon paramter (n) represents the (n+1)-th mission icon
- -- A timeframe of 0 is replaced with the default time to show.
- ShowMission(loc("Dangerous Ducklings"), "", loc("Eliminate the Blue Team"), -amRope, 1);
+ ShowMission(loc("Dangerous Ducklings"), "", loc("Eliminate the Blue Team"), -amRope, 5000);
end
@@ -101,15 +87,14 @@ function onGameTick()
end
-
-- if player falls in water or if player ignores speech
if (CurrentHedgehog ~= nil) and (CurrentHedgehog == player) then
- if (GetY(player) > 2060) and (gameLost == false) then
+ if (GetY(player) > WaterLine) and (gameLost == false) then
HogSay(instructor, loc("DAMMIT, ROOKIE!"), SAY_SHOUT)
gameLost = true
end
- if (GetX(player) > 1324) and (GetY(player) > 1908) and (notListening == false) and (speechStage < 3) then
+ if (GetX(player) > 300) and (GetY(player) > 880) and (notListening == false) and (speechStage < 3) then
HogSay(instructor, loc("DAMMIT, ROOKIE! GET OFF MY HEAD!"), SAY_SHOUT)
notListening = true
end
@@ -126,10 +111,11 @@ function onGameTick()
endTimer = endTimer + 1
if (CurrentHedgehog ~= nil) and (CurrentHedgehog == instructor) then
if endTimer >= 3000 then
- SetHealth(instructor,0)
- TurnTimeLeft = 0
+ --SetHealth(instructor,0)
+ TurnTimeLeft = 1
+ ParseCommand("teamgone " .. loc("Bloody Rookies"))
end
- ShowMission(loc("MISSION FAILED"), loc(":("), loc("You've failed. Try again."), -amRope, 1);
+ ShowMission(loc("MISSION FAILED"), loc(":("), loc("You've failed. Try again."), -amRope, 5000);
end
end
@@ -146,9 +132,12 @@ function onGearDelete(gear)
if GetGearType(gear) == gtHedgehog then
if gear == player then
gameLost = true
- elseif gear == instructor then
+ elseif (gear == instructor) and (GetY(gear) > WaterLine) then
HogSay(player, loc("See ya!"), SAY_THINK)
TurnTimeLeft = 3000
+ AddCaption(loc("Achievement Unlocked") .. ": " .. loc("Naughty Ninja"),0xffba00ff,capgrpMessage2)
+ ParseCommand("teamgone " .. loc("Blue Team"))
+ gameWon = true
elseif gear == enemy then
HogSay(player, loc("Enjoy the swim..."), SAY_THINK)
gameWon = true
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Diver.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Diver.lua
index 65575c2..c6af944 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Diver.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Diver.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil -- This variable will point to the hog's gear
local enemy = nil
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua
index e983f60..a7ff356 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Newton_and_the_Hammock.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil
local enemy = nil
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua
new file mode 100644
index 0000000..20349b4
--- /dev/null
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Nobody_Laugh.lua
@@ -0,0 +1,130 @@
+--------------------------------------
+-- NOBODY LAUGH
+-- a hilarious (not really) adventure
+--------------------------------------
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
+
+local hhs = {}
+
+function onGameInit()
+
+ Seed = 0
+ GameFlags = gfInfAttack + gfPerHogAmmo +gfDisableWind
+ SuddenDeathTurns = 9999
+ TurnTime = 180000
+ CaseFreq = 0
+ MinesNum = 0
+ Explosives = 0
+ Map = "Bath"
+ Theme = "Nature"
+
+ AddTeam(loc("Nameless Heroes"), 14483456, "eyecross", "Wood", "HillBilly", "cm_birdy")
+ hhs[1] = AddHog(loc( "Hunter" ), 0, 1, "Skull")
+ SetGearPosition(hhs[1], 1267, 451)
+ hhs[2] = AddHog(loc("Drowner"), 0, 31, "mp3")
+ SetGearPosition(hhs[2], 1332, 451)
+
+ AddTeam(loc("Clowns"), 1175851, "Duck2", "Tank", "Mobster", "cm_spider")
+ hhs[3] = AddHog("Poison", 5, 100, "WhySoSerious")
+ SetGearPosition(hhs[3], 1133, 446)
+ hhs[4] = AddHog("Bobo", 5, 100, "clown")
+ SetGearPosition(hhs[4], 1215, 553)
+ hhs[5] = AddHog("Copper", 5, 10, "clown-copper")
+ SetGearPosition(hhs[5], 414, 376)
+ hhs[6] = AddHog("Derp", 5, 100, "clown-crossed")
+ SetGearPosition(hhs[6], 1590, 886)
+ hhs[7] = AddHog("Eckles", 5, 100, "clown-copper")
+ SetGearPosition(hhs[7], 772, 754)
+ hhs[8] = AddHog("Frank", 5, 50, "clown-copper")
+ SetGearPosition(hhs[8], 1688, 714)
+ hhs[9] = AddHog("Harry", 5, 50, "clown-copper")
+ SetGearPosition(hhs[9], 1932, 837)
+ hhs[10] = AddHog("Igmund", 5, 50, "WhySoSerious")
+ SetGearPosition(hhs[10], 1601, 733)
+
+end
+
+function onGameStart()
+
+ AddAmmo(enemy, amAirAttack, 100)
+
+ ShowMission( loc("Nobody Laugh"),
+ loc("User Challenge"),
+ loc("Eliminate the enemy before the time runs out")
+ , 0, 0
+ )
+
+ -- GIRDERS
+ PlaceGirder(1212, 710, 7)
+ PlaceGirder(1215, 570, 4)
+ PlaceGirder(1288, 520, 2)
+ PlaceGirder(1184, 468, 4)
+ PlaceGirder(1344, 468, 4)
+ PlaceGirder(1247, 346, 4)
+
+ PlaceGirder(667, 438, 4)
+ PlaceGirder(507, 438, 4)
+ PlaceGirder(434, 487, 2)
+ PlaceGirder(505, 537, 4)
+ PlaceGirder(665, 537, 4)
+ PlaceGirder(737, 487, 2)
+
+ PlaceGirder(416, 465, 6)
+ PlaceGirder(1415, 378, 6)
+ PlaceGirder(1300, 625, 3)
+ PlaceGirder(1359, 566, 3)
+ PlaceGirder(1436, 538, 0)
+ PlaceGirder(1505, 468, 4)
+
+ ------ AMMO CRATE LIST ------
+ tempG = SpawnAmmoCrate(1242, 315, amBaseballBat)
+ tempG = SpawnAmmoCrate(1309, 315, amAirAttack)
+ tempG = SpawnAmmoCrate(144, 895, amAirAttack)
+ tempG = SpawnAmmoCrate(664, 699, amIceGun)
+ tempG = SpawnAmmoCrate(1572, 444, amFirePunch)
+ tempG = SpawnAmmoCrate(1574, 382, amDynamite)
+
+ ------ UTIL CRATE LIST ------
+ tempG = SpawnUtilityCrate(654, 513, amParachute)
+ tempG = SpawnUtilityCrate(1569, 413, amParachute)
+
+ -- HOG AMMO
+ AddAmmo(hhs[1],amParachute,1)
+ AddAmmo(hhs[1],amHammer,1)
+ AddAmmo(hhs[2],amWhip,1)
+
+ for i = 3, 10 do
+ AddAmmo(hhs[i], amDeagle, 100)
+ AddAmmo(hhs[i], amShotgun, 100)
+ AddAmmo(hhs[i], amGrenade, 100)
+ AddAmmo(hhs[i], amBazooka, 100)
+ AddAmmo(hhs[i], amDrill, 100)
+ end
+
+end
+
+function onNewTurn()
+ SetWind(100)
+end
+
+function onAmmoStoreInit()
+
+ SetAmmo(amBaseballBat, 0, 0, 0, 1)
+ SetAmmo(amAirAttack, 0, 0, 0, 1)
+ SetAmmo(amFirePunch, 0, 0, 0, 1)
+ SetAmmo(amDynamite, 0, 0, 0, 1)
+ SetAmmo(amHammer, 0, 0, 0, 1)
+ SetAmmo(amIceGun, 0, 0, 0, 1)
+
+ SetAmmo(amParachute, 0, 0, 0, 1)
+
+ SetAmmo(amSwitch, 9, 0, 0, 0)
+ SetAmmo(amSkip, 9, 0, 0, 0)
+
+end
+
+------------------------------
+-- I'm in whitesppaaaaaaaaaacceeeee :D
+------------------------------
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_RCPlane_Challenge.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_RCPlane_Challenge.lua
index 770abff..d9aa367 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_RCPlane_Challenge.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_RCPlane_Challenge.lua
@@ -1,4 +1,4 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil
local RCGear = nil
@@ -20,7 +20,7 @@ function onGameInit()
Explosives = 0
AddTeam(loc("Wannabe Flyboys"), 14483456, "Simple", "Island", "Default", "Hedgewars")
- player = AddHog(loc("Ace"), 0, 80, "Gasmask") --NoHat
+ player = AddHog(loc("Ace"), 0, 80, "Gasmask")
SetGearPosition(player, 1380, 1500)
end
@@ -314,6 +314,10 @@ function onGearDelete(gear)
if cratesLeft == 0 then
+ if planesUsed == 1 then
+ AddCaption(loc("Achievement Unlocked") .. ": " .. loc("Prestigious Pilot"),0xffba00ff,capgrpMessage2)
+ end
+
ShowMission (
loc("CHALLENGE COMPLETE"),
loc("Congratulations!"),
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Rope_Knock_Challenge.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Rope_Knock_Challenge.lua
index 64b1780..5e9f45f 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Rope_Knock_Challenge.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Rope_Knock_Challenge.lua
@@ -1,4 +1,4 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local hhs = {}
local missionWon = nil
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Spooky_Tree.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Spooky_Tree.lua
index 7f09c32..752eb4d 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Spooky_Tree.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Spooky_Tree.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
---------------------------------------------------------------
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_Teamwork.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_Teamwork.lua
index cc15dfb..7834a87 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_Teamwork.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_Teamwork.lua
@@ -1,4 +1,4 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil -- This variable will point to the hog's gear
local p2 = nil
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua
index 317d5b5..105c951 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_That_Sinking_Feeling.lua
@@ -1,6 +1,6 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player
local hh = {}
diff --git a/share/hedgewars/Data/Missions/Training/User_Mission_-_The_Great_Escape.lua b/share/hedgewars/Data/Missions/Training/User_Mission_-_The_Great_Escape.lua
index e43cb0f..928f45d 100644
--- a/share/hedgewars/Data/Missions/Training/User_Mission_-_The_Great_Escape.lua
+++ b/share/hedgewars/Data/Missions/Training/User_Mission_-_The_Great_Escape.lua
@@ -1,4 +1,4 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local player = nil
local enemy = nil
diff --git a/share/hedgewars/Data/Missions/Training/portal.lua b/share/hedgewars/Data/Missions/Training/portal.lua
index f6b9276..2fcbb24 100644
--- a/share/hedgewars/Data/Missions/Training/portal.lua
+++ b/share/hedgewars/Data/Missions/Training/portal.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Utils.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Utils.lua")
local MineArray = {}
local player
diff --git a/share/hedgewars/Data/Music/CMakeLists.txt b/share/hedgewars/Data/Music/CMakeLists.txt
index b4eb3eb..c4ba127 100644
--- a/share/hedgewars/Data/Music/CMakeLists.txt
+++ b/share/hedgewars/Data/Music/CMakeLists.txt
@@ -1,5 +1,5 @@
-file(GLOB BaseMusic *.ogg)
+file(GLOB BaseMusic *.ogg)
install(FILES
- ${BaseMusic}
- DESTINATION ${SHAREPATH}Data/Music)
+ ${BaseMusic}
+ DESTINATION ${SHAREPATH}Data/Music)
diff --git a/share/hedgewars/Data/Names/CMakeLists.txt b/share/hedgewars/Data/Names/CMakeLists.txt
index b20c322..fb83435 100644
--- a/share/hedgewars/Data/Names/CMakeLists.txt
+++ b/share/hedgewars/Data/Names/CMakeLists.txt
@@ -2,7 +2,7 @@ file(GLOB txtnames *.txt)
file(GLOB cfgnames *.cfg)
install(FILES
- types.ini
- ${txtnames}
- ${cfgnames}
- DESTINATION ${SHAREPATH}Data/Names)
+ types.ini
+ ${txtnames}
+ ${cfgnames}
+ DESTINATION ${SHAREPATH}Data/Names)
diff --git a/share/hedgewars/Data/Scripts/CMakeLists.txt b/share/hedgewars/Data/Scripts/CMakeLists.txt
index 887c434..1a88ec9 100644
--- a/share/hedgewars/Data/Scripts/CMakeLists.txt
+++ b/share/hedgewars/Data/Scripts/CMakeLists.txt
@@ -1,7 +1,7 @@
file(GLOB luafiles *.lua)
install(FILES
- ${luafiles}
- DESTINATION ${SHAREPATH}Data/Scripts)
+ ${luafiles}
+ DESTINATION ${SHAREPATH}Data/Scripts)
add_subdirectory(Multiplayer)
diff --git a/share/hedgewars/Data/Scripts/Locale.lua b/share/hedgewars/Data/Scripts/Locale.lua
index ddc1817..872119f 100644
--- a/share/hedgewars/Data/Scripts/Locale.lua
+++ b/share/hedgewars/Data/Scripts/Locale.lua
@@ -1,18 +1,9 @@
-- Library for localizing strings in lua scripts
-local lang = loadfile(GetUserDataPath() .. "Locale/" .. tostring(L) .. ".lua")
-
-if lang ~= nil then
- lang()
-else
- lang = loadfile(GetDataPath() .. "Locale/" .. tostring(L) .. ".lua")
- if lang ~= nil then
- lang()
- end
-end
+local lang = HedgewarsScriptLoad("Locale/" .. tostring(L) .. ".lua")
function loc(text)
- if lang ~= nil and locale ~= nil and locale[text] ~= nil then return locale[text]
+ if locale ~= nil and locale[text] ~= nil then return locale[text]
else return text
end
end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua b/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
index f85a36d..5bf9a17 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.lua
@@ -1,5 +1,5 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
local weapons = { amGrenade, amClusterBomb, amBazooka, amBee, amShotgun, amMine, amDEagle, amDynamite, amFirePunch, amWhip, amPickHammer, amBaseballBat, amMortar, amCake, amSeduction, amWatermelon, amHellishBomb, amDrill, amBallgun, amRCPlane, amSniperRifle, amMolotov, amBirdy, amBlowTorch, amGasBomb, amFlamethrower, amSMine, amKamikaze }
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/CMakeLists.txt b/share/hedgewars/Data/Scripts/Multiplayer/CMakeLists.txt
index 086205f..b603c25 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/CMakeLists.txt
+++ b/share/hedgewars/Data/Scripts/Multiplayer/CMakeLists.txt
@@ -2,6 +2,6 @@ file(GLOB luafiles *.lua)
file(GLOB cfgfiles *.cfg)
install(FILES
- ${luafiles}
- ${cfgfiles}
- DESTINATION ${SHAREPATH}Data/Scripts/Multiplayer)
+ ${luafiles}
+ ${cfgfiles}
+ DESTINATION ${SHAREPATH}Data/Scripts/Multiplayer)
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua b/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua
index 2248d96..a09ce32 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.lua
@@ -75,7 +75,7 @@
-----------------
-- enable awesome translaction support so we can use loc() wherever we want
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
---------------------------------------------------------------
----------lots of bad variables and things
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua b/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua
index c1e6cca..5d315e4 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Continental_supplies.lua
@@ -1,5 +1,5 @@
--[[
-Continental Supplies version 1.1a
+Version 1.1c
Copyright (C) 2012 Vatten
@@ -10,21 +10,29 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Utils.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Utils.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
function int_sqrt(num)
- temp=num
+ local temp=num
while(temp*temp-div(temp,2)>num)
do
temp=div((temp+div(num,temp)),2)
end
+
return math.abs(temp)
end
function norm(xx,yy)
- return int_sqrt((xx^2)+(yy^2))
+ --to fix overflows
+ if(((math.abs(xx)^2)+(math.abs(yy)^2))>2^26)
+ then
+ local bitr=2^13
+ return int_sqrt((div(math.abs(xx),bitr)^2)+(div(math.abs(yy),bitr)^2))*bitr
+ else
+ return int_sqrt((math.abs(xx)^2)+(math.abs(yy)^2))
+ end
end
function positive(num)
@@ -40,7 +48,7 @@ local teams_ok = {}
local wepcode_teams={}
local swapweps=false
---run when game starts on real
+--variables for seeing if you have swaped around on a weapon
local australianSpecial=false
local africanSpecial=0
local africaspecial2=0
@@ -51,32 +59,37 @@ local sniper_s_in_use=false
local kergulenSpecial=1
local shotgun_s=false
local europe_s=0
+local VampOn=0
local austmine=nil
local inpara=false
local asianflame=0
+local visualcircle=nil
+
local temp_val=0
---för sabotage
+--for sabotage
local disallowattack=0
-local disallowleft=true
local disable_moving={}
+local disableoffsetai=0
+local onsabotageai=false
---skall bytas till för alla teams
local continent = {}
+local generalinfo=loc("- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]")
+
local weapontexts = {
loc("Green lipstick bullet: [Is poisonous]"),
loc("Piñata bullet: [Contains some sweet candy!]"),
loc("Anno 1032: [The explosion will make a strong push ~ wide range, wont affect hogs close to the target]"),
-loc("Dust storm: [Deals 20 damage to all enemies in the circle]"),
+loc("Dust storm: [Deals 15 damage to all enemies in the circle]"),
loc("Fire a mine: [Does what it says ~ Cant be dropped close to an enemy ~ 1 sec]"),
-loc("Drop a bomb: [drop some heroic wind that will turn into a bomb on impact]"),
+loc("Drop a bomb: [drop some heroic wind that will turn into a bomb on impact ~ once per turn]"),
loc("Scream from a Walrus: [Deal 20 damage + 10% of your hogs health to all hogs around you and get half back]"),
loc("Disguise as a Rockhopper Penguin: [Swap place with a random enemy hog in the circle]"),
loc("Flare: [fire up some bombs depending on hogs depending on hogs in the circle"),
-loc("Lonely Cries: [Rise the water if no hog is in the circle and deal 1 damage to all hogs]"),
+loc("Lonely Cries: [Rise the water if no hog is in the circle and deal 7 damage to all enemy hogs]"),
loc("Hedgehog projectile: [fire your hog like a Sticky Bomb]"),
loc("Napalm rocket: [Fire a bomb with napalm!]"),
loc("Eagle Eye: [Blink to the impact ~ one shot]"),
@@ -90,31 +103,43 @@ local weaponsets =
{{amShotgun,100},{amDEagle,100},{amLaserSight,4},{amSniperRifle,100},{amCake,1},{amAirAttack,2},{amSwitch,6}}},
{loc("South America"),"Area: 17,840,000 km2, Population: 387,489,196 ",loc("Special Weapons:").."|"..loc("GasBomb")..": "..weapontexts[3],amGasBomb,
-{{amBirdy,5},{amHellishBomb,1},{amBee,100},{amWhip,100},{amGasBomb,100},{amFlamethrower,100},{amNapalm,1},{amExtraDamage,2}}},
+{{amBirdy,6},{amHellishBomb,1},{amBee,100},{amWhip,100},{amGasBomb,100},{amFlamethrower,100},{amNapalm,1},{amExtraDamage,2}}},
{loc("Europe"),"Area: 10,180,000 km2, Population: 739,165,030",loc("Special Weapons:").."|"..loc("Molotov")..": "..weapontexts[14],amBazooka,
{{amBazooka,100},{amGrenade,100},{amMortar,100},{amClusterBomb,5},{amMolotov,5},{amVampiric,4},{amPiano,1},{amResurrector,2},{amJetpack,2}}},
{loc("Africa"),"Area: 30,221,532 km2, Population: 1,032,532,974",loc("Special Weapons:").."|"..loc("Seduction")..": "..weapontexts[4].."|"..loc("Sticky Mine")..": "..weapontexts[11].."|"..loc("Sticky Mine")..": "..weapontexts[12],amSMine,
-{{amSMine,6},{amWatermelon,1},{amDrillStrike,1},{amExtraTime,2},{amDrill,100},{amLandGun,3},{amSeduction,100}}},
+{{amSMine,100},{amWatermelon,1},{amDrillStrike,1},{amExtraTime,2},{amDrill,100},{amLandGun,3},{amSeduction,100}}},
-{loc("Asia"),"Area: 44,579,000 km2, Population: 3,879,000,000",loc("- Will refresh Parachute each turn.").."|"..loc("Special Weapons:").."|"..loc("Parachute")..": "..weapontexts[6],amRope,
-{{amKamikaze,4},{amRope,100},{amFirePunch,100},{amParachute,1},{amKnife,4},{amDynamite,1}}},
+{loc("Asia"),"Area: 44,579,000 km2, Population: 3,879,000,000",loc("- Will give you a parachute each turn.").."|"..loc("Special Weapons:").."|"..loc("Parachute")..": "..weapontexts[6],amRope,
+{{amKamikaze,4},{amRope,100},{amFirePunch,100},{amParachute,1},{amKnife,2},{amDynamite,1}}},
{loc("Australia"),"Area: 8,468,300 km2, Population: 31,260,000",loc("Special Weapons:").."|"..loc("Baseballbat")..": "..weapontexts[5],amBaseballBat,
{{amBaseballBat,100},{amMine,100},{amLowGravity,6},{amBlowTorch,100},{amRCPlane,2},{amTardis,100}}},
-{loc("Antarctica"),"Area: 14,000,000 km2, Population: ~1,000",loc("- Will refresh portalgun each turn."),amTeleport,
-{{amSnowball,4},{amTeleport,2},{amInvulnerable,6},{amPickHammer,100},{amSineGun,100},{amGirder,4},{amPortalGun,1}}},
+{loc("Antarctica"),"Area: 14,000,000 km2, Population: ~1,000",loc("- Will give you a portalgun every second turn."),amTeleport,
+{{amSnowball,4},{amTeleport,2},{amInvulnerable,6},{amPickHammer,100},{amSineGun,100},{amGirder,3},{amPortalGun,2}}},
-{loc("Kerguelen"),"Area: 1,100,000 km2, Population: ~70",loc("Special Weapons:").."|"..loc("Structure")..": "..weapontexts[7].."|"..loc("Structure")..": "..weapontexts[8].." ("..loc("Duration")..": 2)|"..loc("Structure")..": "..weapontexts[9].."|"..loc("Structure")..": "..weapontexts[10],amStructure,
-{{amHammer,100},{amMineStrike,2},{amBallgun,1},{amStructure,100}}},
---no ,{amIceGun,4} for 0.9.18
+{loc("Kerguelen"),"Area: 1,100,000 km2, Population: ~70",loc("Special Weapons:").."|"..loc("Hammer")..": "..weapontexts[7].."|"..loc("Hammer")..": "..weapontexts[8].." ("..loc("Duration")..": 2)|"..loc("Hammer")..": "..weapontexts[9].."|"..loc("Hammer")..": "..weapontexts[10].."|"..loc("Hammer")..": "..weapontexts[15],amHammer,
+{{amHammer,100},{amMineStrike,2},{amBallgun,1},{amIceGun,2}}},
{loc("Zealandia"),"Area: 3,500,000 km2, Population: 4,650,000",loc("- Will Get 1-3 random weapons"),amInvulnerable,
{{amBazooka,1},{amBlowTorch,1},{amSwitch,1}}}
}
+local weaponsetssounds=
+{
+{sndShotgunFire,sndCover},
+{sndEggBreak,sndLaugh},
+{sndExplosion,sndEnemyDown},
+{sndMelonImpact,sndHello},
+{sndRopeAttach,sndComeonthen},
+{sndBaseballBat,sndNooo},
+{sndSineGun,sndOops},
+{sndPiano5,sndStupid},
+{sndSplash,sndFirstBlood}
+}
+
--weapontype,ammo,?,duration,*times your choice,affect on random team (should be placed with 1,0,1,0,1 on the 6th option for better randomness)
local weapons_dmg = {
{amKamikaze, 0, 1, 0, 1, 0},
@@ -152,8 +177,8 @@ local weapons_dmg = {
{amSMine, 0, 1, 0, 1, 1},
{amHammer, 0, 1, 0, 1, 0},
{amDrillStrike, 0, 1, 4, 1, 2},
- {amSnowball, 0, 1, 0, 1, 0},
- {amStructure, 0, 0, 0, 1, 1}
+ {amSnowball, 0, 1, 0, 1, 0}
+ --{amStructure, 0, 0, 0, 1, 1}
}
local weapons_supp = {
{amParachute, 0, 1, 0, 1, 0},
@@ -175,7 +200,8 @@ local weapons_supp = {
{amIceGun, 0, 1, 0, 1, 0},
{amKnife, 0, 1, 0, 1, 0}
}
-
+
+--will check after borders and stuff
function validate_weapon(hog,weapon,amount)
if(MapHasBorder() == false or (MapHasBorder() == true and weapon ~= amAirAttack and weapon ~= amMineStrike and weapon ~= amNapalm and weapon ~= amDrillStrike and weapon ~= amPiano))
then
@@ -187,8 +213,8 @@ end
function cleanweps(hog)
local i=1
- --+1 for skip
- while(i<=table.getn(weapons_supp)+table.getn(weapons_dmg)+1)
+ --+1 for skip +1 for freezer
+ while(i<=table.maxn(weapons_supp)+table.maxn(weapons_dmg)+2)
do
AddAmmo(hog,i,0)
i=i+1
@@ -197,6 +223,7 @@ function cleanweps(hog)
AddAmmo(hog,amSkip,100)
end
+--get the weapons from a weaponset
function load_weaponset(hog, num)
for v,w in pairs(weaponsets[num][5])
do
@@ -204,6 +231,7 @@ function load_weaponset(hog, num)
end
end
+--list up all weapons from the icons for each continent
function load_continent_selection(hog)
for v,w in pairs(weaponsets)
do
@@ -212,20 +240,27 @@ function load_continent_selection(hog)
AddAmmo(hog,amSwitch) --random continent
end
-function show_continent_info(continent,time)
+--shows the continent info
+function show_continent_info(continent,time,generalinf)
+ local geninftext=""
local ns=false
if(time==-1)
then
time=0
ns=true
end
- ShowMission(weaponsets[continent][1],weaponsets[continent][2],weaponsets[continent][3], -weaponsets[continent][4], time)
+ if(generalinf)
+ then
+ geninftext="| |"..loc("General information")..": |"..generalinfo
+ end
+ ShowMission(weaponsets[continent][1],weaponsets[continent][2],weaponsets[continent][3]..geninftext, -weaponsets[continent][4], time)
if(ns)
then
HideMission()
end
end
+--will show a circle of gears (eye candy)
function visual_gear_explosion(range,xpos,ypos,gear1,gear2)
local degr=0
local lap=30
@@ -245,94 +280,97 @@ function visual_gear_explosion(range,xpos,ypos,gear1,gear2)
end
end
---zealandia
+--zealandia (generates weapons from the weaponinfo above
function get_random_weapon(hog)
- if(GetGearType(hog) == gtHedgehog)
+ if(GetGearType(hog) == gtHedgehog and continent[GetHogTeamName(hog)]==9 and getTeamValue(GetHogTeamName(hog), "rand-done-turn")==nil)
then
+ cleanweps(hog)
+
local random_weapon = 0
local old_rand_weap = 0
local rand_weaponset_power = 0
- if(continent[GetHogTeamName(hog)]==9 and (getTeamValue(GetHogTeamName(hog), "rand-done-turn")==false or getTeamValue(GetHogTeamName(hog), "rand-done-turn")==nil))
- then
- cleanweps(hog)
+ local numberof_weapons_supp=table.maxn(weapons_supp)
+ local numberof_weapons_dmg=table.maxn(weapons_dmg)
+
+ local rand1=GetRandom(table.maxn(weapons_supp))+1
+ local rand2=GetRandom(table.maxn(weapons_dmg))+1
+
+ random_weapon = GetRandom(table.maxn(weapons_dmg))+1
+
+ while(weapons_dmg[random_weapon][4]>TotalRounds)
+ do
+ if(random_weapon>=numberof_weapons_dmg)
+ then
+ random_weapon=0
+ end
+ random_weapon = random_weapon+1
+ end
+ validate_weapon(hog, weapons_dmg[random_weapon][1],1)
+ rand_weaponset_power=weapons_dmg[random_weapon][6]
+ old_rand_weap = random_weapon
- random_weapon = GetRandom(table.getn(weapons_dmg))+1
- while(weapons_dmg[random_weapon][4]>TotalRounds)
+ if(rand_weaponset_power <2)
+ then
+ random_weapon = rand1
+ while(weapons_supp[random_weapon][4]>TotalRounds or rand_weaponset_power+weapons_supp[random_weapon][6]>2)
do
- if(random_weapon>=table.getn(weapons_dmg))
+ if(random_weapon>=numberof_weapons_supp)
then
random_weapon=0
end
random_weapon = random_weapon+1
end
- validate_weapon(hog, weapons_dmg[random_weapon][1],1)
- rand_weaponset_power=weapons_dmg[random_weapon][6]
- old_rand_weap = random_weapon
-
- if(rand_weaponset_power <2)
- then
- random_weapon = GetRandom(table.getn(weapons_supp))+1
- while(weapons_supp[random_weapon][4]>TotalRounds or rand_weaponset_power+weapons_supp[random_weapon][6]>2)
- do
- if(random_weapon>=table.getn(weapons_supp))
- then
- random_weapon=0
- end
- random_weapon = random_weapon+1
- end
- validate_weapon(hog, weapons_supp[random_weapon][1],1)
- rand_weaponset_power=rand_weaponset_power+weapons_supp[random_weapon][6]
- end
- --check again if the power is enough
- if(rand_weaponset_power <1)
- then
- random_weapon = GetRandom(table.getn(weapons_dmg))+1
- while(weapons_dmg[random_weapon][4]>TotalRounds or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0)
- do
- if(random_weapon>=table.getn(weapons_dmg))
- then
- random_weapon=0
- end
- random_weapon = random_weapon+1
+ validate_weapon(hog, weapons_supp[random_weapon][1],1)
+ rand_weaponset_power=rand_weaponset_power+weapons_supp[random_weapon][6]
+ end
+ --check again if the power is enough
+ if(rand_weaponset_power <1)
+ then
+ random_weapon = rand2
+ while(weapons_dmg[random_weapon][4]>TotalRounds or old_rand_weap == random_weapon or weapons_dmg[random_weapon][6]>0)
+ do
+ if(random_weapon>=numberof_weapons_dmg)
+ then
+ random_weapon=0
end
- validate_weapon(hog, weapons_dmg[random_weapon][1],1)
- end
-
- setTeamValue(GetHogTeamName(hog), "rand-done-turn", true)
-
- if(GetHogTeamName(hog)==GetHogTeamName(CurrentHedgehog))
- then
- temp_val=false
+ random_weapon = random_weapon+1
end
+ validate_weapon(hog, weapons_dmg[random_weapon][1],1)
end
+
+ setTeamValue(GetHogTeamName(hog), "rand-done-turn", true)
end
end
-
-function setweapons(skipafter)
+--this will take that hogs settings for the weapons and add them
+function setweapons()
cleanweps(CurrentHedgehog)
load_weaponset(CurrentHedgehog,continent[GetHogTeamName(CurrentHedgehog)])
- if(skipafter==true)
- then
- ParseCommand("setweap " .. string.char(amSkip))
- end
-
- show_continent_info(continent[GetHogTeamName(CurrentHedgehog)],0)
+
+ visualstuff=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-5, vgtDust,0, false)
+ v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 = GetVisualGearValues(visualstuff)
+ SetVisualGearValues(visualstuff, v1, v2, v3, v4, v5, v6, v7, 2, v9, GetClanColor(GetHogClan(CurrentHedgehog)))
+
+ show_continent_info(continent[GetHogTeamName(CurrentHedgehog)],0,false)
end
+--show health tag (will mostly be used when a hog is damaged)
function show_damage_tag(hog,damage)
healthtag=AddVisualGear(GetX(hog), GetY(hog), vgtHealthTag, damage, false)
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 = GetVisualGearValues(healthtag)
SetVisualGearValues(healthtag, v1, v2, v3, v4, v5, v6, v7, v8, v9, GetClanColor(GetHogClan(hog)))
end
+--will use int_sqrt
function fire_gear(hedgehog,geartype,vx,vy,timer)
- return AddGear(div((GetGearRadius(hedgehog)*2*vx),norm(vx,vy))+GetX(hedgehog), div((GetGearRadius(hedgehog)*2*vy),norm(vx,vy))+GetY(hedgehog), geartype, 0, vx, vy, timer)
+ local hypo=norm(vx,vy)
+ return AddGear(div((GetGearRadius(hedgehog)*2*vx),hypo)+GetX(hedgehog), div((GetGearRadius(hedgehog)*2*vy),hypo)+GetY(hedgehog), geartype, 0, vx, vy, timer)
end
--==========================run throw all hog/gear weapons ==========================
+--will check if the mine is nicely placed
function weapon_aust_check(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -343,16 +381,19 @@ function weapon_aust_check(hog)
end
end
+--african special on sedunction
function weapon_duststorm(hog)
if(GetGearType(hog) == gtHedgehog)
then
- local dmg=20
+ local dmg=15
if(gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 250, false)==true and GetHogClan(hog) ~= GetHogClan(CurrentHedgehog))
then
if(GetHealth(hog) > dmg)
then
+ temp_val=temp_val+div(dmg*VampOn,100)
SetHealth(hog, GetHealth(hog)-dmg)
else
+ temp_val=temp_val+div(GetHealth(hog)*VampOn,100)
SetHealth(hog, 0)
end
show_damage_tag(hog,dmg)
@@ -360,6 +401,7 @@ function weapon_duststorm(hog)
end
end
+--kerguelen special on structure
function weapon_scream_walrus(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -367,11 +409,11 @@ function weapon_scream_walrus(hog)
then
if(GetHealth(hog)>(20+GetHealth(CurrentHedgehog)*0.1))
then
+ temp_val=temp_val+10+(GetHealth(CurrentHedgehog)*0.05)+div((20+GetHealth(CurrentHedgehog)*0.1)*VampOn,100)
SetHealth(hog, GetHealth(hog)-(20+GetHealth(CurrentHedgehog)*0.1))
- temp_val=temp_val+10+GetHealth(CurrentHedgehog)*0.05
else
+ temp_val=temp_val+(GetHealth(hog)*0.5)+(GetHealth(CurrentHedgehog)*0.05)+div((GetHealth(hog)+(GetHealth(CurrentHedgehog)*0.1))*VampOn,100)
SetHealth(hog, 0)
- temp_val=temp_val+(GetHealth(hog)*0.5)+(GetHealth(CurrentHedgehog)*0.05)
end
show_damage_tag(hog,(20+GetHealth(CurrentHedgehog)*0.1))
AddVisualGear(GetX(hog), GetY(hog), vgtExplosion, 0, false)
@@ -380,6 +422,7 @@ function weapon_scream_walrus(hog)
end
end
+--kerguelen special swap hog
function weapon_swap_kerg(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -394,6 +437,7 @@ function weapon_swap_kerg(hog)
end
end
+--kerguelen special on structure
function weapon_flare(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -414,6 +458,7 @@ function weapon_flare(hog)
end
end
+--kerguelen special will apply sabotage
function weapon_sabotage(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -426,10 +471,12 @@ function weapon_sabotage(hog)
end
end
+--south american special (used fire gear)
function weapon_anno_south(hog)
- local power_radius_outer=250
- local power_radius_inner=40
+ local power_radius_outer=230
+ local power_radius_inner=45
local power_sa=500000
+ local hypo=0
if(gearIsInCircle(hog,GetX(temp_val), GetY(temp_val), power_radius_outer, false) and gearIsInCircle(hog,GetX(temp_val), GetY(temp_val), power_radius_inner, false)==false)
then
if(hog == CurrentHedgehog)
@@ -437,32 +484,41 @@ function weapon_anno_south(hog)
SetState(CurrentHedgehog, gstMoving)
end
SetGearPosition(hog, GetX(hog),GetY(hog)-3)
- SetGearVelocity(hog, div((power_radius_outer-norm(math.abs(GetX(hog)-GetX(temp_val)),math.abs(GetY(hog)-GetY(temp_val))))*power_sa*positive(GetX(hog)-GetX(temp_val)),power_radius_outer), div((power_radius_outer-norm(math.abs(GetX(hog)-GetX(temp_val)),math.abs(GetY(hog)-GetY(temp_val))))*power_sa*positive(GetY(hog)-GetY(temp_val)),power_radius_outer))
+ hypo=norm(math.abs(GetX(hog)-GetX(temp_val)),math.abs(GetY(hog)-GetY(temp_val)))
+ SetGearVelocity(hog, div((power_radius_outer-hypo)*power_sa*positive(GetX(hog)-GetX(temp_val)),power_radius_outer), div((power_radius_outer-hypo)*power_sa*positive(GetY(hog)-GetY(temp_val)),power_radius_outer))
end
end
+--first part on kerguelen special (lonely cries)
function weapon_cries_a(hog)
- if(GetGearType(hog) == gtHedgehog)
+ if(GetGearType(hog) == gtHedgehog and hog ~= CurrentHedgehog and gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 500, false))
then
- if(GetHogClan(hog) ~= GetHogClan(CurrentHedgehog) and gearIsInCircle(hog,GetX(CurrentHedgehog), GetY(CurrentHedgehog), 500, false))
- then
- kergulenSpecial=-1
- end
+ kergulenSpecial=-1
end
end
+--second part on kerguelen special (lonely cries)
function weapon_cries_b(hog)
if(GetGearType(hog) == gtHedgehog)
then
+ local dmg=7
if(GetHogClan(hog) ~= GetHogClan(CurrentHedgehog))
then
- SetHealth(hog, GetHealth(hog)-1)
- show_damage_tag(hog,1)
+ if(GetHealth(hog) > dmg)
+ then
+ temp_val=temp_val+div(dmg*VampOn,100)
+ SetHealth(hog, GetHealth(hog)-dmg)
+ else
+ temp_val=temp_val+div(GetHealth(hog)*VampOn,100)
+ SetHealth(hog, 0)
+ end
+ show_damage_tag(hog,dmg)
AddVisualGear(GetX(hog), GetY(hog)-30, vgtEvilTrace, 0, false)
end
end
end
+--north american special on sniper
function weapon_lipstick(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -474,6 +530,7 @@ function weapon_lipstick(hog)
end
end
+--european special on molotov (used fire gear)
function weapon_health(hog)
if(GetGearType(hog) == gtHedgehog)
then
@@ -505,13 +562,14 @@ end
function onGameStart()
--trackTeams()
- ShowMission(loc("Continental supplies").." 1.1a",loc("Let a Continent provide your weapons!"),
- loc("- Per team weapons|- 9 weaponschemes|- Unique new weapons| |Select continent first round with the Weapon Menu or by ([switch/tab]=Increase,[presice/left shift]=Decrease) on Skip|Some weapons have a second option. Find them with [switch/tab]"), -amLowGravity, 0)
+ ShowMission(loc("Continental supplies").." 1.1c",loc("Let a Continent provide your weapons!"),
+ loc(generalinfo), -amLowGravity, 0)
end
--what happen when a turn starts
function onNewTurn()
-
+
+ --will refresh the info on each tab weapon
australianSpecial=true
asianSpecial=false
austmine=nil
@@ -524,13 +582,18 @@ function onNewTurn()
shotgun_s=false
sniper_s_in_use=false
europe_s=0
+ VampOn=0
temp_val=0
+ --for sabotage
disallowattack=0
- disallowleft=true
- --when all hogs are "placed"
+ if(disable_moving[CurrentHedgehog]==true)
+ then
+ disableoffsetai=GetHogLevel(CurrentHedgehog)
+ end
+ --when all hogs are "placed"
if(GetCurAmmoType()~=amTeleport)
then
--will run once when the game really starts (after placing hogs and so on
@@ -543,34 +606,42 @@ function onNewTurn()
swapweps=true
teams_ok[GetHogTeamName(CurrentHedgehog)] = 2
else
+ --if its not the initialization turn
swapweps=false
if(continent[GetHogTeamName(CurrentHedgehog)]==0)
then
- continent[GetHogTeamName(CurrentHedgehog)]=GetRandom(table.getn(weaponsets))+1
- setweapons(false)
+ continent[GetHogTeamName(CurrentHedgehog)]=GetRandom(table.maxn(weaponsets))+1
+ setweapons()
+ end
+ show_continent_info(continent[GetHogTeamName(CurrentHedgehog)],-1,true)
+
+ --give zeelandia-teams new weapons so they can plan for the next turn
+ runOnGears(get_random_weapon)
+
+ --some specials for some continents (temp_val is from get random weapons)
+ if(continent[GetHogTeamName(CurrentHedgehog)]==9)
+ then
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "rand-done-turn", nil)
+ elseif(continent[GetHogTeamName(CurrentHedgehog)]==7)
+ then
+ if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")==nil)
+ then
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", 1)
+ end
+
+ if(getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")>=2)
+ then
+ AddAmmo(CurrentHedgehog,amPortalGun)
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", 0)
+ end
+ setTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick", getTeamValue(GetHogTeamName(CurrentHedgehog), "Antarctica-turntick")+1)
+
+ elseif(continent[GetHogTeamName(CurrentHedgehog)]==5)
+ then
+ AddAmmo(CurrentHedgehog,amParachute)
end
- show_continent_info(continent[GetHogTeamName(CurrentHedgehog)],-1)
end
end
-
- if(continent[GetHogTeamName(CurrentHedgehog)]==7)
- then
- AddAmmo(CurrentHedgehog,amPortalGun,0)
- AddAmmo(CurrentHedgehog,amPortalGun,1)
- elseif(continent[GetHogTeamName(CurrentHedgehog)]==5)
- then
- AddAmmo(CurrentHedgehog,amParachute,0)
- AddAmmo(CurrentHedgehog,amParachute,1)
- end
-
- temp_val=true
- runOnGears(get_random_weapon)
-
- if(temp_val==true and continent[GetHogTeamName(CurrentHedgehog)]==9 and getTeamValue(GetHogTeamName(CurrentHedgehog), "rand-done-turn")==true)
- then
- setTeamValue(GetHogTeamName(CurrentHedgehog), "rand-done-turn", false)
- end
-
end
--what happens when you press "tab" (common button)
@@ -645,7 +716,7 @@ function onSwitch()
end
end
- --north america
+ --north america (sniper)
if(GetCurAmmoType() == amSniperRifle and sniper_s_in_use==false)
then
if(namericanSpecial==3)
@@ -663,6 +734,7 @@ function onSwitch()
end
end
+ --north america (shotgun)
if(GetCurAmmoType() == amShotgun and shotgun_s~=nil)
then
if(shotgun_s==false)
@@ -675,6 +747,7 @@ function onSwitch()
end
end
+ --europe
if(GetCurAmmoType() == amMolotov)
then
if(europe_s==0)
@@ -687,45 +760,52 @@ function onSwitch()
end
end
- if(swapweps==true and GetCurAmmoType() == amSkip)
+ --swap forward in the weaponmenu (1.0 style)
+ if(swapweps==true and (GetCurAmmoType() == amSkip or GetCurAmmoType() == amNothing))
then
continent[GetHogTeamName(CurrentHedgehog)]=continent[GetHogTeamName(CurrentHedgehog)]+1
- if(continent[GetHogTeamName(CurrentHedgehog)]> table.getn(weaponsets))
+ if(continent[GetHogTeamName(CurrentHedgehog)]> table.maxn(weaponsets))
then
continent[GetHogTeamName(CurrentHedgehog)]=1
end
- setweapons(true)
+ setweapons()
end
- if(GetCurAmmoType() == amStructure)
+ --kerguelen
+ if(GetCurAmmoType() == amHammer)
then
- if(kergulenSpecial==5)
+ if(kergulenSpecial==6)
then
kergulenSpecial = 1
- AddCaption("#"..weapontexts[7])
- elseif(kergulenSpecial==1 and TotalRounds>=1)
+ AddCaption("Normal")
+ elseif(kergulenSpecial==1)
then
kergulenSpecial = 2
- AddCaption("##"..weapontexts[8])
- elseif(kergulenSpecial==2 or (kergulenSpecial==1 and TotalRounds<1))
+ AddCaption("#"..weapontexts[7])
+ elseif(kergulenSpecial==2 and TotalRounds>=1)
then
kergulenSpecial = 3
- AddCaption("###"..weapontexts[9])
- elseif(kergulenSpecial==3)
+ AddCaption("##"..weapontexts[8])
+ elseif(kergulenSpecial==3 or (kergulenSpecial==2 and TotalRounds<1))
then
kergulenSpecial = 4
- AddCaption("####"..weapontexts[10])
+ AddCaption("###"..weapontexts[9])
elseif(kergulenSpecial==4)
then
kergulenSpecial = 5
+ AddCaption("####"..weapontexts[10])
+ elseif(kergulenSpecial==5)
+ then
+ kergulenSpecial = 6
AddCaption("#####"..weapontexts[15])
end
end
end
function onPrecise()
- if(swapweps==true and GetCurAmmoType() == amSkip)
+ --swap backwards in the weaponmenu (1.0 style)
+ if(swapweps==true and (GetCurAmmoType() == amSkip or GetCurAmmoType() == amNothing))
then
continent[GetHogTeamName(CurrentHedgehog)]=continent[GetHogTeamName(CurrentHedgehog)]-1
@@ -733,98 +813,55 @@ function onPrecise()
then
continent[GetHogTeamName(CurrentHedgehog)]=9
end
- setweapons(true)
- end
-end
-
-function onSlot()
- if(continent[GetHogTeamName(CurrentHedgehog)]==0) then
- ParseCommand("setweap " .. string.char(amSkip))
+ setweapons()
end
end
function onGameTick20()
-
- if(teams_ok[GetHogTeamName(CurrentHedgehog)] == 2)
+ --if you picked a weaponset from the weaponmenu (icon)
+ if(continent[GetHogTeamName(CurrentHedgehog)]==0)
then
- if(GetCurAmmoType()~=amTeleport and swapweps==true and TurnTime-TurnTimeLeft>=100)
+ if(GetCurAmmoType()==amSwitch)
then
- teams_ok[GetHogTeamName(CurrentHedgehog)] = true
- ParseCommand("setweap " .. string.char(amSkip))
+ continent[GetHogTeamName(CurrentHedgehog)]=GetRandom(table.maxn(weaponsets))+1
+ setweapons()
+ PlaySound(sndMineTick)
+ else
+ for v,w in pairs(weaponsets)
+ do
+ if(GetCurAmmoType()==weaponsets[v][4])
+ then
+ continent[GetHogTeamName(CurrentHedgehog)]=v
+ setweapons()
+ PlaySound(weaponsetssounds[v][1])
+ PlaySound(weaponsetssounds[v][2],CurrentHedgehog)
+ end
+ end
end
end
- if(continent[GetHogTeamName(CurrentHedgehog)]==0)
+ --show the kerguelen ring
+ if(kergulenSpecial > 1 and GetCurAmmoType() == amHammer)
then
- if(GetCurAmmoType()==amSniperRifle) then
- continent[GetHogTeamName(CurrentHedgehog)]=1
- setweapons(false)
- elseif(GetCurAmmoType()==amGasBomb) then
- continent[GetHogTeamName(CurrentHedgehog)]=2
- setweapons(false)
- elseif(GetCurAmmoType()==amBazooka) then
- continent[GetHogTeamName(CurrentHedgehog)]=3
- setweapons(false)
- elseif(GetCurAmmoType()==amSMine) then
- continent[GetHogTeamName(CurrentHedgehog)]=4
- setweapons(false)
- elseif(GetCurAmmoType()==amRope) then
- continent[GetHogTeamName(CurrentHedgehog)]=5
- setweapons(false)
- elseif(GetCurAmmoType()==amBaseballBat) then
- continent[GetHogTeamName(CurrentHedgehog)]=6
- setweapons(false)
- elseif(GetCurAmmoType()==amTeleport) then
- continent[GetHogTeamName(CurrentHedgehog)]=7
- setweapons(false)
- elseif(GetCurAmmoType()==amStructure) then
- continent[GetHogTeamName(CurrentHedgehog)]=8
- setweapons(false)
- elseif(GetCurAmmoType()==amInvulnerable) then
- continent[GetHogTeamName(CurrentHedgehog)]=9
- setweapons(false)
- elseif(GetCurAmmoType()==amSwitch) then
- continent[GetHogTeamName(CurrentHedgehog)]=GetRandom(table.getn(weaponsets))+1
- setweapons(false)
+ if(visualcircle==nil)
+ then
+ visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 0, false)
end
- end
-
- if(kergulenSpecial ~= 0 and GetCurAmmoType() == amStructure)
- then
- if(kergulenSpecial == 1)
+
+ if(kergulenSpecial == 2) --walrus scream
then
- if(visualcircle==nil)
- then
- visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 120, false)
- end
SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 120, 4, 0xff0000ee)
- elseif(kergulenSpecial == 2)
+ elseif(kergulenSpecial == 3) --swap hog
then
- if(visualcircle==nil)
- then
- visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 450, false)
- end
SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 450, 3, 0xffff00ee)
- elseif(kergulenSpecial == 3)
+ elseif(kergulenSpecial == 4) --flare
then
- if(visualcircle==nil)
- then
- visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 45, false)
- end
SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 45, 6, 0x00ff00ee)
- elseif(kergulenSpecial == 4)
+ elseif(kergulenSpecial == 5) --cries
then
- if(visualcircle==nil)
- then
- visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 500, false)
- end
SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 500, 1, 0x0000ffee)
- elseif(kergulenSpecial == 5)
+ elseif(kergulenSpecial == 6) --sabotage
then
- if(visualcircle==nil)
- then
- visualcircle=AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtCircle, 100, false)
- end
SetVisualGearValues(visualcircle, GetX(CurrentHedgehog), GetY(CurrentHedgehog),20, 200, 0, 0, 100, 100, 10, 0xeeeeeeee)
end
@@ -834,21 +871,25 @@ function onGameTick20()
visualcircle=nil
end
+ --sabotage
if(disable_moving[CurrentHedgehog]==true)
then
if(TurnTimeLeft<=150)
then
disable_moving[CurrentHedgehog]=false
- SetHogLevel(CurrentHedgehog,0)
+ SetHogLevel(CurrentHedgehog,disableoffsetai)
+ onsabotageai=false
elseif(disallowattack>=15 and disallowattack >= 20)
then
disallowattack=0
+ onsabotageai=true
SetHogLevel(CurrentHedgehog,1)
AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmokeWhite, 0, false)
- elseif(GetHogLevel(CurrentHedgehog)==1)
+ elseif(onsabotageai==true)
then
- SetHogLevel(CurrentHedgehog,0)
+ SetHogLevel(CurrentHedgehog,disableoffsetai)
+ onsabotageai=false
else
disallowattack=disallowattack+1
end
@@ -860,43 +901,48 @@ end
--if you used hogswitch or any similar weapon, dont enable any weaponchange
function onAttack()
swapweps=false
- local around=false
--african special
if(africanSpecial == 1 and GetCurAmmoType() == amSeduction)
then
SetState(CurrentHedgehog, gstAttacked)
+ temp_val=0
runOnGears(weapon_duststorm)
+ SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+temp_val)
--visual stuff
visual_gear_explosion(250,GetX(CurrentHedgehog), GetY(CurrentHedgehog),vgtSmoke,vgtSmokeWhite)
PlaySound(sndParachute)
- end
-
+
--Kerguelen specials
- if(GetCurAmmoType() == amStructure)
+ elseif(GetCurAmmoType() == amHammer and kergulenSpecial > 1)
then
SetState(CurrentHedgehog, gstAttacked)
- if(kergulenSpecial == 1)
+ --scream
+ if(kergulenSpecial == 2)
then
temp_val=0
runOnGears(weapon_scream_walrus)
SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+temp_val)
PlaySound(sndHellish)
-
- elseif(kergulenSpecial == 2 and TotalRounds>=1)
+
+ --swap
+ elseif(kergulenSpecial == 3 and TotalRounds>=1)
then
runOnGears(weapon_swap_kerg)
PlaySound(sndPiano3)
- elseif(kergulenSpecial == 3)
+
+ --flare
+ elseif(kergulenSpecial == 4)
then
runOnGears(weapon_flare)
PlaySound(sndThrowRelease)
AddVisualGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), vgtSmokeWhite, 0, false)
- AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-20, gtCluster, 0, 0, -1000000, 30)
-
- elseif(kergulenSpecial == 4)
+ AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog)-20, gtCluster, 0, 0, -1000000, 34)
+
+ --cries
+ elseif(kergulenSpecial == 5)
then
runOnGears(weapon_cries_a)
if(kergulenSpecial~=-1)
@@ -905,18 +951,25 @@ function onAttack()
PlaySound(sndWarp)
PlaySound(sndMolotov)
+ temp_val=0
runOnGears(weapon_cries_b)
+ SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+temp_val)
else
HogSay(CurrentHedgehog, loc("Hogs in sight!"), SAY_SAY)
end
- elseif(kergulenSpecial == 5)
+
+ --sabotage
+ elseif(kergulenSpecial == 6)
then
runOnGears(weapon_sabotage)
end
DeleteVisualGear(visualcircle)
visualcircle=nil
+
+ elseif(GetCurAmmoType() == amVampiric)
+ then
+ VampOn=75
end
-
--Australian special
if(GetGearType(austmine) == gtMine and austmine ~= nil)
then
@@ -933,10 +986,12 @@ function onAttack()
austmine=nil
end
+ --stop sabotage (avoiding a bug)
if(disable_moving[CurrentHedgehog]==true)
then
disable_moving[CurrentHedgehog]=false
- SetHogLevel(CurrentHedgehog,0)
+ onsabotageai=false
+ SetHogLevel(CurrentHedgehog,disableoffsetai)
end
australianSpecial=false
@@ -945,6 +1000,7 @@ end
function onGearAdd(gearUid)
swapweps=false
+ --track the gears im using
if(GetGearType(gearUid) == gtHedgehog or GetGearType(gearUid) == gtMine or GetGearType(gearUid) == gtExplosives)
then
trackGear(gearUid)
@@ -1010,7 +1066,8 @@ function onGearDelete(gearUid)
then
trackDeletion(gearUid)
end
- --north american specials
+
+ --north american lipstick
if(GetGearType(gearUid)==gtSniperRifleShot )
then
sniper_s_in_use=false
@@ -1027,10 +1084,12 @@ function onGearDelete(gearUid)
SetGearMessage(pinata,1)
end
+ --north american pinata
elseif(GetGearType(gearUid)==gtCluster and GetGearMessage(gearUid)==1 and namericanSpecial==3)
then
AddGear(GetX(gearUid), GetY(gearUid), gtCluster, 0, 0, 0, 20)
+ --north american eagle eye
elseif(GetGearType(gearUid)==gtShotgunShot and shotgun_s==true)
then
SetState(CurrentHedgehog, gstMoving)
@@ -1043,11 +1102,13 @@ function onGearDelete(gearUid)
temp_val=gearUid
runOnGears(weapon_anno_south)
AddVisualGear(GetX(gearUid), GetY(gearUid), vgtExplosion, 0, false)
-
+
+ --asian special
elseif(GetGearType(gearUid)==gtSnowball and GetGearMessage(gearUid)==1)
then
- AddGear(GetX(gearUid), GetY(gearUid)+3, gtCluster, 0, 0, 0, 22)
-
+ AddGear(GetX(gearUid), GetY(gearUid), gtCluster, 0, 0, 0, 22)
+
+ --europe special
elseif(GetGearType(gearUid)==gtCluster and GetGearMessage(gearUid)==2)
then
temp_val=gearUid
@@ -1055,9 +1116,16 @@ function onGearDelete(gearUid)
visual_gear_explosion(100,GetX(gearUid), GetY(gearUid),vgtSmokeWhite,vgtSmokeWhite)
AddVisualGear(GetX(gearUid), GetY(gearUid), vgtExplosion, 0, false)
PlaySound(sndGraveImpact)
-
+
+ --asia (using para)
elseif(GetGearType(gearUid)==gtParachute)
then
inpara=false
end
-end
\ No newline at end of file
+end
+--[[
+sources (populations & area):
+Wikipedia
+Own calculations
+if you think they are wrong, then please tell me :)
+]]
\ No newline at end of file
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg b/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.cfg
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Balanced_Random_Weapon.cfg
copy to share/hedgewars/Data/Scripts/Multiplayer/Frenzy.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua b/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua
new file mode 100644
index 0000000..52ffdec
--- /dev/null
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua
@@ -0,0 +1,142 @@
+-------------------------------------------
+-- FRENZY
+-- a hedgewars mode inspired by Hysteria
+-------------------------------------------
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
+
+local cTimer = 0
+local cn = 0
+
+function initialSetup(gear)
+ SetHealth(gear, 75) -- official is 80, but that assumes bazookas/grenades that do 50 damage
+end
+
+function showStartingInfo()
+
+ ruleSet = "" ..
+ loc("RULES") .. ": " .. "|" ..
+ loc("Each turn is only ONE SECOND!") .. "|" ..
+ loc("Use your ready time to think.") .. "|" ..
+ loc("Slot keys save time! (F1-F10 by default)") .. "|" ..
+ " |" ..
+ loc("SLOTS") .. ": " .. "|" ..
+ loc("Slot") .. " 1 - " .. loc("Bazooka") .. "|" ..
+ loc("Slot") .. " 2 - " .. loc("Grenade") .. "|" ..
+ loc("Slot") .. " 3 - " .. loc("Shotgun") .. "|" ..
+ loc("Slot") .. " 4 - " .. loc("Shoryuken") .. "|" ..
+ loc("Slot") .. " 5 - " .. loc("Mine") .. "|" ..
+ loc("Slot") .. " 6 - " .. loc("Teleport") .. "|" ..
+ loc("Slot") .. " 7 - " .. loc("Blowtorch") .. "|" ..
+ loc("Slot") .. " 8 - " .. loc("Flying Saucer") .. "|" ..
+ loc("Slot") .. " 9 - " .. loc("Molotov") .. "|" ..
+ loc("Slot") .. " 10 - " .. loc("Low Gravity")
+
+ ShowMission(loc("FRENZY"),
+ loc("a frenetic Hedgewars mini-game"),
+ ruleSet, 0, 4000)
+
+end
+
+function onGameInit()
+
+ if TurnTime > 10001 then
+ Ready = 8000
+ else
+ Ready = TurnTime
+ end
+
+ TurnTime = 1000
+
+ --These are the official settings, but I think I prefer allowing customization in this regard
+ --MinesNum = 8
+ --MinesTime = 3000
+ --MinesDudPercent = 30
+ --Explosives = 0
+
+ --Supposedly official settings
+ HealthCaseProb = 0
+ CrateFreq = 0
+
+ --Approximation of Official Settings
+ --SuddenDeathTurns = 10
+ --WaterRise = 47
+ --HealthDecrease = 0
+
+end
+
+function onGameStart()
+ showStartingInfo()
+ runOnHogs(initialSetup)
+end
+
+function onSlot(sln)
+ cTimer = 8
+ cn = sln
+end
+
+function onGameTick()
+ if cTimer ~= 0 then
+ cTimer = cTimer -1
+ if cTimer == 1 then
+ ChangeWep(cn)
+ cn = 0
+ cTimer = 0
+ end
+ end
+end
+
+function ChangeWep(s)
+
+ if s == 0 then
+ ParseCommand("setweap " .. string.char(amBazooka))
+ elseif s == 1 then
+ ParseCommand("setweap " .. string.char(amGrenade))
+ elseif s == 2 then
+ ParseCommand("setweap " .. string.char(amShotgun))
+ elseif s == 3 then
+ ParseCommand("setweap " .. string.char(amFirePunch))
+ elseif s == 4 then
+ ParseCommand("setweap " .. string.char(amMine))
+ elseif s == 5 then
+ ParseCommand("setweap " .. string.char(amTeleport))
+ elseif s == 6 then
+ ParseCommand("setweap " .. string.char(amBlowTorch))
+ elseif s == 7 then
+ ParseCommand("setweap " .. string.char(amJetpack))
+ elseif s == 8 then
+ ParseCommand("setweap " .. string.char(amMolotov))
+ elseif s == 9 then
+ ParseCommand("setweap " .. string.char(amLowGravity))
+ end
+
+end
+
+function onGearAdd(gear)
+ if GetGearType(gear) == gtHedgehog then
+ trackGear(gear)
+ end
+end
+
+function onGearDelete(gear)
+ if GetGearType(gear) == gtHedgehog then
+ trackDeletion(gear)
+ end
+end
+
+function onAmmoStoreInit()
+ SetAmmo(amBazooka, 9, 0, 0, 0)
+ SetAmmo(amGrenade, 9, 0, 0, 0)
+ SetAmmo(amMolotov, 9, 0, 0, 0)
+ SetAmmo(amShotgun, 9, 0, 0, 0)
+ --SetAmmo(amFlamethrower, 9, 0, 0, 0) -- this was suggested on hw.org but it's not present on base
+ SetAmmo(amFirePunch, 9, 0, 0, 0)
+ SetAmmo(amMine, 9, 0, 0, 0)
+ --SetAmmo(amCake, 1, 0, 2, 0) -- maybe it's beefcake?
+ SetAmmo(amJetpack, 9, 0, 0, 0)
+ SetAmmo(amBlowTorch, 9, 0, 0, 0)
+ SetAmmo(amTeleport, 9, 0, 0, 0)
+ SetAmmo(amLowGravity, 9, 0, 0, 0)
+ --SetAmmo(amSkipGo, 9, 0, 0, 0) -- not needed with 1s turn time
+end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg
index 028167b..7ce8f76 100755
--- a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.cfg
@@ -1,2 +1,2 @@
Default
-Default
+locked
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua
index 0624f38..105fe5b 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua
@@ -1,6 +1,6 @@
--------------------------------
-- HIGHLANDER / HOGS OF WAR
--- version 0.3c
+-- version 0.4b
-- by mikade
--------------------------------
@@ -51,15 +51,51 @@
-- added napalm (whoops) to list of possible weapons you can get
-- hogs no longer recieve airstrike-related weps on border maps
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+-----------
+--0.4
+-----------
+-- fix same name/blank weapon transfer bug (issue 541)
+-- show next hog ammo set in full (issue 312)
+-- allow mid-kill multi-shot weapon transfers (issue 503)
+-- allow users to configure hog health
+-- remove 'switched to' message
+-- remove some extraeneous code
+-- add more whitespace
+-- break everything
+
+-----------
+--0.4b
+-----------
+-- as per request, add ice-gun
+
+-------------------------
+-- ideas for the future
+-------------------------
+-- add structure
+-- allow switcher, resurrector
+-- add abuse
+-- nerf teleport
+-- allow more customization
+-- poison hogs using the default team? :/
+-- balance weapon distribution across entire team / all teams
+-- add other inequalities/bonuses like... ???
+-- some hogs start off with an extra 25 health?
+-- some hogs start off poisoned?
+-- some hogs start off with a rope and 2 drills but die after their turn?
+
+-------------------------------
+-- derp, script follows
+-------------------------------
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
local airWeapons = {amAirAttack, amMineStrike, amNapalm, amDrillStrike --[[,amPiano]]}
local atkArray = {
amBazooka, amBee, amMortar, amDrill, --[[amSnowball,]]
amGrenade, amClusterBomb, amMolotov, amWatermelon, amHellishBomb, amGasBomb,
- amShotgun, amDEagle, amFlamethrower, amSniperRifle, amSineGun,
+ amShotgun, amDEagle, amFlamethrower, amSniperRifle, amSineGun, amIceGun,
amFirePunch, amWhip, amBaseballBat, --[[amKamikaze,]] amSeduction, --[[amHammer,]]
amMine, amDynamite, amCake, amBallgun, amRCPlane, amSMine,
amRCPlane, amSMine,
@@ -77,18 +113,42 @@ local utilArray = {
local wepArray = {}
-local currName
-local lastName
+local currHog
+local lastHog
local started = false
local switchStage = 0
+local lastWep = amNothing
+local shotsFired = 0
+
+function CheckForWeaponSwap()
+ if GetCurAmmoType() ~= lastWep then
+ shotsFired = 0
+ end
+ lastWep = GetCurAmmoType()
+end
+
+function onSlot()
+ CheckForWeaponSwap()
+end
+
+function onSetWeapon()
+ CheckForWeaponSwap()
+end
+
+function onHogAttack()
+ CheckForWeaponSwap()
+ shotsFired = shotsFired + 1
+end
+
function StartingSetUp(gear)
for i = 1, #wepArray do
setGearValue(gear,wepArray[i],0)
end
- setGearValue(gear,amKamikaze,1)
+ setGearValue(gear,amKamikaze,100)
+ setGearValue(gear,amSkip,100)
i = 1 + GetRandom(#atkArray)
setGearValue(gear,atkArray[i],1)
@@ -96,13 +156,11 @@ function StartingSetUp(gear)
i = 1 + GetRandom(#utilArray)
setGearValue(gear,utilArray[i],1)
- SetHealth(gear, 100)
-
end
--[[function SaveWeapons(gear)
+-- er, this has no 0 check so presumably if you use a weapon then when it saves you wont have it
- -
for i = 1, (#wepArray) do
setGearValue(gear, wepArray[i], GetAmmoCount(gear, wepArray[i]) )
--AddAmmo(gear, wepArray[i], getGearValue(gear,wepArray[i]) )
@@ -116,10 +174,9 @@ function ConvertValues(gear)
AddAmmo(gear, wepArray[i], getGearValue(gear,wepArray[i]) )
end
-
end
-
+-- this is called when a hog dies
function TransferWeps(gear)
if CurrentHedgehog ~= nil then
@@ -127,8 +184,17 @@ function TransferWeps(gear)
for i = 1, #wepArray do
val = getGearValue(gear,wepArray[i])
if val ~= 0 then
+
setGearValue(CurrentHedgehog, wepArray[i], val)
- AddAmmo(CurrentHedgehog, wepArray[i], val)
+
+ -- if you are using multi-shot weapon, gimme one more
+ if (GetCurAmmoType() == wepArray[i]) and (shotsFired ~= 0) then
+ AddAmmo(CurrentHedgehog, wepArray[i], val+1)
+ -- assign ammo as per normal
+ else
+ AddAmmo(CurrentHedgehog, wepArray[i], val)
+ end
+
end
end
@@ -137,13 +203,12 @@ function TransferWeps(gear)
end
function onGameInit()
- GameFlags = gfInfAttack + gfRandomOrder
+ GameFlags = bor(GameFlags,gfInfAttack + gfRandomOrder + gfPerHogAmmo)
HealthCaseProb = 100
end
function onGameStart()
-
ShowMission (
loc("HIGHLANDER"),
loc("Not all hogs are born equal."),
@@ -156,10 +221,10 @@ function onGameStart()
)
if MapHasBorder() == false then
- for i, w in pairs(airWeapons) do
+ for i, w in pairs(airWeapons) do
table.insert(atkArray, w)
end
- end
+ end
for i, w in pairs(atkArray) do
table.insert(wepArray, w)
@@ -169,33 +234,52 @@ function onGameStart()
table.insert(wepArray, w)
end
+ table.insert(wepArray, amSkip)
+ table.insert(wepArray, amKamikaze)
+
runOnGears(StartingSetUp)
runOnGears(ConvertValues)
end
---function onNewTurn()
---
---end
+function CheckForHogSwitch()
+ if (CurrentHedgehog ~= nil) then
-function onGameTick20()
+ currHog = CurrentHedgehog
- if (CurrentHedgehog ~= nil) then
+ if currHog ~= lastHog then
- currName = GetHogName(CurrentHedgehog)
+ -- re-assign ammo to this guy, so that his entire ammo set will
+ -- be visible during another player's turn
+ if lastHog ~= nil then
+ ConvertValues(lastHog)
+ end
- if (currName ~= lastName) then
- AddCaption(loc("Switched to ") .. currName .. "!")
+ -- give the new hog what he is supposed to have, too
ConvertValues(CurrentHedgehog)
+
end
- lastName = currName
+ lastHog = currHog
+
end
end
+function onNewTurn()
+ CheckForHogSwitch()
+end
+
+--function onGameTick20()
+--CheckForHogSwitch()
+-- if we use gfPerHogAmmo is this even needed? Err, well, weapons reset, so... yes?
+-- orrrr, should we rather call the re-assignment of weapons onNewTurn()? probably not because
+-- then you cant switch hogs... unless we add a thing in onSwitch or whatever
+-- ye, that is probably better actually, but I'll add that when/if I add switch
+--end
+
--[[function onHogHide(gear)
-- waiting for Henek
end
@@ -226,8 +310,6 @@ function onGearDelete(gear)
end
function onAmmoStoreInit()
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amKamikaze, 9, 0, 0, 0)
- --SetAmmo(amSwitch, 9, 0, 0, 0) -------1
+ -- no, you can't set your own ammo scheme
end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua b/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua
index e20c418..5c9a780 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua
@@ -1,614 +1,615 @@
-local MUTANT_VERSION = "v0.9.4"
-
---[[ ___ ___
- ( ) ( )
-___ .-. .-. ___ ___ | |_ .---. ___ .-. | |_
-( ) ' ( )( ( __) / .-, ( ) ( __)
-| .-. .-. | | | | | | (__) ; || .-. .| |
-| | | | | | | | | | | ___ .'` || | | || | ___
-| | | | | | | | | | |( / .'| || | | || |( )
-| | | | | | | | | | | | | / | || | | || | | |
-| | | | | | | ; ' | ' | ; | ; || | | || ' | |
-| | | | | ' `-' / ' `-' ' `-' || | | |' `-' ;
-(___)(___)(___'.__.' `.__.`.__.'_(___)(___)`.__.
-
-
----- IMPORTANT!
-----
----- You should save (press Ctrl+S) this script to:
----- Program Files\Hedgewars\share\hedgewars\Data\Scripts\Multiplayer\Mutant.lua
----- or (on Linux):
----- ~/.hedgewars/Data/Scripts/Multiplayer/Mutant.lua
-----
----- (or wherever scripts like Highlander.lua, Racer.lua are on your system)
-----
----- Also, if you didn't have Mutant script yet, you need to restart Hedgewars for it to find the script file.
-----
-
-
----- GAME RULES
-----
----- Recommended settings:
----- * one hedgehog per team
----- * 'Small' one-island map
-----
----- First one to kill anyone becomes Mutant. Mutant has super-weapons
----- and a lot of health, which however depletes if he doesn't frag fast.
----- Goal of Mutant is to use his weapons to hold his status for as long
----- as he can.
----- Goal of others is to hunt the Mutant down. The one who kills Mutant,
----- becomes Mutant himself.
----- The player with least points (or most deaths) is Bottom Feeder. He
----- can gain points by killing anyone. Other normal players only get points
----- for killing Mutant.
-----
----- Points:
----- +2 for becoming a Mutant
----- +1 to a Mutant for killing anyone
----- +1 to a Bottom Feeder for killing anyone
----- -1 to anyone for a suicide
----- other kills don't give you points.
-----
-
---]]
-
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
-
---[[
- MUTANT SCRIPT
-
- To Do: -Clean-up this fucking piece of code
- -Debug
- -Find a girlfriend
- -Fix Sheepluva's hat +[p]
- -Cookies
-
------------------------]]
-
-local hhs = {}
-local numhhs = 0
-
-local gameOver=false
-
-local mutant = nil
-local mutant_base_health = 200
-local mutant_base_disease = 25
-local disease_timer = 2000
-
-local kill_reward = nil
-local mt_hurt=false
-
-local killsCounter = 0
-
-local team_fire_punishment = 3
-local mutant_kill_reward = 2
-
-local hh_weapons = { amBazooka, amGrenade, amShotgun, amMine}
-
-local mt_weapons = {amWatermelon, amHellishBomb, amBallgun, amRCPlane, amTeleport}
-
-local disease=0
-local timer=0
-
-local winScore = 15
-local hogsLimit = 1
-
-local teams = {}
-
-local circles = {}
-local circleFrame = -1
-
-function onGameInit()
- TurnTime = 20000
- WaterRise = 0
- GameFlags = GameFlags + gfResetWeps + gfPerHogAmmo
- HealthCaseProb=0
- HealthCaseAmount=0
- MinesTime=1000
- CaseFreq = 2
-
-end
-
-
-function limitHogs(gear)
- cnthhs = cnthhs + 1
- if cnthhs > 1 then
- hogLimitHit = true
- SetEffect(gear, heResurrectable, false)
- --SetHealth(gear, 0)
- SetGearPosition(gear, -100,LAND_HEIGHT)
- end
-end
-
-function onGameStart()
- trackTeams()
- teamScan()
- runOnHogs(saveStuff)
- --local str = "/say " .. MUTANT_VERSION
- --ParseCommand(str)
-
- hogLimitHit = false
- for i=0 , TeamsCount - 1 do
- cnthhs = 0
- runOnHogsInTeam(limitHogs, teams[i])
- end
- if hogLimitHit then
- AddCaption(loc("ONE HOG PER TEAM! KILLING EXCESS HEDGES"))
- end
-end
-
-
-
-function giveWeapons(gear)
-
- if gear == mutant then
- AddAmmo(gear, amRope)
- for i=1, #mt_weapons do
- AddAmmo(gear, mt_weapons[i])
- end
-
- else
- for i=1, #hh_weapons do
- AddAmmo(gear,hh_weapons[i])
- end
- end
-end
-
-function onAmmoStoreInit()
-
- SetAmmo(amSkip, 9, 0, 0, 0)
- SetAmmo(amRope,0,1,0,5)
- SetAmmo(amSnowball,0,1,0,1)
-
- for i=1, #hh_weapons do
- SetAmmo(hh_weapons[i], 0, 0, 0, 1)
- end
-
- for i=1, #mt_weapons do
- SetAmmo(mt_weapons[i], 0, 3, 0, 1)
- end
-
-end
-
-function drawCircles()
- for i = 0, #hhs do
- if circles[hhs[i]] ~= nil then
- DeleteVisualGear(circles[hhs[i]])
- circles[hhs[i]] = nil
- end
-
- if hhs[i] ~= CurrentHedgehog then
- if mutant == nil then
- circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
- SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080)
- elseif CurrentHedgehog == mutant then
- circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
- SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070)
- elseif getGearValue(CurrentHedgehog, "Feeder") and hhs[i] ~= mutant then
- circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
- SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070)
- elseif hhs[i] == mutant then
- circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
- SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080)
- end
- end
- end
- circleFrame = 0
-end
-
-function onNewTurn()
-
- trackTeams()
- killsCounter = 0
-
- if mutant == nil then
- AddCaption( loc("FIRST BLOOD MUTATES") )
- end
-
- checkScore()
- giveWeapons(CurrentHedgehog)
- drawCircles()
- kill_reward= numhhs*10
-
- if CurrentHedgehog == mutant then
- mt_hurt=true
- disease= mutant_base_disease - numhhs
- else
- mt_hurt=false
- end
-
- setGearValue(CurrentHedgehog, "Alive", true)
-
-end
-
-function countBodies()
- if killsCounter == 2 then
- AddCaption(loc("DOUBLE KILL"))
- elseif killsCounter == 3 then
- AddCaption(loc("MEGA KILL"))
- PlaySound(sndRegret)
- elseif killsCounter == 4 then
- AddCaption(loc("ULTRA KILL"))
- elseif killsCounter == 5 then
- AddCaption(loc("MONSTER KILL"))
- PlaySound(sndIllGetYou)
- elseif killsCounter == 6 then
- AddCaption(loc("LUDICROUS KILL"))
- PlaySound(sndNutter)
- elseif killsCounter == 7 then
- AddCaption(loc("HOLY SHIT!"))
- PlaySound(sndLaugh)
- elseif killsCounter > 8 then
- AddCaption(loc("FAG"))
- end
-
-end
-
-function onGameTick()
-
- if circleFrame > -1 then
- for i = 0, #hhs do
- if circles[hhs[i]] ~= nil and hhs[i]~= nil then
- hhx, hhy = GetGearPosition(hhs[i])
- X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint = GetVisualGearValues(circles[hhs[i]])
- SetVisualGearValues(circles[hhs[i]], hhx + 1, hhy - 3, 0, 0, 0, 0, 0, 40 - (circleFrame % 25), Timer, Tint)
- end
- end
-
- circleFrame = circleFrame + 0.06
-
- if circleFrame >= 25 then
- for i = 0, #hhs do
- if circles[hhs[i]] ~= nil then
- DeleteVisualGear(circles[hhs[i]])
- circles[hhs[i]] = nil
- end
- end
- end
- end
-
- if TurnTimeLeft==0 and mt_hurt then
- mt_hurt = false
- end
-
- if mt_hurt and mutant~=nil then
- timer = timer + 1
- if timer > disease_timer then
- timer = 0
- SetHealth(mutant, GetHealth(mutant)-disease )
- AddVisualGear(GetX(mutant), GetY(mutant)-5, vgtHealthTag, disease, true)
- if GetHealth(mutant)<=0 then
- SetHealth(mutant,0)
- mt_hurt= false
- setGearValue(mutant,"SelfDestruct",true)
- TurnTimeLeft = 0
- end
- end
- end
-end
-
-function saveStuff(gear)
- setGearValue(gear,"Name",GetHogName(gear))
- setGearValue(gear,"Hat",GetHogHat(gear))
-end
-
-function armageddon(gear)
- SetState(gear, gstLoser)
- SetEffect(gear, heResurrectable, false)
- SetHealth(gear, 0)
-end
-
-function updateScore()
-local showScore = ""
-
- for i=0, TeamsCount-1 do
- if teams[i]~= nil then
-
- local curr_score = getTeamValue(teams[i], "Score")
- showScore = showScore .. teams[i] .. ": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|"
-
- end
- end
-
- ShowMission(loc("Score"),
- "-------",
- showScore, 0, 200)
-
- HideMission()
-
-end
-
-function checkScore()
-local showScore = ""
-local lowest_score_team = nil
-local min_score=nil
-local winTeam = nil
-
-local only_low_score = true
-
- for i=0, TeamsCount-1 do
- if teams[i]~=nil then
- local curr_score = getTeamValue(teams[i], "Score")
-
- runOnHogsInTeam(removeFeeder, teams[i])
-
- showScore = showScore .. teams[i] ..": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|"
-
- if curr_score >= winScore then
- gameOver = true
- winTeam = teams[i]
- end
-
- if min_score==nil then
- min_score= curr_score
- lowest_score_team = teams[i]
- else
- if curr_score <= min_score then
- if curr_score == min_score then
- if getTeamValue(teams[i], "DeadHogs") == getTeamValue(lowest_score_team, "DeadHogs") then
- only_low_score = false
- else
- if getTeamValue(teams[i], "DeadHogs") > getTeamValue(lowest_score_team, "DeadHogs") then
- lowest_score_team = teams[i]
- end
- only_low_score = true
- end
-
- else
- min_score= curr_score
- lowest_score_team = teams[i]
- only_low_score = true
- end
- end
- end
- end
- end
-
- if gameOver then
- TurnTimeLeft = 0
- for i=0, #teams do
- if teams[i]~=winTeam then
- runOnHogsInTeam(armageddon, teams[i])
- end
- end
-
- ShowMission( loc("WINNER IS ") .. winTeam,
- "~~~~~~~~~~~~~~~~~~~~~~~~~",
- showScore, 0, 200)
- else
-
- if only_low_score then
- runOnHogsInTeam(setFeeder, lowest_score_team)
- end
-
- ShowMission( loc("Score"),
- loc("-------"),
- showScore, 0, 200)
-
- end
-end
-
-function backToNormal(gear)
-
- SetHogName(gear, getGearValue(gear,"Name"))
- SetHogHat(gear, 'NoHat')
- SetHogHat(gear, getGearValue(gear,"Hat"))
- setGearValue(mutant,"SelfDestruct",false)
- mt_hurt=false
- mutant=nil
-end
-
-function removeFeeder(gear)
-
- if gear~=nil then
- setGearValue(gear,"Feeder",false)
- if gear~= mutant then
- SetHogName(gear, getGearValue(gear,"Name") )
- SetHogHat(gear, 'NoHat')
- SetHogHat(gear, getGearValue(gear,"Hat"))
- end
- end
-end
-
-function setFeeder(gear)
-
- if gear~= mutant and gear~= nil then
- SetHogName(gear,"BOTTOM FEEDER")
- SetHogHat(gear, 'poke_slowpoke')
- setGearValue(gear,"Feeder", true)
- end
-end
-
-function setMutantStuff(gear)
- mutant = gear
-
- SetHogName(gear,"MUTANT")
- SetHogHat(gear,'WhySoSerious')
- SetHealth(gear, ( mutant_base_health + numhhs*25) )
- SetEffect(gear, hePoisoned, 1)
- setGearValue(mutant,"SelfDestruct",false)
- setGearValue(gear, "Feeder", false)
-
- AddCaption(getGearValue(gear, "Name") .. loc(" HAS MUTATED" ))
-
- TurnTimeLeft=0
-
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- PlaySound(sndSuddenDeath)
-end
-
-function teamScan()
-
- for i=0, TeamsCount-1 do --nil filling
- teams[i]=nil
- end
-
- for i=0, #hhs do
- for j=0, TeamsCount-1 do
- if teams[j] ==nil and hhs[i]~=nil then
- teams[j] = GetHogTeamName(hhs[i])
- setTeamValue(teams[j],"Score",0)
- setTeamValue(teams[j], "DeadHogs",0)
- break
- end
-
- if teams[j] == GetHogTeamName(hhs[i]) then
- break
- end
- end
- end
-
- ---***---
-end
-
-
-function onGearDamage(gear, dmg)
-
-end
-
-function set_Mutant_and_Score(gear)
-
-local curr_team = GetHogTeamName(CurrentHedgehog)
-
- if gear == CurrentHedgehog then
- if CurrentHedgehog == mutant then
- PlaySound(sndHomerun)
- if getGearValue(gear, "SelfDestruct")==false then
- decreaseTeamValue(curr_team,"Score")
- end
- backToNormal(gear)
- else
- decreaseTeamValue(curr_team,"Score")
- end
-
- else
- if gear == mutant then
- backToNormal(mutant)
- if curr_team ~=GetHogTeamName(gear) then
- if getGearValue(CurrentHedgehog, "Alive") then
- setMutantStuff(CurrentHedgehog)
- setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward))
- end
- else
- setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
- end
- else
- if mutant==nil then
- if curr_team ~=GetHogTeamName(gear) then
- if getGearValue(CurrentHedgehog, "Alive") then
- setMutantStuff(CurrentHedgehog)
- setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward))
- else
- increaseTeamValue(curr_team,"Score")
- end
- else
- setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
- end
- else
- if curr_team ~=GetHogTeamName(gear) then
- if CurrentHedgehog==mutant and getGearValue(mutant,"SelfDestruct")==false then
- SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+kill_reward)
- AddCaption("+" .. kill_reward .. loc(" HP") )
- increaseTeamValue(curr_team,"Score")
- end
- if getGearValue(CurrentHedgehog,"Feeder") then
- increaseTeamValue(curr_team,"Score")
- end
- else
- setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
- end
- end
- end
- end
-end
-
-function onGearResurrect(gear)
-if not gameOver then
- if GetGearType(gear) == gtHedgehog then
-
- increaseTeamValue(GetHogTeamName(gear), "DeadHogs")
-
- if gear==CurrentHedgehog then
- setGearValue(CurrentHedgehog, "Alive", false)
- end
- set_Mutant_and_Score(gear)
- if gear~=CurrentHedgehog then
- killsCounter = killsCounter + 1
- countBodies()
- end
- AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
- PlaySound(sndWhack)
- updateScore()
- end
-end
-end
-
-function onGearAdd(gear)
-
- -- Catch hedgehogs for the tracker
- if GetGearType(gear) == gtHedgehog then
- trackGear(gear)
- hhs[numhhs] = gear
- numhhs = numhhs + 1
- SetEffect(gear, heResurrectable, 1)
- end
-end
-
-function checkEmptyTeam (teamName)
- for i=0 , #hhs do
- if hhs[i]~=nil then
- if teamName == GetHogTeamName(hhs[i]) then
- return false
- end
- end
- end
- return true
-end
-
-function onGearDelete(gear)
- -- Remove hogs that are gone
- if GetGearType(gear) == gtHedgehog then
- numhhs = numhhs - 1
-
- local found
- for i=0, #hhs do
- if hhs[i] == gear then
- found = i
- break
- end
- end
- for i = found, #hhs - 1 do
- hhs[i] = hhs[i + 1]
- end
- hhs[#hhs] = nil
-
- local t_name = GetHogTeamName(gear)
- if checkEmptyTeam(t_name) then
- for i = 0, TeamsCount - 1 do
- if teams[i] == t_name then
- found = i
- break
- end
- end
- for i = found, TeamsCount - 2 do
- teams[i] = teams[i + 1]
- end
- teams[TeamsCount - 1] = nil
- TeamsCount = TeamsCount - 1
- end
- AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
- trackDeletion(gear)
- end
-end
-
---[[
-S T A R R I N G
-
- prof - Coding, implementing and evangelism
- vos - Initial idea and script improvements
---]]
+local MUTANT_VERSION = "v0.9.5"
+
+--[[ ___ ___
+ ( ) ( )
+___ .-. .-. ___ ___ | |_ .---. ___ .-. | |_
+( ) ' ( )( ( __) / .-, ( ) ( __)
+| .-. .-. | | | | | | (__) ; || .-. .| |
+| | | | | | | | | | | ___ .'` || | | || | ___
+| | | | | | | | | | |( / .'| || | | || |( )
+| | | | | | | | | | | | | / | || | | || | | |
+| | | | | | | ; ' | ' | ; | ; || | | || ' | |
+| | | | | ' `-' / ' `-' ' `-' || | | |' `-' ;
+(___)(___)(___'.__.' `.__.`.__.'_(___)(___)`.__.
+
+
+---- Recommended settings:
+---- * one hedgehog per team
+---- * 'Small' one-island map
+
+--]]
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
+
+--[[
+ MUTANT SCRIPT
+
+ To Do: -Clean-up this fucking piece of code
+ -Debug
+ -Find a girlfriend
+ -Fix Sheepluva's hat +[p]
+ -Cookies
+-----------------------]]
+
+local hhs = {}
+local numhhs = 0
+local meh = false
+
+local gameOver=false
+
+local mutant = nil
+local mutant_base_health = 200
+local mutant_base_disease = 25
+local disease_timer = 2000
+
+local kill_reward = nil
+local mt_hurt=false
+
+local killsCounter = 0
+
+local team_fire_punishment = 3
+local mutant_kill_reward = 2
+
+local hh_weapons = { amBazooka, amGrenade, amShotgun, amMine}
+
+local mt_weapons = {amWatermelon, amHellishBomb, amBallgun, amRCPlane, amTeleport}
+
+local disease=0
+local timer=0
+
+local winScore = 15
+local hogsLimit = 1
+
+local teams = {}
+
+local circles = {}
+local circleFrame = -1
+
+function showStartingInfo()
+
+ ruleSet = loc("RULES") .. ": " ..
+ " |" .. --" |" ..
+ loc("The first player to kill someone becomes the Mutant.") .. "|" ..
+ loc("The Mutant has super-weapons and a lot of health.") .. "|" ..
+ loc("The Mutant loses health quickly if he doesn't keep scoring kills.") .. "|" ..
+ " |" ..
+ loc("Normal players can only score points by killing the mutant.") .. "|" ..
+ " |" .. "" ..
+ loc("The player with least points (or most deaths) becomes the Bottom Feeder.") .. "|" ..
+ loc("The Bottom Feeder can score points by killing anyone.") .. "|" ..
+ " |" ..
+ loc("POINTS") .. ": " ..
+ " |" ..
+ loc("+2 for becoming a Mutant") .. "|" ..
+ loc("+1 to a Mutant for killing anyone") .. "|" ..
+ loc("+1 to a Bottom Feeder for killing anyone") .. "|" ..
+ loc("-1 to anyone for a suicide") .. "|" ..
+ loc("Other kills don't give you points.")
+
+ ShowMission(loc("Mutant"),
+ loc("a Hedgewars tag game"),
+ ruleSet, 0, 5000)
+
+end
+
+function onGameInit()
+ TurnTime = 20000
+ WaterRise = 0
+ GameFlags = GameFlags + gfResetWeps + gfPerHogAmmo
+ HealthCaseProb=0
+ HealthCaseAmount=0
+ MinesTime=1000
+ CaseFreq = 2
+end
+
+
+function limitHogs(gear)
+ cnthhs = cnthhs + 1
+ if cnthhs > 1 then
+ hogLimitHit = true
+ SetEffect(gear, heResurrectable, false)
+ --SetHealth(gear, 0)
+ SetGearPosition(gear, -100,LAND_HEIGHT)
+ end
+end
+
+function onGameStart()
+ trackTeams()
+ teamScan()
+ runOnHogs(saveStuff)
+ --local str = "/say " .. MUTANT_VERSION
+ --ParseCommand(str)
+
+ hogLimitHit = false
+ for i=0 , TeamsCount - 1 do
+ cnthhs = 0
+ runOnHogsInTeam(limitHogs, teams[i])
+ end
+ if hogLimitHit then
+ AddCaption(loc("ONE HOG PER TEAM! KILLING EXCESS HEDGES"))
+ end
+ showStartingInfo()
+end
+
+
+
+function giveWeapons(gear)
+ if gear == mutant then
+ AddAmmo(gear, amRope)
+ for i=1, #mt_weapons do
+ AddAmmo(gear, mt_weapons[i])
+ end
+
+ else
+ for i=1, #hh_weapons do
+ AddAmmo(gear,hh_weapons[i])
+ end
+ end
+end
+
+function onAmmoStoreInit()
+
+ SetAmmo(amSkip, 9, 0, 0, 0)
+ SetAmmo(amRope,0,1,0,5)
+ SetAmmo(amSnowball,0,1,0,1)
+
+ for i=1, #hh_weapons do
+ SetAmmo(hh_weapons[i], 0, 0, 0, 1)
+ end
+
+ for i=1, #mt_weapons do
+ SetAmmo(mt_weapons[i], 0, 3, 0, 1)
+ end
+
+end
+
+function drawCircles()
+ for i = 0, #hhs do
+ if circles[hhs[i]] ~= nil then
+ DeleteVisualGear(circles[hhs[i]])
+ circles[hhs[i]] = nil
+ end
+
+ if hhs[i] ~= CurrentHedgehog then
+ if mutant == nil then
+ circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
+ SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080)
+ elseif CurrentHedgehog == mutant then
+ circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
+ SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070)
+ elseif getGearValue(CurrentHedgehog, "Feeder") and hhs[i] ~= mutant then
+ circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
+ SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 3, 0xaa000070)
+ elseif hhs[i] == mutant then
+ circles[hhs[i]] = AddVisualGear(0, 0, vgtCircle, 0, false)
+ SetVisualGearValues(circles[hhs[i]], 0, 0, 0, 0, 0, 0, 0, 22, 5, 0xff000080)
+ end
+ end
+ end
+ circleFrame = 0
+end
+
+function onNewTurn()
+
+ trackTeams()
+ killsCounter = 0
+
+ if mutant == nil then
+ AddCaption( loc("FIRST BLOOD MUTATES") )
+ end
+
+ checkScore()
+ giveWeapons(CurrentHedgehog)
+ drawCircles()
+ setAIHints()
+ kill_reward= numhhs*10
+
+ if CurrentHedgehog == mutant then
+ mt_hurt=true
+ disease= mutant_base_disease - numhhs
+ else
+ mt_hurt=false
+ end
+
+ setGearValue(CurrentHedgehog, "Alive", true)
+
+end
+
+function countBodies()
+ if killsCounter == 2 then
+ AddCaption(loc("DOUBLE KILL"))
+ elseif killsCounter == 3 then
+ AddCaption(loc("MEGA KILL"))
+ PlaySound(sndRegret)
+ elseif killsCounter == 4 then
+ AddCaption(loc("ULTRA KILL"))
+ elseif killsCounter == 5 then
+ AddCaption(loc("MONSTER KILL"))
+ PlaySound(sndIllGetYou)
+ elseif killsCounter == 6 then
+ AddCaption(loc("LUDICROUS KILL"))
+ PlaySound(sndNutter)
+ elseif killsCounter == 7 then
+ AddCaption(loc("HOLY SHYTE!"))
+ PlaySound(sndLaugh)
+ elseif killsCounter > 8 then
+ AddCaption(loc("INSANITY"))
+ end
+end
+
+function onGameTick()
+
+ if circleFrame > -1 then
+ for i = 0, #hhs do
+ if circles[hhs[i]] ~= nil and hhs[i]~= nil then
+ hhx, hhy = GetGearPosition(hhs[i])
+ X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint = GetVisualGearValues(circles[hhs[i]])
+ SetVisualGearValues(circles[hhs[i]], hhx + 1, hhy - 3, 0, 0, 0, 0, 0, 40 - (circleFrame % 25), Timer, Tint)
+ end
+ end
+
+ circleFrame = circleFrame + 0.06
+
+ if circleFrame >= 25 then
+ for i = 0, #hhs do
+ if circles[hhs[i]] ~= nil then
+ DeleteVisualGear(circles[hhs[i]])
+ circles[hhs[i]] = nil
+ end
+ end
+ end
+ end
+
+ if TurnTimeLeft==0 and mt_hurt then
+ mt_hurt = false
+ end
+
+ if mt_hurt and mutant~=nil then
+ timer = timer + 1
+ if timer > disease_timer then
+ timer = 0
+ SetHealth(mutant, GetHealth(mutant)-disease )
+ AddVisualGear(GetX(mutant), GetY(mutant)-5, vgtHealthTag, disease, true)
+ if GetHealth(mutant)<=0 then
+ SetHealth(mutant,0)
+ mt_hurt= false
+ setGearValue(mutant,"SelfDestruct",true)
+ TurnTimeLeft = 0
+ end
+ end
+ end
+
+end
+
+function saveStuff(gear)
+ setGearValue(gear,"Name",GetHogName(gear))
+ setGearValue(gear,"Hat",GetHogHat(gear))
+end
+
+function armageddon(gear)
+ SetState(gear, gstLoser)
+ SetEffect(gear, heResurrectable, false)
+ SetHealth(gear, 0)
+end
+
+function updateScore()
+
+ local showScore = ""
+
+ for i=0, TeamsCount-1 do
+ if teams[i]~= nil then
+
+ local curr_score = getTeamValue(teams[i], "Score")
+ showScore = showScore .. teams[i] .. ": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|"
+
+ end
+ end
+
+ ShowMission(loc("Score"),
+ "-------",
+ showScore, 0, 200)
+
+ HideMission()
+
+end
+
+function checkScore()
+local showScore = ""
+local lowest_score_team = nil
+local min_score=nil
+local winTeam = nil
+
+local only_low_score = true
+
+ for i=0, TeamsCount-1 do
+ if teams[i]~=nil then
+ local curr_score = getTeamValue(teams[i], "Score")
+
+ runOnHogsInTeam(removeFeeder, teams[i])
+
+ showScore = showScore .. teams[i] ..": " .. curr_score .. " (deaths: " .. getTeamValue(teams[i], "DeadHogs") .. ") " .. "|"
+
+ if curr_score >= winScore then
+ gameOver = true
+ winTeam = teams[i]
+ end
+
+ if min_score==nil then
+ min_score= curr_score
+ lowest_score_team = teams[i]
+ else
+ if curr_score <= min_score then
+ if curr_score == min_score then
+ if getTeamValue(teams[i], "DeadHogs") == getTeamValue(lowest_score_team, "DeadHogs") then
+ only_low_score = false
+ else
+ if getTeamValue(teams[i], "DeadHogs") > getTeamValue(lowest_score_team, "DeadHogs") then
+ lowest_score_team = teams[i]
+ end
+ only_low_score = true
+ end
+
+ else
+ min_score= curr_score
+ lowest_score_team = teams[i]
+ only_low_score = true
+ end
+ end
+ end
+ end
+ end
+
+ if gameOver then
+ TurnTimeLeft = 0
+ for i=0, #teams do
+ if teams[i]~=winTeam then
+ runOnHogsInTeam(armageddon, teams[i])
+ end
+ end
+
+ ShowMission( loc("WINNER IS ") .. winTeam,
+ "~~~~~~~~~~~~~~~~~~~~~~~~~",
+ showScore, 0, 200)
+ else
+
+ if only_low_score then
+ runOnHogsInTeam(setFeeder, lowest_score_team)
+ end
+
+ if meh == false then
+ meh = true
+ else
+ ShowMission( loc("Score"),
+ loc("-------"),
+ showScore, 0, 200)
+ end
+
+ end
+end
+
+function backToNormal(gear)
+ SetHogName(gear, getGearValue(gear,"Name"))
+ SetHogHat(gear, 'NoHat')
+ SetHogHat(gear, getGearValue(gear,"Hat"))
+ setGearValue(mutant,"SelfDestruct",false)
+ mt_hurt=false
+ mutant=nil
+end
+
+function setAIHints()
+ for i = 0, #hhs do
+ if mutant == nil or hhs[i] == mutant or CurrentHedgehog == mutant then
+ SetGearAIHints(hhs[i], aihUsual)
+ else
+ SetGearAIHints(hhs[i], aihDoesntMatter)
+ end
+ end
+end
+
+function removeFeeder(gear)
+ if gear~=nil then
+ setGearValue(gear,"Feeder",false)
+ if gear~= mutant then
+ SetHogName(gear, getGearValue(gear,"Name") )
+ SetHogHat(gear, 'NoHat')
+ SetHogHat(gear, getGearValue(gear,"Hat"))
+ end
+ end
+end
+
+function setFeeder(gear)
+ if gear~= mutant and gear~= nil then
+ SetHogName(gear,"BOTTOM FEEDER")
+ SetHogHat(gear, 'poke_slowpoke')
+ setGearValue(gear,"Feeder", true)
+ end
+end
+
+function setMutantStuff(gear)
+ mutant = gear
+
+ SetHogName(gear,"MUTANT")
+ SetHogHat(gear,'WhySoSerious')
+ SetHealth(gear, ( mutant_base_health + numhhs*25) )
+ SetEffect(gear, hePoisoned, 1)
+ setGearValue(mutant,"SelfDestruct",false)
+ setGearValue(gear, "Feeder", false)
+
+ AddCaption(getGearValue(gear, "Name") .. loc(" HAS MUTATED"))
+
+ TurnTimeLeft=0
+
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ PlaySound(sndSuddenDeath)
+end
+
+function teamScan()
+
+ for i=0, TeamsCount-1 do --nil filling
+ teams[i]=nil
+ end
+
+ for i=0, #hhs do
+ for j=0, TeamsCount-1 do
+ if teams[j] ==nil and hhs[i]~=nil then
+ teams[j] = GetHogTeamName(hhs[i])
+ setTeamValue(teams[j],"Score",0)
+ setTeamValue(teams[j], "DeadHogs",0)
+ break
+ end
+
+ if teams[j] == GetHogTeamName(hhs[i]) then
+ break
+ end
+ end
+ end
+
+ ---***---
+end
+
+function set_Mutant_and_Score(gear)
+
+local curr_team = GetHogTeamName(CurrentHedgehog)
+
+ if gear == CurrentHedgehog then
+ if CurrentHedgehog == mutant then
+ PlaySound(sndHomerun)
+ if getGearValue(gear, "SelfDestruct")==false then
+ decreaseTeamValue(curr_team,"Score")
+ end
+ backToNormal(gear)
+ else
+ decreaseTeamValue(curr_team,"Score")
+ end
+
+ else
+ if gear == mutant then
+ backToNormal(mutant)
+ if curr_team ~=GetHogTeamName(gear) then
+ if getGearValue(CurrentHedgehog, "Alive") then
+ setMutantStuff(CurrentHedgehog)
+ setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward))
+ end
+ else
+ setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
+ end
+ else
+ if mutant==nil then
+ if curr_team ~=GetHogTeamName(gear) then
+ if getGearValue(CurrentHedgehog, "Alive") then
+ setMutantStuff(CurrentHedgehog)
+ setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") + mutant_kill_reward))
+ else
+ increaseTeamValue(curr_team,"Score")
+ end
+ else
+ setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
+ end
+ else
+ if curr_team ~=GetHogTeamName(gear) then
+ if CurrentHedgehog==mutant and getGearValue(mutant,"SelfDestruct")==false then
+ SetHealth(CurrentHedgehog, GetHealth(CurrentHedgehog)+kill_reward)
+ AddCaption("+" .. kill_reward .. loc(" HP") )
+ increaseTeamValue(curr_team,"Score")
+ end
+ if getGearValue(CurrentHedgehog,"Feeder") then
+ increaseTeamValue(curr_team,"Score")
+ end
+ else
+ setTeamValue(curr_team,"Score",(getTeamValue(curr_team,"Score") - team_fire_punishment))
+ end
+ end
+ end
+ end
+end
+
+function onGearResurrect(gear)
+if not gameOver then
+ if GetGearType(gear) == gtHedgehog then
+
+ increaseTeamValue(GetHogTeamName(gear), "DeadHogs")
+
+ if gear==CurrentHedgehog then
+ setGearValue(CurrentHedgehog, "Alive", false)
+ end
+ set_Mutant_and_Score(gear)
+ if gear~=CurrentHedgehog then
+ killsCounter = killsCounter + 1
+ countBodies()
+ end
+ AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
+ PlaySound(sndWhack)
+ updateScore()
+ end
+end
+end
+
+function onGearAdd(gear)
+
+ -- Catch hedgehogs for the tracker
+ if GetGearType(gear) == gtHedgehog then
+ trackGear(gear)
+ hhs[numhhs] = gear
+ numhhs = numhhs + 1
+ SetEffect(gear, heResurrectable, 1)
+ end
+end
+
+function checkEmptyTeam (teamName)
+ for i=0 , #hhs do
+ if hhs[i]~=nil then
+ if teamName == GetHogTeamName(hhs[i]) then
+ return false
+ end
+ end
+ end
+ return true
+end
+
+function onGearDelete(gear)
+ -- Remove hogs that are gone
+ if GetGearType(gear) == gtHedgehog then
+ numhhs = numhhs - 1
+
+ local found
+ for i=0, #hhs do
+ if hhs[i] == gear then
+ found = i
+ break
+ end
+ end
+ for i = found, #hhs - 1 do
+ hhs[i] = hhs[i + 1]
+ end
+ hhs[#hhs] = nil
+
+ local t_name = GetHogTeamName(gear)
+ if checkEmptyTeam(t_name) then
+ for i = 0, TeamsCount - 1 do
+ if teams[i] == t_name then
+ found = i
+ break
+ end
+ end
+ for i = found, TeamsCount - 2 do
+ teams[i] = teams[i + 1]
+ end
+ teams[TeamsCount - 1] = nil
+ TeamsCount = TeamsCount - 1
+ end
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+ trackDeletion(gear)
+ end
+end
+
+--[[
+S T A R R I N G
+ prof - Coding, implementing and evangelism
+ vos - Initial idea and script improvements
+ mikade - Moving the `how to play` into the game so that people know `how to play`, and whitespace :D
+--]]
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua b/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua
index 68c2ba0..985d55d 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/No_Jumping.lua
@@ -2,7 +2,7 @@
-- NO JUMPING
--------------------------------
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
local specialGear = nil
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua
index ade1d3b..4992dff 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua
@@ -1,700 +1,706 @@
-
-------------------------------------------
--- RACER 0.5
--- map-independant racing script
--- by mikade
------------------------------------------
-
------------------------------------
---0.1: took all the code from crazy racer and scrapped most of it
------------------------------------
-
--- Removed tumbler system
--- Removed extra adds like boosters etc
--- Added experimental waypoint placement system
--- More user feedback
--- Reduced race complexity limit to 5 waypoints
--- stop placement at complexity limit reached and end turn
--- guys dont keep racing after dying
--- invulnerable feasibility
--- reverted time keeping method
--- reduced feedback display time
--- colour-coded addcaptions
--- cleaned up code
--- support for more players properly added
--- tardis fix
--- remove airstrikes
-
--- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn
-
--- update feedback
-
--------
--- 0.2
--------
-
--- allow gameflags
--- extend time to 90s
--- remove other air-attack based weps
--- turn off water rise for sd
-
--------
--- 0.3
--------
-
--- prevent WP being placed in land
--- prevent waypoints being placed outside border
-
--------
--- 0.4
--------
-
--- update user feedback
--- add more sounds
-
--------
--- 0.5
--------
-
--- fix ghost disappearing if hog falls in water or somehow dies
--- lengthen ghost tracking interval to improve performance on slower machines
--- increase waypoint limit to 8
--- allow for persistent showmission information
-
------------------------------
--- SCRIPT BEGINS
------------------------------
-
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-
-------------------
--- Got Variables?
-------------------
-
-local fMod = 1000000 -- 1
-local roundLimit = 3
-local roundNumber = 0
-local firstClan = 10
-
-local fastX = {}
-local fastY = {}
-local fastCount = 0
-local fastIndex = 0
-local fastColour
-
-local currX = {}
-local currY = {}
-local currCount = 0
-
---------------------------
--- hog and team tracking variales
---------------------------
-
-local numhhs = 0 -- store number of hedgehogs
-local hhs = {} -- store hedgehog gears
-
-local numTeams -- store the number of teams in the game
-local teamNameArr = {} -- store the list of teams
-local teamClan = {}
-local teamSize = {} -- store how many hogs per team
-local teamIndex = {} -- at what point in the hhs{} does each team begin
-
-local teamComment = {}
-local teamScore = {}
-
--------
--- racer vars
---------
-
-local cGear = nil
-
-local bestClan = nil
-local bestTime = nil
-
-local gameBegun = false
-local gameOver = false
-local racerActive = false
-local trackTime = 0
-
-local wpCirc = {}
-local wpX = {}
-local wpY = {}
-local wpCol = {}
-local wpActive = {}
-local wpRad = 450 --75
-local wpCount = 0
-local wpLimit = 8
-
-local roundN
-local lastRound
-local RoundHasChanged
-
--------------------
--- general methods
--------------------
-
-function RebuildTeamInfo()
-
-
- -- make a list of individual team names
- for i = 0, (TeamsCount-1) do
- teamNameArr[i] = " " -- = i
- teamSize[i] = 0
- teamIndex[i] = 0
- teamScore[i] = 100000
- end
- numTeams = 0
-
- for i = 0, (numhhs-1) do
-
- z = 0
- unfinished = true
- while(unfinished == true) do
-
- newTeam = true
- tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
-
- if tempHogTeamName == teamNameArr[z] then
- newTeam = false
- unfinished = false
- end
-
- z = z + 1
-
- if z == TeamsCount then
- unfinished = false
- if newTeam == true then
- teamNameArr[numTeams] = tempHogTeamName
- numTeams = numTeams + 1
- end
- end
-
- end
-
- end
-
- -- find out how many hogs per team, and the index of the first hog in hhs
- for i = 0, (numTeams-1) do
- for z = 0, (numhhs-1) do
- if GetHogTeamName(hhs[z]) == teamNameArr[i] then
- teamClan[i] = GetHogClan(hhs[z])
- if teamSize[i] == 0 then
- teamIndex[i] = z -- should give starting index
- end
- teamSize[i] = teamSize[i] + 1
- --add a pointer so this hog appears at i in hhs
- end
- end
-
- end
-
-end
-
-
------------------
--- RACER METHODS
------------------
-
-function CheckWaypoints()
-
- trackFinished = true
-
- for i = 0, (wpCount-1) do
-
- g1X, g1Y = GetGearPosition(CurrentHedgehog)
- g2X, g2Y = wpX[i], wpY[i]
-
- g1X = g1X - g2X
- g1Y = g1Y - g2Y
- dist = (g1X*g1X) + (g1Y*g1Y)
-
- --if i == 0 then
- -- AddCaption(dist .. "/" .. (wpRad*wpRad) )
- --end
-
- NR = (48/100*wpRad)/2
-
- if dist < (NR*NR) then
- --if dist < (wpRad*wpRad) then
- --AddCaption("howdy")
- wpActive[i] = true
- wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new --GetClanColor(1)
- SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
-
- wpRem = 0
- for k = 0, (wpCount-1) do
- if wpActive[k] == false then
- wpRem = wpRem + 1
- end
- end
-
- AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo)
-
- end
-
- if wpActive[i] == false then
- trackFinished = false
- end
-
- end
-
- return(trackFinished)
-
-end
-
-function AdjustScores()
-
- if bestTime == nil then
- bestTime = 100000
- bestClan = 10
- bestTimeComment = "N/A"
- end
-
- newScore = false
-
- -- update this clan's time if the new track is better
- for i = 0, (numTeams-1) do
- if teamClan[i] == GetHogClan(CurrentHedgehog) then
- if trackTime < teamScore[i] then
- teamScore[i] = trackTime
- newScore = true
- else
- newScore = false
- end
- end
- end
-
- --bestTime = 100000
- --bestClan = 10
-
- -- find the best time out of those so far
- for i = 0, (numTeams-1) do
- if teamScore[i] < bestTime then
- bestTime = teamScore[i]
- bestClan = teamClan[i]
- end
- end
-
- if bestTime ~= 100000 then
- bestTimeComment = (bestTime/1000) ..loc("s")
- end
-
- if newScore == true then
- if trackTime == bestTime then -- best time of the race
- ShowMission(loc("RACER"),
- loc("TRACK COMPLETED"),
- loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
- loc("WINNING TIME: ") .. bestTimeComment, 0, 4000)
- PlaySound(sndHomerun)
- else -- best time for the clan
- ShowMission(loc("RACER"),
- loc("TRACK COMPLETED"),
- loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
- loc("WINNING TIME: ") .. bestTimeComment, 4, 4000)
- end
- else -- not any kind of new score
- ShowMission(loc("RACER"),
- loc("TRACK COMPLETED"),
- loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" ..
- loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
- PlaySound(sndHellish)
- end
-
-
- --------
- --new
- --------
-
- if bestTime == trackTime then
- --AddCaption("wooooooooooooooooooooooooooooo")
-
- fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
-
- for i = 0, (currCount-1) do
- fastX[i] = currX[i]
- fastY[i] = currY[i]
- end
-
- fastCount = currCount
- fastIndex = 0
-
- --currCount = 0 -- is this needed?
-
- else
- currCount = 0
- fastIndex = 0
- end
-
-
-end
-
-function onNewRound()
-
- roundNumber = roundNumber + 1
-
- totalComment = ""
- for i = 0, (TeamsCount-1) do
- if teamNameArr[i] ~= " " then -- teamScore[teamClan[i]]
- teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|")
- totalComment = totalComment .. teamComment[i]
- elseif teamNameArr[i] == " " then
- teamComment[i] = "|"
- end
- end
-
- ShowMission( loc("RACER"),
- loc("STATUS UPDATE"),
- loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" ..
- loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000)
-
- -- end game if its at round limit
- if roundNumber == roundLimit then
- for i = 0, (numhhs-1) do
- if GetHogClan(hhs[i]) ~= bestClan then
- SetEffect(hhs[i], heResurrectable, 0)
- SetHealth(hhs[i],0)
- end
- end
- gameOver = true
- TurnTimeLeft = 1
- end
-
-end
-
-function CheckForNewRound()
-
- -------------
- ------ new
- -------------
-
- --[[turnN = turnN + 1
- if gameBegun == false then
- if turnN == 2 then
- for i = 0, (numhhs-1) do
- if hhs[i] ~= nil then
- SetEffect(hhs[i], heResurrectable, 0)
- SetHealth(hhs[i],0)
- end
- end
- gameOver = true
- TurnTimeLeft = 1
- end
- else
-
-
- end]]
-
- --[[if roundBegun == true then
-
- if RoundHasChanged == true then
- roundN = roundN + 1
- RoundHasChanged = false
- onNewRound()
- end
-
- if lastRound ~= TotalRounds then -- new round, but not really
-
- if RoundHasChanged == false then
- RoundHasChanged = true
- end
-
- end
-
- AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds)
-
- lastRound = TotalRounds
-
- end]]
-
- ------------
- ----- old
- ------------
-
- if GetHogClan(CurrentHedgehog) == firstClan then
- onNewRound()
- end
-
-end
-
-function DisableTumbler()
- currCount = 0
- fastIndex = 0
- TurnTimeLeft = 0
- racerActive = false -- newadd
-end
-
-function HandleGhost()
-
- -- get the current xy of the racer at this point
- currX[currCount] = GetX(CurrentHedgehog)
- currY[currCount] = GetY(CurrentHedgehog)
- currCount = currCount + 1
-
- -- draw a ping of smoke where the fastest player was at this point
- if (fastCount ~= 0) and (fastIndex < fastCount) then
-
- fastIndex = fastIndex + 1
-
- tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
- g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
- SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
-
- --AddCaption("fC: " .. fastIndex .. " / " .. fastCount)
-
- else
-
- --AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount)
-
- end
-
-
-
-end
-
-----------------------------------
--- GAME METHODS / EVENT HANDLERS
-----------------------------------
-
-function onGameInit()
- GameFlags = GameFlags + gfInfAttack + gfInvulnerable
- CaseFreq = 0
- TurnTime = 90000
- WaterRise = 0
-end
-
-
-function onGameStart()
-
- roundN = 0
- lastRound = TotalRounds
- RoundHasChanged = false -- true
-
- RebuildTeamInfo()
-
- ShowMission (
- loc("RACER"),
- loc("a Hedgewars mini-game"),
-
- loc("Build a track and race.") .. "|" ..
- loc("Round Limit:") .. " " .. roundLimit .. "|" ..
-
- "", 4, 4000
- )
-end
-
-function PlaceWayPoint(x,y)
-
- if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek
-
- wpX[wpCount] = x
- wpY[wpCount] = y
- wpCol[wpCount] = 0xffffffff
- wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
- --100
- SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount])
-
- wpCount = wpCount + 1
-
- AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount))
-
- end
-
-end
-
-function onNewTurn()
-
- CheckForNewRound()
-
- racerActive = false
-
- trackTime = 0
-
- currCount = 0 -- hopefully this solves problem
- AddAmmo(CurrentHedgehog, amAirAttack, 0)
- gTimer = 0
-
- -- Set the waypoints to unactive on new round
- for i = 0,(wpCount-1) do
- wpActive[i] = false
- wpCol[i] = 0xffffffff
- SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
- end
-
- -- Handle Starting Stage of Game
- if (gameOver == false) and (gameBegun == false) then
- if wpCount >= 3 then
- gameBegun = true
- roundNumber = 0
- firstClan = GetHogClan(CurrentHedgehog)
- ShowMission(loc("RACER"),
- loc("GAME BEGUN!!!"),
- loc("Complete the track as fast as you can!"), 2, 4000)
- else
- ShowMission(loc("RACER"),
- loc("NOT ENOUGH WAYPOINTS"),
- loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000)
- AddAmmo(CurrentHedgehog, amAirAttack, 4000)
- ParseCommand("setweap " .. string.char(amAirAttack))
- end
- end
-
- if gameOver == true then
- gameBegun = false
- racerActive = false -- newadd
- end
-
- AddAmmo(CurrentHedgehog, amTardis, 0)
- AddAmmo(CurrentHedgehog, amDrillStrike, 0)
- AddAmmo(CurrentHedgehog, amMineStrike, 0)
- AddAmmo(CurrentHedgehog, amNapalm, 0)
- AddAmmo(CurrentHedgehog, amPiano, 0)
-
-end
-
-function onGameTick20()
-
- -- airstrike detected, convert this into a potential waypoint spot
- if cGear ~= nil then
- x,y = GetGearPosition(cGear)
- if x > -9000 then
- x,y = GetGearTarget(cGear)
-
-
- if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
- AddCaption(loc("Please place the way-point in the open, within the map boundaries."))
- PlaySound(sndDenied)
- elseif (y > WaterLine-50) then
- AddCaption(loc("Please place the way-point further from the waterline."))
- PlaySound(sndDenied)
- else
- PlaceWayPoint(x, y)
- if wpCount == wpLimit then
- AddCaption(loc("Race complexity limit reached."))
- DisableTumbler()
- end
- end
- else
- DeleteGear(cGear)
- end
- SetGearPosition(cGear, -10000, 0)
- end
-
-
- -- start the player tumbling with a boom once their turn has actually begun
- if racerActive == false then
-
- if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
-
- -- if the gamehas started put the player in the middle of the first
- --waypoint that was placed
- if gameBegun == true then
- AddCaption(loc("Good to go!"))
- racerActive = true
- trackTime = 0
-
- SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
- AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
- FollowGear(CurrentHedgehog)
-
- HideMission()
-
- else
- -- still in placement mode
- end
-
- end
- end
-
-
-
- -- has the player started his tumbling spree?
- if (CurrentHedgehog ~= nil) then
-
- --airstrike conversion used to be here
-
- -- if the RACE has started, show tracktimes and keep tabs on waypoints
- if (racerActive == true) and (gameBegun == true) then
-
- --ghost
- if GameTime%40 == 0 then
- HandleGhost()
- end
-
- trackTime = trackTime + 20
-
- if GameTime%100 == 0 then
-
- if trackTime%1000 == 0 then
- AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
- else
- AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
- end
-
- if (CheckWaypoints() == true) then
- AdjustScores()
- racerActive = false
- DisableTumbler()
- end
-
- end
-
- end
-
-
-
- -- if the player has expended his tunbling time, stop him tumbling
- if TurnTimeLeft <= 20 then
- DisableTumbler()
- end
-
- end
-
-end
-
-function onGearResurrect(gear)
-
- AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
-
- if gear == CurrentHedgehog then
- DisableTumbler()
- end
-
- -- if the player stops and "dies" or flies into water, stop him racing
- --[[if gear == CurrentHedgehog then
- DisableTumbler()
- ShowMission(loc("RACER"),
- loc("TRACK FAILED!"),
- loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
- end]]
-
-end
-
-function onGearAdd(gear)
-
- if GetGearType(gear) == gtHedgehog then
- hhs[numhhs] = gear
- numhhs = numhhs + 1
- SetEffect(gear, heResurrectable, 1)
- end
-
- if GetGearType(gear) == gtAirAttack then
- cGear = gear
- end
-
-end
-
-function onGearDelete(gear)
-
- if GetGearType(gear) == gtAirAttack then
- cGear = nil
- end
-
-end
-
---[[function onAmmoStoreInit()
- SetAmmo(amRope, 9, 0, 0, 0)
- SetAmmo(amJetpack, 9, 0, 0, 0)
- SetAmmo(amSkip, 9, 0, 0, 0)
-end]]
-
-
+
+------------------------------------------
+-- RACER 0.6
+-- map-independant racing script
+-- by mikade
+-----------------------------------------
+
+-----------------------------------
+--0.1: took all the code from crazy racer and scrapped most of it
+-----------------------------------
+
+-- Removed tumbler system
+-- Removed extra adds like boosters etc
+-- Added experimental waypoint placement system
+-- More user feedback
+-- Reduced race complexity limit to 5 waypoints
+-- stop placement at complexity limit reached and end turn
+-- guys dont keep racing after dying
+-- invulnerable feasibility
+-- reverted time keeping method
+-- reduced feedback display time
+-- colour-coded addcaptions
+-- cleaned up code
+-- support for more players properly added
+-- tardis fix
+-- remove airstrikes
+
+-- i think the remainder 0 .456 sec of the tracktime isnt getting reset on newturn
+
+-- update feedback
+
+-------
+-- 0.2
+-------
+
+-- allow gameflags
+-- extend time to 90s
+-- remove other air-attack based weps
+-- turn off water rise for sd
+
+-------
+-- 0.3
+-------
+
+-- prevent WP being placed in land
+-- prevent waypoints being placed outside border
+
+-------
+-- 0.4
+-------
+
+-- update user feedback
+-- add more sounds
+
+-------
+-- 0.5
+-------
+
+-- fix ghost disappearing if hog falls in water or somehow dies
+-- lengthen ghost tracking interval to improve performance on slower machines
+-- increase waypoint limit to 8
+-- allow for persistent showmission information
+
+-------
+-- 0.6
+-------
+
+-- remove hogs from racing area as per request
+
+-----------------------------
+-- SCRIPT BEGINS
+-----------------------------
+
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+
+------------------
+-- Got Variables?
+------------------
+
+local fMod = 1000000 -- 1
+local roundLimit = 3
+local roundNumber = 0
+local firstClan = 10
+
+local fastX = {}
+local fastY = {}
+local fastCount = 0
+local fastIndex = 0
+local fastColour
+
+local currX = {}
+local currY = {}
+local currCount = 0
+
+--------------------------
+-- hog and team tracking variales
+--------------------------
+
+local numhhs = 0 -- store number of hedgehogs
+local hhs = {} -- store hedgehog gears
+
+local numTeams -- store the number of teams in the game
+local teamNameArr = {} -- store the list of teams
+local teamClan = {}
+local teamSize = {} -- store how many hogs per team
+local teamIndex = {} -- at what point in the hhs{} does each team begin
+
+local teamComment = {}
+local teamScore = {}
+
+-------
+-- racer vars
+--------
+
+local cGear = nil
+
+local bestClan = nil
+local bestTime = nil
+
+local gameBegun = false
+local gameOver = false
+local racerActive = false
+local trackTime = 0
+
+local wpCirc = {}
+local wpX = {}
+local wpY = {}
+local wpCol = {}
+local wpActive = {}
+local wpRad = 450 --75
+local wpCount = 0
+local wpLimit = 8
+
+local roundN
+local lastRound
+local RoundHasChanged
+
+-------------------
+-- general methods
+-------------------
+
+function RebuildTeamInfo()
+
+
+ -- make a list of individual team names
+ for i = 0, (TeamsCount-1) do
+ teamNameArr[i] = " " -- = i
+ teamSize[i] = 0
+ teamIndex[i] = 0
+ teamScore[i] = 100000
+ end
+ numTeams = 0
+
+ for i = 0, (numhhs-1) do
+
+ z = 0
+ unfinished = true
+ while(unfinished == true) do
+
+ newTeam = true
+ tempHogTeamName = GetHogTeamName(hhs[i]) -- this is the new name
+
+ if tempHogTeamName == teamNameArr[z] then
+ newTeam = false
+ unfinished = false
+ end
+
+ z = z + 1
+
+ if z == TeamsCount then
+ unfinished = false
+ if newTeam == true then
+ teamNameArr[numTeams] = tempHogTeamName
+ numTeams = numTeams + 1
+ end
+ end
+
+ end
+
+ end
+
+ -- find out how many hogs per team, and the index of the first hog in hhs
+ for i = 0, (numTeams-1) do
+ for z = 0, (numhhs-1) do
+ if GetHogTeamName(hhs[z]) == teamNameArr[i] then
+ teamClan[i] = GetHogClan(hhs[z])
+ if teamSize[i] == 0 then
+ teamIndex[i] = z -- should give starting index
+ end
+ teamSize[i] = teamSize[i] + 1
+ --add a pointer so this hog appears at i in hhs
+ end
+ end
+
+ end
+
+end
+
+
+-----------------
+-- RACER METHODS
+-----------------
+
+function CheckWaypoints()
+
+ trackFinished = true
+
+ for i = 0, (wpCount-1) do
+
+ g1X, g1Y = GetGearPosition(CurrentHedgehog)
+ g2X, g2Y = wpX[i], wpY[i]
+
+ g1X = g1X - g2X
+ g1Y = g1Y - g2Y
+ dist = (g1X*g1X) + (g1Y*g1Y)
+
+ --if i == 0 then
+ -- AddCaption(dist .. "/" .. (wpRad*wpRad) )
+ --end
+
+ NR = (48/100*wpRad)/2
+
+ if dist < (NR*NR) then
+ --if dist < (wpRad*wpRad) then
+ --AddCaption("howdy")
+ wpActive[i] = true
+ wpCol[i] = GetClanColor(GetHogClan(CurrentHedgehog)) -- new --GetClanColor(1)
+ SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+
+ wpRem = 0
+ for k = 0, (wpCount-1) do
+ if wpActive[k] == false then
+ wpRem = wpRem + 1
+ end
+ end
+
+ AddCaption(loc("Way-Points Remaining") .. ": " .. wpRem,0xffba00ff,capgrpAmmoinfo)
+
+ end
+
+ if wpActive[i] == false then
+ trackFinished = false
+ end
+
+ end
+
+ return(trackFinished)
+
+end
+
+function AdjustScores()
+
+ if bestTime == nil then
+ bestTime = 100000
+ bestClan = 10
+ bestTimeComment = "N/A"
+ end
+
+ newScore = false
+
+ -- update this clan's time if the new track is better
+ for i = 0, (numTeams-1) do
+ if teamClan[i] == GetHogClan(CurrentHedgehog) then
+ if trackTime < teamScore[i] then
+ teamScore[i] = trackTime
+ newScore = true
+ else
+ newScore = false
+ end
+ end
+ end
+
+ --bestTime = 100000
+ --bestClan = 10
+
+ -- find the best time out of those so far
+ for i = 0, (numTeams-1) do
+ if teamScore[i] < bestTime then
+ bestTime = teamScore[i]
+ bestClan = teamClan[i]
+ end
+ end
+
+ if bestTime ~= 100000 then
+ bestTimeComment = (bestTime/1000) ..loc("s")
+ end
+
+ if newScore == true then
+ if trackTime == bestTime then -- best time of the race
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("NEW RACE RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, 0, 4000)
+ PlaySound(sndHomerun)
+ else -- best time for the clan
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("NEW CLAN RECORD: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, 4, 4000)
+ end
+ else -- not any kind of new score
+ ShowMission(loc("RACER"),
+ loc("TRACK COMPLETED"),
+ loc("TIME: ") .. (trackTime/1000) ..loc("s") .. "|" ..
+ loc("WINNING TIME: ") .. bestTimeComment, -amSkip, 4000)
+ PlaySound(sndHellish)
+ end
+
+
+ --------
+ --new
+ --------
+
+ if bestTime == trackTime then
+ --AddCaption("wooooooooooooooooooooooooooooo")
+
+ fastColour = GetClanColor(GetHogClan(CurrentHedgehog))
+
+ for i = 0, (currCount-1) do
+ fastX[i] = currX[i]
+ fastY[i] = currY[i]
+ end
+
+ fastCount = currCount
+ fastIndex = 0
+
+ --currCount = 0 -- is this needed?
+
+ else
+ currCount = 0
+ fastIndex = 0
+ end
+
+
+end
+
+function onNewRound()
+
+ roundNumber = roundNumber + 1
+
+ totalComment = ""
+ for i = 0, (TeamsCount-1) do
+ if teamNameArr[i] ~= " " then -- teamScore[teamClan[i]]
+ teamComment[i] = teamNameArr[i] .. ": " .. (teamScore[i]/1000) .. loc("s|")
+ totalComment = totalComment .. teamComment[i]
+ elseif teamNameArr[i] == " " then
+ teamComment[i] = "|"
+ end
+ end
+
+ ShowMission( loc("RACER"),
+ loc("STATUS UPDATE"),
+ loc("Rounds Complete: ") .. roundNumber .. "/" .. roundLimit .. "|" .. " " .. "|" ..
+ loc("Best Team Times: ") .. "|" .. totalComment, 0, 4000)
+
+ -- end game if its at round limit
+ if roundNumber == roundLimit then
+ for i = 0, (numhhs-1) do
+ if GetHogClan(hhs[i]) ~= bestClan then
+ SetEffect(hhs[i], heResurrectable, 0)
+ SetHealth(hhs[i],0)
+ end
+ end
+ gameOver = true
+ TurnTimeLeft = 1
+ end
+
+end
+
+function CheckForNewRound()
+
+ -------------
+ ------ new
+ -------------
+
+ --[[turnN = turnN + 1
+ if gameBegun == false then
+ if turnN == 2 then
+ for i = 0, (numhhs-1) do
+ if hhs[i] ~= nil then
+ SetEffect(hhs[i], heResurrectable, 0)
+ SetHealth(hhs[i],0)
+ end
+ end
+ gameOver = true
+ TurnTimeLeft = 1
+ end
+ else
+
+
+ end]]
+
+ --[[if roundBegun == true then
+
+ if RoundHasChanged == true then
+ roundN = roundN + 1
+ RoundHasChanged = false
+ onNewRound()
+ end
+
+ if lastRound ~= TotalRounds then -- new round, but not really
+
+ if RoundHasChanged == false then
+ RoundHasChanged = true
+ end
+
+ end
+
+ AddCaption("RoundN:" .. roundN .. "; " .. "TR: " .. TotalRounds)
+
+ lastRound = TotalRounds
+
+ end]]
+
+ ------------
+ ----- old
+ ------------
+
+ if GetHogClan(CurrentHedgehog) == firstClan then
+ onNewRound()
+ end
+
+end
+
+function DisableTumbler()
+ currCount = 0
+ fastIndex = 0
+ TurnTimeLeft = 0
+ racerActive = false -- newadd
+end
+
+function HandleGhost()
+
+ -- get the current xy of the racer at this point
+ currX[currCount] = GetX(CurrentHedgehog)
+ currY[currCount] = GetY(CurrentHedgehog)
+ currCount = currCount + 1
+
+ -- draw a ping of smoke where the fastest player was at this point
+ if (fastCount ~= 0) and (fastIndex < fastCount) then
+
+ fastIndex = fastIndex + 1
+
+ tempE = AddVisualGear(fastX[fastIndex], fastY[fastIndex], vgtSmoke, 0, false)
+ g1, g2, g3, g4, g5, g6, g7, g8, g9, g10 = GetVisualGearValues(tempE)
+ SetVisualGearValues(tempE, g1, g2, g3, g4, g5, g6, g7, g8, g9, fastColour )
+
+ --AddCaption("fC: " .. fastIndex .. " / " .. fastCount)
+
+ else
+
+ --AddCaption("excep fC: " .. fastIndex .. " / " .. fastCount)
+
+ end
+
+
+
+end
+
+function TryRepositionHogs()
+
+ if MapHasBorder() == true then
+
+ for i = 0, (numhhs-1) do
+ if hhs[i] ~= nil then
+ SetGearPosition(hhs[i],GetX(hhs[i]), TopY-10)
+ end
+ end
+
+ end
+
+end
+
+----------------------------------
+-- GAME METHODS / EVENT HANDLERS
+----------------------------------
+
+function onGameInit()
+ GameFlags = bor(GameFlags,gfInfAttack + gfInvulnerable)
+ CaseFreq = 0
+ TurnTime = 90000
+ WaterRise = 0
+end
+
+
+function onGameStart()
+
+ roundN = 0
+ lastRound = TotalRounds
+ RoundHasChanged = false -- true
+
+ RebuildTeamInfo()
+
+ ShowMission (
+ loc("RACER"),
+ loc("a Hedgewars mini-game"),
+
+ loc("Build a track and race.") .. "|" ..
+ loc("Round Limit:") .. " " .. roundLimit .. "|" ..
+
+ "", 4, 4000
+ )
+
+ TryRepositionHogs()
+
+end
+
+function PlaceWayPoint(x,y)
+
+ if (wpCount < wpLimit) then -- seems to not work with a hedgehog nil chek
+
+ wpX[wpCount] = x
+ wpY[wpCount] = y
+ wpCol[wpCount] = 0xffffffff
+ wpCirc[wpCount] = AddVisualGear(wpX[wpCount],wpY[wpCount],vgtCircle,0,true)
+ --100
+ SetVisualGearValues(wpCirc[wpCount], wpX[wpCount], wpY[wpCount], 20, 100, 1, 10, 0, wpRad, 5, wpCol[wpCount])
+
+ wpCount = wpCount + 1
+
+ AddCaption(loc("Waypoint placed.") .. " " .. loc("Available points remaining: ") .. (wpLimit-wpCount))
+
+ end
+
+end
+
+function onNewTurn()
+
+ CheckForNewRound()
+ TryRepositionHogs()
+
+ racerActive = false
+
+ trackTime = 0
+
+ currCount = 0 -- hopefully this solves problem
+ AddAmmo(CurrentHedgehog, amAirAttack, 0)
+ gTimer = 0
+
+ -- Set the waypoints to unactive on new round
+ for i = 0,(wpCount-1) do
+ wpActive[i] = false
+ wpCol[i] = 0xffffffff
+ SetVisualGearValues(wpCirc[i], wpX[i], wpY[i], 20, 100, 1, 10, 0, wpRad, 5, wpCol[i])
+ end
+
+ -- Handle Starting Stage of Game
+ if (gameOver == false) and (gameBegun == false) then
+ if wpCount >= 3 then
+ gameBegun = true
+ roundNumber = 0
+ firstClan = GetHogClan(CurrentHedgehog)
+ ShowMission(loc("RACER"),
+ loc("GAME BEGUN!!!"),
+ loc("Complete the track as fast as you can!"), 2, 4000)
+ else
+ ShowMission(loc("RACER"),
+ loc("NOT ENOUGH WAYPOINTS"),
+ loc("Place more waypoints using the 'Air Attack' weapon."), 2, 4000)
+ AddAmmo(CurrentHedgehog, amAirAttack, 4000)
+ ParseCommand("setweap " .. string.char(amAirAttack))
+ end
+ end
+
+ if gameOver == true then
+ gameBegun = false
+ racerActive = false -- newadd
+ end
+
+ AddAmmo(CurrentHedgehog, amTardis, 0)
+ AddAmmo(CurrentHedgehog, amDrillStrike, 0)
+ AddAmmo(CurrentHedgehog, amMineStrike, 0)
+ AddAmmo(CurrentHedgehog, amNapalm, 0)
+ AddAmmo(CurrentHedgehog, amPiano, 0)
+
+end
+
+function onGameTick20()
+
+ -- airstrike detected, convert this into a potential waypoint spot
+ if cGear ~= nil then
+ x,y = GetGearPosition(cGear)
+ if x > -9000 then
+ x,y = GetGearTarget(cGear)
+
+
+ if TestRectForObstacle(x-20, y-20, x+20, y+20, true) then
+ AddCaption(loc("Please place the way-point in the open, within the map boundaries."))
+ PlaySound(sndDenied)
+ elseif (y > WaterLine-50) then
+ AddCaption(loc("Please place the way-point further from the waterline."))
+ PlaySound(sndDenied)
+ else
+ PlaceWayPoint(x, y)
+ if wpCount == wpLimit then
+ AddCaption(loc("Race complexity limit reached."))
+ DisableTumbler()
+ end
+ end
+ else
+ DeleteGear(cGear)
+ end
+ SetGearPosition(cGear, -10000, 0)
+ end
+
+
+ -- start the player tumbling with a boom once their turn has actually begun
+ if racerActive == false then
+
+ if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) then
+
+ -- if the gamehas started put the player in the middle of the first
+ --waypoint that was placed
+ if gameBegun == true then
+ AddCaption(loc("Good to go!"))
+ racerActive = true
+ trackTime = 0
+
+ SetGearPosition(CurrentHedgehog, wpX[0], wpY[0])
+ AddGear(GetX(CurrentHedgehog), GetY(CurrentHedgehog), gtGrenade, 0, 0, 0, 1)
+ FollowGear(CurrentHedgehog)
+
+ HideMission()
+
+ else
+ -- still in placement mode
+ end
+
+ end
+ end
+
+
+
+ -- has the player started his tumbling spree?
+ if (CurrentHedgehog ~= nil) then
+
+ --airstrike conversion used to be here
+
+ -- if the RACE has started, show tracktimes and keep tabs on waypoints
+ if (racerActive == true) and (gameBegun == true) then
+
+ --ghost
+ if GameTime%40 == 0 then
+ HandleGhost()
+ end
+
+ trackTime = trackTime + 20
+
+ if GameTime%100 == 0 then
+
+ if trackTime%1000 == 0 then
+ AddCaption((trackTime/1000)..'.0',GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+ else
+ AddCaption(trackTime/1000,GetClanColor(GetHogClan(CurrentHedgehog)),capgrpMessage2)
+ end
+
+ if (CheckWaypoints() == true) then
+ AdjustScores()
+ racerActive = false
+ DisableTumbler()
+ end
+
+ end
+
+ end
+
+ -- if the player has expended his tunbling time, stop him tumbling
+ if TurnTimeLeft <= 20 then
+ DisableTumbler()
+ end
+
+ end
+
+end
+
+function onGearResurrect(gear)
+
+ AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
+
+ if gear == CurrentHedgehog then
+ DisableTumbler()
+ end
+
+end
+
+function onGearAdd(gear)
+
+ if GetGearType(gear) == gtHedgehog then
+ hhs[numhhs] = gear
+ numhhs = numhhs + 1
+ SetEffect(gear, heResurrectable, 1)
+ end
+
+ if GetGearType(gear) == gtAirAttack then
+ cGear = gear
+ end
+
+end
+
+function onGearDelete(gear)
+
+ if GetGearType(gear) == gtAirAttack then
+ cGear = nil
+ end
+
+end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua b/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua
index bceca93..6d7c31b 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua
@@ -1,10 +1,10 @@
-- Random Weapons, example for gameplay scripts
-- Load the library for localisation ("loc" function)
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
-- Load the gear tracker
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
-- List of available weapons
local weapons = { amGrenade, amClusterBomb, amBazooka, amBee, amShotgun,
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg b/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.cfg
old mode 100755
new mode 100644
similarity index 100%
copy from share/hedgewars/Data/Scripts/Multiplayer/Capture_the_Flag.cfg
copy to share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.cfg
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.lua b/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.lua
new file mode 100644
index 0000000..35f2258
--- /dev/null
+++ b/share/hedgewars/Data/Scripts/Multiplayer/ShoppaMap.lua
@@ -0,0 +1,450 @@
+ObjectList = {}
+PointsBuffer = '' -- A string to accumulate points in
+
+-- Overall padding for roping freedom
+Padding = 430
+
+function AddPoint(x, y, width, erase)
+ PointsBuffer = PointsBuffer .. string.char(band(x,0xff00) / 256 , band(x,0xff) , band(y,0xff00) / 256 , band(y,0xff))
+ if width then
+ width = bor(width,0x80)
+ if erase then
+ width = bor(width,0x40)
+ end
+ PointsBuffer = PointsBuffer .. string.char(width)
+ else
+ PointsBuffer = PointsBuffer .. string.char(0)
+ end
+ if #PointsBuffer > 245 then
+ ParseCommand('draw '..PointsBuffer)
+ PointsBuffer = ''
+ end
+end
+function FlushPoints()
+ if #PointsBuffer > 0 then
+ ParseCommand('draw '..PointsBuffer)
+ PointsBuffer = ''
+ end
+end
+
+-- This could probably use less points and more precision
+-- 700x700 for object space
+function DrawStar(x, y, d, f)
+-- default scale is 700x700 or so
+ s = 700
+ if not(d == 1) then s = div(s,d) end
+ if NoOverlap(x,y,s,s) then
+ AddCollision(x,y,s,s)
+ if not(d == 1) then
+ i = 6-d
+ j = math.min(div(5,d),1)
+ -- centre
+ AddPoint(x,y,div(20,d))
+ -- arms
+ AddPoint(x-div(325,d),y-f*div(108,d),2)
+ AddPoint(x+div(325,d),y-f*div(108,d))
+ AddPoint(x-div(205,d),y+f*div(270,d))
+ AddPoint(x,y-f*div(345,d))
+ AddPoint(x+div(205,d),y+f*div(270,d))
+ AddPoint(x-div(325,d),y-f*div(108,d))
+ if d < 4 then
+ -- fill in arm 1
+ AddPoint(x-div(275,d),y-f*div(92,d),i)
+ AddPoint(x-div(50,d),y-f*div(92,d))
+ AddPoint(x-div(105,d),y+f*div(25,d))
+ AddPoint(x-div(250,d),y-f*div(80,d))
+ AddPoint(x-div(115,d),y-f*div(70,d))
+ AddPoint(x-div(130,d),y-f*div(25,d))
+ AddPoint(x-div(175,d),y-f*div(60,d))
+ -- fill in arm 2
+ AddPoint(x+div(275,d),y-f*div(92,d),i)
+ AddPoint(x+div(50,d),y-f*div(92,d))
+ AddPoint(x+div(105,d),y+f*div(25,d))
+ AddPoint(x+div(250,d),y-f*div(80,d))
+ AddPoint(x+div(115,d),y-f*div(70,d))
+ AddPoint(x+div(130,d),y-f*div(25,d))
+ AddPoint(x+div(175,d),y-f*div(60,d))
+ -- fill in arm 3
+ AddPoint(x-div(175,d),y+f*div(230,d),i)
+ AddPoint(x-div(110,d),y+f*div(60,d))
+ AddPoint(x,y+f*div(120,d))
+ AddPoint(x-div(155,d),y+f*div(215,d))
+ AddPoint(x-div(105,d),y+f*div(95,d))
+ AddPoint(x-div(60,d),y+f*div(130,d))
+ AddPoint(x-div(85,d),y+f*div(155,d),j)
+ -- fill in arm 4
+ AddPoint(x,y-f*div(300,d),3)
+ AddPoint(x+div(50,d),y-f*div(125,d))
+ AddPoint(x-div(50,d),y-f*div(125,d))
+ AddPoint(x,y-f*div(270,d))
+ AddPoint(x-div(40,d),y-f*div(160,d))
+ AddPoint(x+div(40,d),y-f*div(160,d))
+ AddPoint(x,y-f*div(195,d),j)
+ -- fill in arm 5
+ AddPoint(x+div(175,d),y+f*div(230,d),i)
+ AddPoint(x+div(110,d),y+f*div(60,d))
+ AddPoint(x,y+f*div(120,d))
+ AddPoint(x+div(155,d),y+f*div(215,d))
+ AddPoint(x+div(105,d),y+f*div(95,d))
+ AddPoint(x+div(60,d),y+f*div(130,d))
+ AddPoint(x+div(85,d),y+f*div(155,d),j)
+ end
+ else
+ -- centre
+ AddPoint(x,y,20)
+ -- arms
+ AddPoint(x-325,y-f*108,1)
+ AddPoint(x+325,y-f*108)
+ AddPoint(x-205,y+f*270)
+ AddPoint(x,y-f*345)
+ AddPoint(x+205,y+f*270)
+ AddPoint(x-325,y-f*108)
+ -- fill in arm 1
+ AddPoint(x-275,y-f*92,4)
+ AddPoint(x-50,y-f*92)
+ AddPoint(x-105,y+f*25)
+ AddPoint(x-250,y-f*80)
+ AddPoint(x-115,y-f*70)
+ AddPoint(x-130,y-f*25)
+ AddPoint(x-175,y-f*60)
+ -- fill in arm 2
+ AddPoint(x+275,y-f*92,4)
+ AddPoint(x+50,y-f*92)
+ AddPoint(x+105,y+f*25)
+ AddPoint(x+250,y-f*80)
+ AddPoint(x+115,y-f*70)
+ AddPoint(x+130,y-f*25)
+ AddPoint(x+175,y-f*60)
+ -- fill in arm 3
+ AddPoint(x-175,y+f*230,4)
+ AddPoint(x-110,y+f*60)
+ AddPoint(x-10,y+f*120)
+ AddPoint(x-155,y+f*215)
+ AddPoint(x-105,y+f*95)
+ AddPoint(x-60,y+f*130)
+ AddPoint(x-85,y+f*155,5)
+ -- fill in arm 4
+ AddPoint(x,y-f*300,3)
+ AddPoint(x+50,y-f*125)
+ AddPoint(x-50,y-f*125)
+ AddPoint(x,y-f*270)
+ AddPoint(x-40,y-f*160)
+ AddPoint(x+40,y-f*160)
+ AddPoint(x,y-f*195,5)
+ -- fill in arm 5
+ AddPoint(x+175,y+f*230,4)
+ AddPoint(x+110,y+f*60)
+ AddPoint(x+10,y+f*120)
+ AddPoint(x+155,y+f*215)
+ AddPoint(x+105,y+f*95)
+ AddPoint(x+60,y+f*130)
+ AddPoint(x+85,y+f*155,5)
+ end
+ return true
+ else
+ return false
+ end
+end
+
+-- well. this was easy
+function DrawCircle(x, y, w)
+ if NoOverlap(x,y,w*10+6,w*10+6) then
+ AddCollision(x,y,w*10+6,w*10+6)
+ AddPoint(x,y,w)
+ return true
+ else
+ return false
+ end
+end
+
+function DrawCrescent(x, y, w, s)
+ b = div(w*(GetRandom(4)+1)*10+6,6)
+
+ if NoOverlap(x,y,w*10+6,w*10+6) then
+ AddCollision(x,y,w*10+6,w*10+6)
+ AddPoint(x,y,w)
+ if s then -- side
+ if GetRandom(1) == 0 then
+ b = b*-1
+ end
+ AddPoint(x-b,y,w,true)
+ else -- top
+ AddPoint(x,y-b,w,true)
+ end
+ return true
+ else
+ return false
+ end
+end
+
+function DrawCones(x,w,h,c)
+ y = 2048-h
+ hw = div(w,2)
+ if NoOverlap(x+div(w*c,2),y+div(h,2),w*c,h) then
+ AddCollision(x+div(w*c,2),y+div(h,2),w*c,h)
+ x = x + hw
+ for i = 1,c do -- I'm guessing outlining is slightly more efficient than fanning at 16px brush
+ AddPoint(x,y,1)
+ AddPoint(x-hw+8,2048)
+ AddPoint(x+hw-8,2048)
+ AddPoint(x,y)
+ for j = x-hw+25,x+hw,34 do
+ AddPoint(x,y+30,3)
+ AddPoint(j,2048)
+ end
+ if GetRandom(2)==0 then
+ AddPoint(x,y-20,8)
+ end
+ x = x + w
+ end
+ else
+ return false
+ end
+
+end
+
+function DrawPlateau(x,y,l,t,b)
+ if NoOverlapXY(x-28,y-28,x+l+28,y+l+28) then
+ AddPoint(x,y,5)
+ AddPoint(x+l,y)
+
+ to = GetRandom(6)
+ if not(to==0) then
+ if GetRandom(2)==0 then
+ to = div(l,to)
+ else
+ to = l-div(l,to)
+ end
+ end
+ if t>0 and NoOverlapXY(x+to-28,y-t-28,x+to+28,y+28) then
+ AddPoint(x+to,y-t,5)
+ AddPoint(x+to,y)
+ if GetRandom(2)==0 then
+ AddPoint(x+to,y-t+75,20)
+ else -- square off
+ AddPoint(x+to-20,y-t,1)
+ AddPoint(x+to-20,y-t-20)
+ AddPoint(x+to+20,y-t-20)
+ AddPoint(x+to+20,y-t)
+ end
+ tSucc = true
+ end
+
+ if to > 120 and GetRandom(2)==0 then -- left bumper
+ AddPoint(x+15,y-20,9)
+ else -- square off
+ --AddPoint(x-50,y,2)
+ AddPoint(x,y+20,1)
+ AddPoint(x-20,y+20)
+ AddPoint(x-20,y-20)
+ AddPoint(x,y-20)
+ end
+ if to < (l-120) and GetRandom(2)==0 then -- right bumper
+ AddPoint(x+l-15,y-20,9)
+ else -- square off
+ --AddPoint(x+l+50,y,2)
+ AddPoint(x+l,y+20,1)
+ AddPoint(x+l+20,y+20)
+ AddPoint(x+l+20,y-20)
+ AddPoint(x+l,y-20)
+ end
+ bo = GetRandom(6)
+ if not(bo == 0) then
+ if GetRandom(2)==0 then
+ bo = div(l,bo)
+ else
+ bo = l-div(l,bo)
+ end
+ end
+ -- still consider a success even if we can't place this one. Might need to return more than true/false
+ if b>0 and NoOverlapXY(x+bo-28,y-28,x+bo+28,y+b+28) then
+ AddPoint(x+bo,y,5)
+ AddPoint(x+bo,y+b)
+ if GetRandom(2)==0 then
+ AddPoint(x+bo,y+b-75,20)
+ else -- square off
+ AddPoint(x+bo-20,y+b,1)
+ AddPoint(x+bo-20,y+b+20)
+ AddPoint(x+bo+20,y+b+20)
+ AddPoint(x+bo+20,y+b)
+ end
+ bSucc = true
+ end
+ if bSucc then AddCollisionXY(x+bo-28,y-28,x+bo+28,y+b+28) end
+ if tSucc then AddCollisionXY(x+to-28,y-t-28,x+to+28,y+28) end
+ AddCollisionXY(x-28,y-28,x+l+28,y+28)
+ return true
+ else
+ return false
+ end
+end
+
+function AddCollision(x,y,w,h)
+ table.insert(ObjectList,{x-div(w+Padding,2),
+ y-div(h+Padding,2),
+ x+div(w+Padding,2),
+ y+div(h+Padding,2)})
+end
+
+function AddCollisionXY(x,y,x2,y2)
+ table.insert(ObjectList,{x-div(Padding,2),
+ y-div(Padding,2),
+ x2+div(Padding,2),
+ y2+div(Padding,2)})
+end
+
+-- bounding box check
+function NoOverlap(x,y,w,h)
+ w = w
+ h = h
+ x = x-div(w,2)
+ y = y-div(h,2)
+ x2 = x+w
+ y2 = y+h
+ return NoOverlapXY(x,y,x2,y2)
+end
+function NoOverlapXY(x,y,x2,y2)
+ i=1
+ l=table.getn(ObjectList)
+ while i<=l do
+ ox = ObjectList[i][1]
+ oy = ObjectList[i][2]
+ ox2 = ObjectList[i][3]
+ oy2 = ObjectList[i][4]
+ -- WriteLnToConsole(ox..' '..oy..' '..ox2..' '..oy2..' - '..x..' '..y..' '..x2..' '..y2)
+ --if (math.abs(ox + ox2 -x - x2) <= (ox2 - ox + x2 - x)) and (math.abs(oy + oy2 - y - y2) <= (oy - oy2 + y - y2)) then
+ if x < ox2 and ox < x2 and y < oy2 and oy < y2 then
+ return false
+ end
+ i=i+1
+ end
+ return true
+end
+
+function dbg()
+ i=1
+ l=table.getn(ObjectList)
+ while i<=l do
+ ox = ObjectList[i][1]
+ oy = ObjectList[i][2]
+ ox2 = ObjectList[i][3]
+ oy2 = ObjectList[i][4]
+ AddPoint(ox,oy,1)
+ AddPoint(ox2,oy)
+ AddPoint(ox2,oy2)
+ AddPoint(ox,oy2)
+ AddPoint(ox,oy)
+ AddPoint(ox2,oy2)
+ i=i+1
+ end
+end
+
+function onGameInit()
+ MapGen = 2
+ TemplateFilter = 0
+ TotGen = 0
+ Tries = 0
+ if band(GameFlags,gfBottomBorder) == 0 and GetRandom(2) == 0 then
+ AddPoint(-50,2010,7)
+ AddPoint(4150,2010)
+ for i = 0,GetRandom(3) do
+ x = GetRandom(4096)
+ w = GetRandom(40)+10
+ AddPoint(x,2200,w,true)
+ AddPoint(x,1900)
+ table.insert(ObjectList,{x-div(w*9,2),
+ 2010-div(100,2),
+ x+div(w*9,2),
+ 2010+div(100,2)})
+ end
+ end
+
+ if GetRandom(2) == 0 then
+ l = GetRandom(3)+1
+ w = GetRandom(200)+200
+ h = GetRandom(350)+200
+ x = GetRandom(4096-w*l)
+ DrawCones(x,w,h,l)
+ --if DrawCones(x,w,h,l) then TotGen = TotGen+1
+ end
+ if GetRandom(2) == 0 then
+ for i = 1,GetRandom(5)+1 do
+ w = GetRandom(35)+15
+ x = GetRandom(4096-w*12)+w
+ if GetRandom(2)==0 then
+ y = 2048-GetRandom(w*10+6)
+ else
+ y = 2048
+ end
+ -- if AddPoint(x,y,w) then TotGetn = TotGen+1
+ DrawCircle(x,y,w)
+ end
+ end
+ if GetRandom(2)==0 then
+ x = GetRandom(3300)+350
+ y = GetRandom(1300)+350
+ if DrawStar(x,y, 1, 1+GetRandom(2)*-2) then
+ TotGen = TotGen+1
+ end
+ end
+
+ while (TotGen < 6) and (Tries < 100) do
+ l = GetRandom(1000-Tries*10)+300
+ x = GetRandom(3900-l)+100
+ y = GetRandom(1900)+100
+ if GetRandom(2)==0 then b = GetRandom(800)+300
+ else b = 0 end
+ if GetRandom(2)==0 then t = GetRandom(800)+300
+ else t = 0 end
+ if y-t < 50 then t = y - 50 end
+ if t < 200 then t = 0 end
+ if DrawPlateau(x,y,l,t,b) then
+ TotGen = TotGen+1
+ end
+ Tries = Tries + 1
+ end
+ Tries = 0
+ while (TotGen < 17) and (Tries < 1000) do
+ if Tries < 500 and GetRandom(2)==0 then
+ x = GetRandom(3300)+350
+ y = GetRandom(1300)+350
+ if DrawStar(x,y, 1, 1+GetRandom(2)*-2) then
+ TotGen = TotGen+1
+ end
+ else
+ if Tries > 500 then d = GetRandom(2)+3
+ else d = GetRandom(3)+2 end
+ x = GetRandom(4000-div(700,d))+div(700,d*2)
+ y = GetRandom(1300-div(700,d))+div(700,d*2)
+ if DrawStar(x,y, d, 1+GetRandom(2)*-2) then
+ TotGen = TotGen+1
+ end
+ end
+ w = GetRandom(35-div(Tries,29))+15
+ x = GetRandom(4050-w*20)+w*10
+ y = GetRandom(2000-w*20)+w*10
+ if DrawCircle(x,y,w) then
+ TotGen = TotGen+1
+ end
+ w = GetRandom(35-div(Tries,29))+5
+ x = GetRandom(4050-w*20)+w*10
+ y = GetRandom(2000-w*20)+w*10
+ if DrawCrescent(x,y,w,GetRandom(2)==0) then
+ TotGen = TotGen+1
+ end
+ Tries = Tries + 1
+ end
+-- Padding = div(Padding,2)
+-- Tries = 0
+-- while (TotGen < 21) and (Tries < 10000) do
+-- r = GetRandom(20-div(Tries,223))+5
+-- x = GetRandom(4050-r*20)+r*10
+-- y = GetRandom(2000-r*20)+r*10
+-- if DrawCircle(x,y,r) then
+-- TotGen = TotGen+1
+-- end
+-- Tries = Tries + 1
+-- end
+ --dbg()
+ FlushPoints()
+end
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua
index 1c2a92e..b42398a 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua
@@ -1,6 +1,6 @@
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
---------------------------------------------------
---------------------------------------------------
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua
index 0d32392..f61fe7e 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua
@@ -52,8 +52,8 @@
-- balance hog health, maybe
-- add proper gameflag checking, maybe (so that we can throw in a .cfg and let the users break everything)
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
local numhhs = 0
local hhs = {}
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua b/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua
index f8788d7..1cc14d0 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua
@@ -3,8 +3,8 @@
-- v.0.7.1
------------------------------------
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
local fMod = 1000000 -- use this for dev and .16+ games
diff --git a/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua b/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua
index ee43962..a8028e3 100644
--- a/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua
+++ b/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua
@@ -54,9 +54,9 @@
-- GO PONIES, GO PONIES, GO!
-----------------------------
-loadfile(GetDataPath() .. "Scripts/Locale.lua")()
-loadfile(GetDataPath() .. "Scripts/Tracker.lua")()
-loadfile(GetDataPath() .. "Scripts/Utils.lua")()
+HedgewarsScriptLoad("/Scripts/Locale.lua")
+HedgewarsScriptLoad("/Scripts/Tracker.lua")
+HedgewarsScriptLoad("/Scripts/Utils.lua")
-- experimental menu stuff
local menuIndex = 1
diff --git a/share/hedgewars/Data/Sounds/CMakeLists.txt b/share/hedgewars/Data/Sounds/CMakeLists.txt
index 61cf8aa..3457392 100644
--- a/share/hedgewars/Data/Sounds/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/CMakeLists.txt
@@ -1,7 +1,7 @@
add_subdirectory(voices)
-file(GLOB BaseSounds *.ogg)
+file(GLOB BaseSounds *.ogg)
install(FILES
- ${BaseSounds}
- DESTINATION ${SHAREPATH}Data/Sounds)
+ ${BaseSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds)
diff --git a/share/hedgewars/Data/Sounds/frozen_hog_impact.ogg b/share/hedgewars/Data/Sounds/frozen_hog_impact.ogg
new file mode 100644
index 0000000..b9687ad
Binary files /dev/null and b/share/hedgewars/Data/Sounds/frozen_hog_impact.ogg differ
diff --git a/share/hedgewars/Data/Sounds/hog_freeze.ogg b/share/hedgewars/Data/Sounds/hog_freeze.ogg
new file mode 100644
index 0000000..6368c26
Binary files /dev/null and b/share/hedgewars/Data/Sounds/hog_freeze.ogg differ
diff --git a/share/hedgewars/Data/Sounds/ice_beam.ogg b/share/hedgewars/Data/Sounds/ice_beam.ogg
new file mode 100644
index 0000000..396374b
Binary files /dev/null and b/share/hedgewars/Data/Sounds/ice_beam.ogg differ
diff --git a/share/hedgewars/Data/Sounds/voices/British/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/British/CMakeLists.txt
index cbd409d..1bd08fa 100644
--- a/share/hedgewars/Data/Sounds/voices/British/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/British/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/British)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/British)
diff --git a/share/hedgewars/Data/Sounds/voices/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/CMakeLists.txt
index 51f56dc..08ef954 100644
--- a/share/hedgewars/Data/Sounds/voices/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/CMakeLists.txt
@@ -1,16 +1,16 @@
foreach(dir
British
- Classic
- Default
- Mobster
- Pirate
- Robot
- Russian
- Singer
- Surfer
- Default_uk
- Default_es
- HillBilly
- )
- add_subdirectory(${dir})
+ Classic
+ Default
+ Mobster
+ Pirate
+ Robot
+ Russian
+ Singer
+ Surfer
+ Default_uk
+ Default_es
+ HillBilly
+ )
+ add_subdirectory(${dir})
endforeach(dir)
diff --git a/share/hedgewars/Data/Sounds/voices/Classic/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Classic/CMakeLists.txt
index adc7d69..c1f73d4 100644
--- a/share/hedgewars/Data/Sounds/voices/Classic/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Classic/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Classic)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Classic)
diff --git a/share/hedgewars/Data/Sounds/voices/Default/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Default/CMakeLists.txt
index c7db7fe..326b6dc 100644
--- a/share/hedgewars/Data/Sounds/voices/Default/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Default/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Default)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Default)
diff --git a/share/hedgewars/Data/Sounds/voices/Default_es/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Default_es/CMakeLists.txt
index 43a8412..3d7f1c3 100644
--- a/share/hedgewars/Data/Sounds/voices/Default_es/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Default_es/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Default_es)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Default_es)
diff --git a/share/hedgewars/Data/Sounds/voices/Default_uk/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Default_uk/CMakeLists.txt
index 7409973..f612618 100644
--- a/share/hedgewars/Data/Sounds/voices/Default_uk/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Default_uk/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Default_uk)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Default_uk)
diff --git a/share/hedgewars/Data/Sounds/voices/Default_uk/JustYouwait.ogg b/share/hedgewars/Data/Sounds/voices/Default_uk/Justyouwait.ogg
similarity index 100%
rename from share/hedgewars/Data/Sounds/voices/Default_uk/JustYouwait.ogg
rename to share/hedgewars/Data/Sounds/voices/Default_uk/Justyouwait.ogg
diff --git a/share/hedgewars/Data/Sounds/voices/HillBilly/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/HillBilly/CMakeLists.txt
index dbb60e2..c604e9e 100644
--- a/share/hedgewars/Data/Sounds/voices/HillBilly/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/HillBilly/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/HillBilly)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/HillBilly)
diff --git a/share/hedgewars/Data/Sounds/voices/HillBilly/readme.txt b/share/hedgewars/Data/Sounds/voices/HillBilly/readme.txt
index 71e8233..da4760d 100644
--- a/share/hedgewars/Data/Sounds/voices/HillBilly/readme.txt
+++ b/share/hedgewars/Data/Sounds/voices/HillBilly/readme.txt
@@ -3,8 +3,8 @@ sloan2189 at gmail.com
-What can I say? I got bored and decided to add a little West Virginia to the game.
+What can I say? I got bored and decided to add a little West Virginia to the game.
-This version has better quality audio, and the oofs, fireballs, oops, and ows were replaced as well.
+This version has better quality audio, and the oofs, fireballs, oops, and ows were replaced as well.
Enjoy.
diff --git a/share/hedgewars/Data/Sounds/voices/Mobster/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Mobster/CMakeLists.txt
index 231f682..92710b9 100644
--- a/share/hedgewars/Data/Sounds/voices/Mobster/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Mobster/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Mobster)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Mobster)
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Pirate/CMakeLists.txt
index 3122e48..3f0a363 100644
--- a/share/hedgewars/Data/Sounds/voices/Pirate/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Pirate/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Pirate)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Pirate)
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch2.ogg b/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch2.ogg
deleted file mode 100644
index 3e68237..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch2.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch3.ogg b/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch3.ogg
deleted file mode 100644
index 3e68237..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch3.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch4.ogg b/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch4.ogg
deleted file mode 100644
index 3e68237..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch4.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch5.ogg b/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch5.ogg
deleted file mode 100644
index 3e68237..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch5.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch6.ogg b/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch6.ogg
deleted file mode 100644
index 3e68237..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Pirate/Firepunch6.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Robot/CMakeLists.txt
index b05b06a..0218ce1 100644
--- a/share/hedgewars/Data/Sounds/voices/Robot/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Robot/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Robot)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Robot)
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch2.ogg b/share/hedgewars/Data/Sounds/voices/Robot/Firepunch2.ogg
deleted file mode 100644
index 418f609..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch2.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch3.ogg b/share/hedgewars/Data/Sounds/voices/Robot/Firepunch3.ogg
deleted file mode 100644
index 418f609..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch3.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch4.ogg b/share/hedgewars/Data/Sounds/voices/Robot/Firepunch4.ogg
deleted file mode 100644
index 418f609..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch4.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch5.ogg b/share/hedgewars/Data/Sounds/voices/Robot/Firepunch5.ogg
deleted file mode 100644
index 418f609..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch5.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch6.ogg b/share/hedgewars/Data/Sounds/voices/Robot/Firepunch6.ogg
deleted file mode 100644
index 418f609..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Robot/Firepunch6.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Russian/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Russian/CMakeLists.txt
index 4b467fa..fbcaab3 100644
--- a/share/hedgewars/Data/Sounds/voices/Russian/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Russian/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Russian)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Russian)
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Singer/CMakeLists.txt
index 1127432..1a6d255 100644
--- a/share/hedgewars/Data/Sounds/voices/Singer/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Singer/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Singer)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Singer)
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch2.ogg b/share/hedgewars/Data/Sounds/voices/Singer/Firepunch2.ogg
deleted file mode 100644
index 4a9fade..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch2.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch3.ogg b/share/hedgewars/Data/Sounds/voices/Singer/Firepunch3.ogg
deleted file mode 100644
index 4a9fade..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch3.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch4.ogg b/share/hedgewars/Data/Sounds/voices/Singer/Firepunch4.ogg
deleted file mode 100644
index 4a9fade..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch4.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch5.ogg b/share/hedgewars/Data/Sounds/voices/Singer/Firepunch5.ogg
deleted file mode 100644
index 4a9fade..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch5.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch6.ogg b/share/hedgewars/Data/Sounds/voices/Singer/Firepunch6.ogg
deleted file mode 100644
index 4a9fade..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Singer/Firepunch6.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/CMakeLists.txt b/share/hedgewars/Data/Sounds/voices/Surfer/CMakeLists.txt
index 23256bf..485515e 100644
--- a/share/hedgewars/Data/Sounds/voices/Surfer/CMakeLists.txt
+++ b/share/hedgewars/Data/Sounds/voices/Surfer/CMakeLists.txt
@@ -37,5 +37,5 @@ Youllregretthat.ogg
)
install(FILES
- ${VoiceSounds}
- DESTINATION ${SHAREPATH}Data/Sounds/voices/Surfer)
+ ${VoiceSounds}
+ DESTINATION ${SHAREPATH}Data/Sounds/voices/Surfer)
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch2.ogg b/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch2.ogg
deleted file mode 100644
index e5f3065..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch2.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch3.ogg b/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch3.ogg
deleted file mode 100644
index e5f3065..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch3.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch4.ogg b/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch4.ogg
deleted file mode 100644
index e5f3065..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch4.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch5.ogg b/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch5.ogg
deleted file mode 100644
index e5f3065..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch5.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch6.ogg b/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch6.ogg
deleted file mode 100644
index e5f3065..0000000
Binary files a/share/hedgewars/Data/Sounds/voices/Surfer/Firepunch6.ogg and /dev/null differ
diff --git a/share/hedgewars/Data/Themes/Bamboo/Flake.png b/share/hedgewars/Data/Themes/Bamboo/Flake.png
index 3455a98..886b877 100644
Binary files a/share/hedgewars/Data/Themes/Bamboo/Flake.png and b/share/hedgewars/Data/Themes/Bamboo/Flake.png differ
diff --git a/share/hedgewars/Data/Themes/Blox/LandBackTex.png b/share/hedgewars/Data/Themes/Blox/LandBackTex.png
index 0a232c8..788bbd1 100644
Binary files a/share/hedgewars/Data/Themes/Blox/LandBackTex.png and b/share/hedgewars/Data/Themes/Blox/LandBackTex.png differ
diff --git a/share/hedgewars/Data/Themes/Brick/theme.cfg b/share/hedgewars/Data/Themes/Brick/theme.cfg
index 612e7fd..ee7794c 100644
--- a/share/hedgewars/Data/Themes/Brick/theme.cfg
+++ b/share/hedgewars/Data/Themes/Brick/theme.cfg
@@ -18,4 +18,4 @@ spray = spray1, 2
spray = spray2, 2
spray = spray3, 2
;Should this theme have flakes? they where disabled
-;flakes = 20, 30, 50, 50, 250
+flakes = 2, 0, 0, 15, 3000
diff --git a/share/hedgewars/Data/Themes/CMakeLists.txt b/share/hedgewars/Data/Themes/CMakeLists.txt
index 84c79d2..bccfa8e 100644
--- a/share/hedgewars/Data/Themes/CMakeLists.txt
+++ b/share/hedgewars/Data/Themes/CMakeLists.txt
@@ -1,34 +1,35 @@
foreach(dir
- Art
- Bamboo
- Bath
- Blox
- Brick
- Cake
- Cave
- Castle
- Cheese
- Christmas
- Compost
- Deepspace
- Desert
- City
- CrazyMission
- EarthRise
- Eyes
- Freeway
- Golf
- Halloween
- Hell
- Island
- Jungle
- Nature
- Olympics
- Planes
- Sheep
- Snow
- Stage
- Underwater
- )
- add_subdirectory(${dir})
+ Art
+ Bamboo
+ Bath
+ Blox
+ Brick
+ Cake
+ Cave
+ Castle
+ Cheese
+ Christmas
+ City
+ Compost
+ CrazyMission
+ Deepspace
+ Desert
+ EarthRise
+ Eyes
+ Freeway
+ Fruit
+ Golf
+ Halloween
+ Hell
+ Island
+ Jungle
+ Nature
+ Olympics
+ Planes
+ Sheep
+ Snow
+ Stage
+ Underwater
+ )
+ add_subdirectory(${dir})
endforeach(dir)
diff --git a/share/hedgewars/Data/Themes/Cave/Stalactite.png b/share/hedgewars/Data/Themes/Cave/Stalactite.png
index f2a2696..da4d8bf 100644
Binary files a/share/hedgewars/Data/Themes/Cave/Stalactite.png and b/share/hedgewars/Data/Themes/Cave/Stalactite.png differ
diff --git a/share/hedgewars/Data/Themes/Cave/Stalactite_mask.png b/share/hedgewars/Data/Themes/Cave/Stalactite_mask.png
new file mode 100644
index 0000000..03e739b
Binary files /dev/null and b/share/hedgewars/Data/Themes/Cave/Stalactite_mask.png differ
diff --git a/share/hedgewars/Data/Themes/Cave/Stalagmite01.png b/share/hedgewars/Data/Themes/Cave/Stalagmite01.png
index 2c4d1b1..029d622 100644
Binary files a/share/hedgewars/Data/Themes/Cave/Stalagmite01.png and b/share/hedgewars/Data/Themes/Cave/Stalagmite01.png differ
diff --git a/share/hedgewars/Data/Themes/Cave/Stalagmite01_mask.png b/share/hedgewars/Data/Themes/Cave/Stalagmite01_mask.png
new file mode 100644
index 0000000..19549d5
Binary files /dev/null and b/share/hedgewars/Data/Themes/Cave/Stalagmite01_mask.png differ
diff --git a/share/hedgewars/Data/Themes/Cave/Stalagmite02.png b/share/hedgewars/Data/Themes/Cave/Stalagmite02.png
index f6c6bec..6c6c2a2 100644
Binary files a/share/hedgewars/Data/Themes/Cave/Stalagmite02.png and b/share/hedgewars/Data/Themes/Cave/Stalagmite02.png differ
diff --git a/share/hedgewars/Data/Themes/Cave/Stalagmite02_mask.png b/share/hedgewars/Data/Themes/Cave/Stalagmite02_mask.png
new file mode 100644
index 0000000..1477f87
Binary files /dev/null and b/share/hedgewars/Data/Themes/Cave/Stalagmite02_mask.png differ
diff --git a/share/hedgewars/Data/Themes/Cheese/cheese.png b/share/hedgewars/Data/Themes/Cheese/cheese.png
index 9b7cfbc..3b18b18 100644
Binary files a/share/hedgewars/Data/Themes/Cheese/cheese.png and b/share/hedgewars/Data/Themes/Cheese/cheese.png differ
diff --git a/share/hedgewars/Data/Themes/Cheese/cheese_mask.png b/share/hedgewars/Data/Themes/Cheese/cheese_mask.png
new file mode 100644
index 0000000..bb71ad2
Binary files /dev/null and b/share/hedgewars/Data/Themes/Cheese/cheese_mask.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/Chunk.png b/share/hedgewars/Data/Themes/EarthRise/Chunk.png
index c171bb9..f3cc13f 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/Chunk.png and b/share/hedgewars/Data/Themes/EarthRise/Chunk.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/Rock.png b/share/hedgewars/Data/Themes/EarthRise/Rock.png
index df265a8..7afbcbf 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/Rock.png and b/share/hedgewars/Data/Themes/EarthRise/Rock.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/RockShort.png b/share/hedgewars/Data/Themes/EarthRise/RockShort.png
index fc50ecc..5e9736a 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/RockShort.png and b/share/hedgewars/Data/Themes/EarthRise/RockShort.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/RockShort_mask.png b/share/hedgewars/Data/Themes/EarthRise/RockShort_mask.png
new file mode 100644
index 0000000..b700b6f
Binary files /dev/null and b/share/hedgewars/Data/Themes/EarthRise/RockShort_mask.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/Rock_mask.png b/share/hedgewars/Data/Themes/EarthRise/Rock_mask.png
new file mode 100644
index 0000000..2a29b12
Binary files /dev/null and b/share/hedgewars/Data/Themes/EarthRise/Rock_mask.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/horizontL.png b/share/hedgewars/Data/Themes/EarthRise/horizontL.png
index abbe1ff..d04c623 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/horizontL.png and b/share/hedgewars/Data/Themes/EarthRise/horizontL.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/horizontR.png b/share/hedgewars/Data/Themes/EarthRise/horizontR.png
index abbe1ff..d04c623 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/horizontR.png and b/share/hedgewars/Data/Themes/EarthRise/horizontR.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/icon.png b/share/hedgewars/Data/Themes/EarthRise/icon.png
index 22c0f47..578b3c5 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/icon.png and b/share/hedgewars/Data/Themes/EarthRise/icon.png differ
diff --git a/share/hedgewars/Data/Themes/EarthRise/icon at 2x.png b/share/hedgewars/Data/Themes/EarthRise/icon at 2x.png
index d3af966..708d239 100644
Binary files a/share/hedgewars/Data/Themes/EarthRise/icon at 2x.png and b/share/hedgewars/Data/Themes/EarthRise/icon at 2x.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Banana1.png b/share/hedgewars/Data/Themes/Fruit/Banana1.png
new file mode 100644
index 0000000..66bdd0c
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Banana1.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Banana2.png b/share/hedgewars/Data/Themes/Fruit/Banana2.png
new file mode 100644
index 0000000..21301d4
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Banana2.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/BlueWater.png b/share/hedgewars/Data/Themes/Fruit/BlueWater.png
new file mode 100644
index 0000000..b2b7160
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/BlueWater.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Border.png b/share/hedgewars/Data/Themes/Fruit/Border.png
new file mode 100644
index 0000000..c71b28e
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Border.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/CMakeLists.txt b/share/hedgewars/Data/Themes/Fruit/CMakeLists.txt
new file mode 100644
index 0000000..9795fee
--- /dev/null
+++ b/share/hedgewars/Data/Themes/Fruit/CMakeLists.txt
@@ -0,0 +1,6 @@
+file(GLOB images *.png)
+
+install(FILES
+ theme.cfg
+ ${images}
+ DESTINATION ${SHAREPATH}Data/Themes/Fruit)
diff --git a/share/hedgewars/Data/Themes/Fruit/Chunk.png b/share/hedgewars/Data/Themes/Fruit/Chunk.png
new file mode 100644
index 0000000..bc3053a
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Chunk.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Clouds.png b/share/hedgewars/Data/Themes/Fruit/Clouds.png
new file mode 100644
index 0000000..39a6640
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Clouds.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Droplet.png b/share/hedgewars/Data/Themes/Fruit/Droplet.png
new file mode 100644
index 0000000..ed993d2
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Droplet.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Flake.png b/share/hedgewars/Data/Themes/Fruit/Flake.png
new file mode 100644
index 0000000..887feb8
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Flake.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Girder.png b/share/hedgewars/Data/Themes/Fruit/Girder.png
new file mode 100644
index 0000000..c8340ab
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Girder.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/LandBackTex.png b/share/hedgewars/Data/Themes/Fruit/LandBackTex.png
new file mode 100644
index 0000000..090b89a
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/LandBackTex.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/LandTex.png b/share/hedgewars/Data/Themes/Fruit/LandTex.png
new file mode 100644
index 0000000..c41c489
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/LandTex.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Orange1.png b/share/hedgewars/Data/Themes/Fruit/Orange1.png
new file mode 100644
index 0000000..6612054
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Orange1.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Orange2.png b/share/hedgewars/Data/Themes/Fruit/Orange2.png
new file mode 100644
index 0000000..c562233
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Orange2.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Sky.png b/share/hedgewars/Data/Themes/Fruit/Sky.png
new file mode 100644
index 0000000..5d351a7
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Sky.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/SkyL.png b/share/hedgewars/Data/Themes/Fruit/SkyL.png
new file mode 100644
index 0000000..b43c6b1
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/SkyL.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Snowball.png b/share/hedgewars/Data/Themes/Fruit/Snowball.png
new file mode 100644
index 0000000..0d5b308
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Snowball.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Splash.png b/share/hedgewars/Data/Themes/Fruit/Splash.png
new file mode 100644
index 0000000..4f9365a
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Splash.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Watermelon.png b/share/hedgewars/Data/Themes/Fruit/Watermelon.png
new file mode 100644
index 0000000..664b4d4
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Watermelon.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/Watermelon_mask.png b/share/hedgewars/Data/Themes/Fruit/Watermelon_mask.png
new file mode 100644
index 0000000..d8cec6b
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/Watermelon_mask.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/amSnowball.png b/share/hedgewars/Data/Themes/Fruit/amSnowball.png
new file mode 100644
index 0000000..aaeab4a
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/amSnowball.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/horizont.png b/share/hedgewars/Data/Themes/Fruit/horizont.png
new file mode 100644
index 0000000..843b0aa
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/horizont.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/icon.png b/share/hedgewars/Data/Themes/Fruit/icon.png
new file mode 100644
index 0000000..8407871
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/icon.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/icon at 2x.png b/share/hedgewars/Data/Themes/Fruit/icon at 2x.png
new file mode 100644
index 0000000..891e4fe
Binary files /dev/null and b/share/hedgewars/Data/Themes/Fruit/icon at 2x.png differ
diff --git a/share/hedgewars/Data/Themes/Fruit/theme.cfg b/share/hedgewars/Data/Themes/Fruit/theme.cfg
new file mode 100644
index 0000000..d0160e0
--- /dev/null
+++ b/share/hedgewars/Data/Themes/Fruit/theme.cfg
@@ -0,0 +1,13 @@
+sky = 50, 40, 131
+border = 0, 128, 0
+water-top = 255, 98, 0
+water-bottom = 255, 68, 0
+water-opacity = 125
+music = oriental.ogg
+clouds = 20
+object = Orange1, 1, 50, 84, 15, 3, 1, 8, 2, 90, 73
+object = Orange2, 1, 50, 84, 15, 3, 1, 8, 2, 90, 73
+object = Watermelon, 1, 87, 272, 77, 10, 1, 21, 2, 242, 219
+object = Banana1, 1, 152, 191, 37, 24, 1, 2, 1, 163, 174
+object = Banana2, 1, 1, 190, 37, 24, 1, 22, 0, 163, 174
+flakes = 20, 3, 999999999, 100, 260
diff --git a/share/hedgewars/Data/misc/CMakeLists.txt b/share/hedgewars/Data/misc/CMakeLists.txt
index 7ea7db5..6b1aa41 100644
--- a/share/hedgewars/Data/misc/CMakeLists.txt
+++ b/share/hedgewars/Data/misc/CMakeLists.txt
@@ -1,14 +1,9 @@
-if(DEFINED DATA_INSTALL_DIR)
- set(HEDGEWARS_DATADIR ${DATA_INSTALL_DIR}
-)
-else()
- set(HEDGEWARS_DATADIR ${CMAKE_INSTALL_PREFIX}/share/)
-endif()
if(UNIX AND NOT APPLE)
-configure_file(hwengine.desktop.in hwengine.desktop)
-endif()
+ configure_file(hwengine.desktop.in hwengine.desktop)
+
+ file(GLOB miscfiles *.xml *.desktop)
-file(GLOB miscfiles *.xml *.desktop)
+ install(FILES ${miscfiles} DESTINATION ${SHAREPATH}/Data/misc)
+endif()
-install(FILES ${miscfiles} DESTINATION ${SHAREPATH}Data/misc)
diff --git a/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml b/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml
old mode 100644
new mode 100755
index 391ad0f..f8e3577
--- a/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml
+++ b/share/hedgewars/Data/misc/hedgewars-mimeinfo.xml
@@ -18,6 +18,7 @@
<comment xml:lang="cs">Ukázka hry Hedgewars</comment>
<comment xml:lang="sv">Demo för Hedgewars</comment>
<comment xml:lang="da">Hedgewars-demo</comment>
+ <comment xml:lang="tr">Hedgewars Dösteri</comment>
<magic priority="50">
<match required="yes" type="byte" offset="0" value="2"/>
<match required="yes" type="big16" offset="1" value="21572"/>
@@ -39,10 +40,21 @@
<comment xml:lang="cs">Uložená hra Hedgewars</comment>
<comment xml:lang="sv">Sparfil för Hedgewars</comment>
<comment xml:lang="da">Gemt Hedgewars-spil</comment>
+ <comment xml:lang="tr">Hedgewars kayıtlı oyun</comment>
<magic priority="50">
<match required="yes" type="byte" offset="0" value="2"/>
<match required="yes" type="big16" offset="1" value="21587"/>
</magic>
<glob weight="60" pattern="*.hws"/>
</mime-type>
+ <mime-type type="x-scheme-handler/hwplay">
+ <icon name="hedgewars" />
+ <!--<generic-icon name="applications-games"/>-->
+ <comment>Hedgewars ServerAccess Scheme</comment>
+ <magic priority="50">
+ <match required="yes" type="byte" offset="0" value="2"/>
+ <match required="yes" type="big16" offset="1" value="21587"/>
+ </magic>
+ <glob weight="60" pattern="hwplay://*"/>
+ </mime-type>
</mime-info>
diff --git a/share/hedgewars/Data/misc/hedgewars.desktop b/share/hedgewars/Data/misc/hedgewars.desktop
new file mode 100755
index 0000000..7878969
--- /dev/null
+++ b/share/hedgewars/Data/misc/hedgewars.desktop
@@ -0,0 +1,25 @@
+[Desktop Entry]
+Type=Application
+Version=1.0
+Encoding=UTF-8
+Name=Hedgewars
+GenericName=Fighting Hedgehogs
+GenericName[de]=Kämpfende Igel
+GenericName[es]=Batallas entre erizos
+GenericName[fr]=Bataille de hérissons
+GenericName[ko]=ê³ ì´ëì¹ ì¸ì°ê¸°
+GenericName[ja]=ãã¡ã¤ãã³ã°ããªããºã
+GenericName[it]=Ricci combattenti
+GenericName[pl]=WalczÄ
ce jeże
+GenericName[pt]=Batalhas entre ouriços
+GenericName[ru]=ÐиÑÐ²Ñ ÐµÐ¶ÐµÐ¹
+GenericName[sk]=Bojujúci ježkovia
+GenericName[cs]=BojujÃcà ježci
+GenericName[sv]=Stridande igelkottar
+GenericName[tr]=DövüÅen Kirpiler
+Icon=hedgewars.png
+Exec=hedgewars %U
+Terminal=false
+StartupNotify=false
+Categories=Application;Game;StrategyGame;
+MimeType=x-scheme-handler/hwplay
diff --git a/share/hedgewars/Data/misc/hwengine.desktop.in b/share/hedgewars/Data/misc/hwengine.desktop.in
index 5a4e366..3a5e5f2 100644
--- a/share/hedgewars/Data/misc/hwengine.desktop.in
+++ b/share/hedgewars/Data/misc/hwengine.desktop.in
@@ -13,11 +13,12 @@ GenericName[pl]=Silnik gry Hedgewars do odtwarzania dem i zapisów gier
GenericName[pt]=Motor de jogo Hedgewars, para reprodução de jogos guardados e demos
GenericName[ru]=Ðвижок Hedgewars Ð´Ð»Ñ Ð¿ÑоигÑÑÐ²Ð°Ð½Ð¸Ñ ÑоÑ
ÑанÑннÑÑ
Ð¸Ð³Ñ Ð¸ демок
GenericName[sk]=Engine hry Hedgewars, pre prehrávanie uložených hier a demo súborov
+GenericName[tr]=Kayıtların ve gösterilerin oynatılması için Hedgewars motoru
GenericName[cs]=Engine hry Hedgewars pro pÅehrávánà uložených her a ukázkových souborů
GenericName[sv]=Hedgewarsmotorn, för att öppna demo- och sparfiler
GenericName[da]=Kæmpende Pindsvin
Icon=hedgewars.png
-Exec=${CMAKE_INSTALL_PREFIX}/bin/hwengine ${HEDGEWARS_DATADIR}/hedgewars/Data %f
+Exec=${CMAKE_INSTALL_PREFIX}/${target_binary_install_dir}/hwengine %f
Path=/tmp
Terminal=false
StartupNotify=false
diff --git a/share/version_info.txt b/share/version_info.txt
new file mode 100644
index 0000000..a2028c1
--- /dev/null
+++ b/share/version_info.txt
@@ -0,0 +1,3 @@
+Hedgewars versioning information, do not modify
+rev 9057
+hash 1617149e01a4
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 0c7d499..6b0d95e 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -13,10 +13,9 @@ if (APPLE)
find_package(SDL_net REQUIRED)
find_package(SDL_ttf REQUIRED)
find_package(SDL_mixer REQUIRED)
- find_package(OGGVORBIS REQUIRED)
+ find_package(OggVorbis REQUIRED)
if(NOT NOAUTOUPDATE)
- #needed for SPARKLE_FOUND variable
- find_package(Sparkle QUIET)
+ find_package(Sparkle) #needed for SPARKLE_FOUND variable
#needed because the 'if' clause in the script prints silly policy warnings
if(${SPARKLE_FOUND})
set(SPARKLE_FOUND 1)
@@ -29,11 +28,19 @@ if (APPLE)
string(REGEX REPLACE "(.*)/include.*" "\\1" qt_base_dir "${QT_INCLUDE_DIR}")
#remove the ";-framework Cocoa" from the SDL_LIBRARY variable
- string(REGEX REPLACE "(.*);-.*" "\\1" sdl_dir "${SDL_LIBRARY}")
+ string(REGEX REPLACE "(.*);-.*" "\\1" sdl_library_only "${SDL_LIBRARY}")
if(NOT NOPNG)
#get the neme of the library (harmelss if it is static)
string(REGEX REPLACE ".*/(.*)$" "\\1" PNG_LIBNAME "${PNG_LIBRARY}")
+ string(REGEX REPLACE ".*/(.*)$" "\\1" ZLIB_LIBNAME "${ZLIB_LIBRARY}")
+ endif()
+
+ set(frameworks_dir ${CMAKE_INSTALL_PREFIX}/${target_library_install_dir})
+ if(${BUILD_ENGINE_LIBRARY})
+ set(engine_full_path "${frameworks_dir}/${CMAKE_SHARED_LIBRARY_PREFIX}hwengine${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ else()
+ set(engine_full_path "${CMAKE_INSTALL_PREFIX}/hwengine${CMAKE_EXECUTABLE_SUFFIX}")
endif()
#this tool is present in qt 4.5 but only if you compile from sources
diff --git a/tools/CreateMacBundle.cmake.in b/tools/CreateMacBundle.cmake.in
index af2b58c..6e19265 100644
--- a/tools/CreateMacBundle.cmake.in
+++ b/tools/CreateMacBundle.cmake.in
@@ -1,34 +1,35 @@
message(STATUS "Performing standalone bundle creation...")
-execute_process(COMMAND ls ${frameworks_dir} RESULT_VARIABLE doBundle OUTPUT_QUIET ERROR_QUIET)
+execute_process(COMMAND stat ${frameworks_dir} RESULT_VARIABLE doBundle OUTPUT_QUIET ERROR_QUIET)
execute_process(COMMAND mkdir -p ${frameworks_dir})
# macdeployqt will convert safely any absolute path library for 'hedgewars'
-execute_process(COMMAND ${macdeployqt_executable} ${CMAKE_BINARY_DIR}/${bundle_name} OUTPUT_QUIET ERROR_QUIET)
+execute_process(COMMAND ${macdeployqt_executable} ${CMAKE_BINARY_DIR}/Hedgewars.app OUTPUT_QUIET ERROR_QUIET)
if(NOT ${NOVIDEOREC})
# but macdeployqt will not work for 'hwengine'; luckily the dylibs were already updated before
- execute_process(COMMAND install_name_tool -change ${FFMPEG_LIBAVCODEC} @executable_path/../Frameworks/libavcodec.dylib ${CMAKE_BINARY_DIR}/${bundle_name}/Contents/MacOS/hwengine)
- execute_process(COMMAND install_name_tool -change ${FFMPEG_LIBAVFORMAT} @executable_path/../Frameworks/libavformat.dylib ${CMAKE_BINARY_DIR}/${bundle_name}/Contents/MacOS/hwengine)
- execute_process(COMMAND install_name_tool -change ${FFMPEG_LIBAVUTIL} @executable_path/../Frameworks/libavutil.dylib ${CMAKE_BINARY_DIR}/${bundle_name}/Contents/MacOS/hwengine)
+ execute_process(COMMAND install_name_tool -change ${LIBAVCODEC_LIBRARY} @executable_path/../Frameworks/libavcodec.dylib ${engine_full_path})
+ execute_process(COMMAND install_name_tool -change ${LIBAVFORMAT_LIBRARY} @executable_path/../Frameworks/libavformat.dylib ${engine_full_path})
+ execute_process(COMMAND install_name_tool -change ${LIBAVUTIL_LIBRARY} @executable_path/../Frameworks/libavutil.dylib ${engine_full_path})
endif()
if(NOT ${NOPNG})
#same here, for libpng and hwengine, let's assume the version pulled by macdeployqt is the same
#(yes libpng is pulled by macdeployqt even when NOVIDEOREC is active)
- execute_process(COMMAND install_name_tool -change ${PNG_LIBRARY} @executable_path/../Frameworks/${PNG_LIBNAME} ${CMAKE_BINARY_DIR}/${bundle_name}/Contents/MacOS/hwengine)
+ execute_process(COMMAND install_name_tool -change ${PNG_LIBRARY} @executable_path/../Frameworks/${PNG_LIBNAME} ${engine_full_path})
+ execute_process(COMMAND install_name_tool -change ${ZLIB_LIBRARY} @executable_path/../Frameworks/${ZLIB_LIBNAME} ${engine_full_path})
endif()
if(doBundle EQUAL 1)
- execute_process(COMMAND cp -pPR ${sdl_dir} ${CMAKE_BINARY_DIR}/${frameworks_dir}/SDL.framework)
- execute_process(COMMAND cp -pPR ${SDLIMAGE_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/SDL_image.framework)
- execute_process(COMMAND cp -pPR ${SDLNET_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/SDL_net.framework)
- execute_process(COMMAND cp -pPR ${SDLTTF_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/SDL_ttf.framework)
- execute_process(COMMAND cp -pPR ${SDLMIXER_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/SDL_mixer.framework)
- execute_process(COMMAND cp -pPR ${OGG_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/Ogg.framework)
- execute_process(COMMAND cp -pPR ${VORBIS_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/Vorbis.framework)
+ execute_process(COMMAND cp -pPR ${sdl_library_only} ${frameworks_dir}/SDL.framework)
+ execute_process(COMMAND cp -pPR ${SDLIMAGE_LIBRARY} ${frameworks_dir}/SDL_image.framework)
+ execute_process(COMMAND cp -pPR ${SDLNET_LIBRARY} ${frameworks_dir}/SDL_net.framework)
+ execute_process(COMMAND cp -pPR ${SDLTTF_LIBRARY} ${frameworks_dir}/SDL_ttf.framework)
+ execute_process(COMMAND cp -pPR ${SDLMIXER_LIBRARY} ${frameworks_dir}/SDL_mixer.framework)
+ execute_process(COMMAND cp -pPR ${OGG_LIBRARY} ${frameworks_dir}/Ogg.framework)
+ execute_process(COMMAND cp -pPR ${VORBIS_LIBRARY} ${frameworks_dir}/Vorbis.framework)
if(${SPARKLE_FOUND})
- execute_process(COMMAND cp -pPR ${SPARKLE_LIBRARY} ${CMAKE_BINARY_DIR}/${frameworks_dir}/Sparkle.framework)
+ execute_process(COMMAND cp -pPR ${SPARKLE_LIBRARY} ${frameworks_dir}/Sparkle.framework)
endif()
message(STATUS "Bundle frameworks added")
else()
diff --git a/tools/PascalBasics.hs b/tools/PascalBasics.hs
deleted file mode 100644
index 3b94c28..0000000
--- a/tools/PascalBasics.hs
+++ /dev/null
@@ -1,70 +0,0 @@
-{-# LANGUAGE FlexibleContexts #-}
-module PascalBasics where
-
-import Text.Parsec.Combinator
-import Text.Parsec.Char
-import Text.Parsec.Prim
-import Text.Parsec.Token
-import Text.Parsec.Language
-import Data.Char
-
-builtin = ["succ", "pred", "low", "high", "ord", "inc", "dec", "exit", "break", "continue", "length"]
-
-pascalLanguageDef
- = emptyDef
- { commentStart = "(*"
- , commentEnd = "*)"
- , commentLine = "//"
- , nestedComments = False
- , identStart = letter <|> oneOf "_"
- , identLetter = alphaNum <|> oneOf "_"
- , reservedNames = [
- "begin", "end", "program", "unit", "interface"
- , "implementation", "and", "or", "xor", "shl"
- , "shr", "while", "do", "repeat", "until", "case", "of"
- , "type", "var", "const", "out", "array", "packed"
- , "procedure", "function", "with", "for", "to"
- , "downto", "div", "mod", "record", "set", "nil"
- , "cdecl", "external", "if", "then", "else"
- ] -- ++ builtin
- , reservedOpNames= []
- , caseSensitive = False
- }
-
-preprocessorSwitch :: Stream s m Char => ParsecT s u m String
-preprocessorSwitch = do
- try $ string "{$"
- s <- manyTill (noneOf "\n") $ char '}'
- return s
-
-caseInsensitiveString s = do
- mapM_ (\a -> satisfy (\b -> toUpper a == toUpper b)) s <?> s
- return s
-
-pas = patch $ makeTokenParser pascalLanguageDef
- where
- patch tp = tp {stringLiteral = stringL}
-
-comment = choice [
- char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}')
- , (try $ string "(*") >> manyTill anyChar (try $ string "*)")
- , (try $ string "//") >> manyTill anyChar (try newline)
- ]
-
-comments = do
- spaces
- skipMany $ do
- preprocessorSwitch <|> comment
- spaces
-
-stringL = do
- (char '\'')
- s <- (many $ noneOf "'")
- (char '\'')
- ss <- many $ do
- (char '\'')
- s' <- (many $ noneOf "'")
- (char '\'')
- return $ '\'' : s'
- comments
- return $ concat (s:ss)
diff --git a/tools/PascalParser.hs b/tools/PascalParser.hs
deleted file mode 100644
index b10fcad..0000000
--- a/tools/PascalParser.hs
+++ /dev/null
@@ -1,659 +0,0 @@
-module PascalParser where
-
-import Text.Parsec
-import Text.Parsec.Char
-import Text.Parsec.Token
-import Text.Parsec.Language
-import Text.Parsec.Expr
-import Text.Parsec.Prim
-import Text.Parsec.Combinator
-import Text.Parsec.String
-import Control.Monad
-import Data.Maybe
-import Data.Char
-
-import PascalBasics
-import PascalUnitSyntaxTree
-
-knownTypes = ["shortstring", "ansistring", "char", "byte"]
-
-pascalUnit = do
- comments
- u <- choice [program, unit, systemUnit, redoUnit]
- comments
- return u
-
-iD = do
- i <- liftM (flip Identifier BTUnknown) (identifier pas)
- comments
- return i
-
-unit = do
- string "unit" >> comments
- name <- iD
- semi pas
- comments
- int <- interface
- impl <- implementation
- comments
- return $ Unit name int impl Nothing Nothing
-
-
-reference = buildExpressionParser table term <?> "reference"
- where
- term = comments >> choice [
- parens pas (liftM RefExpression expression >>= postfixes) >>= postfixes
- , try $ typeCast >>= postfixes
- , char '@' >> liftM Address reference >>= postfixes
- , liftM SimpleReference iD >>= postfixes
- ] <?> "simple reference"
-
- table = [
- ]
-
- postfixes r = many postfix >>= return . foldl (flip ($)) r
- postfix = choice [
- parens pas (option [] parameters) >>= return . FunCall
- , char '^' >> return Dereference
- , (brackets pas) (commaSep1 pas $ expression) >>= return . ArrayElement
- , (char '.' >> notFollowedBy (char '.')) >> liftM (flip RecordField) reference
- ]
-
- typeCast = do
- t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
- e <- parens pas expression
- comments
- return $ TypeCast (Identifier t BTUnknown) e
-
-varsDecl1 = varsParser sepEndBy1
-varsDecl = varsParser sepEndBy
-varsParser m endsWithSemi = do
- vs <- m (aVarDecl endsWithSemi) (semi pas)
- return vs
-
-aVarDecl endsWithSemi = do
- isVar <- liftM (== Just "var") $
- if not endsWithSemi then
- optionMaybe $ choice [
- try $ string "var"
- , try $ string "const"
- , try $ string "out"
- ]
- else
- return Nothing
- comments
- ids <- do
- i <- (commaSep1 pas) $ (try iD <?> "variable declaration")
- char ':'
- return i
- comments
- t <- typeDecl <?> "variable type declaration"
- comments
- init <- option Nothing $ do
- char '='
- comments
- e <- initExpression
- comments
- return (Just e)
- return $ VarDeclaration isVar False (ids, t) init
-
-
-constsDecl = do
- vs <- many1 (try (aConstDecl >>= \i -> semi pas >> return i) >>= \i -> comments >> return i)
- comments
- return vs
- where
- aConstDecl = do
- comments
- i <- iD
- t <- optionMaybe $ do
- char ':'
- comments
- t <- typeDecl
- comments
- return t
- char '='
- comments
- e <- initExpression
- comments
- return $ VarDeclaration False (isNothing t) ([i], fromMaybe (DeriveType e) t) (Just e)
-
-typeDecl = choice [
- char '^' >> typeDecl >>= return . PointerTo
- , try (string "shortstring") >> return (String 255)
- , try (string "string") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
- , try (string "ansistring") >> optionMaybe (brackets pas $ integer pas) >>= return . String . fromMaybe 255
- , arrayDecl
- , recordDecl
- , setDecl
- , functionType
- , sequenceDecl >>= return . Sequence
- , try iD >>= return . SimpleType
- , rangeDecl >>= return . RangeType
- ] <?> "type declaration"
- where
- arrayDecl = do
- try $ do
- optional $ (try $ string "packed") >> comments
- string "array"
- comments
- r <- option [] $ do
- char '['
- r <- commaSep pas rangeDecl
- char ']'
- comments
- return r
- string "of"
- comments
- t <- typeDecl
- if null r then
- return $ ArrayDecl Nothing t
- else
- return $ foldr (\a b -> ArrayDecl (Just a) b) (ArrayDecl (Just $ head r) t) (tail r)
- recordDecl = do
- try $ do
- optional $ (try $ string "packed") >> comments
- string "record"
- comments
- vs <- varsDecl True
- union <- optionMaybe $ do
- string "case"
- comments
- iD
- comments
- string "of"
- comments
- many unionCase
- string "end"
- return $ RecordType vs union
- setDecl = do
- try $ string "set" >> space
- comments
- string "of"
- comments
- liftM Set typeDecl
- unionCase = do
- try $ commaSep pas $ (iD >> return ()) <|> (integer pas >> return ())
- char ':'
- comments
- u <- parens pas $ varsDecl True
- char ';'
- comments
- return u
- sequenceDecl = (parens pas) $ (commaSep pas) (iD >>= \i -> optional (spaces >> char '=' >> spaces >> integer pas) >> return i)
- functionType = do
- fp <- try (string "function") <|> try (string "procedure")
- comments
- vs <- option [] $ parens pas $ varsDecl False
- comments
- ret <- if (fp == "function") then do
- char ':'
- comments
- ret <- typeDecl
- comments
- return ret
- else
- return VoidType
- optional $ try $ char ';' >> comments >> string "cdecl"
- comments
- return $ FunctionType ret vs
-
-typesDecl = many (aTypeDecl >>= \t -> comments >> return t)
- where
- aTypeDecl = do
- i <- try $ do
- i <- iD <?> "type declaration"
- comments
- char '='
- return i
- comments
- t <- typeDecl
- comments
- semi pas
- comments
- return $ TypeDeclaration i t
-
-rangeDecl = choice [
- try $ rangeft
- , iD >>= return . Range
- ] <?> "range declaration"
- where
- rangeft = do
- e1 <- initExpression
- string ".."
- e2 <- initExpression
- return $ RangeFromTo e1 e2
-
-typeVarDeclaration isImpl = (liftM concat . many . choice) [
- varSection,
- constSection,
- typeSection,
- funcDecl,
- operatorDecl
- ]
- where
- varSection = do
- try $ string "var"
- comments
- v <- varsDecl1 True <?> "variable declaration"
- comments
- return v
-
- constSection = do
- try $ string "const"
- comments
- c <- constsDecl <?> "const declaration"
- comments
- return c
-
- typeSection = do
- try $ string "type"
- comments
- t <- typesDecl <?> "type declaration"
- comments
- return t
-
- operatorDecl = do
- try $ string "operator"
- comments
- i <- manyTill anyChar space
- comments
- vs <- parens pas $ varsDecl False
- comments
- rid <- iD
- comments
- char ':'
- comments
- ret <- typeDecl
- comments
- return ret
- char ';'
- comments
- forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
- inline <- liftM (any (== "inline;")) $ many functionDecorator
- b <- if isImpl && (not forward) then
- liftM Just functionBody
- else
- return Nothing
- return $ [OperatorDeclaration i rid inline ret vs b]
-
-
- funcDecl = do
- fp <- try (string "function") <|> try (string "procedure")
- comments
- i <- iD
- vs <- option [] $ parens pas $ varsDecl False
- comments
- ret <- if (fp == "function") then do
- char ':'
- comments
- ret <- typeDecl
- comments
- return ret
- else
- return VoidType
- char ';'
- comments
- forward <- liftM isJust $ optionMaybe (try (string "forward;") >> comments)
- inline <- liftM (any (== "inline;")) $ many functionDecorator
- b <- if isImpl && (not forward) then
- liftM Just functionBody
- else
- return Nothing
- return $ [FunctionDeclaration i inline ret vs b]
-
- functionDecorator = do
- d <- choice [
- try $ string "inline;"
- , try $ caseInsensitiveString "cdecl;"
- , try $ string "overload;"
- , try $ string "export;"
- , try $ string "varargs;"
- , try (string "external") >> comments >> iD >> optional (string "name" >> comments >> stringLiteral pas)>> string ";"
- ]
- comments
- return d
-
-
-program = do
- string "program"
- comments
- name <- iD
- (char ';')
- comments
- comments
- u <- uses
- comments
- tv <- typeVarDeclaration True
- comments
- p <- phrase
- comments
- char '.'
- comments
- return $ Program name (Implementation u (TypesAndVars tv)) p
-
-interface = do
- string "interface"
- comments
- u <- uses
- comments
- tv <- typeVarDeclaration False
- comments
- return $ Interface u (TypesAndVars tv)
-
-implementation = do
- string "implementation"
- comments
- u <- uses
- comments
- tv <- typeVarDeclaration True
- string "end."
- comments
- return $ Implementation u (TypesAndVars tv)
-
-expression = do
- buildExpressionParser table term <?> "expression"
- where
- term = comments >> choice [
- builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n BTUnknown))
- , try (parens pas $ expression >>= \e -> notFollowedBy (comments >> char '.') >> return e)
- , brackets pas (commaSep pas iD) >>= return . SetExpression
- , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i
- , float pas >>= return . FloatLiteral . show
- , try $ integer pas >>= return . NumberLiteral . show
- , try (string "_S" >> stringLiteral pas) >>= return . StringLiteral
- , try (string "_P" >> stringLiteral pas) >>= return . PCharLiteral
- , stringLiteral pas >>= return . strOrChar
- , try (string "#$") >> many hexDigit >>= \c -> comments >> return (HexCharCode c)
- , char '#' >> many digit >>= \c -> comments >> return (CharCode c)
- , char '$' >> many hexDigit >>= \h -> comments >> return (HexNumber h)
- --, char '-' >> expression >>= return . PrefixOp "-"
- , char '-' >> reference >>= return . PrefixOp "-" . Reference
- , (try $ string "not" >> notFollowedBy comments) >> unexpected "'not'"
- , try $ string "nil" >> return Null
- , reference >>= return . Reference
- ] <?> "simple expression"
-
- table = [
- [ Prefix (try (string "not") >> return (PrefixOp "not"))
- , Prefix (try (char '-') >> return (PrefixOp "-"))]
- ,
- [ Infix (char '*' >> return (BinOp "*")) AssocLeft
- , Infix (char '/' >> return (BinOp "/")) AssocLeft
- , Infix (try (string "div") >> return (BinOp "div")) AssocLeft
- , Infix (try (string "mod") >> return (BinOp "mod")) AssocLeft
- , Infix (try (string "in") >> return (BinOp "in")) AssocNone
- , Infix (try $ string "and" >> return (BinOp "and")) AssocLeft
- , Infix (try $ string "shl" >> return (BinOp "shl")) AssocLeft
- , Infix (try $ string "shr" >> return (BinOp "shr")) AssocLeft
- ]
- , [ Infix (char '+' >> return (BinOp "+")) AssocLeft
- , Infix (char '-' >> return (BinOp "-")) AssocLeft
- , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
- , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
- ]
- , [ Infix (try (string "<>") >> return (BinOp "<>")) AssocNone
- , Infix (try (string "<=") >> return (BinOp "<=")) AssocNone
- , Infix (try (string ">=") >> return (BinOp ">=")) AssocNone
- , Infix (char '<' >> return (BinOp "<")) AssocNone
- , Infix (char '>' >> return (BinOp ">")) AssocNone
- ]
- {-, [ Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone
- , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone
- ]
- , [
- Infix (try $ string "or" >> return (BinOp "or")) AssocLeft
- , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft
- ]-}
- , [
- Infix (char '=' >> return (BinOp "=")) AssocNone
- ]
- ]
- strOrChar [a] = CharCode . show . ord $ a
- strOrChar a = StringLiteral a
-
-phrasesBlock = do
- try $ string "begin"
- comments
- p <- manyTill phrase (try $ string "end" >> notFollowedBy alphaNum)
- comments
- return $ Phrases p
-
-phrase = do
- o <- choice [
- phrasesBlock
- , ifBlock
- , whileCycle
- , repeatCycle
- , switchCase
- , withBlock
- , forCycle
- , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> comments >> expression >>= return . Assignment r
- , builtInFunction expression >>= \(n, e) -> return $ BuiltInFunctionCall e (SimpleReference (Identifier n BTUnknown))
- , procCall
- , char ';' >> comments >> return NOP
- ]
- optional $ char ';'
- comments
- return o
-
-ifBlock = do
- try $ string "if" >> notFollowedBy (alphaNum <|> char '_')
- comments
- e <- expression
- comments
- string "then"
- comments
- o1 <- phrase
- comments
- o2 <- optionMaybe $ do
- try $ string "else" >> space
- comments
- o <- option NOP phrase
- comments
- return o
- return $ IfThenElse e o1 o2
-
-whileCycle = do
- try $ string "while"
- comments
- e <- expression
- comments
- string "do"
- comments
- o <- phrase
- return $ WhileCycle e o
-
-withBlock = do
- try $ string "with" >> space
- comments
- rs <- (commaSep1 pas) reference
- comments
- string "do"
- comments
- o <- phrase
- return $ foldr WithBlock o rs
-
-repeatCycle = do
- try $ string "repeat" >> space
- comments
- o <- many phrase
- string "until"
- comments
- e <- expression
- comments
- return $ RepeatCycle e o
-
-forCycle = do
- try $ string "for" >> space
- comments
- i <- iD
- comments
- string ":="
- comments
- e1 <- expression
- comments
- up <- liftM (== Just "to") $
- optionMaybe $ choice [
- try $ string "to"
- , try $ string "downto"
- ]
- --choice [string "to", string "downto"]
- comments
- e2 <- expression
- comments
- string "do"
- comments
- p <- phrase
- comments
- return $ ForCycle i e1 e2 p up
-
-switchCase = do
- try $ string "case"
- comments
- e <- expression
- comments
- string "of"
- comments
- cs <- many1 aCase
- o2 <- optionMaybe $ do
- try $ string "else" >> notFollowedBy alphaNum
- comments
- o <- many phrase
- comments
- return o
- string "end"
- comments
- return $ SwitchCase e cs o2
- where
- aCase = do
- e <- (commaSep pas) $ (liftM InitRange rangeDecl <|> initExpression)
- comments
- char ':'
- comments
- p <- phrase
- comments
- return (e, p)
-
-procCall = do
- r <- reference
- p <- option [] $ (parens pas) parameters
- return $ ProcCall r p
-
-parameters = (commaSep pas) expression <?> "parameters"
-
-functionBody = do
- tv <- typeVarDeclaration True
- comments
- p <- phrasesBlock
- char ';'
- comments
- return (TypesAndVars tv, p)
-
-uses = liftM Uses (option [] u)
- where
- u = do
- string "uses"
- comments
- u <- (iD >>= \i -> comments >> return i) `sepBy1` (char ',' >> comments)
- char ';'
- comments
- return u
-
-initExpression = buildExpressionParser table term <?> "initialization expression"
- where
- term = comments >> choice [
- liftM (uncurry BuiltInFunction) $ builtInFunction initExpression
- , try $ brackets pas (commaSep pas $ initExpression) >>= return . InitSet
- , try $ parens pas (commaSep pas $ initExpression) >>= \ia -> when (null $ tail ia) mzero >> return (InitArray ia)
- , try $ parens pas (sepEndBy recField (char ';' >> comments)) >>= return . InitRecord
- , parens pas initExpression
- , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . InitNumber . show) i
- , try $ float pas >>= return . InitFloat . show
- , try $ integer pas >>= return . InitNumber . show
- , stringLiteral pas >>= return . InitString
- , char '#' >> many digit >>= \c -> comments >> return (InitChar c)
- , char '$' >> many hexDigit >>= \h -> comments >> return (InitHexNumber h)
- , char '@' >> initExpression >>= \c -> comments >> return (InitAddress c)
- , try $ string "nil" >> return InitNull
- , itypeCast
- , iD >>= return . InitReference
- ]
-
- recField = do
- i <- iD
- spaces
- char ':'
- spaces
- e <- initExpression
- spaces
- return (i ,e)
-
- table = [
- [
- Prefix (char '-' >> return (InitPrefixOp "-"))
- ,Prefix (try (string "not") >> return (InitPrefixOp "not"))
- ]
- , [ Infix (char '*' >> return (InitBinOp "*")) AssocLeft
- , Infix (char '/' >> return (InitBinOp "/")) AssocLeft
- , Infix (try (string "div") >> return (InitBinOp "div")) AssocLeft
- , Infix (try (string "mod") >> return (InitBinOp "mod")) AssocLeft
- , Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
- , Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
- , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
- ]
- , [ Infix (char '+' >> return (InitBinOp "+")) AssocLeft
- , Infix (char '-' >> return (InitBinOp "-")) AssocLeft
- , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
- , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
- ]
- , [ Infix (try (string "<>") >> return (InitBinOp "<>")) AssocNone
- , Infix (try (string "<=") >> return (InitBinOp "<=")) AssocNone
- , Infix (try (string ">=") >> return (InitBinOp ">=")) AssocNone
- , Infix (char '<' >> return (InitBinOp "<")) AssocNone
- , Infix (char '>' >> return (InitBinOp ">")) AssocNone
- , Infix (char '=' >> return (InitBinOp "=")) AssocNone
- ]
- {--, [ Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft
- , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft
- , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft
- ]
- , [ Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone
- , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone
- ]--}
- --, [Prefix (try (string "not") >> return (InitPrefixOp "not"))]
- ]
-
- itypeCast = do
- t <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) knownTypes
- i <- parens pas initExpression
- comments
- return $ InitTypeCast (Identifier t BTUnknown) i
-
-builtInFunction e = do
- name <- choice $ map (\s -> try $ caseInsensitiveString s >>= \i -> notFollowedBy alphaNum >> return i) builtin
- spaces
- exprs <- option [] $ parens pas $ option [] $ commaSep1 pas $ e
- spaces
- return (name, exprs)
-
-systemUnit = do
- string "system;"
- comments
- string "type"
- comments
- t <- typesDecl
- string "var"
- v <- varsDecl True
- return $ System (t ++ v)
-
-redoUnit = do
- string "redo;"
- comments
- string "type"
- comments
- t <- typesDecl
- string "var"
- v <- varsDecl True
- return $ Redo (t ++ v)
-
diff --git a/tools/PascalPreprocessor.hs b/tools/PascalPreprocessor.hs
deleted file mode 100644
index 8c98980..0000000
--- a/tools/PascalPreprocessor.hs
+++ /dev/null
@@ -1,135 +0,0 @@
-module PascalPreprocessor where
-
-import Text.Parsec
-import Control.Monad.IO.Class
-import Control.Monad
-import System.IO
-import qualified Data.Map as Map
-import Data.Char
-
-
--- comments are removed
-comment = choice [
- char '{' >> notFollowedBy (char '$') >> manyTill anyChar (try $ char '}') >> return ""
- , (try $ string "(*") >> manyTill anyChar (try $ string "*)") >> return ""
- , (try $ string "//") >> manyTill anyChar (try newline) >> return "\n"
- ]
-
-initDefines = Map.fromList [
- ("FPC", "")
- , ("PAS2C", "")
- , ("ENDIAN_LITTLE", "")
- , ("S3D_DISABLED", "")
- ]
-
-preprocess :: String -> IO String
-preprocess fn = do
- r <- runParserT (preprocessFile fn) (initDefines, [True]) "" ""
- case r of
- (Left a) -> do
- hPutStrLn stderr (show a)
- return ""
- (Right a) -> return a
-
- where
- preprocessFile fn = do
- f <- liftIO (readFile fn)
- setInput f
- preprocessor
-
- preprocessor, codeBlock, switch :: ParsecT String (Map.Map String String, [Bool]) IO String
-
- preprocessor = chainr codeBlock (return (++)) ""
-
- codeBlock = do
- s <- choice [
- switch
- , comment
- , char '\'' >> many (noneOf "'\n") >>= \s -> char '\'' >> return ('\'' : s ++ "'")
- , identifier >>= replace
- , noneOf "{" >>= \a -> return [a]
- ]
- (_, ok) <- getState
- return $ if and ok then s else ""
-
- --otherChar c = c `notElem` "{/('_" && not (isAlphaNum c)
- identifier = do
- c <- letter <|> oneOf "_"
- s <- many (alphaNum <|> oneOf "_")
- return $ c:s
-
- switch = do
- try $ string "{$"
- s <- choice [
- include
- , ifdef
- , if'
- , elseSwitch
- , endIf
- , define
- , unknown
- ]
- return s
-
- include = do
- try $ string "INCLUDE"
- spaces
- (char '"')
- fn <- many1 $ noneOf "\"\n"
- char '"'
- spaces
- char '}'
- f <- liftIO (readFile fn `catch` error ("File not found: " ++ fn))
- c <- getInput
- setInput $ f ++ c
- return ""
-
- ifdef = do
- s <- try (string "IFDEF") <|> try (string "IFNDEF")
- let f = if s == "IFNDEF" then not else id
-
- spaces
- d <- identifier
- spaces
- char '}'
-
- updateState $ \(m, b) ->
- (m, (f $ d `Map.member` m) : b)
-
- return ""
-
- if' = do
- s <- try (string "IF" >> notFollowedBy alphaNum)
-
- manyTill anyChar (char '}')
- --char '}'
-
- updateState $ \(m, b) ->
- (m, False : b)
-
- return ""
-
- elseSwitch = do
- try $ string "ELSE}"
- updateState $ \(m, b:bs) -> (m, (not b):bs)
- return ""
- endIf = do
- try $ string "ENDIF}"
- updateState $ \(m, b:bs) -> (m, bs)
- return ""
- define = do
- try $ string "DEFINE"
- spaces
- i <- identifier
- d <- ((string ":=" >> return ()) <|> spaces) >> many (noneOf "}")
- char '}'
- updateState $ \(m, b) -> (if (and b) && (head i /= '_') then Map.insert i d m else m, b)
- return ""
- replace s = do
- (m, _) <- getState
- return $ Map.findWithDefault s s m
-
- unknown = do
- fn <- many1 $ noneOf "}\n"
- char '}'
- return $ "{$" ++ fn ++ "}"
diff --git a/tools/PascalUnitSyntaxTree.hs b/tools/PascalUnitSyntaxTree.hs
deleted file mode 100644
index 8123e6a..0000000
--- a/tools/PascalUnitSyntaxTree.hs
+++ /dev/null
@@ -1,119 +0,0 @@
-module PascalUnitSyntaxTree where
-
-import Data.Maybe
-import Data.Char
-
-data PascalUnit =
- Program Identifier Implementation Phrase
- | Unit Identifier Interface Implementation (Maybe Initialize) (Maybe Finalize)
- | System [TypeVarDeclaration]
- | Redo [TypeVarDeclaration]
- deriving Show
-data Interface = Interface Uses TypesAndVars
- deriving Show
-data Implementation = Implementation Uses TypesAndVars
- deriving Show
-data Identifier = Identifier String BaseType
- deriving Show
-data TypesAndVars = TypesAndVars [TypeVarDeclaration]
- deriving Show
-data TypeVarDeclaration = TypeDeclaration Identifier TypeDecl
- | VarDeclaration Bool Bool ([Identifier], TypeDecl) (Maybe InitExpression)
- | FunctionDeclaration Identifier Bool TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
- | OperatorDeclaration String Identifier Bool TypeDecl [TypeVarDeclaration] (Maybe (TypesAndVars, Phrase))
- deriving Show
-data TypeDecl = SimpleType Identifier
- | RangeType Range
- | Sequence [Identifier]
- | ArrayDecl (Maybe Range) TypeDecl
- | RecordType [TypeVarDeclaration] (Maybe [[TypeVarDeclaration]])
- | PointerTo TypeDecl
- | String Integer
- | Set TypeDecl
- | FunctionType TypeDecl [TypeVarDeclaration]
- | DeriveType InitExpression
- | VoidType
- | VarParamType TypeDecl -- this is a hack
- deriving Show
-data Range = Range Identifier
- | RangeFromTo InitExpression InitExpression
- | RangeInfinite
- deriving Show
-data Initialize = Initialize String
- deriving Show
-data Finalize = Finalize String
- deriving Show
-data Uses = Uses [Identifier]
- deriving Show
-data Phrase = ProcCall Reference [Expression]
- | IfThenElse Expression Phrase (Maybe Phrase)
- | WhileCycle Expression Phrase
- | RepeatCycle Expression [Phrase]
- | ForCycle Identifier Expression Expression Phrase Bool -- The last Boolean indicates wether it's up or down counting
- | WithBlock Reference Phrase
- | Phrases [Phrase]
- | SwitchCase Expression [([InitExpression], Phrase)] (Maybe [Phrase])
- | Assignment Reference Expression
- | BuiltInFunctionCall [Expression] Reference
- | NOP
- deriving Show
-data Expression = Expression String
- | BuiltInFunCall [Expression] Reference
- | PrefixOp String Expression
- | PostfixOp String Expression
- | BinOp String Expression Expression
- | StringLiteral String
- | PCharLiteral String
- | CharCode String
- | HexCharCode String
- | NumberLiteral String
- | FloatLiteral String
- | HexNumber String
- | Reference Reference
- | SetExpression [Identifier]
- | Null
- deriving Show
-data Reference = ArrayElement [Expression] Reference
- | FunCall [Expression] Reference
- | TypeCast Identifier Expression
- | SimpleReference Identifier
- | Dereference Reference
- | RecordField Reference Reference
- | Address Reference
- | RefExpression Expression
- deriving Show
-data InitExpression = InitBinOp String InitExpression InitExpression
- | InitPrefixOp String InitExpression
- | InitReference Identifier
- | InitArray [InitExpression]
- | InitRecord [(Identifier, InitExpression)]
- | InitFloat String
- | InitNumber String
- | InitHexNumber String
- | InitString String
- | InitChar String
- | BuiltInFunction String [InitExpression]
- | InitSet [InitExpression]
- | InitAddress InitExpression
- | InitNull
- | InitRange Range
- | InitTypeCast Identifier InitExpression
- deriving Show
-
-data BaseType = BTUnknown
- | BTChar
- | BTString
- | BTInt
- | BTBool
- | BTFloat
- | BTRecord String [(String, BaseType)]
- | BTArray Range BaseType BaseType
- | BTFunction Bool Int BaseType
- | BTPointerTo BaseType
- | BTUnresolved String
- | BTSet BaseType
- | BTEnum [String]
- | BTVoid
- | BTUnit
- | BTVarParam BaseType
- deriving Show
diff --git a/tools/build_windows.bat b/tools/build_windows.bat
index 59f6d26..18af9ac 100644
--- a/tools/build_windows.bat
+++ b/tools/build_windows.bat
@@ -1,6 +1,6 @@
@echo off
::edit these variables if you need
-set PASCAL=C:\FPC\2.4.4\bin\i386-win32\
+set PASCAL=C:\FPC\2.6.0\bin\i386-win32\
set QTDIR=C:\QtSDK\Desktop\Qt\4.7.4\mingw\bin
set PATH=%PATH%;%PASCAL%
set BUILD_TYPE="Debug"
@@ -13,7 +13,8 @@ echo Fetching all DLLs...
if %BUILD_TYPE%=="Debug" (
for %%G in (QtCored4 QtGuid4 QtNetworkd4) do xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\
)
-for %%G in (QtCore4 QtGui4 QtNetwork4 libgcc_s_dw2-1 mingwm10) do (
+:: should you libgcc dynamically you should try adding libgcc_s_dw2-1 and mingwm10
+for %%G in (QtCore4 QtGui4 QtNetwork4) do (
xcopy /d/y %QTDIR%\%%G.dll %CD%\bin\
)
@@ -39,13 +40,13 @@ call %QTDIR%\qtenv2.bat
echo Running cmake...
set ERRORLEVEL=
-cmake -G "MinGW Makefiles" -DCMAKE_INCLUDE_PATH="%CD%\misc\winutils\include" -DCMAKE_LIBRARY_PATH="%CD%\misc\winutils\lib" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" . -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
+cmake . -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="%CD%\misc\winutils\" -DPNG_LIBRARY="%CD%\misc\winutils\bin\libpng13.dll" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%"
if %ERRORLEVEL% NEQ 0 goto exitpoint
echo Running make...
set ERRORLEVEL=
-mingw32-make
+mingw32-make VERBOSE=1
if %ERRORLEVEL% NEQ 0 goto exitpoint
echo Installing...
diff --git a/tools/cmake_uninstall.cmake b/tools/cmake_uninstall.cmake
index 824df61..4364c22 100644
--- a/tools/cmake_uninstall.cmake
+++ b/tools/cmake_uninstall.cmake
@@ -1,14 +1,14 @@
-IF(NOT EXISTS "/home/nemo/hg/hedgewars/0.9.18/tools/../install_manifest.txt")
- MESSAGE(FATAL_ERROR "Cannot find install manifest: \"/home/nemo/hg/hedgewars/0.9.18/tools/../install_manifest.txt\"")
-ENDIF(NOT EXISTS "/home/nemo/hg/hedgewars/0.9.18/tools/../install_manifest.txt")
+IF(NOT EXISTS "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt")
+ MESSAGE(FATAL_ERROR "Cannot find install manifest: \"/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt\"")
+ENDIF(NOT EXISTS "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt")
-FILE(READ "/home/nemo/hg/hedgewars/0.9.18/tools/../install_manifest.txt" files)
+FILE(READ "/usr/home/unC0Rr/Sources/Hedgewars/Hedgewars-Clone/tools/../install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
- "/usr/bin/cmake" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
+ "/usr/local/bin/cmake" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
diff --git a/tools/pas2c.hs b/tools/pas2c.hs
deleted file mode 100644
index 981ab9d..0000000
--- a/tools/pas2c.hs
+++ /dev/null
@@ -1,1086 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-module Pas2C where
-
-import Text.PrettyPrint.HughesPJ
-import Data.Maybe
-import Data.Char
-import Text.Parsec.Prim hiding (State)
-import Control.Monad.State
-import System.IO
-import System.Directory
-import Control.Monad.IO.Class
-import PascalPreprocessor
-import Control.Exception
-import System.IO.Error
-import qualified Data.Map as Map
-import qualified Data.Set as Set
-import Data.List (find)
-import Numeric
-
-import PascalParser(pascalUnit)
-import PascalUnitSyntaxTree
-
-
-data InsertOption =
- IOInsert
- | IOInsertWithType Doc
- | IOLookup
- | IOLookupLast
- | IOLookupFunction Int
- | IODeferred
-
-data Record = Record
- {
- lcaseId :: String,
- baseType :: BaseType,
- typeDecl :: Doc
- }
- deriving Show
-type Records = Map.Map String [Record]
-data RenderState = RenderState
- {
- currentScope :: Records,
- lastIdentifier :: String,
- lastType :: BaseType,
- lastIdTypeDecl :: Doc,
- stringConsts :: [(String, String)],
- uniqCounter :: Int,
- toMangle :: Set.Set String,
- currentUnit :: String,
- currentFunctionResult :: String,
- namespaces :: Map.Map String Records
- }
-
-rec2Records = map (\(a, b) -> Record a b empty)
-
-emptyState = RenderState Map.empty "" BTUnknown empty [] 0 Set.empty "" ""
-
-getUniq :: State RenderState Int
-getUniq = do
- i <- gets uniqCounter
- modify(\s -> s{uniqCounter = uniqCounter s + 1})
- return i
-
-addStringConst :: String -> State RenderState Doc
-addStringConst str = do
- strs <- gets stringConsts
- let a = find ((==) str . snd) strs
- if isJust a then
- do
- modify (\s -> s{lastType = BTString})
- return . text . fst . fromJust $ a
- else
- do
- i <- getUniq
- let sn = "__str" ++ show i
- modify (\s -> s{lastType = BTString, stringConsts = (sn, str) : strs})
- return $ text sn
-
-escapeStr :: String -> String
-escapeStr = foldr escapeChar []
-
-escapeChar :: Char -> ShowS
-escapeChar '"' s = "\\\"" ++ s
-escapeChar '\\' s = "\\\\" ++ s
-escapeChar a s = a : s
-
-strInit :: String -> Doc
-strInit a = text "STRINIT" <> parens (doubleQuotes (text $ escapeStr a))
-
-renderStringConsts :: State RenderState Doc
-renderStringConsts = liftM (vcat . map (\(a, b) -> text "static const string255" <+> (text a) <+> text "=" <+> strInit b <> semi))
- $ gets stringConsts
-
-docToLower :: Doc -> Doc
-docToLower = text . map toLower . render
-
-pas2C :: String -> IO ()
-pas2C fn = do
- setCurrentDirectory "../hedgewars/"
- s <- flip execStateT initState $ f fn
- renderCFiles s
- where
- printLn = liftIO . hPutStrLn stdout
- print = liftIO . hPutStr stdout
- initState = Map.empty
- f :: String -> StateT (Map.Map String PascalUnit) IO ()
- f fileName = do
- processed <- gets $ Map.member fileName
- unless processed $ do
- print ("Preprocessing '" ++ fileName ++ ".pas'... ")
- fc' <- liftIO
- $ tryJust (guard . isDoesNotExistError)
- $ preprocess (fileName ++ ".pas")
- case fc' of
- (Left a) -> do
- modify (Map.insert fileName (System []))
- printLn "doesn't exist"
- (Right fc) -> do
- print "ok, parsing... "
- let ptree = parse pascalUnit fileName fc
- case ptree of
- (Left a) -> do
- liftIO $ writeFile "preprocess.out" fc
- printLn $ show a ++ "\nsee preprocess.out for preprocessed source"
- fail "stop"
- (Right a) -> do
- printLn "ok"
- modify (Map.insert fileName a)
- mapM_ f (usesFiles a)
-
-
-renderCFiles :: Map.Map String PascalUnit -> IO ()
-renderCFiles units = do
- let u = Map.toList units
- let nss = Map.map (toNamespace nss) units
- --hPutStrLn stderr $ "Units: " ++ (show . Map.keys . Map.filter (not . Map.null) $ nss)
- --writeFile "pas2c.log" $ unlines . map (\t -> show (fst t) ++ "\n" ++ (unlines . map ((:) '\t' . show) . snd $ t)) . Map.toList $ nss
- mapM_ (toCFiles nss) u
- where
- toNamespace :: Map.Map String Records -> PascalUnit -> Records
- toNamespace nss (System tvs) =
- currentScope $ execState f (emptyState nss)
- where
- f = do
- checkDuplicateFunDecls tvs
- mapM_ (tvar2C True False True False) tvs
- toNamespace nss (Redo tvs) = -- functions that are re-implemented, add prefix to all of them
- currentScope $ execState f (emptyState nss){currentUnit = "fpcrtl_"}
- where
- f = do
- checkDuplicateFunDecls tvs
- mapM_ (tvar2C True False True False) tvs
- toNamespace _ (Program {}) = Map.empty
- toNamespace nss (Unit (Identifier i _) interface _ _ _) =
- currentScope $ execState (interface2C interface True) (emptyState nss){currentUnit = map toLower i ++ "_"}
-
-
-withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a
-withState' f sf = do
- st <- liftM f get
- let (a, s) = runState sf st
- modify(\st -> st{
- lastType = lastType s
- , uniqCounter = uniqCounter s
- , stringConsts = stringConsts s
- })
- return a
-
-withLastIdNamespace f = do
- li <- gets lastIdentifier
- nss <- gets namespaces
- withState' (\st -> st{currentScope = fromMaybe Map.empty $ Map.lookup li (namespaces st)}) f
-
-withRecordNamespace :: String -> [Record] -> State RenderState Doc -> State RenderState Doc
-withRecordNamespace _ [] = error "withRecordNamespace: empty record"
-withRecordNamespace prefix recs = withState' f
- where
- f st = st{currentScope = Map.unionWith un records (currentScope st), currentUnit = ""}
- records = Map.fromList $ map (\(Record a b d) -> (map toLower a, [Record (prefix ++ a) b d])) recs
- un [a] b = a : b
-
-toCFiles :: Map.Map String Records -> (String, PascalUnit) -> IO ()
-toCFiles _ (_, System _) = return ()
-toCFiles _ (_, Redo _) = return ()
-toCFiles ns p@(fn, pu) = do
- hPutStrLn stdout $ "Rendering '" ++ fn ++ "'..."
- toCFiles' p
- where
- toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ "#include \"fpcrtl.h\"\n" ++ (render2C initialState . pascal2C) p
- toCFiles' (fn, (Unit unitId@(Identifier i _) interface implementation _ _)) = do
- let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface True) initialState{currentUnit = map toLower i ++ "_"}
- (a', s') = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface False) initialState{currentUnit = map toLower i ++ "_"}
- writeFile (fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text ""))
- writeFile (fn ++ ".c") $ "#include \"fpcrtl.h\"\n\n#include \"" ++ fn ++ ".h\"\n" ++ render (a' $+$ text "") ++ (render2C s . implementation2C) implementation
- initialState = emptyState ns
-
- render2C :: RenderState -> State RenderState Doc -> String
- render2C a = render . ($+$ empty) . flip evalState a
-
-
-usesFiles :: PascalUnit -> [String]
-usesFiles (Program _ (Implementation uses _) _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses
-usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses1 ++ uses2List uses2
-usesFiles (System {}) = []
-usesFiles (Redo {}) = []
-
-pascal2C :: PascalUnit -> State RenderState Doc
-pascal2C (Unit _ interface implementation init fin) =
- liftM2 ($+$) (interface2C interface True) (implementation2C implementation)
-
-pascal2C (Program _ implementation mainFunction) = do
- impl <- implementation2C implementation
- [main] <- tvar2C True False True True (FunctionDeclaration (Identifier "main" BTInt) False (SimpleType $ Identifier "int" BTInt) [VarDeclaration False False ([Identifier "argc" BTInt], SimpleType (Identifier "Integer" BTInt)) Nothing, VarDeclaration False False ([Identifier "argv" BTUnknown], SimpleType (Identifier "PPChar" BTUnknown)) Nothing] (Just (TypesAndVars [], mainFunction)))
- return $ impl $+$ main
-
-
--- the second bool indicates whether do normal interface translation or generate variable declarations
--- that will be inserted into implementation files
-interface2C :: Interface -> Bool -> State RenderState Doc
-interface2C (Interface uses tvars) True = do
- u <- uses2C uses
- tv <- typesAndVars2C True True True tvars
- r <- renderStringConsts
- return (u $+$ r $+$ tv)
-interface2C (Interface uses tvars) False = do
- u <- uses2C uses
- tv <- typesAndVars2C True False False tvars
- r <- renderStringConsts
- return tv
-
-implementation2C :: Implementation -> State RenderState Doc
-implementation2C (Implementation uses tvars) = do
- u <- uses2C uses
- tv <- typesAndVars2C True False True tvars
- r <- renderStringConsts
- return (u $+$ r $+$ tv)
-
-checkDuplicateFunDecls :: [TypeVarDeclaration] -> State RenderState ()
-checkDuplicateFunDecls tvs =
- modify $ \s -> s{toMangle = Map.keysSet . Map.filter (> 1) . foldr ins initMap $ tvs}
- where
- initMap = Map.empty
- --initMap = Map.fromList [("reset", 2)]
- ins (FunctionDeclaration (Identifier i _) _ _ _ _) m = Map.insertWith (+) (map toLower i) 1 m
- ins _ m = m
-
--- the second bool indicates whether declare variable as extern or not
--- the third bool indicates whether include types or not
-
-typesAndVars2C :: Bool -> Bool -> Bool -> TypesAndVars -> State RenderState Doc
-typesAndVars2C b externVar includeType(TypesAndVars ts) = do
- checkDuplicateFunDecls ts
- liftM (vcat . map (<> semi) . concat) $ mapM (tvar2C b externVar includeType False) ts
-
-setBaseType :: BaseType -> Identifier -> Identifier
-setBaseType bt (Identifier i _) = Identifier i bt
-
-uses2C :: Uses -> State RenderState Doc
-uses2C uses@(Uses unitIds) = do
-
- mapM_ injectNamespace (Identifier "pas2cSystem" undefined : unitIds)
- mapM_ injectNamespace (Identifier "pas2cRedo" undefined : unitIds)
- mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds
- return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses
- where
- injectNamespace (Identifier i _) = do
- getNS <- gets (flip Map.lookup . namespaces)
- modify (\s -> s{currentScope = Map.unionWith (++) (fromMaybe Map.empty (getNS i)) $ currentScope s})
-
-uses2List :: Uses -> [String]
-uses2List (Uses ids) = map (\(Identifier i _) -> i) ids
-
-
-setLastIdValues vv = (\s -> s{lastType = baseType vv, lastIdentifier = lcaseId vv, lastIdTypeDecl = typeDecl vv})
-
-id2C :: InsertOption -> Identifier -> State RenderState Doc
-id2C IOInsert i = id2C (IOInsertWithType empty) i
-id2C (IOInsertWithType d) (Identifier i t) = do
- ns <- gets currentScope
- tom <- gets (Set.member n . toMangle)
- cu <- gets currentUnit
- let (i', t') = case (t, tom) of
- (BTFunction _ p _, True) -> (cu ++ i ++ ('_' : show p), t)
- (BTFunction _ _ _, _) -> (cu ++ i, t)
- (BTVarParam t', _) -> ('(' : '*' : i ++ ")" , t')
- _ -> (i, t)
- modify (\s -> s{currentScope = Map.insertWith (++) n [Record i' t' d] (currentScope s), lastIdentifier = n})
- return $ text i'
- where
- n = map toLower i
-
-id2C IOLookup i = id2CLookup head i
-id2C IOLookupLast i = id2CLookup last i
-id2C (IOLookupFunction params) (Identifier i t) = do
- let i' = map toLower i
- v <- gets $ Map.lookup i' . currentScope
- lt <- gets lastType
- if isNothing v then
- error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt ++ "\nwith num of params = " ++ show params ++ "\n" ++ show v
- else
- let vv = fromMaybe (head $ fromJust v) . find checkParam $ fromJust v in
- modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
- where
- checkParam (Record _ (BTFunction _ p _) _) = p == params
- checkParam _ = False
-id2C IODeferred (Identifier i t) = do
- let i' = map toLower i
- v <- gets $ Map.lookup i' . currentScope
- if (isNothing v) then
- modify (\s -> s{lastType = BTUnknown, lastIdentifier = i}) >> return (text i)
- else
- let vv = head $ fromJust v in modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
-
-id2CLookup :: ([Record] -> Record) -> Identifier -> State RenderState Doc
-id2CLookup f (Identifier i t) = do
- let i' = map toLower i
- v <- gets $ Map.lookup i' . currentScope
- lt <- gets lastType
- if isNothing v then
- error $ "Not defined: '" ++ i' ++ "'\n" ++ show lt
- else
- let vv = f $ fromJust v in modify (setLastIdValues vv) >> (return . text . lcaseId $ vv)
-
-
-id2CTyped :: TypeDecl -> Identifier -> State RenderState Doc
-id2CTyped = id2CTyped2 Nothing
-
-id2CTyped2 :: Maybe Doc -> TypeDecl -> Identifier -> State RenderState Doc
-id2CTyped2 md t (Identifier i _) = do
- tb <- resolveType t
- case (t, tb) of
- (_, BTUnknown) -> do
- error $ "id2CTyped: type BTUnknown for " ++ show i ++ "\ntype: " ++ show t
- (SimpleType {}, BTRecord _ r) -> do
- ts <- type2C t
- id2C (IOInsertWithType $ ts empty) (Identifier i (BTRecord (render $ ts empty) r))
- (_, BTRecord _ r) -> do
- ts <- type2C t
- id2C (IOInsertWithType $ ts empty) (Identifier i (BTRecord i r))
- _ -> case md of
- Nothing -> id2C IOInsert (Identifier i tb)
- Just ts -> id2C (IOInsertWithType ts) (Identifier i tb)
-
-
-resolveType :: TypeDecl -> State RenderState BaseType
-resolveType st@(SimpleType (Identifier i _)) = do
- let i' = map toLower i
- v <- gets $ Map.lookup i' . currentScope
- if isJust v then return . baseType . head $ fromJust v else return $ f i'
- where
- f "integer" = BTInt
- f "pointer" = BTPointerTo BTVoid
- f "boolean" = BTBool
- f "float" = BTFloat
- f "char" = BTChar
- f "string" = BTString
- f _ = error $ "Unknown system type: " ++ show st
-resolveType (PointerTo (SimpleType (Identifier i _))) = return . BTPointerTo $ BTUnresolved (map toLower i)
-resolveType (PointerTo t) = liftM BTPointerTo $ resolveType t
-resolveType (RecordType tv mtvs) = do
- tvs <- mapM f (concat $ tv : fromMaybe [] mtvs)
- return . BTRecord "" . concat $ tvs
- where
- f :: TypeVarDeclaration -> State RenderState [(String, BaseType)]
- f (VarDeclaration _ _ (ids, td) _) = mapM (\(Identifier i _) -> liftM ((,) i) $ resolveType td) ids
-resolveType (ArrayDecl (Just i) t) = do
- t' <- resolveType t
- return $ BTArray i BTInt t'
-resolveType (ArrayDecl Nothing t) = liftM (BTArray RangeInfinite BTInt) $ resolveType t
-resolveType (FunctionType t a) = liftM (BTFunction False (length a)) $ resolveType t
-resolveType (DeriveType (InitHexNumber _)) = return BTInt
-resolveType (DeriveType (InitNumber _)) = return BTInt
-resolveType (DeriveType (InitFloat _)) = return BTFloat
-resolveType (DeriveType (InitString _)) = return BTString
-resolveType (DeriveType (InitBinOp {})) = return BTInt
-resolveType (DeriveType (InitPrefixOp _ e)) = initExpr2C e >> gets lastType
-resolveType (DeriveType (BuiltInFunction{})) = return BTInt
-resolveType (DeriveType (InitReference (Identifier{}))) = return BTBool -- TODO: derive from actual type
-resolveType (DeriveType _) = return BTUnknown
-resolveType (String _) = return BTString
-resolveType VoidType = return BTVoid
-resolveType (Sequence ids) = return $ BTEnum $ map (\(Identifier i _) -> map toLower i) ids
-resolveType (RangeType _) = return $ BTVoid
-resolveType (Set t) = liftM BTSet $ resolveType t
-resolveType (VarParamType t) = liftM BTVarParam $ resolveType t
-
-
-resolve :: String -> BaseType -> State RenderState BaseType
-resolve s (BTUnresolved t) = do
- v <- gets $ Map.lookup t . currentScope
- if isJust v then
- resolve s . baseType . head . fromJust $ v
- else
- error $ "Unknown type " ++ show t ++ "\n" ++ s
-resolve _ t = return t
-
-fromPointer :: String -> BaseType -> State RenderState BaseType
-fromPointer s (BTPointerTo t) = resolve s t
-fromPointer s t = do
- error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s
-
-
-functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False False True True) params
-
-numberOfDeclarations :: [TypeVarDeclaration] -> Int
-numberOfDeclarations = sum . map cnt
- where
- cnt (VarDeclaration _ _ (ids, _) _) = length ids
- cnt _ = 1
-
-hasPassByReference :: [TypeVarDeclaration] -> Bool
-hasPassByReference = or . map isVar
- where
- isVar (VarDeclaration v _ (_, _) _) = v
- isVar _ = error $ "hasPassByReference called not on function parameters"
-
-toIsVarList :: [TypeVarDeclaration] -> [Bool]
-toIsVarList = concatMap isVar
- where
- isVar (VarDeclaration v _ (p, _) _) = replicate (length p) v
- isVar _ = error $ "toIsVarList called not on function parameters"
-
-
-funWithVarsToDefine :: String -> [TypeVarDeclaration] -> Doc
-funWithVarsToDefine n params = text "#define" <+> text n <> parens abc <+> text (n ++ "__vars") <> parens cparams
- where
- abc = hcat . punctuate comma . map (char . fst) $ ps
- cparams = hcat . punctuate comma . map (\(c, v) -> if v then char '&' <> parens (char c) else char c) $ ps
- ps = zip ['a'..] (toIsVarList params)
-
-fun2C :: Bool -> String -> TypeVarDeclaration -> State RenderState [Doc]
-fun2C _ _ (FunctionDeclaration name inline returnType params Nothing) = do
- t <- type2C returnType
- t'<- gets lastType
- p <- withState' id $ functionParams2C params
- n <- liftM render . id2C IOInsert $ setBaseType (BTFunction hasVars (numberOfDeclarations params) t') name
- let decor = if inline then text "inline" else empty
- if hasVars then
- return [funWithVarsToDefine n params $+$ decor <+> t empty <+> text (n ++ "__vars") <> parens p]
- else
- return [decor <+> t empty <+> text n <> parens p]
- where
- hasVars = hasPassByReference params
-
-
-fun2C True rv (FunctionDeclaration name@(Identifier i _) inline returnType params (Just (tvars, phrase))) = do
- let res = docToLower $ text rv <> text "_result"
- t <- type2C returnType
- t'<- gets lastType
-
- notDeclared <- liftM isNothing . gets $ Map.lookup (map toLower i) . currentScope
-
- n <- liftM render . id2C IOInsert $ setBaseType (BTFunction hasVars (numberOfDeclarations params) t') name
-
- let isVoid = case returnType of
- VoidType -> True
- _ -> False
-
- (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [Record (render res) t' empty] $ currentScope st
- , currentFunctionResult = if isVoid then [] else render res}) $ do
- p <- functionParams2C params
- ph <- liftM2 ($+$) (typesAndVars2C False False True tvars) (phrase2C' phrase)
- return (p, ph)
-
- let phrasesBlock = if isVoid then ph else t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi
- let define = if hasVars then text "#ifndef" <+> text n $+$ funWithVarsToDefine n params $+$ text "#endif" else empty
- let decor = if inline then text "inline" else empty
- return [
- define
- $+$
- --(if notDeclared && hasVars then funWithVarsToDefine n params else empty) $+$
- decor <+> t empty <+> text (if hasVars then n ++ "__vars" else n) <> parens p
- $+$
- text "{"
- $+$
- nest 4 phrasesBlock
- $+$
- text "}"]
- where
- phrase2C' (Phrases p) = liftM vcat $ mapM phrase2C p
- phrase2C' p = phrase2C p
- un [a] b = a : b
- hasVars = hasPassByReference params
-
-fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _ _) = error $ "nested functions not allowed: " ++ name
-fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv
-
--- the second bool indicates whether declare variable as extern or not
--- the third bool indicates whether include types or not
--- the fourth bool indicates whether ignore initialization or not (basically for dynamic arrays since we cannot do initialization in function params)
-tvar2C :: Bool -> Bool -> Bool -> Bool -> TypeVarDeclaration -> State RenderState [Doc]
-tvar2C b _ includeType _ f@(FunctionDeclaration (Identifier name _) _ _ _ _) = do
- t <- fun2C b name f
- if includeType then return t else return []
-tvar2C _ _ includeType _ td@(TypeDeclaration i' t) = do
- i <- id2CTyped t i'
- tp <- type2C t
- return $ if includeType then [text "typedef" <+> tp i] else []
-
-tvar2C _ _ _ _ (VarDeclaration True _ (ids, t) Nothing) = do
- t' <- liftM ((empty <+>) . ) $ type2C t
- liftM (map(\i -> t' i)) $ mapM (id2CTyped2 (Just $ t' empty) (VarParamType t)) ids
-
-tvar2C _ externVar includeType ignoreInit (VarDeclaration _ isConst (ids, t) mInitExpr) = do
- t' <- liftM (((if isConst then text "static const" else if externVar
- then text "extern"
- else empty)
- <+>) . ) $ type2C t
- ie <- initExpr mInitExpr
- lt <- gets lastType
- case (isConst, lt, ids, mInitExpr) of
- (True, BTInt, [i], Just _) -> do
- i' <- id2CTyped t i
- return $ if includeType then [text "enum" <> braces (i' <+> ie)] else []
- (True, BTFloat, [i], Just e) -> do
- i' <- id2CTyped t i
- ie <- initExpr2C e
- return $ if includeType then [text "#define" <+> i' <+> parens ie <> text "\n"] else []
- (_, BTFunction{}, _, Nothing) -> liftM (map(\i -> t' i)) $ mapM (id2CTyped t) ids
- (_, BTArray r _ _, [i], _) -> do
- i' <- id2CTyped t i
- ie' <- return $ case (r, mInitExpr, ignoreInit) of
- (RangeInfinite, Nothing, False) -> text "= NULL" -- force dynamic array to be initialized as NULL if not initialized at all
- (_, _, _) -> ie
- result <- liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie')) $ mapM (id2CTyped t) ids
- case (r, ignoreInit) of
- (RangeInfinite, False) ->
- -- if the array is dynamic, add dimension info to it
- return $ [dimDecl] ++ result
- where
- arrayDimStr = show $ arrayDimension t
- arrayDimInitExp = text ("={" ++ ".dim = " ++ arrayDimStr ++ ", .a = {0, 0, 0, 0}}")
- dimDecl = varDeclDecision isConst includeType (text "fpcrtl_dimension_t" <+> i' <> text "_dimension_info") arrayDimInitExp
-
- (_, _) -> return result
-
- _ -> liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie)) $ mapM (id2CTyped2 (Just $ t' empty) t) ids
- where
- initExpr Nothing = return $ empty
- initExpr (Just e) = liftM (text "=" <+>) (initExpr2C e)
- varDeclDecision True True varStr expStr = varStr <+> expStr
- varDeclDecision False True varStr expStr = if externVar then varStr else varStr <+> expStr
- varDeclDecision False False varStr expStr = varStr <+> expStr
- varDeclDecision True False varStr expStr = empty
- arrayDimension a = case a of
- ArrayDecl Nothing t -> let a = arrayDimension t in if a > 3 then error "Dynamic array with dimension > 4 is not supported." else 1 + arrayDimension t
- ArrayDecl _ _ -> error "Mixed dynamic array and static array are not supported."
- _ -> 0
-
-tvar2C f _ _ _ (OperatorDeclaration op (Identifier i _) inline ret params body) = do
- r <- op2CTyped op (extractTypes params)
- fun2C f i (FunctionDeclaration r inline ret params body)
-
-
-op2CTyped :: String -> [TypeDecl] -> State RenderState Identifier
-op2CTyped op t = do
- t' <- liftM (render . hcat . punctuate (char '_') . map (\t -> t empty)) $ mapM type2C t
- bt <- gets lastType
- return $ Identifier (t' ++ "_op_" ++ opStr) bt
- where
- opStr = case op of
- "+" -> "add"
- "-" -> "sub"
- "*" -> "mul"
- "/" -> "div"
- "/(float)" -> "div"
- "=" -> "eq"
- "<" -> "lt"
- ">" -> "gt"
- "<>" -> "neq"
- _ -> error $ "op2CTyped: unknown op '" ++ op ++ "'"
-
-extractTypes :: [TypeVarDeclaration] -> [TypeDecl]
-extractTypes = concatMap f
- where
- f (VarDeclaration _ _ (ids, t) _) = replicate (length ids) t
- f a = error $ "extractTypes: can't extract from " ++ show a
-
-initExpr2C, initExpr2C' :: InitExpression -> State RenderState Doc
-initExpr2C (InitArray values) = liftM (braces . vcat . punctuate comma) $ mapM initExpr2C values
-initExpr2C a = initExpr2C' a
-initExpr2C' InitNull = return $ text "NULL"
-initExpr2C' (InitAddress expr) = do
- ie <- initExpr2C' expr
- lt <- gets lastType
- case lt of
- BTFunction True _ _ -> return $ text "&" <> ie <> text "__vars"
- _ -> return $ text "&" <> ie
-initExpr2C' (InitPrefixOp op expr) = liftM (text (op2C op) <>) (initExpr2C' expr)
-initExpr2C' (InitBinOp op expr1 expr2) = do
- e1 <- initExpr2C' expr1
- e2 <- initExpr2C' expr2
- return $ parens $ e1 <+> text (op2C op) <+> e2
-initExpr2C' (InitNumber s) = return $ text s
-initExpr2C' (InitFloat s) = return $ text s
-initExpr2C' (InitHexNumber s) = return $ text "0x" <> (text . map toLower $ s)
-initExpr2C' (InitString [a]) = return . quotes $ text [a]
-initExpr2C' (InitString s) = return $ strInit s
-initExpr2C' (InitChar a) = return $ quotes $ text "\\x" <> text (showHex (read a) "")
-initExpr2C' (InitReference i) = id2C IOLookup i
-initExpr2C' (InitRecord fields) = do
- (fs :: [Doc]) <- mapM (\(Identifier a _, b) -> liftM (text "." <> text a <+> equals <+>) $ initExpr2C b) fields
- return $ lbrace $+$ (nest 4 . vcat . punctuate comma $ fs) $+$ rbrace
-initExpr2C' (InitArray [value]) = initExpr2C value
-initExpr2C' r@(InitRange (Range i@(Identifier i' _))) = do
- id2C IOLookup i
- t <- gets lastType
- case t of
- BTEnum s -> return . int $ length s
- BTInt -> case i' of
- "byte" -> return $ int 256
- _ -> error $ "InitRange identifier: " ++ i'
- _ -> error $ "InitRange: " ++ show r
-initExpr2C' (InitRange (RangeFromTo (InitNumber "0") r)) = initExpr2C $ BuiltInFunction "succ" [r]
-initExpr2C' (InitRange (RangeFromTo (InitChar "0") (InitChar r))) = initExpr2C $ BuiltInFunction "succ" [InitNumber r]
-initExpr2C' (InitRange a) = error $ show a --return $ text "<<range>>"
-initExpr2C' (InitSet []) = return $ text "0"
-initExpr2C' (InitSet a) = return $ text "<<set>>"
-initExpr2C' (BuiltInFunction "low" [InitReference e]) = return $
- case e of
- (Identifier "LongInt" _) -> int (-2^31)
- (Identifier "SmallInt" _) -> int (-2^15)
- _ -> error $ "BuiltInFunction 'low': " ++ show e
-initExpr2C' (BuiltInFunction "high" [e]) = do
- initExpr2C e
- t <- gets lastType
- case t of
- (BTArray i _ _) -> initExpr2C' $ BuiltInFunction "pred" [InitRange i]
- a -> error $ "BuiltInFunction 'high': " ++ show a
-initExpr2C' (BuiltInFunction "succ" [BuiltInFunction "pred" [e]]) = initExpr2C' e
-initExpr2C' (BuiltInFunction "pred" [BuiltInFunction "succ" [e]]) = initExpr2C' e
-initExpr2C' (BuiltInFunction "succ" [e]) = liftM (<> text " + 1") $ initExpr2C' e
-initExpr2C' (BuiltInFunction "pred" [e]) = liftM (<> text " - 1") $ initExpr2C' e
-initExpr2C' b@(BuiltInFunction _ _) = error $ show b
-initExpr2C' a = error $ "initExpr2C: don't know how to render " ++ show a
-
-
-range2C :: InitExpression -> State RenderState [Doc]
-range2C (InitString [a]) = return [quotes $ text [a]]
-range2C (InitRange (Range i)) = liftM (flip (:) []) $ id2C IOLookup i
-range2C (InitRange (RangeFromTo (InitString [a]) (InitString [b]))) = return $ map (\i -> quotes $ text [i]) [a..b]
-range2C a = liftM (flip (:) []) $ initExpr2C a
-
-baseType2C :: String -> BaseType -> Doc
-baseType2C _ BTFloat = text "float"
-baseType2C _ BTBool = text "bool"
-baseType2C _ BTString = text "string255"
-baseType2C s a = error $ "baseType2C: " ++ show a ++ "\n" ++ s
-
-type2C :: TypeDecl -> State RenderState (Doc -> Doc)
-type2C (SimpleType i) = liftM (\i a -> i <+> a) $ id2C IOLookup i
-type2C t = do
- r <- type2C' t
- rt <- resolveType t
- modify (\st -> st{lastType = rt})
- return r
- where
- type2C' VoidType = return (text "void" <+>)
- type2C' (String l) = return (text "string255" <+>)--return (text ("string" ++ show l) <+>)
- type2C' (PointerTo (SimpleType i)) = do
- i' <- id2C IODeferred i
- lt <- gets lastType
- case lt of
- BTRecord _ _ -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
- BTUnknown -> return $ \a -> text "struct __" <> i' <+> text "*" <+> a
- _ -> return $ \a -> i' <+> text "*" <+> a
- type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t
- type2C' (RecordType tvs union) = do
- t <- withState' f $ mapM (tvar2C False False True False) tvs
- u <- unions
- return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i
- where
- f s = s{currentUnit = ""}
- unions = case union of
- Nothing -> return empty
- Just a -> do
- structs <- mapM struct2C a
- return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi
- struct2C tvs = do
- t <- withState' f $ mapM (tvar2C False False True False) tvs
- return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi
- type2C' (RangeType r) = return (text "int" <+>)
- type2C' (Sequence ids) = do
- is <- mapM (id2C IOInsert . setBaseType bt) ids
- return (text "enum" <+> (braces . vcat . punctuate comma . map (\(a, b) -> a <+> equals <+> text "0x" <> text (showHex b "")) $ zip is [0..]) <+>)
- where
- bt = BTEnum $ map (\(Identifier i _) -> map toLower i) ids
- type2C' (ArrayDecl Nothing t) = type2C (PointerTo t)
- type2C' (ArrayDecl (Just r) t) = do
- t' <- type2C t
- lt <- gets lastType
- ft <- case lt of
- -- BTFunction {} -> type2C (PointerTo t)
- _ -> return t'
- r' <- initExpr2C (InitRange r)
- return $ \i -> ft i <> brackets r'
- type2C' (Set t) = return (text "<<set>>" <+>)
- type2C' (FunctionType returnType params) = do
- t <- type2C returnType
- p <- withState' id $ functionParams2C params
- return (\i -> (t empty <> (parens $ text "*" <> i) <> parens p))
- type2C' (DeriveType (InitBinOp _ _ i)) = type2C' (DeriveType i)
- type2C' (DeriveType (InitPrefixOp _ i)) = type2C' (DeriveType i)
- type2C' (DeriveType (InitNumber _)) = return (text "int" <+>)
- type2C' (DeriveType (InitHexNumber _)) = return (text "int" <+>)
- type2C' (DeriveType (InitFloat _)) = return (text "float" <+>)
- type2C' (DeriveType (BuiltInFunction {})) = return (text "int" <+>)
- type2C' (DeriveType (InitString {})) = return (text "string255" <+>)
- type2C' (DeriveType r@(InitReference {})) = do
- initExpr2C r
- t <- gets lastType
- return (baseType2C (show r) t <+>)
- type2C' (DeriveType a) = error $ "Can't derive type from " ++ show a
-
-phrase2C :: Phrase -> State RenderState Doc
-phrase2C (Phrases p) = do
- ps <- mapM phrase2C p
- return $ text "{" $+$ (nest 4 . vcat $ ps) $+$ text "}"
-phrase2C (ProcCall f@(FunCall {}) []) = liftM (<> semi) $ ref2C f
-phrase2C (ProcCall ref []) = liftM (<> semi) $ ref2CF ref
-phrase2C (ProcCall ref params) = error $ "ProcCall"{-do
- r <- ref2C ref
- ps <- mapM expr2C params
- return $ r <> parens (hsep . punctuate (char ',') $ ps) <> semi -}
-phrase2C (IfThenElse (expr) phrase1 mphrase2) = do
- e <- expr2C expr
- p1 <- (phrase2C . wrapPhrase) phrase1
- el <- elsePart
- return $
- text "if" <> parens e $+$ p1 $+$ el
- where
- elsePart | isNothing mphrase2 = return $ empty
- | otherwise = liftM (text "else" $$) $ (phrase2C . wrapPhrase) (fromJust mphrase2)
-phrase2C (Assignment ref expr) = do
- r <- ref2C ref
- t <- gets lastType
- case (t, expr) of
- (BTFunction {}, (Reference r')) -> do
- e <- ref2C r'
- return $ r <+> text "=" <+> e <> semi
- (BTString, _) -> do
- e <- expr2C expr
- lt <- gets lastType
- case lt of
- -- assume pointer to char for simplicity
- BTPointerTo _ -> do
- e <- expr2C $ Reference $ FunCall [Reference $ RefExpression expr] (SimpleReference (Identifier "pchar2str" BTUnknown))
- return $ r <+> text "=" <+> e <> semi
- BTString -> do
- e <- expr2C expr
- return $ r <+> text "=" <+> e <> semi
- _ -> error $ "Assignment to string from " ++ show lt
- (BTArray _ _ _, _) -> do
- case expr of
- Reference er -> do
- exprRef <- ref2C er
- exprT <- gets lastType
- case exprT of
- BTArray RangeInfinite _ _ ->
- return $ text "FIXME: assign a dynamic array to an array"
- BTArray _ _ _ -> phrase2C $
- ProcCall (FunCall
- [
- Reference $ ref
- , Reference $ RefExpression expr
- , Reference $ FunCall [expr] (SimpleReference (Identifier "sizeof" BTUnknown))
- ]
- (SimpleReference (Identifier "memcpy" BTUnknown))
- ) []
- _ -> return $ text "FIXME: assign a non-specific value to an array"
-
- _ -> return $ text "FIXME: dynamic array assignment 2"
- _ -> do
- e <- expr2C expr
- return $ r <+> text "=" <+> e <> semi
-phrase2C (WhileCycle expr phrase) = do
- e <- expr2C expr
- p <- phrase2C $ wrapPhrase phrase
- return $ text "while" <> parens e $$ p
-phrase2C (SwitchCase expr cases mphrase) = do
- e <- expr2C expr
- cs <- mapM case2C cases
- d <- dflt
- return $
- text "switch" <> parens e $+$ braces (nest 4 . vcat $ cs ++ d)
- where
- case2C :: ([InitExpression], Phrase) -> State RenderState Doc
- case2C (e, p) = do
- ies <- mapM range2C e
- ph <- phrase2C p
- return $
- vcat (map (\i -> text "case" <+> i <> colon) . concat $ ies) <> nest 4 (ph $+$ text "break;")
- dflt | isNothing mphrase = return [text "default: break;"] -- avoid compiler warning
- | otherwise = do
- ph <- mapM phrase2C $ fromJust mphrase
- return [text "default:" <+> nest 4 (vcat ph)]
-
-phrase2C wb@(WithBlock ref p) = do
- r <- ref2C ref
- t <- gets lastType
- case t of
- (BTRecord _ rs) -> withRecordNamespace (render r ++ ".") (rec2Records rs) $ phrase2C $ wrapPhrase p
- a -> do
- error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb
-phrase2C (ForCycle i' e1' e2' p up) = do
- i <- id2C IOLookup i'
- iType <- gets lastIdTypeDecl
- e1 <- expr2C e1'
- e2 <- expr2C e2'
- let inc = if up then "inc" else "dec"
- let add = if up then "+ 1" else "- 1"
- let iEnd = i <> text "__end__"
- ph <- phrase2C . appendPhrase (BuiltInFunctionCall [Reference $ SimpleReference i'] (SimpleReference (Identifier inc BTUnknown))) $ wrapPhrase p
- return . braces $
- i <+> text "=" <+> e1 <> semi
- $$
- iType <+> iEnd <+> text "=" <+> e2 <> semi
- $$
- text "if" <+> (parens $ i <+> text "<=" <+> iEnd) <+> text "do" <+> ph <+>
- text "while" <> parens (i <+> text "!=" <+> iEnd <+> text add) <> semi
- where
- appendPhrase p (Phrases ps) = Phrases $ ps ++ [p]
-phrase2C (RepeatCycle e' p') = do
- e <- expr2C e'
- p <- phrase2C (Phrases p')
- return $ text "do" <+> p <+> text "while" <> parens (text "!" <> parens e) <> semi
-phrase2C NOP = return $ text ";"
-
-phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "exit" BTUnknown))) = do
- f <- gets currentFunctionResult
- if null f then
- return $ text "return" <> semi
- else
- return $ text "return" <+> text f <> semi
-phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "break" BTUnknown))) = return $ text "break" <> semi
-phrase2C (BuiltInFunctionCall [] (SimpleReference (Identifier "continue" BTUnknown))) = return $ text "continue" <> semi
-phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "exit" BTUnknown))) = liftM (\e -> text "return" <+> e <> semi) $ expr2C e
-phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "dec" BTUnknown))) = liftM (\e -> text "--" <> e <> semi) $ expr2C e
-phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "dec" BTUnknown))) = liftM2 (\a b -> a <> text " -= " <> b <> semi) (expr2C e1) (expr2C e2)
-phrase2C (BuiltInFunctionCall [e] (SimpleReference (Identifier "inc" BTUnknown))) = liftM (\e -> text "++" <> e <> semi) $ expr2C e
-phrase2C (BuiltInFunctionCall [e1, e2] (SimpleReference (Identifier "inc" BTUnknown))) = liftM2 (\a b -> a <+> text "+=" <+> b <> semi) (expr2C e1) (expr2C e2)
-phrase2C a = error $ "phrase2C: " ++ show a
-
-wrapPhrase p@(Phrases _) = p
-wrapPhrase p = Phrases [p]
-
-expr2C :: Expression -> State RenderState Doc
-expr2C (Expression s) = return $ text s
-expr2C b@(BinOp op expr1 expr2) = do
- e1 <- expr2C expr1
- t1 <- gets lastType
- e2 <- expr2C expr2
- t2 <- gets lastType
- case (op2C op, t1, t2) of
- ("+", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strconcat" (BTFunction False 2 BTString))
- ("+", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strappend" (BTFunction False 2 BTString))
- ("+", BTChar, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strprepend" (BTFunction False 2 BTString))
- ("+", BTChar, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_chrconcat" (BTFunction False 2 BTString))
- ("==", BTString, BTChar) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcomparec" (BTFunction False 2 BTBool))
- ("==", BTString, BTString) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strcompare" (BTFunction False 2 BTBool))
- ("!=", BTString, _) -> expr2C $ BuiltInFunCall [expr1, expr2] (SimpleReference $ Identifier "_strncompare" (BTFunction False 2 BTBool))
- ("&", BTBool, _) -> return $ parens e1 <+> text "&&" <+> parens e2
- ("|", BTBool, _) -> return $ parens e1 <+> text "||" <+> parens e2
- (_, BTRecord t1 _, BTRecord t2 _) -> do
- i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier t2 undefined)]
- ref2C $ FunCall [expr1, expr2] (SimpleReference i)
- (_, BTRecord t1 _, BTInt) -> do
- -- aw, "LongInt" here is hwengine-specific hack
- i <- op2CTyped op [SimpleType (Identifier t1 undefined), SimpleType (Identifier "LongInt" undefined)]
- ref2C $ FunCall [expr1, expr2] (SimpleReference i)
- ("in", _, _) ->
- case expr2 of
- SetExpression set -> do
- ids <- mapM (id2C IOLookup) set
- modify(\s -> s{lastType = BTBool})
- return . parens . hcat . punctuate (text " || ") . map (\i -> parens $ e1 <+> text "==" <+> i) $ ids
- _ -> error "'in' against not set expression"
- (o, _, _) | o `elem` boolOps -> do
- modify(\s -> s{lastType = BTBool})
- return $ parens e1 <+> text o <+> parens e2
- | otherwise -> do
- o' <- return $ case o of
- "/(float)" -> text "/(float)" -- pascal returns real value
- _ -> text o
- e1' <- return $ case (o, t1, t2) of
- ("-", BTInt, BTInt) -> parens $ text "(int64_t)" <+> parens e1
- _ -> parens e1
- e2' <- return $ case (o, t1, t2) of
- ("-", BTInt, BTInt) -> parens $ text "(int64_t)" <+> parens e2
- _ -> parens e2
- return $ e1' <+> o' <+> e2'
- where
- boolOps = ["==", "!=", "<", ">", "<=", ">="]
-expr2C (NumberLiteral s) = do
- modify(\s -> s{lastType = BTInt})
- return $ text s
-expr2C (FloatLiteral s) = return $ text s
-expr2C (HexNumber s) = return $ text "0x" <> (text . map toLower $ s)
-{-expr2C (StringLiteral [a]) = do
- modify(\s -> s{lastType = BTChar})
- return . quotes . text $ escape a
- where
- escape '\'' = "\\\'"
- escape a = [a]-}
-expr2C (StringLiteral s) = addStringConst s
-expr2C (PCharLiteral s) = return . doubleQuotes $ text s
-expr2C (Reference ref) = ref2CF ref
-expr2C (PrefixOp op expr) = do
- e <- expr2C expr
- lt <- gets lastType
- case lt of
- BTRecord t _ -> do
- i <- op2CTyped op [SimpleType (Identifier t undefined)]
- ref2C $ FunCall [expr] (SimpleReference i)
- BTBool -> do
- o <- return $ case op of
- "not" -> text "!"
- _ -> text (op2C op)
- return $ o <> parens e
- _ -> return $ text (op2C op) <> parens e
-expr2C Null = return $ text "NULL"
-expr2C (CharCode a) = do
- modify(\s -> s{lastType = BTChar})
- return $ quotes $ text "\\x" <> text (showHex (read a) "")
-expr2C (HexCharCode a) = if length a <= 2 then return $ quotes $ text "\\x" <> text (map toLower a) else expr2C $ HexNumber a
-expr2C (SetExpression ids) = mapM (id2C IOLookup) ids >>= return . parens . hcat . punctuate (text " | ")
-
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "low" _))) = do
- e' <- liftM (map toLower . render) $ expr2C e
- lt <- gets lastType
- case lt of
- BTEnum a -> return $ int 0
- BTInt -> case e' of
- "longint" -> return $ int (-2147483648)
- BTArray {} -> return $ int 0
- _ -> error $ "BuiltInFunCall 'low' from " ++ show e ++ "\ntype: " ++ show lt
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "high" _))) = do
- e' <- liftM (map toLower . render) $ expr2C e
- lt <- gets lastType
- case lt of
- BTEnum a -> return . int $ length a - 1
- BTInt -> case e' of
- "longint" -> return $ int (2147483647)
- BTString -> return $ int 255
- BTArray (RangeFromTo _ n) _ _ -> initExpr2C n
- _ -> error $ "BuiltInFunCall 'high' from " ++ show e ++ "\ntype: " ++ show lt
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - (int64_t)1") $ expr2C e
-expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "length" _))) = do
- e' <- expr2C e
- lt <- gets lastType
- modify (\s -> s{lastType = BTInt})
- case lt of
- BTString -> return $ text "fpcrtl_Length" <> parens e'
- BTArray RangeInfinite _ _ -> error $ "length() called on variable size array " ++ show e'
- BTArray (RangeFromTo _ n) _ _ -> initExpr2C (BuiltInFunction "succ" [n])
- _ -> error $ "length() called on " ++ show lt
-expr2C (BuiltInFunCall params ref) = do
- r <- ref2C ref
- t <- gets lastType
- ps <- mapM expr2C params
- case t of
- BTFunction _ _ t' -> do
- modify (\s -> s{lastType = t'})
- _ -> error $ "BuiltInFunCall lastType: " ++ show t
- return $
- r <> parens (hsep . punctuate (char ',') $ ps)
-expr2C a = error $ "Don't know how to render " ++ show a
-
-ref2CF :: Reference -> State RenderState Doc
-ref2CF (SimpleReference name) = do
- i <- id2C IOLookup name
- t <- gets lastType
- case t of
- BTFunction _ _ rt -> do
- modify(\s -> s{lastType = rt})
- return $ i <> parens empty --xymeng: removed parens
- _ -> return $ i
-ref2CF r@(RecordField (SimpleReference _) (SimpleReference _)) = do
- i <- ref2C r
- t <- gets lastType
- case t of
- BTFunction _ _ rt -> do
- modify(\s -> s{lastType = rt})
- return $ i <> parens empty
- _ -> return $ i
-ref2CF r = ref2C r
-
-ref2C :: Reference -> State RenderState Doc
--- rewrite into proper form
-ref2C (RecordField ref1 (ArrayElement exprs ref2)) = ref2C $ ArrayElement exprs (RecordField ref1 ref2)
-ref2C (RecordField ref1 (Dereference ref2)) = ref2C $ Dereference (RecordField ref1 ref2)
-ref2C (RecordField ref1 (RecordField ref2 ref3)) = ref2C $ RecordField (RecordField ref1 ref2) ref3
-ref2C (RecordField ref1 (FunCall params ref2)) = ref2C $ FunCall params (RecordField ref1 ref2)
-ref2C (ArrayElement (a:b:xs) ref) = ref2C $ ArrayElement (b:xs) (ArrayElement [a] ref)
--- conversion routines
-ref2C ae@(ArrayElement [expr] ref) = do
- e <- expr2C expr
- r <- ref2C ref
- t <- gets lastType
- case t of
- (BTArray _ _ t') -> modify (\st -> st{lastType = t'})
--- (BTFunctionReturn _ (BTArray _ _ t')) -> modify (\st -> st{lastType = t'})
--- (BTFunctionReturn _ (BTString)) -> modify (\st -> st{lastType = BTChar})
- (BTString) -> modify (\st -> st{lastType = BTChar})
- (BTPointerTo t) -> do
- t'' <- fromPointer (show t) =<< gets lastType
- case t'' of
- BTChar -> modify (\st -> st{lastType = BTChar})
- a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
- a -> error $ "Getting element of " ++ show a ++ "\nReference: " ++ show ae
- case t of
- BTString -> return $ r <> text ".s" <> brackets e
- _ -> return $ r <> brackets e
-ref2C (SimpleReference name) = id2C IOLookup name
-ref2C rf@(RecordField (Dereference ref1) ref2) = do
- r1 <- ref2C ref1
- t <- fromPointer (show ref1) =<< gets lastType
- r2 <- case t of
- BTRecord _ rs -> withRecordNamespace "" (rec2Records rs) $ ref2C ref2
- BTUnit -> error "What??"
- a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf
- return $
- r1 <> text "->" <> r2
-ref2C rf@(RecordField ref1 ref2) = do
- r1 <- ref2C ref1
- t <- gets lastType
- case t of
- BTRecord _ rs -> do
- r2 <- withRecordNamespace "" (rec2Records rs) $ ref2C ref2
- return $ r1 <> text "." <> r2
- BTUnit -> withLastIdNamespace $ ref2C ref2
- a -> error $ "dereferencing from " ++ show a ++ "\n" ++ show rf
-ref2C d@(Dereference ref) = do
- r <- ref2C ref
- t <- fromPointer (show d) =<< gets lastType
- modify (\st -> st{lastType = t})
- return $ (parens $ text "*" <> r)
-ref2C f@(FunCall params ref) = do
- r <- fref2C ref
- t <- gets lastType
- case t of
- BTFunction _ _ t' -> do
- ps <- liftM (parens . hsep . punctuate (char ',')) $ mapM expr2C params
- modify (\s -> s{lastType = t'})
- return $ r <> ps
- _ -> case (ref, params) of
- (SimpleReference i, [p]) -> ref2C $ TypeCast i p
- _ -> error $ "ref2C FunCall erroneous type cast detected: " ++ show f ++ "\nType detected: " ++ show t
- where
- fref2C (SimpleReference name) = id2C (IOLookupFunction $ length params) name
- fref2C a = ref2C a
-
-ref2C (Address ref) = do
- r <- ref2C ref
- lt <- gets lastType
- case lt of
- BTFunction True _ _ -> return $ text "&" <> parens (r <> text "__vars")
- _ -> return $ text "&" <> parens r
-ref2C (TypeCast t'@(Identifier i _) expr) = do
- lt <- expr2C expr >> gets lastType
- case (map toLower i, lt) of
- ("pchar", BTString) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "_pchar" $ BTPointerTo BTChar))
- ("shortstring", BTPointerTo _) -> ref2C $ FunCall [expr] (SimpleReference (Identifier "pchar2str" $ BTString))
- (a, _) -> do
- e <- expr2C expr
- t <- id2C IOLookup t'
- return . parens $ parens t <> e
-ref2C (RefExpression expr) = expr2C expr
-
-
-op2C :: String -> String
-op2C "or" = "|"
-op2C "and" = "&"
-op2C "not" = "~"
-op2C "xor" = "^"
-op2C "div" = "/"
-op2C "mod" = "%"
-op2C "shl" = "<<"
-op2C "shr" = ">>"
-op2C "<>" = "!="
-op2C "=" = "=="
-op2C "/" = "/(float)"
-op2C a = a
-
diff --git a/tools/unitCycles.hs b/tools/unitCycles.hs
deleted file mode 100644
index 2d5571c..0000000
--- a/tools/unitCycles.hs
+++ /dev/null
@@ -1,46 +0,0 @@
-module Main where
-
-import PascalParser
-import System
-import Control.Monad
-import Data.Either
-import Data.List
-import Data.Graph
-import Data.Maybe
-
-unident :: Identificator -> String
-unident (Identificator s) = s
-
-extractUnits :: PascalUnit -> (String, [String])
-extractUnits (Program (Identificator name) (Implementation (Uses idents) _ _) _) = ("program " ++ name, map unident idents)
-extractUnits (Unit (Identificator name) (Interface (Uses idents1) _) (Implementation (Uses idents2) _ _) _ _) = (name, map unident $ idents1 ++ idents2)
-
-f :: [(String, [String])] -> String
-f = unlines . map showSCC . stronglyConnComp . map (\(a, b) -> (a, a, b))
- where
- showSCC (AcyclicSCC v) = v
- showSCC (CyclicSCC vs) = intercalate ", " vs
-
-myf :: [(String, [String])] -> String
-myf d = unlines . map (findCycle . fst) $ d
- where
- findCycle :: String -> String
- findCycle searched = searched ++ ": " ++ (intercalate ", " $ fc searched [])
- where
- fc :: String -> [String] -> [String]
- fc curSearch visited = let uses = curSearch `lookup` d; res = dropWhile null . map t $ fromJust uses in if isNothing uses || null res then [] else head res
- where
- t u =
- if u == searched then
- [u]
- else
- if u `elem` visited then
- []
- else
- let chain = fc u (u:visited) in if null chain then [] else u:chain
-
-
-main = do
- fileNames <- getArgs
- files <- mapM readFile fileNames
- putStrLn . myf . map extractUnits . rights . map parsePascalUnit $ files
diff --git a/tools/w32DownloadUnzip.vbs b/tools/w32DownloadUnzip.vbs
index cf3e9f2..fc970fd 100644
--- a/tools/w32DownloadUnzip.vbs
+++ b/tools/w32DownloadUnzip.vbs
@@ -7,6 +7,7 @@
' References
' http://superuser.com/questions/59465/is-it-possible-to-download-using-the-windows-command-line
' http://stackoverflow.com/questions/1021557/how-to-unzip-a-file-using-the-command-line
+' http://stackoverflow.com/questions/424331/get-the-current-temporary-directory-path-in-vbscript
Set ArgObj = WScript.Arguments
@@ -23,7 +24,8 @@ Else
End if
End if
-strHDLocation = "C:\Windows\Temp\temp.zip"
+' Temporary directory
+strHDLocation = WScript.CreateObject("Scripting.FileSystemObject").GetSpecialFolder(2) + "\hwlibtemp.zip"
' Fetch the file
WScript.Echo ( "Trying to download from " & strFileURL)
@@ -37,7 +39,7 @@ If objXMLHTTP.Status = 200 Then
objADOStream.Type = 1 'adTypeBinary
objADOStream.Write objXMLHTTP.ResponseBody
- objADOStream.Position = 0 'Set the stream position to the start
+ objADOStream.Position = 0 'Set the stream position to the start
Set objFSO = Createobject("Scripting.FileSystemObject")
If objFSO.Fileexists(strHDLocation) Then objFSO.DeleteFile strHDLocation
@@ -46,12 +48,12 @@ If objXMLHTTP.Status = 200 Then
objADOStream.SaveToFile strHDLocation
objADOStream.Close
Set objADOStream = Nothing
+ Set objXMLHTTP = Nothing
Else
WScript.Echo ("Error downloading file (error code: " & objXMLHTTP.Status & ")")
Set objXMLHTTP = Nothing
WScript.Quit
End if
-Set objXMLHTTP = Nothing
WScript.Echo ( "Extracting file to " & strOutputPath)
Set objShell = CreateObject( "Shell.Application" )
--
Worms style game
More information about the Pkg-games-commits
mailing list